diff options
-rw-r--r-- | src/main.c | 102 |
1 files changed, 46 insertions, 56 deletions
@@ -55,6 +55,7 @@ static int server_timeout = 5; static char *token_server_addrmask = NULL; static gboolean conflict_is_restart = FALSE; static GInetAddressMask *stp_inet_addrmask = NULL; +static GMainLoop *loop = NULL; static GOptionEntry entries[] = { @@ -93,20 +94,21 @@ get_server_ctx_from_msg (SoupMessage *msg, static STPStreamToken* stp_validate_fetch_token_from_query (GHashTable *tokens, const char *sessionid, - const char *query_string, + GHashTable *query, guint *http_status_code) { - GHashTable *query; - char *type, *udp_clients; + char *query_string, *type, *udp_clients; STPStreamToken *token, *perms_token; - if (!query_string) { - g_debug ("Rejecting stream: no query string specified"); + if (!query) { + g_debug ("Rejecting stream: no query specified"); *http_status_code = SOUP_STATUS_BAD_REQUEST; return NULL; } + query_string = soup_form_encode_hash (query); g_debug ("Recv query string: %s\n", query_string); + g_free (query_string); if (stp_inet_addrmask && !g_hash_table_contains (tokens, sessionid)) { @@ -115,8 +117,6 @@ stp_validate_fetch_token_from_query (GHashTable *tokens, return NULL; } - query = soup_form_decode (query_string); - token = g_new0 (STPStreamToken, 1); type = g_hash_table_lookup (query, "type"); @@ -318,12 +318,12 @@ stream_finished_cb (SoupMessage *msg, /* This is called when the entire request body has been read */ static void -handle_request_cb (SoupServer *server, - SoupMessage *msg, - const char *path, - GHashTable *query, - SoupClientContext *client, - STPHashTables *tables) +handle_request_with_body_cb (SoupServer *server, + SoupMessage *msg, + const char *path, + GHashTable *query, + SoupClientContext *client, + STPHashTables *tables) { STPServerCtx *server_ctx; @@ -431,7 +431,7 @@ GET: /* Add to pipeline and sync state */ gst_bin_add (GST_BIN (server_ctx->pipeline), bin); - + if (!gst_element_sync_state_with_parent (bin)) { g_critical ("Unable to sync appsink bin with parent pipeline\n"); goto err; @@ -444,7 +444,7 @@ GET: /* Send the WebM stream header through the src pad first */ caps = gst_pad_get_current_caps (srcpad); - + buffer = stp_get_streamheader_from_caps (caps); if (!buffer) { g_critical ("Unable to get streamheader from caps"); @@ -616,11 +616,14 @@ got_first_request_body_chunk (SoupMessage *msg, } static void -got_request_headers (SoupMessage *msg, - STPHashTables *tables) +handle_request_with_headers_cb (SoupServer *server, + SoupMessage *msg, + const char *path, + GHashTable *query, + SoupClientContext *client, + STPHashTables *tables) { - SoupURI *uri; - const char *path, *sessionid, *query; + const char *sessionid; #ifdef HEADERS_DEBUG SoupMessageHeadersIter iter; @@ -630,9 +633,6 @@ got_request_headers (SoupMessage *msg, g_debug ("%s: %s", name, value); #endif - g_object_get (msg, "uri", &uri, NULL); - path = soup_uri_get_path (uri); - query = soup_uri_get_query (uri); g_debug ("%s on uri %s", msg->method, path); /* Token API methods are handled in the server callbacks, @@ -759,7 +759,7 @@ PUT: { goto PUT_out; } -new_conn: + new_conn: /* This is a new connection; treat it as such */ ctx = g_new0 (STPServerCtx, 1); ctx->stream_type = token->stream_type; @@ -807,25 +807,10 @@ GET: { } out: - soup_uri_free (uri); return; } static void -request_started_cb (SoupServer *server, - SoupMessage *msg, - SoupClientContext *client, - STPHashTables *tables) -{ - g_debug ("New %s request started", msg->method); - - /* SoupMessage is useful only once we have headers, - * so we do all initialization there */ - g_signal_connect (msg, "got-headers", - G_CALLBACK (got_request_headers), tables); -} - -static void handle_add_token_cb (SoupServer *server, SoupMessage *msg, const char *path, @@ -857,7 +842,7 @@ POST: { soup_message_set_status (msg, SOUP_STATUS_FORBIDDEN); goto out; } - + if (!query || !g_hash_table_contains (query, "sessionid") || !g_hash_table_contains (query, "type")) { @@ -923,7 +908,7 @@ DELETE: { soup_message_set_status (msg, SOUP_STATUS_FORBIDDEN); goto out; } - + if (!query || !g_hash_table_contains (query, "sessionid")) { soup_message_set_status (msg, SOUP_STATUS_BAD_REQUEST); @@ -1091,7 +1076,7 @@ GET: { json_builder_set_member_name (b, "status"); json_builder_add_string_value (b, ctx->status); - + json_builder_end_object (b); } json_builder_end_array (b); @@ -1170,8 +1155,9 @@ out: gboolean exit_on_signal_cb (SoupServer *server) { - soup_server_quit (server); + soup_server_disconnect (server); g_object_unref (server); + g_main_loop_quit (loop); return G_SOURCE_REMOVE; } @@ -1216,16 +1202,18 @@ main (int argc, /* TODO: Accept command-line argument for host */ server = soup_server_new (SOUP_SERVER_SERVER_HEADER, - "soup-transcode-proxy ", - SOUP_SERVER_PORT, port, NULL); - - /* Handle the end of POST/PUT, and all GET requests */ + "soup-transcode-proxy ", NULL); + + /* Handle streaming (chunked) requests when we recv headers */ + soup_server_add_early_handler (server, NULL, + (SoupServerCallback)handle_request_with_headers_cb, + tables, NULL); + /* Handle completed requests; i.e. the end of POST/PUT and all GET requests */ soup_server_add_handler (server, NULL, - (SoupServerCallback)handle_request_cb, + (SoupServerCallback)handle_request_with_body_cb, tables, NULL); - /* NOTE: When adding a new path handler, an exception must be made in - * got_request_headers() for that path, otherwise a 405 will be returned */ + /* REST API for server status query handling */ soup_server_add_handler (server, STP_REST_ABORT_STREAM, (SoupServerCallback)handle_abort_stream_cb, tables, NULL); @@ -1246,15 +1234,17 @@ main (int argc, tables, NULL); } - /* Since chunked streaming requests send all the data in a single request, - * we need to handle those when we get the headers. Hence, all PUT stream - * handling is done here. */ - g_signal_connect (server, "request-started", - G_CALLBACK (request_started_cb), tables); - g_unix_signal_add (SIGINT, (GSourceFunc)exit_on_signal_cb, server); - soup_server_run (server); + soup_server_listen_all (server, port, 0, &error); + if (error) { + g_printerr ("Error starting soup server: %s\n", error->message); + return 1; + } + + g_debug ("SoupServer setup, running mainloop..."); + loop = g_main_loop_new (NULL, FALSE); + g_main_loop_run (loop); g_hash_table_unref (tables->tokens); g_hash_table_unref (tables->ctxs); |