static void
server_callback (SoupServer        *server,
		 SoupMessage       *msg,
		 const char        *path,
		 GHashTable        *query,
		 SoupClientContext *client,
		 gpointer           user_data)
{
	RemoteDisplayHost *host = user_data;
	RemoteDisplayHostPrivate *priv = GET_PRIVATE (host);
	RemoteDisplayHostFile *file;

	if (!client_allowed (host, client)) {
		g_debug ("Client %s not allowed", soup_client_context_get_host (client));
		soup_message_set_status (msg, SOUP_STATUS_FORBIDDEN);
		return;
	}

	if (msg->method != SOUP_METHOD_GET &&
	    msg->method != SOUP_METHOD_HEAD) {
		g_debug ("Method is not GET or HEAD");
		soup_message_set_status (msg, SOUP_STATUS_NOT_IMPLEMENTED);
		return;
	}

	if (path == NULL || *path != '/') {
		g_debug ("Invalid path '%s'requested", path);
		soup_message_set_status (msg, SOUP_STATUS_NOT_FOUND);
		return;
	}

	file = g_hash_table_lookup (priv->files, path + 1);
	if (!file) {
		soup_message_set_status (msg, SOUP_STATUS_NOT_FOUND);
		return;
	}

	if (!file->mapped_file) {
		file->mapped_file = g_mapped_file_new (file->path, FALSE, NULL);
		if (!file->mapped_file) {
			soup_message_set_status (msg, SOUP_STATUS_NOT_FOUND);
			return;
		}
	}

	if (msg->method == SOUP_METHOD_GET) {
		soup_message_set_response (msg, file->mime_type,
					   SOUP_MEMORY_STATIC,
					   g_mapped_file_get_contents (file->mapped_file),
					   g_mapped_file_get_length (file->mapped_file));
	} else {
		soup_message_headers_set_content_type (msg->response_headers,
						       file->mime_type, NULL);

		soup_message_headers_set_content_length (msg->response_headers,
							 g_mapped_file_get_length (file->mapped_file));
	}

	soup_message_set_status(msg, SOUP_STATUS_OK);
}
// This callback will not be called if the content sniffer is disabled in startHttp.
static void contentSniffedCallback(SoupMessage* msg, const char* sniffedType, GHashTable *params, gpointer data)
{
    if (sniffedType) {
        const char* officialType = soup_message_headers_get_one(msg->response_headers, "Content-Type");

        if (!officialType || strcmp(officialType, sniffedType))
            soup_message_headers_set_content_type(msg->response_headers, sniffedType, params);
    }

    if (statusWillBeHandledBySoup(msg->status_code))
        return;

    RefPtr<ResourceHandle> handle = static_cast<ResourceHandle*>(data);
    if (!handle)
        return;
    ResourceHandleInternal* d = handle->getInternal();
    if (d->m_cancelled)
        return;
    ResourceHandleClient* client = handle->client();
    if (!client)
        return;

    fillResponseFromMessage(msg, &d->m_response);
    client->didReceiveResponse(handle.get(), d->m_response);
}
static void contentSniffedCallback(SoupMessage* msg, const char* sniffedType, GHashTable *params, gpointer data)
{
    if (sniffedType) {
        const char* officialType = soup_message_headers_get_one(msg->response_headers, "Content-Type");

        if (!officialType || strcmp(officialType, sniffedType))
            soup_message_headers_set_content_type(msg->response_headers, sniffedType, params);
    }

    // The 304 status code (SOUP_STATUS_NOT_MODIFIED) needs to be fed
    // into WebCore, as opposed to other kinds of redirections, which
    // are handled by soup directly, so we special-case it here and in
    // gotChunk.
    if (SOUP_STATUS_IS_TRANSPORT_ERROR(msg->status_code)
        || (SOUP_STATUS_IS_REDIRECTION(msg->status_code) && (msg->status_code != SOUP_STATUS_NOT_MODIFIED))
        || (msg->status_code == SOUP_STATUS_UNAUTHORIZED))
        return;

    RefPtr<ResourceHandle> handle = static_cast<ResourceHandle*>(data);
    if (!handle)
        return;
    ResourceHandleInternal* d = handle->getInternal();
    if (d->m_cancelled)
        return;
    ResourceHandleClient* client = handle->client();
    if (!client)
        return;

    fillResponseFromMessage(msg, &d->m_response);
    client->didReceiveResponse(handle.get(), d->m_response);
}
示例#4
0
void
soup_soap_message_persist (SoupSoapMessage *msg)
{
	g_return_if_fail (SOUP_SOAP_IS_MESSAGE (msg));

	xmlChar *buffer;
	const gchar *contents;

	SoupSoapMessagePrivate *priv = msg->priv;

	xmlDocPtr doc = xmlNewDoc (BAD_CAST "1.0");


	xmlNodePtr envelope_node = xmlNewNode (NULL, BAD_CAST "Envelope");
	xmlSetNs (envelope_node,
	          xmlNewNs (envelope_node,
	                    BAD_CAST SOAP_ENV_NAMESPACE,
	                    BAD_CAST "SOAP-ENV"));
	xmlNewNs (envelope_node,
	          BAD_CAST XSD_NAMESPACE,
	          BAD_CAST "xsd");
	xmlNewNs (envelope_node,
	          BAD_CAST XSI_NAMESPACE,
	          BAD_CAST "xsi");
	xmlNewNs (envelope_node,
	          BAD_CAST SOAP_ENC_NAMESPACE,
	          BAD_CAST "SOAP-ENC");
	xmlSetProp (envelope_node,
	            BAD_CAST "SOAP-ENV:encodingStyle",
	            BAD_CAST SOAP_ENCODING_STYLE);
	xmlDocSetRootElement (doc, envelope_node);

	create_param_node (doc, SOUP_SOAP_PARAM (priv->header), envelope_node);

	xmlNodePtr body_node = xmlNewChild (envelope_node, NULL, BAD_CAST "Body", NULL);
	create_param_node (doc, SOUP_SOAP_PARAM (priv->body), body_node);


	xmlDocDumpFormatMemoryEnc (doc, &buffer, NULL, "UTF-8", 0);

	contents = (gchar *) buffer;
	soup_message_body_truncate (priv->message_body);
	soup_message_body_append (priv->message_body, SOUP_MEMORY_COPY,
	                          contents, strlen (contents));
	soup_message_body_complete (priv->message_body);

	xmlFree (buffer);


	xmlFreeDoc (doc);


	soup_message_headers_set_content_type (priv->message_headers,
	                                       "text/xml", NULL);
}
示例#5
0
static gboolean
home_handler (VSGIRequest        *req,
              VSGIResponse       *res,
              ValumNextCallback   next,
              void               *next_user_data,
              ValumContext       *context,
              void               *user_data,
              GError            **error)
{
	soup_message_headers_set_content_type (vsgi_response_get_headers (res), "text/plain", NULL);
	return vsgi_response_expand_utf8 (res, "Hello world!", NULL, error);
}
示例#6
0
static
void
test_http_callback(
    SoupServer* server,
    SoupMessage* msg,
    const char* path,
    GHashTable* query,
    SoupClientContext* context,
    gpointer data)
{
    char* uri = soup_uri_to_string(soup_message_get_uri (msg), FALSE);
    MMS_VERBOSE("%s %s HTTP/1.%d", msg->method, uri,
        soup_message_get_http_version(msg));
    g_free(uri);
    if (msg->method == SOUP_METHOD_CONNECT) {
        soup_message_set_status(msg, SOUP_STATUS_NOT_IMPLEMENTED);
    } else {
        TestHttp* http = data;
        if (msg->request_body->length) {
            SoupBuffer* request = soup_message_body_flatten(msg->request_body);
            if (http->req_bytes) g_bytes_unref(http->req_bytes);
            http->req_bytes = g_bytes_new_with_free_func(request->data,
                request->length, (GDestroyNotify)soup_buffer_free, request);
        }
        soup_message_set_status(msg, http->resp_status);
        soup_message_headers_set_content_type(msg->response_headers,
            http->resp_content_type ? http->resp_content_type : "text/plain",
            NULL);
        soup_message_headers_append(msg->response_headers,
            "Accept-Ranges", "bytes");
        soup_message_headers_append(msg->response_headers,
            "Connection", "close");
        if (http->resp_file) {
            soup_message_headers_set_content_length(msg->response_headers,
                g_mapped_file_get_length(http->resp_file));
            soup_message_body_append(msg->response_body, SOUP_MEMORY_TEMPORARY,
                g_mapped_file_get_contents(http->resp_file),
                g_mapped_file_get_length(http->resp_file));
        } else {
            soup_message_headers_set_content_length(msg->response_headers, 0);
        }
    }
    soup_message_body_complete(msg->request_body);
}
示例#7
0
static void
korva_upnp_file_server_handle_request (SoupServer        *server,
                                       SoupMessage       *msg,
                                       const char        *path,
                                       GHashTable        *query,
                                       SoupClientContext *client,
                                       gpointer           user_data)
{
    KorvaUPnPFileServer *self = KORVA_UPNP_FILE_SERVER (user_data);
    GMatchInfo *info;
    char *id;
    GFile *file;
    KorvaUPnPHostData *data;
    ServeData *serve_data;
    SoupRange *ranges = NULL;
    int length;
    const char *content_features;
    GError *error = NULL;
    goffset size;

    if (msg->method != SOUP_METHOD_HEAD &&
        msg->method != SOUP_METHOD_GET) {
        soup_message_set_status (msg, SOUP_STATUS_METHOD_NOT_ALLOWED);

        return;
    }

    g_debug ("Got %s request for uri: %s", msg->method, path);
    soup_message_headers_foreach (msg->request_headers, print_header, NULL);

    soup_server_pause_message (server, msg);
    soup_message_set_status (msg, SOUP_STATUS_OK);

    if (!g_regex_match (self->priv->path_regex,
                        path,
                        0,
                        &info)) {
        soup_message_set_status (msg, SOUP_STATUS_NOT_FOUND);
        g_match_info_free (info);

        goto out;
    }

    id = g_match_info_fetch (info, 1);
    g_match_info_free (info);

    file = g_hash_table_lookup (self->priv->id_map, id);
    g_free (id);

    if (file == NULL) {
        soup_message_set_status (msg, SOUP_STATUS_NOT_FOUND);

        goto out;
    }

    data = g_hash_table_lookup (self->priv->host_data, file);
    if (data == NULL) {
        soup_message_set_status (msg, SOUP_STATUS_NOT_FOUND);

        goto out;
    }

    if (!korva_upnp_host_data_valid_for_peer (data, soup_client_context_get_host (client))) {
        soup_message_set_status (msg, SOUP_STATUS_NOT_FOUND);

        goto out;
    }

    serve_data = g_slice_new0 (ServeData);
    serve_data->host_data = data;
    g_object_add_weak_pointer (G_OBJECT (data), (gpointer *) &(serve_data->host_data));
    korva_upnp_host_data_add_request (data);
    size = korva_upnp_host_data_get_size (data);
    if (soup_message_headers_get_ranges (msg->request_headers, size, &ranges, &length)) {
        goffset start, end;
        start = ranges[0].start;
        end = ranges[0].end;

        if (start > size || start > end || end > size) {
            soup_message_set_status (msg, SOUP_STATUS_REQUESTED_RANGE_NOT_SATISFIABLE);
            g_slice_free (ServeData, serve_data);

            goto out;
        } else {
            soup_message_set_status (msg, SOUP_STATUS_PARTIAL_CONTENT);
            soup_message_headers_set_content_range (msg->response_headers, start, end, size);
        }
        serve_data->start = start;
        serve_data->end = end;
    } else {
        serve_data->start = 0;
        serve_data->end = size - 1;
        soup_message_set_status (msg, SOUP_STATUS_OK);
    }

    soup_message_headers_set_content_length (msg->response_headers,
                                             serve_data->end - serve_data->start + 1);
    soup_message_headers_set_content_type (msg->response_headers,
                                           korva_upnp_host_data_get_content_type (data),
                                           NULL);

    content_features = soup_message_headers_get_one (msg->request_headers,
                                                     "getContentFeatures.dlna.org");
    if (content_features != NULL && atol (content_features) == 1) {
        const GVariant *value;

        value = korva_upnp_host_data_lookup_meta_data (data, "DLNAProfile");
        if (value == NULL) {
            soup_message_headers_append (msg->response_headers,
                                         "contentFeatures.dlna.org", "*");
        } else {
            soup_message_headers_append (msg->response_headers,
                                         "contentFeatures.dlna.org",
                                         korva_upnp_host_data_get_protocol_info (data));
        }
    }

    soup_message_headers_append (msg->response_headers, "Connection", "close");

    g_debug ("Response headers:");
    soup_message_headers_foreach (msg->response_headers, print_header, NULL);

    if (g_ascii_strcasecmp (msg->method, "HEAD") == 0) {
        g_debug ("Handled HEAD request of %s: %d", path, msg->status_code);
        g_slice_free (ServeData, serve_data);

        goto out;
    }

    soup_message_headers_set_encoding (msg->response_headers, SOUP_ENCODING_CONTENT_LENGTH);
    soup_message_body_set_accumulate (msg->response_body, FALSE);

    serve_data->stream = G_INPUT_STREAM (g_file_read (file, NULL, &error));
    serve_data->server = server;
    if (error != NULL) {
        g_warning ("Failed to MMAP file %s: %s",
                   path,
                   error->message);

        g_error_free (error);
        g_slice_free (ServeData, serve_data);

        soup_message_set_status (msg, SOUP_STATUS_INTERNAL_SERVER_ERROR);

        goto out;
    }
    g_seekable_seek (G_SEEKABLE (serve_data->stream), serve_data->start, G_SEEK_SET, NULL, NULL);

    /* Drop timeout until the message is done */
    korva_upnp_host_data_cancel_timeout (data);

    g_signal_connect (msg,
                      "wrote-chunk",
                      G_CALLBACK (korva_upnp_file_server_on_wrote_chunk),
                      serve_data);
    g_signal_connect (msg,
                      "wrote-headers",
                      G_CALLBACK (korva_upnp_file_server_on_wrote_chunk),
                      serve_data);
    g_signal_connect (msg,
                      "finished",
                      G_CALLBACK (korva_upnp_file_server_on_finished),
                      serve_data);

out:
    if (ranges != NULL) {
        soup_message_headers_free_ranges (msg->request_headers, ranges);
    }

    soup_server_unpause_message (server, msg);
}
示例#8
0
static void prv_soup_server_cb(SoupServer *server, SoupMessage *msg,
			       const char *path, GHashTable *query,
			       SoupClientContext *client, gpointer user_data)
{
	dlr_host_file_t *hf;
	dlr_host_server_t *hs = user_data;
	const gchar *file_name;
	const char *hdr;

	if ((msg->method != SOUP_METHOD_GET) &&
	    (msg->method != SOUP_METHOD_HEAD)) {
		soup_message_set_status(msg, SOUP_STATUS_NOT_IMPLEMENTED);
		goto on_error;
	}

	hf = prv_host_server_find_file(hs, path, &file_name);

	if (!hf) {
		soup_message_set_status(msg, SOUP_STATUS_NOT_FOUND);
		goto on_error;
	}

	hdr = soup_message_headers_get_one(msg->request_headers,
					   "getContentFeatures.dlna.org");

	if (hdr) {
		if (strcmp(hdr, "1") != 0) {
			soup_message_set_status(msg, SOUP_STATUS_BAD_REQUEST);
			goto on_error;
		}

		if ((hf->dlna_header) && strlen(hf->dlna_header) > 0)
			soup_message_headers_append(msg->response_headers,
						    "contentFeatures.dlna.org",
						    hf->dlna_header);
	}

	if (hf->mapped_file) {
		g_mapped_file_ref(hf->mapped_file);
		++hf->mapped_count;
	} else {
		hf->mapped_file = g_mapped_file_new(file_name,
						    FALSE,
						    NULL);

		if (!hf->mapped_file) {
			soup_message_set_status(msg,
						SOUP_STATUS_NOT_FOUND);
			goto on_error;
		}

		hf->mapped_count = 1;
	}

	if (msg->method == SOUP_METHOD_GET) {
		g_signal_connect(msg, "finished",
				 G_CALLBACK(prv_soup_message_finished_cb), hf);

		soup_message_set_response(
				msg, hf->mime_type,
				SOUP_MEMORY_STATIC,
				g_mapped_file_get_contents(hf->mapped_file),
				g_mapped_file_get_length(hf->mapped_file));
	} else {
		soup_message_headers_set_content_type(msg->response_headers,
						      hf->mime_type, NULL);

		soup_message_headers_set_content_length(
			msg->response_headers,
			g_mapped_file_get_length(hf->mapped_file));
	}

	soup_message_set_status(msg, SOUP_STATUS_OK);

on_error:

	return;
}