static void server_callback (SoupServer *server, SoupMessage *msg, const char *path, GHashTable *query, SoupClientContext *context, gpointer data) { SlowData *sd; if (msg->method != SOUP_METHOD_GET) { soup_message_set_status (msg, SOUP_STATUS_NOT_IMPLEMENTED); return; } soup_message_set_status (msg, SOUP_STATUS_OK); if (!strcmp (path, "/fast")) { soup_message_set_response (msg, "text/plain", SOUP_MEMORY_STATIC, "OK\r\n", 4); return; } soup_message_headers_set_encoding (msg->response_headers, SOUP_ENCODING_CHUNKED); g_object_ref (msg); soup_server_pause_message (server, msg); sd = g_new (SlowData, 1); sd->server = server; sd->msg = msg; sd->timeout = soup_add_timeout ( soup_server_get_async_context (server), 200, add_body_chunk, sd); g_signal_connect (msg, "finished", G_CALLBACK (request_failed), sd); }
static void snra_server_client_wrote_headers (SoupMessage * msg, SnraServerClient * client) { GList *cur; /* Pause the message so Soup doesn't do any more responding */ soup_server_pause_message (client->soup, msg); g_print ("client %u ready for traffic\n", client->conn_id); client->io = g_io_channel_unix_new (soup_socket_get_fd (client->socket)); g_io_channel_set_encoding (client->io, NULL, NULL); g_io_channel_set_buffered (client->io, FALSE); client->io_watch = g_io_add_watch (client->io, G_IO_IN | G_IO_HUP, (GIOFunc) (snra_server_client_io_cb), client); /* Send any pending messages */ while ((cur = client->pending_msgs)) { GList *next; PendingMsg *msg = (PendingMsg *) (cur->data); next = g_list_next (cur); snra_server_client_send_message (client, msg->body, msg->len); client->pending_msgs = g_list_delete_link (client->pending_msgs, cur); g_free (msg->body); g_free (msg); cur = next; } }
static void korva_upnp_file_server_on_wrote_chunk (SoupMessage *msg, gpointer user_data) { ServeData *data = (ServeData *) user_data; int chunk_size; char *file_buffer; GError *error = NULL; gsize bytes_read; soup_server_pause_message (data->server, msg); chunk_size = MIN (data->end - data->start + 1, G_MAXUINT16 + 1); if (chunk_size <= 0) { soup_message_body_complete (msg->response_body); soup_server_unpause_message (data->server, msg); return; } file_buffer = g_malloc0 (chunk_size); g_input_stream_read_all (data->stream, (void *) file_buffer, chunk_size, &bytes_read, NULL, &error); data->start += chunk_size; soup_message_body_append (msg->response_body, SOUP_MEMORY_TAKE, file_buffer, chunk_size); soup_server_unpause_message (data->server, msg); }
void gss_transaction_delay (GssTransaction * t, int msec) { GssTransaction *new_t; /* FIXME this is pure evil */ new_t = g_malloc0 (sizeof (GssTransaction)); memcpy (new_t, t, sizeof (GssTransaction)); soup_server_pause_message (t->soupserver, t->msg); g_timeout_add (msec, unpause, new_t); }
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 server_callback (SoupServer *server, SoupMessage *msg, const char *path, GHashTable *query, SoupClientContext *client, gpointer user_data) { if (g_str_equal (path, "/stream")) { soup_message_set_status (msg, SOUP_STATUS_OK); soup_message_headers_set_encoding (msg->response_headers, SOUP_ENCODING_CHUNKED); soup_server_pause_message (server, msg); server_count = 1; g_idle_add (send_chunks, msg); } }
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 postal_http_handle_v1_users_user_devices (UrlRouter *router, SoupServer *server, SoupMessage *message, const gchar *path, GHashTable *params, GHashTable *query, SoupClientContext *client, gpointer user_data) { const gchar *user; PostalHttp *http = user_data; ENTRY; g_assert(router); g_assert(SOUP_IS_SERVER(server)); g_assert(SOUP_IS_MESSAGE(message)); g_assert(path); g_assert(params); g_assert(g_hash_table_contains(params, "user")); g_assert(client); g_assert(POSTAL_IS_HTTP(http)); user = g_hash_table_lookup(params, "user"); soup_server_pause_message(server, message); if (message->method == SOUP_METHOD_GET) { postal_service_find_devices(http->priv->service, user, get_int_param(query, "offset"), get_int_param(query, "limit"), NULL, /* TODO */ devices_get_cb, g_object_ref(message)); EXIT; } soup_message_set_status(message, SOUP_STATUS_METHOD_NOT_ALLOWED); soup_server_unpause_message(server, message); EXIT; }
static void try_tunnel (SoupServer *server, SoupMessage *msg, SoupClientContext *context) { Tunnel *tunnel; SoupURI *dest_uri; GSocketClient *sclient; soup_server_pause_message (server, msg); tunnel = g_new0 (Tunnel, 1); tunnel->self = g_object_ref (server); tunnel->msg = g_object_ref (msg); tunnel->context = context; dest_uri = soup_message_get_uri (msg); sclient = g_socket_client_new (); g_socket_client_connect_to_host_async (sclient, dest_uri->host, dest_uri->port, NULL, tunnel_connected_cb, tunnel); g_object_unref (sclient); }
static void server_handler (SoupServer *server, SoupMessage *msg, const char *path, GHashTable *query, SoupClientContext *client, gpointer user_data) { soup_message_set_status (msg, SOUP_STATUS_OK); soup_message_set_response (msg, "text/plain", SOUP_MEMORY_STATIC, "ok\r\n", 4); if (!strcmp (path, "/slow")) { soup_server_pause_message (server, msg); g_object_set_data (G_OBJECT (msg), "server", server); soup_add_timeout (soup_server_get_async_context (server), 1100, timeout_finish_message, msg); } }
SnraServerClient * snra_server_client_new_single (SoupServer * soup, SoupMessage * msg, G_GNUC_UNUSED SoupClientContext * context) { SnraServerClient *client = g_object_new (SNRA_TYPE_SERVER_CLIENT, NULL); client->soup = soup; client->event_pipe = msg; client->host = g_strdup (soup_client_context_get_host (context)); client->net_event_sig = g_signal_connect (msg, "network-event", G_CALLBACK (snra_server_client_network_event), client); client->disco_sig = g_signal_connect (msg, "finished", G_CALLBACK (snra_server_client_disconnect), client); client->type = SNRA_SERVER_CLIENT_SINGLE; client->need_body_complete = TRUE; soup_message_set_status (msg, SOUP_STATUS_OK); soup_server_pause_message (client->soup, msg); return client; }
void dacp_share_ctrl_int (DMAPShare * share, SoupServer * server, SoupMessage * message, const char *path, GHashTable * query, SoupClientContext * context) { const char *rest_of_path; DACPShare *dacp_share = DACP_SHARE (share); g_debug ("Path is %s.", path); if (query) { g_hash_table_foreach (query, debug_param, NULL); } rest_of_path = strchr (path + 1, '/'); /* If calling /ctrl-int without args, the client doesnt need a * session-id, otherwise it does and it should be validated. */ if ((rest_of_path != NULL) && (!_dmap_share_session_id_validate (share, context, message, query, NULL))) { soup_message_set_status (message, SOUP_STATUS_FORBIDDEN); return; } if (rest_of_path == NULL) { /* CACI control-int * MSTT status * MUTY update type * MTCO specified total count * MRCO returned count * MLCL listing * MLIT listing item * MIID item id * CMIK Unknown (TRUE) * CMSP Unknown (TRUE) * CMSV Unknown (TRUE) * CASS Unknown (TRUE) * CASU Unknown (TRUE) * CASG Unknown (TRUE) */ GNode *caci; GNode *mlcl; GNode *mlit; // dacp.controlint caci = dmap_structure_add (NULL, DMAP_CC_CACI); // dmap.status dmap_structure_add (caci, DMAP_CC_MSTT, (gint32) DMAP_STATUS_OK); // dmap.updatetype dmap_structure_add (caci, DMAP_CC_MUTY, 0); // dmap.specifiedtotalcount dmap_structure_add (caci, DMAP_CC_MTCO, (gint32) 1); // dmap.returnedcount dmap_structure_add (caci, DMAP_CC_MRCO, (gint32) 1); // dmap.listing mlcl = dmap_structure_add (caci, DMAP_CC_MLCL); // dmap.listingitem mlit = dmap_structure_add (mlcl, DMAP_CC_MLIT); // dmap.itemid dmap_structure_add (mlit, DMAP_CC_MIID, (gint32) 1); // Unknown (TRUE) dmap_structure_add (mlit, DMAP_CC_CMIK, (gint32) 1); // Unknown (TRUE) dmap_structure_add (mlit, DMAP_CC_CMSP, (gint32) 1); // Unknown (TRUE) dmap_structure_add (mlit, DMAP_CC_CMSV, (gint32) 1); // Unknown (TRUE) dmap_structure_add (mlit, DMAP_CC_CASS, (gint32) 1); // Unknown (TRUE) dmap_structure_add (mlit, DMAP_CC_CASU, (gint32) 1); // Unknown (TRUE) dmap_structure_add (mlit, DMAP_CC_CASG, (gint32) 1); _dmap_share_message_set_from_dmap_structure (share, message, caci); dmap_structure_destroy (caci); } else if (g_ascii_strcasecmp ("/1/getproperty", rest_of_path) == 0) { gchar *properties_query, **properties, **property; GNode *cmgt; properties_query = g_hash_table_lookup (query, "properties"); if (!properties_query) { g_warning ("No property specified"); return; } cmgt = dmap_structure_add (NULL, DMAP_CC_CMGT); dmap_structure_add (cmgt, DMAP_CC_MSTT, DMAP_STATUS_OK); properties = g_strsplit (properties_query, ",", -1); for (property = properties; *property; property++) { if (g_ascii_strcasecmp (*property, "dmcp.volume") == 0) { gulong volume; g_object_get (dacp_share->priv->player, "volume", &volume, NULL); //g_debug ("Sending volume: %lu", volume); dmap_structure_add (cmgt, DMAP_CC_CMVO, volume); } else { g_warning ("Unhandled property %s", *property); } } g_strfreev (properties); _dmap_share_message_set_from_dmap_structure (share, message, cmgt); dmap_structure_destroy (cmgt); } else if (g_ascii_strcasecmp ("/1/setproperty", rest_of_path) == 0) { if (g_hash_table_lookup (query, "dmcp.volume")) { gdouble volume = strtod (g_hash_table_lookup (query, "dmcp.volume"), NULL); g_object_set (dacp_share->priv->player, "volume", (gulong) volume, NULL); } soup_message_set_status (message, SOUP_STATUS_NO_CONTENT); } else if (g_ascii_strcasecmp ("/1/getspeakers", rest_of_path) == 0) { GNode *casp; casp = dmap_structure_add (NULL, DMAP_CC_CASP); dmap_structure_add (casp, DMAP_CC_MSTT, (gint32) DMAP_STATUS_OK); dmap_structure_add (casp, DMAP_CC_MDCL); dmap_structure_add (casp, DMAP_CC_CAIA, TRUE); dmap_structure_add (casp, DMAP_CC_MINM, "Computer"); dmap_structure_add (casp, DMAP_CC_MSMA, (gint32) 0); _dmap_share_message_set_from_dmap_structure (share, message, casp); dmap_structure_destroy (casp); } else if (g_ascii_strcasecmp ("/1/playstatusupdate", rest_of_path) == 0) { gchar *revision = g_hash_table_lookup (query, "revision-number"); gint revision_number = atoi (revision); if (revision_number >= dacp_share->priv->current_revision) { g_object_ref (message); dacp_share->priv->update_queue = g_slist_prepend (dacp_share-> priv->update_queue, message); g_signal_connect_object (message, "finished", G_CALLBACK (status_update_message_finished), dacp_share, 0); soup_server_pause_message (server, message); } else { dacp_share_fill_playstatusupdate (dacp_share, message); } } else if (g_ascii_strcasecmp ("/1/playpause", rest_of_path) == 0) { dacp_player_play_pause (dacp_share->priv->player); soup_message_set_status (message, SOUP_STATUS_NO_CONTENT); } else if (g_ascii_strcasecmp ("/1/pause", rest_of_path) == 0) { dacp_player_pause (dacp_share->priv->player); soup_message_set_status (message, SOUP_STATUS_NO_CONTENT); } else if (g_ascii_strcasecmp ("/1/nextitem", rest_of_path) == 0) { dacp_player_next_item (dacp_share->priv->player); soup_message_set_status (message, SOUP_STATUS_NO_CONTENT); } else if (g_ascii_strcasecmp ("/1/previtem", rest_of_path) == 0) { dacp_player_prev_item (dacp_share->priv->player); soup_message_set_status (message, SOUP_STATUS_NO_CONTENT); } else if (g_ascii_strcasecmp ("/1/nowplayingartwork", rest_of_path) == 0) { guint width = 320; guint height = 320; gchar *artwork_filename; gchar *buffer; gsize buffer_len; if (g_hash_table_lookup (query, "mw")) width = atoi (g_hash_table_lookup (query, "mw")); if (g_hash_table_lookup (query, "mh")) height = atoi (g_hash_table_lookup (query, "mh")); artwork_filename = dacp_player_now_playing_artwork (dacp_share-> priv->player, width, height); if (!artwork_filename) { g_debug ("No artwork for currently playing song"); soup_message_set_status (message, SOUP_STATUS_NOT_FOUND); return; } #ifdef HAVE_GDKPIXBUF GdkPixbuf *artwork = gdk_pixbuf_new_from_file_at_scale (artwork_filename, width, height, TRUE, NULL); if (!artwork) { g_debug ("Error loading image file"); g_free (artwork_filename); soup_message_set_status (message, SOUP_STATUS_INTERNAL_SERVER_ERROR); return; } if (!gdk_pixbuf_save_to_buffer (artwork, &buffer, &buffer_len, "png", NULL, NULL)) { g_debug ("Error saving artwork to PNG"); g_object_unref (artwork); g_free (artwork_filename); soup_message_set_status (message, SOUP_STATUS_INTERNAL_SERVER_ERROR); return; } g_object_unref (artwork); #else if (!g_file_get_contents (artwork_filename, &buffer, &buffer_len, NULL)) { g_debug ("Error getting artwork data"); g_free (artwork_filename); soup_message_set_status (message, SOUP_STATUS_INTERNAL_SERVER_ERROR); return; } #endif g_free (artwork_filename); soup_message_set_status (message, SOUP_STATUS_OK); soup_message_set_response (message, "image/png", SOUP_MEMORY_TAKE, buffer, buffer_len); } else if (g_ascii_strcasecmp ("/1/cue", rest_of_path) == 0) { gchar *command; command = g_hash_table_lookup (query, "command"); if (!command) { g_debug ("No CUE command specified"); soup_message_set_status (message, SOUP_STATUS_NO_CONTENT); return; } else if (g_ascii_strcasecmp ("clear", command) == 0) { dacp_player_cue_clear (dacp_share->priv->player); soup_message_set_status (message, SOUP_STATUS_NO_CONTENT); } else if (g_ascii_strcasecmp ("play", command) == 0) { GNode *cacr; gchar *record_query; gchar *sort_by; GHashTable *records; GList *sorted_records; GSList *filter_def; DMAPDb *db; gint index = atoi (g_hash_table_lookup (query, "index")); g_object_get (share, "db", &db, NULL); record_query = g_hash_table_lookup (query, "query"); filter_def = _dmap_share_build_filter (record_query); records = dmap_db_apply_filter (db, filter_def); sorted_records = g_hash_table_get_values (records); sort_by = g_hash_table_lookup (query, "sort"); if (g_strcmp0 (sort_by, "album") == 0) { sorted_records = g_list_sort_with_data (sorted_records, (GCompareDataFunc) daap_record_cmp_by_album, db); } else if (sort_by != NULL) { g_warning ("Unknown sort column: %s", sort_by); } dacp_player_cue_play (dacp_share->priv->player, sorted_records, index); g_list_free (sorted_records); g_hash_table_unref (records); dmap_share_free_filter (filter_def); cacr = dmap_structure_add (NULL, DMAP_CC_CACR); dmap_structure_add (cacr, DMAP_CC_MSTT, DMAP_STATUS_OK); dmap_structure_add (cacr, DMAP_CC_MIID, index); _dmap_share_message_set_from_dmap_structure (share, message, cacr); dmap_structure_destroy (cacr); } else { g_warning ("Unhandled cue command: %s", command); soup_message_set_status (message, SOUP_STATUS_NO_CONTENT); return; } } else { g_warning ("Unhandled ctrl-int command: %s", rest_of_path); soup_message_set_status (message, SOUP_STATUS_BAD_REQUEST); } }
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); }
static void server_callback (SoupServer *server, SoupMessage *msg, const char *path, GHashTable *query, SoupClientContext *context, gpointer data) { SoupURI *uri = soup_message_get_uri (msg); const char *server_protocol = data; soup_message_headers_append (msg->response_headers, "X-Handled-By", "server_callback"); if (!strcmp (path, "*")) { debug_printf (1, " default server_callback got request for '*'!\n"); errors++; soup_message_set_status (msg, SOUP_STATUS_INTERNAL_SERVER_ERROR); return; } if (msg->method != SOUP_METHOD_GET && msg->method != SOUP_METHOD_POST) { soup_message_set_status (msg, SOUP_STATUS_NOT_IMPLEMENTED); return; } if (!strcmp (path, "/redirect")) { soup_message_set_redirect (msg, SOUP_STATUS_FOUND, "/"); return; } if (!strcmp (path, "/alias-redirect")) { SoupURI *redirect_uri; char *redirect_string; const char *redirect_protocol; redirect_protocol = soup_message_headers_get_one (msg->request_headers, "X-Redirect-Protocol"); redirect_uri = soup_uri_copy (uri); soup_uri_set_scheme (redirect_uri, "foo"); if (!g_strcmp0 (redirect_protocol, "https")) soup_uri_set_port (redirect_uri, ssl_base_uri->port); else soup_uri_set_port (redirect_uri, base_uri->port); soup_uri_set_path (redirect_uri, "/alias-redirected"); redirect_string = soup_uri_to_string (redirect_uri, FALSE); soup_message_set_redirect (msg, SOUP_STATUS_FOUND, redirect_string); g_free (redirect_string); soup_uri_free (redirect_uri); return; } else if (!strcmp (path, "/alias-redirected")) { soup_message_set_status (msg, SOUP_STATUS_OK); soup_message_headers_append (msg->response_headers, "X-Redirected-Protocol", server_protocol); return; } if (!strcmp (path, "/slow")) { soup_server_pause_message (server, msg); g_object_set_data (G_OBJECT (msg), "server", server); soup_add_timeout (soup_server_get_async_context (server), 1000, timeout_finish_message, msg); } soup_message_set_status (msg, SOUP_STATUS_OK); if (!strcmp (uri->host, "foo")) { soup_message_set_response (msg, "text/plain", SOUP_MEMORY_STATIC, "foo-index", 9); return; } else { soup_message_set_response (msg, "text/plain", SOUP_MEMORY_STATIC, "index", 5); return; } }
static void postal_http_handle_v1_users_user_devices_device (UrlRouter *router, SoupServer *server, SoupMessage *message, const gchar *path, GHashTable *params, GHashTable *query, SoupClientContext *client, gpointer user_data) { PostalDevice *pdev; const gchar *user; const gchar *device; PostalHttp *http = user_data; GError *error = NULL; JsonNode *node; ENTRY; g_assert(router); g_assert(SOUP_IS_SERVER(server)); g_assert(SOUP_IS_MESSAGE(message)); g_assert(path); g_assert(params); g_assert(g_hash_table_contains(params, "device")); g_assert(g_hash_table_contains(params, "user")); g_assert(client); g_assert(POSTAL_IS_HTTP(http)); device = g_hash_table_lookup(params, "device"); user = g_hash_table_lookup(params, "user"); if (message->method == SOUP_METHOD_GET) { postal_service_find_device(http->priv->service, user, device, NULL, /* TODO */ postal_http_find_device_cb, g_object_ref(message)); soup_server_pause_message(server, message); EXIT; } else if (message->method == SOUP_METHOD_DELETE) { pdev = g_object_new(POSTAL_TYPE_DEVICE, "device-token", device, "user", user, NULL); postal_service_remove_device(http->priv->service, pdev, NULL, /* TODO */ postal_http_remove_device_cb, g_object_ref(message)); soup_server_pause_message(server, message); g_object_unref(pdev); EXIT; } else if (message->method == SOUP_METHOD_PUT) { if (!(node = postal_http_parse_body(message, &error))) { postal_http_reply_error(http, message, error); soup_server_unpause_message(server, message); g_error_free(error); EXIT; } pdev = postal_device_new(); if (!postal_device_load_from_json(pdev, node, &error)) { postal_http_reply_error(http, message, error); soup_server_unpause_message(server, message); json_node_free(node); g_error_free(error); g_object_unref(pdev); EXIT; } postal_device_set_device_token(pdev, device); postal_device_set_user(pdev, user); json_node_free(node); g_object_set_data_full(G_OBJECT(message), "device", g_object_ref(pdev), g_object_unref); postal_service_add_device(http->priv->service, pdev, NULL, /* TODO */ postal_http_add_device_cb, g_object_ref(message)); soup_server_pause_message(server, message); g_object_unref(pdev); EXIT; } else { soup_message_set_status(message, SOUP_STATUS_METHOD_NOT_ALLOWED); EXIT; } g_assert_not_reached(); }
static void gss_adaptive_resource_get_content (GssTransaction * t, GssAdaptive * adaptive) { const char *stream; const char *start_time_str; const char *bitrate_str; guint64 start_time; guint64 bitrate; gboolean is_init; GssAdaptiveLevel *level; GssIsomFragment *fragment; gboolean ret; //GST_ERROR ("content request"); if (t->query == NULL) { gss_transaction_error_not_found (t, "no smooth streaming query"); return; } stream = g_hash_table_lookup (t->query, "stream"); if (stream == NULL) { gss_transaction_error_not_found (t, "missing stream parameterr"); return; } start_time_str = g_hash_table_lookup (t->query, "start_time"); if (start_time_str == NULL) { gss_transaction_error_not_found (t, "missing start_time parameter"); return; } bitrate_str = g_hash_table_lookup (t->query, "bitrate"); if (bitrate_str == NULL) { gss_transaction_error_not_found (t, "missing bitrate parameter"); return; } ret = parse_guint64 (bitrate_str, &bitrate); if (!ret) { gss_transaction_error_not_found (t, "bitrate is not a number"); return; } if (strcmp (start_time_str, "init") == 0) { is_init = TRUE; start_time = 0; } else { is_init = FALSE; ret = parse_guint64 (start_time_str, &start_time); if (!ret) { gss_transaction_error_not_found (t, "start_time is not a number or \"init\""); return; } } if (strcmp (stream, "audio") != 0 && strcmp (stream, "video") != 0) { gss_transaction_error_not_found (t, "stream is not \"audio\" or \"video\""); return; } level = gss_adaptive_get_level (adaptive, (stream[0] == 'v'), bitrate); if (level == NULL) { gss_transaction_error_not_found (t, "level not found for stream and bitrate"); return; } soup_message_headers_replace (t->msg->response_headers, "Content-Type", (stream[0] == 'v') ? "video/mp4" : "audio/mp4"); if (is_init) { soup_message_body_append (t->msg->response_body, SOUP_MEMORY_COPY, level->track->ccff_header_data, level->track->ccff_header_size); } else { GssAdaptiveQuery *query; fragment = gss_isom_track_get_fragment_by_timestamp (level->track, start_time); if (fragment == NULL) { gss_transaction_error_not_found (t, "fragment not found for start_time"); return; } //GST_ERROR ("frag %s %" G_GUINT64_FORMAT " %" G_GUINT64_FORMAT, // level->filename, fragment->offset, fragment->size); soup_server_pause_message (t->soupserver, t->msg); query = g_malloc0 (sizeof (GssAdaptiveQuery)); query->adaptive = adaptive; query->level = level; query->fragment = fragment; gss_transaction_process_async (t, gss_adaptive_async_assemble_chunk, gss_adaptive_async_assemble_chunk_finish, query); } }
static void gss_adaptive_resource_get_dash_range_fragment (GssTransaction * t, GssAdaptive * adaptive, const char *path) { gboolean have_range; SoupRange *ranges; int n_ranges; int index; GssAdaptiveLevel *level; gsize start, end; /* skip over content/ */ path += 8; if (path[0] != 'a' && path[0] != 'v') { GST_ERROR ("bad path: %s", path); return; } index = strtoul (path + 1, NULL, 10); level = NULL; if (path[0] == 'a') { if (index < adaptive->n_audio_levels) { level = &adaptive->audio_levels[index]; } } else { if (index < adaptive->n_video_levels) { level = &adaptive->video_levels[index]; } } if (level == NULL) { GST_ERROR ("bad level: %c%d from path %s", path[0], index, path); return; } if (t->msg->method == SOUP_METHOD_HEAD) { GST_DEBUG ("%s: HEAD", path); soup_message_headers_set_content_length (t->msg->response_headers, level->track->dash_size); return; } have_range = soup_message_headers_get_ranges (t->msg->request_headers, level->track->dash_size, &ranges, &n_ranges); if (have_range) { if (n_ranges != 1) { GST_ERROR ("too many ranges"); } start = ranges[0].start; end = ranges[0].end + 1; } else { start = 0; end = level->track->dash_size; } GST_DEBUG ("%s: range: %ld-%ld", path, start, end); t->start = start; t->end = end; if (have_range) { soup_message_headers_set_content_range (t->msg->response_headers, ranges[0].start, ranges[0].end, level->track->dash_size); soup_message_set_status (t->msg, SOUP_STATUS_PARTIAL_CONTENT); soup_message_headers_free_ranges (t->msg->response_headers, ranges); } else { soup_message_set_status (t->msg, SOUP_STATUS_OK); } soup_message_headers_replace (t->msg->response_headers, "Content-Type", (path[0] == 'v') ? "video/mp4" : "audio/mp4"); { GssAdaptiveQuery *query; soup_server_pause_message (t->soupserver, t->msg); query = g_malloc0 (sizeof (GssAdaptiveQuery)); query->adaptive = adaptive; query->level = level; gss_transaction_process_async (t, gss_adaptive_dash_range_async, gss_adaptive_dash_range_async_finish, query); } }
static void postal_http_handle_v1_users_user_badge (UrlRouter *router, SoupServer *server, SoupMessage *message, const gchar *path, GHashTable *params, GHashTable *query, SoupClientContext *client, gpointer user_data) { const gchar *user; PostalHttp *http = user_data; JsonNode *node = NULL; GError *error = NULL; guint badge; ENTRY; g_assert(router); g_assert(SOUP_IS_SERVER(server)); g_assert(SOUP_IS_MESSAGE(message)); g_assert(path); g_assert(params); g_assert(g_hash_table_contains(params, "user")); g_assert(client); g_assert(POSTAL_IS_HTTP(http)); user = g_hash_table_lookup(params, "user"); if (message->method == SOUP_METHOD_PUT) { if (!(node = postal_http_parse_body(message, &error)) || !JSON_NODE_HOLDS_VALUE(node)) { if (!error) { error = g_error_new(JSON_PARSER_ERROR, JSON_PARSER_ERROR_UNKNOWN, _("JSON must contain integer.")); } postal_http_reply_error(http, message, error); GOTO(cleanup); } badge = json_node_get_int(node); g_object_set_data(G_OBJECT(message), "http", http); postal_service_set_user_badge(http->priv->service, user, badge, NULL, postal_http_set_user_badge_cb, g_object_ref(message)); soup_server_pause_message(server, message); EXIT; } soup_message_set_status(message, SOUP_STATUS_METHOD_NOT_ALLOWED); cleanup: g_clear_error(&error); if (node) { json_node_free(node); } EXIT; }
static void postal_http_handle_v1_notify (UrlRouter *router, SoupServer *server, SoupMessage *message, const gchar *path, GHashTable *params, GHashTable *query, SoupClientContext *client, gpointer user_data) { PostalNotification *notif; const gchar *collapse_key = NULL; const gchar *str; PostalHttp *http = user_data; JsonObject *aps; JsonObject *c2dm; JsonObject *gcm; JsonObject *object; JsonArray *devices; JsonArray *users; GPtrArray *devices_ptr; GPtrArray *users_ptr; JsonNode *node; GError *error = NULL; guint count; guint i; g_assert(SOUP_IS_SERVER(server)); g_assert(SOUP_IS_MESSAGE(message)); g_assert(path); g_assert(client); g_assert(POSTAL_IS_HTTP(http)); if (message->method != SOUP_METHOD_POST) { soup_message_set_status(message, SOUP_STATUS_METHOD_NOT_ALLOWED); return; } soup_server_pause_message(server, message); if (!(node = postal_http_parse_body(message, &error))) { postal_http_reply_error(http, message, error); g_error_free(error); return; } if (!JSON_NODE_HOLDS_OBJECT(node) || !(object = json_node_get_object(node)) || !json_object_has_member(object, "aps") || !(node = json_object_get_member(object, "aps")) || !JSON_NODE_HOLDS_OBJECT(node) || !(aps = json_object_get_object_member(object, "aps")) || !json_object_has_member(object, "c2dm") || !(node = json_object_get_member(object, "c2dm")) || !JSON_NODE_HOLDS_OBJECT(node) || !(c2dm = json_object_get_object_member(object, "c2dm")) || !json_object_has_member(object, "gcm") || !(node = json_object_get_member(object, "gcm")) || !JSON_NODE_HOLDS_OBJECT(node) || !(gcm = json_object_get_object_member(object, "gcm")) || !json_object_has_member(object, "users") || !(node = json_object_get_member(object, "users")) || !JSON_NODE_HOLDS_ARRAY(node) || !(users = json_object_get_array_member(object, "users")) || !json_object_has_member(object, "devices") || !(node = json_object_get_member(object, "devices")) || !JSON_NODE_HOLDS_ARRAY(node) || !(devices = json_object_get_array_member(object, "devices"))) { error = g_error_new(postal_json_error_quark(), 0, "Missing or invalid fields in JSON payload."); postal_http_reply_error(http, message, error); json_node_free(node); g_error_free(error); return; } if (json_object_has_member(object, "collapse_key") && (node = json_object_get_member(object, "collapse_key")) && JSON_NODE_HOLDS_VALUE(node)) { collapse_key = json_node_get_string(node); } notif = g_object_new(POSTAL_TYPE_NOTIFICATION, "aps", aps, "c2dm", c2dm, "collapse-key", collapse_key, "gcm", gcm, NULL); count = json_array_get_length(users); users_ptr = g_ptr_array_sized_new(count); for (i = 0; i < count; i++) { node = json_array_get_element(users, i); if (json_node_get_value_type(node) == G_TYPE_STRING) { str = json_node_get_string(node); g_ptr_array_add(users_ptr, (gchar *)str); } } g_ptr_array_add(users_ptr, NULL); count = json_array_get_length(devices); devices_ptr = g_ptr_array_sized_new(count); g_ptr_array_set_free_func(devices_ptr, g_free); for (i = 0; i < count; i++) { node = json_array_get_element(devices, i); if (json_node_get_value_type(node) == G_TYPE_STRING) { str = json_node_get_string(node); g_ptr_array_add(devices_ptr, g_strdup(str)); } } g_ptr_array_add(devices_ptr, NULL); postal_service_notify(http->priv->service, notif, (gchar **)users_ptr->pdata, (gchar **)devices_ptr->pdata, NULL, /* TODO: Cancellable/Timeout? */ postal_http_notify_cb, g_object_ref(message)); g_ptr_array_unref(devices_ptr); g_ptr_array_unref(users_ptr); json_node_free(node); g_object_unref(notif); }