static void process_image_callback (SoupServer *server, SoupMessage *msg, const char *path, GHashTable *query, SoupClientContext *context, gpointer user_data) { UiConnection *self = (UiConnection *)user_data; // Lookup network Network *network = NULL; { const gchar *graph_id = g_hash_table_lookup(query, "graph"); network = (graph_id) ? g_hash_table_lookup(self->network_map, graph_id) : NULL; } if (!network) { soup_message_set_status_full(msg, SOUP_STATUS_BAD_REQUEST, "'graph' not specified or wrong"); return; } // Lookup node Processor *processor = NULL; { const gchar *node_id = g_hash_table_lookup(query, "node"); processor = (node_id) ? network_processor(network, node_id) : NULL; } if (!processor) { soup_message_set_status_full(msg, SOUP_STATUS_BAD_REQUEST, "'node' not specified or wrong"); return; } // Render output // FIXME: allow region-of-interest and scale as query params gchar *rgba = NULL; GeglRectangle roi; const gboolean success = processor_blit(processor, babl_format("R'G'B'A u8"), &roi, &rgba); if (!success) { soup_message_set_status(msg, SOUP_STATUS_BAD_REQUEST); g_free(rgba); return; } if (!(roi.width > 0 && roi.height > 0)) { soup_message_set_status(msg, SOUP_STATUS_BAD_REQUEST); g_free(rgba); return; } // Compress to PNG { PngEncoder *encoder = png_encoder_new(); png_encoder_encode_rgba(encoder, roi.width, roi.height, rgba); char *png = encoder->buffer; const size_t len = encoder->size; soup_message_set_status(msg, SOUP_STATUS_OK); soup_message_set_response(msg, "image/png", SOUP_MEMORY_COPY, png, len); png_encoder_free(encoder); } }
static void io_error (SoupSocket *sock, SoupMessage *msg, GError *error) { SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg); SoupMessageIOData *io = priv->io_data; if (error && error->domain == SOUP_SSL_ERROR) { soup_message_set_status_full (msg, SOUP_STATUS_SSL_FAILED, error->message); } else if (io->mode == SOUP_MESSAGE_IO_CLIENT && io->read_state <= SOUP_MESSAGE_IO_STATE_HEADERS && io->read_meta_buf->len == 0 && !g_error_matches (error, G_IO_ERROR, G_IO_ERROR_TIMED_OUT) && request_is_idempotent (msg)) { /* Connection got closed, but we can safely try again */ priv->io_status = SOUP_MESSAGE_IO_STATUS_QUEUED; } else if (!SOUP_STATUS_IS_TRANSPORT_ERROR (msg->status_code)) soup_message_set_status (msg, SOUP_STATUS_IO_ERROR); if (error) g_error_free (error); soup_message_io_finished (msg); }
static void redirect_handler (SoupMessage *msg, gpointer user_data) { if (SOUP_STATUS_IS_REDIRECTION (msg->status_code)) { CallbackInfo *info = user_data; SoupURI *new_uri; const gchar *new_loc; new_loc = soup_message_headers_get (msg->response_headers, "Location"); if (!new_loc) return; info->reset=1; new_uri = soup_uri_new_with_base (soup_message_get_uri (msg), new_loc); if (!new_uri) { soup_message_set_status_full (msg, SOUP_STATUS_MALFORMED, "Invalid Redirect URL"); return; } soup_message_set_uri (msg, new_uri); soup_session_requeue_message (info->ss, msg); soup_uri_free (new_uri); } }
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); }
static void io_error (SoupSocket *sock, SoupMessage *msg, GError *error) { if (!SOUP_STATUS_IS_TRANSPORT_ERROR (msg->status_code)) { if (error && error->domain == SOUP_SSL_ERROR) { soup_message_set_status_full (msg, SOUP_STATUS_SSL_FAILED, error->message); } else soup_message_set_status (msg, SOUP_STATUS_IO_ERROR); } if (error) g_error_free (error); soup_message_io_finished (msg); }
static void io_run (SoupMessage *msg, gboolean blocking) { SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg); SoupMessageIOData *io = priv->io_data; GError *error = NULL; GCancellable *cancellable; if (io->io_source) { g_source_destroy (io->io_source); g_source_unref (io->io_source); io->io_source = NULL; } g_object_ref (msg); cancellable = io->cancellable ? g_object_ref (io->cancellable) : NULL; if (io_run_until (msg, blocking, SOUP_MESSAGE_IO_STATE_DONE, SOUP_MESSAGE_IO_STATE_DONE, cancellable, &error)) { soup_message_io_finished (msg); } else if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)) { g_clear_error (&error); io->io_source = soup_message_io_get_source (msg, NULL, io_run_ready, msg); g_source_attach (io->io_source, io->async_context); } else if (error && priv->io_data == io) { if (g_error_matches (error, SOUP_HTTP_ERROR, SOUP_STATUS_TRY_AGAIN)) io->item->state = SOUP_MESSAGE_RESTARTING; else if (error->domain == G_TLS_ERROR) { soup_message_set_status_full (msg, SOUP_STATUS_SSL_FAILED, error->message); } else if (!SOUP_STATUS_IS_TRANSPORT_ERROR (msg->status_code)) soup_message_set_status (msg, SOUP_STATUS_IO_ERROR); g_error_free (error); soup_message_io_finished (msg); } else if (error) g_error_free (error); g_object_unref (msg); g_clear_object (&cancellable); }
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); }
static void redirect_handler (SoupMessage *msg, gpointer user_data) { SoupSession *session = user_data; const char *new_loc; SoupURI *new_uri; new_loc = soup_message_headers_get_one (msg->response_headers, "Location"); g_return_if_fail (new_loc != NULL); if (msg->status_code == SOUP_STATUS_SEE_OTHER || (msg->status_code == SOUP_STATUS_FOUND && !SOUP_METHOD_IS_SAFE (msg->method))) { /* Redirect using a GET */ g_object_set (msg, SOUP_MESSAGE_METHOD, SOUP_METHOD_GET, NULL); soup_message_set_request (msg, NULL, SOUP_MEMORY_STATIC, NULL, 0); soup_message_headers_set_encoding (msg->request_headers, SOUP_ENCODING_NONE); } else if (msg->status_code == SOUP_STATUS_MOVED_PERMANENTLY || msg->status_code == SOUP_STATUS_TEMPORARY_REDIRECT || msg->status_code == SOUP_STATUS_FOUND) { /* Don't redirect non-safe methods */ if (!SOUP_METHOD_IS_SAFE (msg->method)) return; } else { /* Three possibilities: * * 1) This was a non-3xx response that happened to * have a "Location" header * 2) It's a non-redirecty 3xx response (300, 304, * 305, 306) * 3) It's some newly-defined 3xx response (308+) * * We ignore all of these cases. In the first two, * redirecting would be explicitly wrong, and in the * last case, we have no clue if the 3xx response is * supposed to be redirecty or non-redirecty. Plus, * 2616 says unrecognized status codes should be * treated as the equivalent to the x00 code, and we * don't redirect on 300, so therefore we shouldn't * redirect on 308+ either. */ return; } /* Location is supposed to be an absolute URI, but some sites * are lame, so we use soup_uri_new_with_base(). */ new_uri = soup_uri_new_with_base (soup_message_get_uri (msg), new_loc); if (!new_uri) { soup_message_set_status_full (msg, SOUP_STATUS_MALFORMED, "Invalid Redirect URL"); return; } soup_message_set_uri (msg, new_uri); soup_uri_free (new_uri); soup_session_requeue_message (session, msg); }