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); }
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); } }
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); } }
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); }
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); }
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"); }
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); }
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); } }
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); }
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); }
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); }
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); }
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"); }
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", "/"); } }
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); }
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); } } }
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; }
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; }