Ejemplo n.º 1
0
static void
server_callback (SoupServer *server, SoupMessage *msg,
		 const char *path, GHashTable *query,
		 SoupClientContext *context, gpointer data)
{
	char *file_path;
	SoupMessageHeadersIter iter;
	const char *name, *value;

	g_print ("%s %s HTTP/1.%d\n", msg->method, path,
		 soup_message_get_http_version (msg));
	soup_message_headers_iter_init (&iter, msg->request_headers);
	while (soup_message_headers_iter_next (&iter, &name, &value))
		g_print ("%s: %s\n", name, value);
	if (msg->request_body->length)
		g_print ("%s\n", msg->request_body->data);

	file_path = g_strdup_printf (".%s", path);

	if (msg->method == SOUP_METHOD_GET || msg->method == SOUP_METHOD_HEAD)
		do_get (server, msg, file_path);
	else if (msg->method == SOUP_METHOD_PUT)
		do_put (server, msg, file_path);
	else
		soup_message_set_status (msg, SOUP_STATUS_NOT_IMPLEMENTED);

	g_free (file_path);
	g_print ("  -> %d %s\n\n", msg->status_code, msg->reason_phrase);
}
Ejemplo n.º 2
0
Archivo: ui.c Proyecto: automata/imgflo
static void
server_callback (SoupServer *server, SoupMessage *msg,
		 const char *path, GHashTable *query,
		 SoupClientContext *context, gpointer data)
{

    SoupMessageHeadersIter iter;
    const char *name, *value;

    g_print("%s %s HTTP/1.%d\n", msg->method, path,
         soup_message_get_http_version(msg));

    if (g_strcmp0(path, "/process") == 0 && msg->method == SOUP_METHOD_GET) {
        process_image_callback(server, msg, path, query, context, data);
    } else {
        soup_message_headers_iter_init(&iter, msg->request_headers);
        while (soup_message_headers_iter_next(&iter, &name, &value))
            g_print("%s: %s\n", name, value);
        if (msg->request_body->length)
            g_print("%s\n", msg->request_body->data);

        g_print("  -> %d %s\n\n", msg->status_code, msg->reason_phrase);

        soup_message_set_status(msg, SOUP_STATUS_NOT_IMPLEMENTED);
    }
}
Ejemplo n.º 3
0
Archivo: ui.c Proyecto: imgflo/imgflo
static void
server_callback (SoupServer *server, SoupMessage *msg,
		 const char *path, GHashTable *query,
		 SoupClientContext *context, gpointer data)
{
    UiConnection *self = (UiConnection *)data;

    imgflo_debug("%s %s HTTP/1.%d\n", msg->method, path,
         soup_message_get_http_version(msg));
    ensure_hostname_set(self, soup_message_get_uri(msg));

    if (msg->method == SOUP_METHOD_GET && g_strcmp0(path, "/process") == 0) {
        process_image_callback(server, msg, path, query, context, self);
    } else if (msg_is_upgrade(msg)) {
        // fall-through, let libsoup WebSocket handle this
    } else if (msg->method == SOUP_METHOD_GET && g_strcmp0(path, "/") == 0) {
        serve_frontpage(server, msg, path, query, context, self);
    } else {
        imgflo_warning("Unknown HTTP request: %s, %s", msg->method, path);
        SoupMessageHeadersIter iter;
        const char *name, *value;
        soup_message_headers_iter_init(&iter, msg->request_headers);
        while (soup_message_headers_iter_next(&iter, &name, &value))
            imgflo_debug("%s: %s\n", name, value);
        if (msg->request_body->length)
            imgflo_debug("%s\n", msg->request_body->data);
        soup_message_set_status(msg, SOUP_STATUS_NOT_IMPLEMENTED);
    }
}
Ejemplo n.º 4
0
static void
send_headers (SoupMessage *from, SoupMessage *to)
{
	g_print ("[%p] HTTP/1.%d %d %s\n", to,
		 soup_message_get_http_version (from),
		 from->status_code, from->reason_phrase);

	soup_message_set_status_full (to, from->status_code,
				      from->reason_phrase);
	soup_message_headers_foreach (from->response_headers, copy_header,
				      to->response_headers);
	soup_message_headers_remove (to->response_headers, "Content-Length");
	soup_server_unpause_message (server, to);
}
Ejemplo n.º 5
0
void trex_callback(SoupServer *server, SoupMessage *msg,
	const char *path, GHashTable *query, const char *dest)
{
	SoupMessage *new_msg;
	SoupSession *session;
	char *uri_str;

	struct destination_info *to = malloc(sizeof(struct destination_info));
	to->server = server;
	to->msg = msg;

	session = soup_session_async_new();

	uri_str = soup_uri_to_string(soup_message_get_uri(msg), true);
	/*
	 * TODO Memory Leak :-)
	*/
	uri_str = g_strjoin(NULL, dest, uri_str, NULL);

	g_print("[%p] %s %s HTTP/1.%d\n", msg, msg->method, uri_str,
		soup_message_get_http_version(msg));

	/* build new request */
	new_msg = soup_message_new(msg->method, uri_str);
	soup_message_headers_foreach(msg->request_headers, copy_header,
		new_msg->request_headers);
	soup_message_headers_remove(new_msg->request_headers, "Host");
	if (msg->request_body->length) {
		SoupBuffer *request =
			soup_message_body_flatten(msg->request_body);
		soup_message_body_append_buffer(new_msg->request_body,
			request);
		soup_buffer_free(request);
	}
	soup_message_headers_set_encoding(msg->response_headers,
		SOUP_ENCODING_CHUNKED);

	soup_server_pause_message(server, msg);

	g_signal_connect(new_msg, "got_headers",
		G_CALLBACK(recv_headers), to);
	g_signal_connect(new_msg, "got_chunk",
		G_CALLBACK(recv_chunk), to);

	soup_session_queue_message(session, new_msg, finish_msg, to);

	g_object_ref(msg);

	g_object_unref(session);
}
Ejemplo n.º 6
0
static void trap_callback(SoupServer *server, SoupMessage *msg,
	const char *path, GHashTable *query,
	SoupClientContext *client, gpointer user_data)
{
	g_print("%s\n", path);
	rest_parse(path, NULL);
	SoupHTTPVersion version = soup_message_get_http_version(msg);
	if (version == SOUP_HTTP_1_0)
		g_print("1\n");
	if (version == SOUP_HTTP_1_1)
		g_print("1.1\n");
	g_print("%s\n", soup_client_context_get_host(client));

	trex_callback(server, msg, path, query, "http://127.0.0.1");
}
Ejemplo n.º 7
0
static void
server_cb (SoupServer        *server,
           SoupMessage       *msg,
           const char        *path,
           GHashTable        *query,
           SoupClientContext *client,
           DBusClient        *dbus_client)
{
  g_debug ("%s %s HTTP/1.%d", msg->method, path, soup_message_get_http_version (msg));

  if (msg->method == SOUP_METHOD_POST || msg->method == SOUP_METHOD_GET || msg->method == SOUP_METHOD_HEAD)
    http_post_handler (msg, path, dbus_client); /*
  else if (msg->method == SOUP_METHOD_GET || msg->method == SOUP_METHOD_HEAD)
    send_response (server, msg, path, self, NORMAL);*/
  else
    soup_message_set_status (msg, SOUP_STATUS_NOT_IMPLEMENTED);
}
Ejemplo n.º 8
0
static void
print_response (SoupLogger *logger, SoupMessage *msg)
{
	SoupLoggerPrivate *priv = SOUP_LOGGER_GET_PRIVATE (logger);
	SoupLoggerLogLevel log_level;
	SoupMessageHeadersIter iter;
	const char *name, *value;

	if (priv->response_filter) {
		log_level = priv->response_filter (logger, msg,
						   priv->response_filter_data);
	} else
		log_level = priv->level;

	if (log_level == SOUP_LOGGER_LOG_NONE)
		return;

	soup_logger_print (logger, SOUP_LOGGER_LOG_MINIMAL, '<',
			   "HTTP/1.%d %u %s\n",
			   soup_message_get_http_version (msg),
			   msg->status_code, msg->reason_phrase);

	soup_logger_print (logger, SOUP_LOGGER_LOG_MINIMAL, '<',
			   "Soup-Debug-Timestamp: %lu",
			   (unsigned long)time (0));
	soup_logger_print (logger, SOUP_LOGGER_LOG_MINIMAL, '<',
			   "Soup-Debug: %s %u (%p)",
			   g_type_name_from_instance ((GTypeInstance *)msg),
			   soup_logger_get_id (logger, msg), msg);

	if (log_level == SOUP_LOGGER_LOG_MINIMAL)
		return;

	soup_message_headers_iter_init (&iter, msg->response_headers);
	while (soup_message_headers_iter_next (&iter, &name, &value)) {
		soup_logger_print (logger, SOUP_LOGGER_LOG_HEADERS, '<',
				   "%s: %s", name, value);
	}
	if (log_level == SOUP_LOGGER_LOG_HEADERS)
		return;

	if (msg->response_body->data) {
		soup_logger_print (logger, SOUP_LOGGER_LOG_BODY, '<',
				   "\n%s", msg->response_body->data);
	}
}
Ejemplo n.º 9
0
static void
server_callback (SoupServer * server, SoupMessage * msg,
    const char *path, GHashTable * query,
    SoupClientContext * context, gpointer data)
{
  GST_DEBUG ("%s %s HTTP/1.%d", msg->method, path,
      soup_message_get_http_version (msg));
  soup_message_headers_foreach (msg->request_headers, print_header, NULL);
  if (msg->request_body->length)
    GST_DEBUG ("%s", msg->request_body->data);

  if (msg->method == SOUP_METHOD_GET || msg->method == SOUP_METHOD_HEAD)
    do_get (msg, path);
  else
    soup_message_set_status (msg, SOUP_STATUS_NOT_IMPLEMENTED);

  GST_DEBUG ("  -> %d %s", msg->status_code, msg->reason_phrase);
}
Ejemplo n.º 10
0
static void
server_callback (SoupServer *server, SoupMessage *msg,
		 const char *path, GHashTable *query,
		 SoupClientContext *context, gpointer data)
{
	SoupMessage *msg2;
	char *uristr;

	uristr = soup_uri_to_string (soup_message_get_uri (msg), FALSE);
	printf ("[%p] %s %s HTTP/1.%d\n", msg, msg->method, uristr,
		soup_message_get_http_version (msg));

	if (msg->method == SOUP_METHOD_CONNECT) {
		soup_message_set_status (msg, SOUP_STATUS_NOT_IMPLEMENTED);
		return;
	}

	msg2 = soup_message_new (msg->method, uristr);
        msg2 = soup_message_new (msg->method, uristr);
	soup_message_headers_foreach (msg->request_headers, copy_header,
				      msg2->request_headers);
	soup_message_headers_remove (msg2->request_headers, "Host");
	soup_message_headers_remove (msg2->request_headers, "Connection");

	if (msg->request_body->length) {
		SoupBuffer *request = soup_message_body_flatten (msg->request_body);
		soup_message_body_append_buffer (msg2->request_body, request);
		soup_buffer_free (request);
	}
	soup_message_headers_set_encoding (msg->response_headers,
					   SOUP_ENCODING_CHUNKED);

	g_signal_connect (msg2, "got_headers",
			  G_CALLBACK (send_headers), msg);
	g_signal_connect (msg2, "got_chunk",
			  G_CALLBACK (send_chunk), msg);

	g_signal_connect (msg, "finished", G_CALLBACK (client_msg_failed), msg2);

	soup_session_queue_message (session, msg2, finish_msg, msg);

	g_object_ref (msg);
	soup_server_pause_message (server, msg);
}
Ejemplo n.º 11
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);
}
Ejemplo n.º 12
0
static void recv_headers(SoupMessage *from, gpointer data)
{
	SoupMessage *to = ((struct destination_info *) data)->msg;
	SoupServer *server = ((struct destination_info *) data)->server;

	g_print("[%p] HTTP/1.%d %d %s\n", to,
		soup_message_get_http_version(from),
		from->status_code, from->reason_phrase);

	soup_message_set_status_full(to,
		from->status_code, from->reason_phrase);

	soup_message_headers_foreach(from->response_headers,
		copy_header, to->response_headers);
	/* we remove it, because libsoup appending at the end */
	soup_message_headers_remove(to->response_headers, "Content-Length");

	soup_server_unpause_message(server, to);
}
Ejemplo n.º 13
0
void server_callback (SoupServer *server,
                      SoupMessage *msg,
                      const char *path,
                      gpointer data,
                      SoupClientContext *client,
                      gpointer user_data)
{
	g_debug("got server callback");
        printf ("%s %s HTTP/1.%d\n", msg->method, path,
                soup_message_get_http_version (msg));
	soup_message_headers_foreach (msg->request_headers,
                                      print_headers, NULL);

	if (msg->method == SOUP_METHOD_GET)
		get(server,msg,path);
	else if (msg->method == SOUP_METHOD_POST)
		post(server,msg,path);
	else {
		soup_message_set_status (msg, SOUP_STATUS_NOT_IMPLEMENTED);
		return;
	}

}
static void
get_response_headers (SoupMessage *msg, GString *headers,
		      SoupEncoding *encoding, gpointer user_data)
{
	SoupEncoding claimed_encoding;
	SoupMessageHeadersIter iter;
	const char *name, *value;

	handle_partial_get (msg);

	g_string_append_printf (headers, "HTTP/1.%c %d %s\r\n",
				soup_message_get_http_version (msg) == SOUP_HTTP_1_0 ? '0' : '1',
				msg->status_code, msg->reason_phrase);

	claimed_encoding = soup_message_headers_get_encoding (msg->response_headers);
	if ((msg->method == SOUP_METHOD_HEAD ||
	     msg->status_code  == SOUP_STATUS_NO_CONTENT ||
	     msg->status_code  == SOUP_STATUS_NOT_MODIFIED ||
	     SOUP_STATUS_IS_INFORMATIONAL (msg->status_code)) ||
	    (msg->method == SOUP_METHOD_CONNECT &&
	     SOUP_STATUS_IS_SUCCESSFUL (msg->status_code)))
		*encoding = SOUP_ENCODING_NONE;
	else
		*encoding = claimed_encoding;

	if (claimed_encoding == SOUP_ENCODING_CONTENT_LENGTH &&
	    !soup_message_headers_get_content_length (msg->response_headers)) {
		soup_message_headers_set_content_length (msg->response_headers,
							 msg->response_body->length);
	}

	soup_message_headers_iter_init (&iter, msg->response_headers);
	while (soup_message_headers_iter_next (&iter, &name, &value))
		g_string_append_printf (headers, "%s: %s\r\n", name, value);
	g_string_append (headers, "\r\n");
}
Ejemplo n.º 15
0
static void
server_callback (SoupServer *server, SoupMessage *msg,
                 const char *path, GHashTable *query,
                 SoupClientContext *context, gpointer data)
{
    char *remainder;
    guint status_code;

    if (g_str_has_prefix (path, "/bad")) {
        if (!strcmp (path, "/bad")) {
            soup_message_set_status (msg, SOUP_STATUS_FOUND);
            soup_message_headers_replace (msg->response_headers,
                                          "Location",
                                          "/bad with spaces");
        } else if (!strcmp (path, "/bad with spaces"))
            soup_message_set_status (msg, SOUP_STATUS_OK);
        else
            soup_message_set_status (msg, SOUP_STATUS_NOT_FOUND);
        return;
    }

    if (!strcmp (path, "/")) {
        if (msg->method != SOUP_METHOD_GET &&
                msg->method != SOUP_METHOD_HEAD) {
            soup_message_set_status (msg, SOUP_STATUS_METHOD_NOT_ALLOWED);
            return;
        }

        /* Make sure that redirecting a POST clears the body */
        if (msg->request_body->length) {
            soup_message_set_status (msg, SOUP_STATUS_BAD_REQUEST);
            return;
        }

        /* Make sure that a HTTP/1.0 redirect doesn't cause an
         * HTTP/1.0 re-request. (#521848)
         */
        if (soup_message_get_http_version (msg) == SOUP_HTTP_1_0) {
            soup_message_set_status (msg, SOUP_STATUS_BAD_REQUEST);
            return;
        }

        soup_message_set_status (msg, SOUP_STATUS_OK);

        /* FIXME: this is wrong, though it doesn't matter for
         * the purposes of this test, and to do the right
         * thing currently we'd have to set Content-Length by
         * hand.
         */
        if (msg->method != SOUP_METHOD_HEAD) {
            soup_message_set_response (msg, "text/plain",
                                       SOUP_MEMORY_STATIC,
                                       "OK\r\n", 4);
        }
        return;
    }

    status_code = strtoul (path + 1, &remainder, 10);
    if (!SOUP_STATUS_IS_REDIRECTION (status_code) ||
            (*remainder && *remainder != '/')) {
        soup_message_set_status (msg, SOUP_STATUS_NOT_FOUND);
        return;
    }

    /* See above comment re bug 521848. */
    soup_message_set_http_version (msg, SOUP_HTTP_1_0);

    soup_message_set_status (msg, status_code);
    if (*remainder) {
        soup_message_headers_replace (msg->response_headers,
                                      "Location", remainder);
    } else {
        soup_message_headers_replace (msg->response_headers,
                                      "Location", "/");
    }
}
Ejemplo n.º 16
0
static void
postal_http_log_message (PostalHttp        *http,
                         SoupMessage       *message,
                         const gchar       *path,
                         SoupClientContext *client)
{
   const gchar *ip_addr;
   const gchar *version;
   GTimeVal event_time;
   struct tm tt;
   time_t t;
   gchar *epath;
   gchar *formatted = NULL;
   gchar *referrer;
   gchar *user_agent;
   gchar ftime[32];

   g_assert(POSTAL_IS_HTTP(http));
   g_assert(SOUP_IS_MESSAGE(message));
   g_assert(client);

   g_get_current_time(&event_time);
   t = (time_t)event_time.tv_sec;
   localtime_r(&t, &tt);
   strftime(ftime, sizeof ftime, "%b %d %H:%M:%S", &tt);
   ftime[31] = '\0';

   switch (soup_message_get_http_version(message)) {
   case SOUP_HTTP_1_0:
      version = "HTTP/1.0";
      break;
   case SOUP_HTTP_1_1:
      version = "HTTP/1.1";
      break;
   default:
      g_assert_not_reached();
      version = NULL;
      break;
   }

   ip_addr = soup_client_context_get_host(client);
   referrer = (gchar *)soup_message_headers_get_one(message->request_headers, "Referrer");
   user_agent = (gchar *)soup_message_headers_get_one(message->request_headers, "User-Agent");

   epath = g_strescape(path, NULL);
   referrer = g_strescape(referrer ?: "", NULL);
   user_agent = g_strescape(user_agent ?: "", NULL);

   formatted = g_strdup_printf("%s %s \"%s %s %s\" %u %"G_GSIZE_FORMAT" \"%s\" \"%s\"\n",
                               ip_addr,
                               ftime,
                               message->method,
                               epath,
                               version,
                               message->status_code,
                               message->response_body->length,
                               referrer,
                               user_agent);

   neo_logger_log(http->priv->logger,
                  &event_time,
                  NULL,
                  NULL,
                  0,
                  0,
                  0,
                  NULL,
                  formatted);

   g_free(epath);
   g_free(referrer);
   g_free(user_agent);
   g_free(formatted);
}
Ejemplo n.º 17
0
static void
print_request (SoupLogger *logger, SoupMessage *msg,
	       SoupSession *session, SoupSocket *socket,
	       gboolean restarted)
{
	SoupLoggerPrivate *priv = SOUP_LOGGER_GET_PRIVATE (logger);
	SoupLoggerLogLevel log_level;
	SoupMessageHeadersIter iter;
	const char *name, *value;
	SoupURI *uri;

	if (priv->request_filter) {
		log_level = priv->request_filter (logger, msg,
						  priv->request_filter_data);
	} else
		log_level = priv->level;

	if (log_level == SOUP_LOGGER_LOG_NONE)
		return;

	uri = soup_message_get_uri (msg);
	if (msg->method == SOUP_METHOD_CONNECT) {
		soup_logger_print (logger, SOUP_LOGGER_LOG_MINIMAL, '>',
				   "CONNECT %s:%u HTTP/1.%d",
				   uri->host, uri->port,
				   soup_message_get_http_version (msg));
	} else {
		soup_logger_print (logger, SOUP_LOGGER_LOG_MINIMAL, '>',
				   "%s %s%s%s HTTP/1.%d",
				   msg->method, uri->path,
				   uri->query ? "?" : "",
				   uri->query ? uri->query : "",
				   soup_message_get_http_version (msg));
	}

	soup_logger_print (logger, SOUP_LOGGER_LOG_MINIMAL, '>',
			   "Soup-Debug-Timestamp: %lu",
			   (unsigned long)time (0));
	soup_logger_print (logger, SOUP_LOGGER_LOG_MINIMAL, '>',
			   "Soup-Debug: %s %u (%p), %s %u (%p), %s %u (%p)%s",
			   g_type_name_from_instance ((GTypeInstance *)session),
			   soup_logger_get_id (logger, session), session,
			   g_type_name_from_instance ((GTypeInstance *)msg),
			   soup_logger_get_id (logger, msg), msg,
			   g_type_name_from_instance ((GTypeInstance *)socket),
			   soup_logger_get_id (logger, socket), socket,
			   restarted ? ", restarted" : "");

	if (log_level == SOUP_LOGGER_LOG_MINIMAL)
		return;

	if (!soup_message_headers_get_one (msg->request_headers, "Host")) {
		char *uri_host;

		if (strchr (uri->host, ':'))
			uri_host = g_strdup_printf ("[%s]", uri->host);
		else if (g_hostname_is_non_ascii (uri->host))
			uri_host = g_hostname_to_ascii (uri->host);
		else
			uri_host = uri->host;

		soup_logger_print (logger, SOUP_LOGGER_LOG_HEADERS, '>',
				   "Host: %s%c%u", uri_host,
				   soup_uri_uses_default_port (uri) ? '\0' : ':',
				   uri->port);

		if (uri_host != uri->host)
			g_free (uri_host);
	}
	soup_message_headers_iter_init (&iter, msg->request_headers);
	while (soup_message_headers_iter_next (&iter, &name, &value)) {
		if (!g_ascii_strcasecmp (name, "Authorization") &&
		    !g_ascii_strncasecmp (value, "Basic ", 6))
			soup_logger_print_basic_auth (logger, value);
		else {
			soup_logger_print (logger, SOUP_LOGGER_LOG_HEADERS, '>',
					   "%s: %s", name, value);
		}
	}
	if (log_level == SOUP_LOGGER_LOG_HEADERS)
		return;

	if (msg->request_body->length &&
	    soup_message_body_get_accumulate (msg->request_body)) {
		SoupBuffer *request;

		request = soup_message_body_flatten (msg->request_body);
		g_return_if_fail (request != NULL);
		soup_buffer_free (request);

		if (soup_message_headers_get_expectations (msg->request_headers) != SOUP_EXPECTATION_CONTINUE) {
			soup_logger_print (logger, SOUP_LOGGER_LOG_BODY, '>',
					   "\n%s", msg->request_body->data);
		}
	}
}
Ejemplo n.º 18
0
SoupBuffer *
open_app_get_data_by_request (SoupSession *session, const gchar *request)
{
	SoupMessage *msg;
	SoupBuffer *buf;
	const gchar *name;
	const gchar *header;
	const gchar *method;

	g_return_val_if_fail (request != NULL, NULL);

//	g_debug ("open_app_get_data_by_request: %s\n", request);

	buf = NULL;
	method = SOUP_METHOD_GET;
	msg = soup_message_new (method, request);
	soup_message_set_flags (msg, SOUP_MESSAGE_NO_REDIRECT);
	soup_session_send_message (session, msg);

	name = soup_message_get_uri (msg)->path;

	
	if (SOUP_STATUS_IS_TRANSPORT_ERROR (msg->status_code)) {
		g_debug ("%s: %d %s\n", name, msg->status_code, msg->reason_phrase);
	} else {
#ifdef SERVER_DEBUG
		SoupMessageHeadersIter iter;
		const gchar *hname, *value;
		gchar *path = soup_uri_to_string (soup_message_get_uri (msg), TRUE);

		g_debug ("%s %s HTTP/1.%d\n", method, path,
			soup_message_get_http_version (msg));
		g_free (path);
		soup_message_headers_iter_init (&iter, msg->request_headers);
		while (soup_message_headers_iter_next (&iter, &hname, &value))
			g_debug ("%s: %s\r\n", hname, value);
		g_debug ("\n");

		g_debug ("HTTP/1.%d %d %s\n",
			soup_message_get_http_version (msg),
			msg->status_code, msg->reason_phrase);
		soup_message_headers_iter_init (&iter, msg->response_headers);
		while (soup_message_headers_iter_next (&iter, &hname, &value))
			g_debug ("%s: %s\r\n", hname, value);
		g_debug ("\n");
#endif
	}

	if (SOUP_STATUS_IS_REDIRECTION (msg->status_code)) {
		header = soup_message_headers_get_one (msg->response_headers,
						       "Location");
		if (header) {
			SoupURI *request;
			gchar *request_string;

			g_debug ("   -> %s\n", header);

			request = soup_uri_new_with_base (soup_message_get_uri (msg), header);
			request_string = soup_uri_to_string (request, FALSE);
			buf = open_app_get_data_by_request (session, request_string);
			g_free (request_string);
			soup_uri_free (request);
		}
	} else if (SOUP_STATUS_IS_SUCCESSFUL (msg->status_code)) {
		buf = soup_message_body_flatten (msg->response_body);
	}

	g_object_unref (msg);

	return buf;
}
Ejemplo n.º 19
0
static void
send_chunked_file (SoupServer * server, SoupMessage * message,
		   DAAPRecord * record, guint64 filesize, guint64 offset,
		   const gchar * transcode_mimetype)
{
	gchar *format = NULL;
	gchar *location = NULL;
	GInputStream *stream = NULL;
	gboolean has_video;
	GError *error = NULL;
	ChunkData *cd = NULL;

	cd = g_new (ChunkData, 1);
	if (NULL == cd) {
		g_warning ("Error allocating chunk\n");
		goto _error;
	}

	g_object_get (record, "location", &location, "has-video", &has_video, NULL);
	if (NULL == location) {
		g_warning ("Error getting location from record\n");
		goto _error;
	}

	/* FIXME: This crashes on powerpc-440fp-linux-gnu:
	 * g_debug ("Sending %s chunked from offset %" G_GUINT64_FORMAT ".", location, offset);
	 */

	cd->server = server;

	stream = G_INPUT_STREAM (daap_record_read (record, &error));
	if (error != NULL) {
		g_warning ("Couldn't open %s: %s.", location, error->message);
		goto _error;
	}

	g_object_get (record, "format", &format, NULL);
	if (NULL == format) {
		g_warning ("Error getting format from record\n");
		goto _error;
	}

	// Not presently transcoding videos (see also same comments elsewhere).
	if (should_transcode (format, has_video, transcode_mimetype)) {
#ifdef HAVE_GSTREAMERAPP
		cd->stream = dmap_gst_input_stream_new (transcode_mimetype, stream);
#else
		g_warning ("Transcode format %s not supported", transcode_mimetype);
		cd->stream = stream;
#endif /* HAVE_GSTREAMERAPP */
	} else {
		g_debug ("Not transcoding %s", location);
		cd->stream = stream;
	}

	if (cd->stream == NULL) {
		g_warning ("Could not set up input stream");
		goto _error;
	}

	if (offset != 0) {
		if (g_seekable_seek (G_SEEKABLE (cd->stream), offset, G_SEEK_SET, NULL, &error) == FALSE) {
			g_warning ("Error seeking: %s.", error->message);
			goto _error;
		}
		filesize -= offset;
	}

	/* Free memory after each chunk sent out over network. */
	soup_message_body_set_accumulate (message->response_body, FALSE);

	if (! should_transcode (format, has_video, transcode_mimetype)) {
	        /* NOTE: iTunes seems to require this or it stops reading 
	         * video data after about 2.5MB. Perhaps this is so iTunes
	         * knows how much data to buffer.
	         */
		g_debug ("Using HTTP 1.1 content length encoding.");
		soup_message_headers_set_encoding (message->response_headers, SOUP_ENCODING_CONTENT_LENGTH);

	        /* NOTE: iTunes 8 (and other versions?) will not seek
	         * properly without a Content-Length header.
	         */
		g_debug ("Content length is %" G_GUINT64_FORMAT ".", filesize);
		soup_message_headers_set_content_length (message->response_headers, filesize);
	} else if (soup_message_get_http_version (message) == SOUP_HTTP_1_0) {
		/* NOTE: Roku clients support only HTTP 1.0. */
#ifdef HAVE_ENCODING_EOF
		g_debug ("Using HTTP 1.0 encoding.");
		soup_message_headers_set_encoding (message->response_headers, SOUP_ENCODING_EOF);
#else
		g_warning ("Received HTTP 1.0 request, but not built with HTTP 1.0 support");
		soup_message_headers_set_encoding (message->response_headers, SOUP_ENCODING_CHUNKED);
#endif
	} else {
		/* NOTE: Can not provide Content-Length when performing
		 * real-time transcoding.
		 */
		g_debug ("Using HTTP 1.1 chunked encoding.");
		soup_message_headers_set_encoding (message->response_headers, SOUP_ENCODING_CHUNKED);
	}

	soup_message_headers_append (message->response_headers, "Connection",
				     "Close");
	soup_message_headers_append (message->response_headers,
				     "Content-Type",
				     "application/x-dmap-tagged");

	g_signal_connect (message, "wrote_headers",
			  G_CALLBACK (dmap_write_next_chunk), cd);
	g_signal_connect (message, "wrote_chunk",
			  G_CALLBACK (dmap_write_next_chunk), cd);
	g_signal_connect (message, "finished",
			  G_CALLBACK (dmap_chunked_message_finished), cd);
	/* NOTE: cd g_free'd by chunked_message_finished(). */

	return;
_error:
	soup_message_set_status (message, SOUP_STATUS_INTERNAL_SERVER_ERROR);

	if (NULL != cd) {
		g_free (cd);
	}

	if (NULL != format) {
		g_free (format);
	}

	if (NULL != location) {
		g_free (location);
	}

	if (NULL != error) {
		g_error_free (error);
	}
	
	if (NULL != cd->stream) {
		g_input_stream_close (cd->stream, NULL, NULL);
	}
	
	if (NULL != stream) {
		g_input_stream_close (cd->stream, NULL, NULL);
	}

	return;
}