Beispiel #1
0
/*
 * SCPD URL downloaded.
 */
static void
got_scpd_url (G_GNUC_UNUSED SoupSession *session,
              SoupMessage               *msg,
              GetSCPDURLData            *data)
{
        GUPnPServiceIntrospection *introspection;
        GError *error;
        GUPnPServiceInfoPrivate *priv;

        introspection = NULL;
        error = NULL;

        if (msg->status_code == SOUP_STATUS_CANCELLED)
                return;

        if (SOUP_STATUS_IS_SUCCESSFUL (msg->status_code)) {
                xmlDoc *scpd;

                scpd = xmlRecoverMemory (msg->response_body->data,
                                         msg->response_body->length);
                if (scpd) {
                        introspection = gupnp_service_introspection_new (scpd);

                        xmlFreeDoc (scpd);
                }

                if (!introspection) {
                        error = g_error_new
                                        (GUPNP_SERVER_ERROR,
                                         GUPNP_SERVER_ERROR_INVALID_RESPONSE,
                                         "Could not parse SCPD");
                }
        } else
                error = _gupnp_error_new_server_error (msg);

        /* prevent the callback from canceling the cancellable
         * (and so freeing data just before we do) */
        if (data->cancellable)
                g_cancellable_disconnect (data->cancellable,
                                          data->cancelled_id);

        priv = gupnp_service_info_get_instance_private (data->info);
        priv->pending_gets = g_list_remove (priv->pending_gets, data);

        data->callback (data->info,
                        introspection,
                        error,
                        data->user_data);

        if (error)
                g_error_free (error);

        get_scpd_url_data_free (data);
}
/*
 * SCPD URL downloaded.
 */
static void
got_scpd_url (SoupSession    *session,
              SoupMessage    *msg,
              GetSCPDURLData *data)
{
        GUPnPServiceIntrospection *introspection;
        GError *error;

        introspection = NULL;
        error = NULL;

        if (msg->status_code == SOUP_STATUS_CANCELLED)
                return;

        if (SOUP_STATUS_IS_SUCCESSFUL (msg->status_code)) {
                xmlDoc *scpd;

                scpd = xmlRecoverMemory (msg->response_body->data,
                                         msg->response_body->length);
                if (scpd) {
                        introspection = gupnp_service_introspection_new (scpd);

                        xmlFreeDoc (scpd);
                }

                if (!introspection) {
                        error = g_error_new
                                        (GUPNP_SERVER_ERROR,
                                         GUPNP_SERVER_ERROR_INVALID_RESPONSE,
                                         "Could not parse SCPD");
                }
        } else
                error = _gupnp_error_new_server_error (msg);

        data->info->priv->pending_gets =
                g_list_remove (data->info->priv->pending_gets, data);

        data->callback (data->info,
                        introspection,
                        error,
                        data->user_data);

        if (error)
                g_error_free (error);

        get_scpd_url_data_free (data);
}
/**
 * gupnp_service_info_get_introspection
 * @info: A #GUPnPServiceInfo
 * @error: return location for a #GError, or %NULL
 *
 * Note that introspection object is created from the information in service
 * description document (SCPD) provided by the service so it can not be created
 * if the service does not provide an SCPD.
 *
 * Warning: You  should use gupnp_service_info_get_introspection_async()
 * instead, this function re-enter the GMainloop before returning.
 *
 * Return value: (transfer full):  A new #GUPnPServiceIntrospection for this
 * service or %NULL. Unref after use.
 **/
GUPnPServiceIntrospection *
gupnp_service_info_get_introspection (GUPnPServiceInfo *info,
                                      GError          **error)
{
        GUPnPServiceIntrospection *introspection;
        SoupSession *session;
        SoupMessage *msg;
        int status;
        char *scpd_url;
        xmlDoc *scpd;

        g_return_val_if_fail (GUPNP_IS_SERVICE_INFO (info), NULL);

        introspection = NULL;

        scpd_url = gupnp_service_info_get_scpd_url (info);

        msg = NULL;
        if (scpd_url != NULL) {
                msg = soup_message_new (SOUP_METHOD_GET, scpd_url);

                g_free (scpd_url);
        }

        if (msg == NULL) {
                g_set_error (error,
                             GUPNP_SERVER_ERROR,
                             GUPNP_SERVER_ERROR_INVALID_URL,
                             "No valid SCPD URL defined");

                return NULL;
        }

        /* Send off the message */
        session = gupnp_context_get_session (info->priv->context);

        status = soup_session_send_message (session, msg);
        if (!SOUP_STATUS_IS_SUCCESSFUL (status)) {
                _gupnp_error_set_server_error (error, msg);

                g_object_unref (msg);

                return NULL;
        }

        scpd = xmlRecoverMemory (msg->response_body->data,
                                 msg->response_body->length);

        g_object_unref (msg);

        if (scpd) {
                introspection = gupnp_service_introspection_new (scpd);

                xmlFreeDoc (scpd);
        }

        if (!introspection) {
                g_set_error (error,
                             GUPNP_SERVER_ERROR,
                             GUPNP_SERVER_ERROR_INVALID_RESPONSE,
                             "Could not parse SCPD");
        }

        return introspection;
}