Exemple #1
0
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);
}
Exemple #3
0
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);
	}
}
Exemple #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);
}
Exemple #5
0
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);
}
Exemple #7
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);
}
Exemple #8
0
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);
}