예제 #1
0
GDataOutputStream *ekg_connection_add(
		GSocketConnection *conn,
		GInputStream *raw_instream,
		GOutputStream *raw_outstream,
		ekg_input_callback_t callback,
		ekg_failure_callback_t failure_callback,
		gpointer priv_data)
{
	struct ekg_connection *c = g_slice_new(struct ekg_connection);
	GOutputStream *bout = g_buffered_output_stream_new(raw_outstream);

	c->conn = conn;
	c->instream = g_data_input_stream_new(raw_instream);
	c->outstream = g_data_output_stream_new(bout);
	c->cancellable = g_cancellable_new();
	c->wr_buffer = g_string_new("");

	c->callback = callback;
	c->failure_callback = failure_callback;
	c->priv_data = priv_data;

#if NEED_SLAVERY
	c->master = get_slave_connection_by_conn(conn);
	c->slave = NULL;

		/* be a good slave.. er, servant */
	if (G_UNLIKELY(c->master)) {
		struct ekg_connection *ci;
		c->master->slave = c;

		/* shift flush handlers (if set)
		 * this is required in order to be able to easily set flush
		 * handlers for future slaves */
		for (ci = c;
				ci->master && (ci->master->flush_handler != setup_async_write);
				ci = ci->master)
			ci->flush_handler = ci->master->flush_handler;
		ci->flush_handler = setup_async_write;
	} else
#endif
		c->flush_handler = setup_async_write;

		/* LF works fine for CRLF */
	g_data_input_stream_set_newline_type(c->instream, G_DATA_STREAM_NEWLINE_TYPE_LF);
		/* disallow any blocking writes */
	g_buffered_output_stream_set_auto_grow(G_BUFFERED_OUTPUT_STREAM(bout), TRUE);

	connections = g_slist_prepend(connections, c);
#if NEED_SLAVERY
	if (G_LIKELY(!c->master))
#endif
		setup_async_read(c);

	return c->outstream;
}
예제 #2
0
static gboolean on_incoming_connection(GThreadedSocketService *service,
    GSocketConnection *connection, GObject *source_object, OwrImageServer *image_server)
{
    GOutputStream *bos;
    GDataInputStream *dis;
    gchar *error_body, *error_header = NULL, *response_header = NULL;
    gchar *line, *tag;
    gsize line_length, i;
    guint content_length = 0;
    OwrImageRenderer *image_renderer;
    GBytes *image;
    gconstpointer image_data;
    gsize image_data_size = 0;

    OWR_UNUSED(service);
    OWR_UNUSED(source_object);

    g_return_val_if_fail(OWR_IS_IMAGE_SERVER(image_server), TRUE);

    bos = g_buffered_output_stream_new(g_io_stream_get_output_stream(G_IO_STREAM(connection)));
    dis = g_data_input_stream_new(g_io_stream_get_input_stream(G_IO_STREAM(connection)));
    g_data_input_stream_set_newline_type(dis, G_DATA_STREAM_NEWLINE_TYPE_CR_LF);

    error_body = "404 Not Found";
    error_header = g_strdup_printf(HTTP_RESPONSE_HEADER_TEMPLATE, 404, "Not Found",
        "text/plain", (guint)strlen(error_body));

    while (TRUE) {
        line = g_data_input_stream_read_line(dis, &line_length, NULL, NULL);
        if (!line)
            break;

        if (line_length > 6) {
            tag = g_strdup(line + 7);
            for (i = 0; i < strlen(tag); i++) {
                if (tag[i] == '-') {
                    tag[i] = '\0';
                    break;
                }
            }
        } else
            tag = NULL;

        g_free(line);

        while ((line = g_data_input_stream_read_line(dis, &line_length, NULL, NULL))) {
            g_free(line);

            if (!line_length) {
                /* got all request headers */
                break;
            }
        }

        if (!line)
            break;

        g_mutex_lock(&image_server->priv->image_renderers_mutex);
        image_renderer = tag ? g_hash_table_lookup(image_server->priv->image_renderers, tag) : NULL;
        g_mutex_unlock(&image_server->priv->image_renderers_mutex);

        image = image_renderer ? _owr_image_renderer_pull_bmp_image(image_renderer) : NULL;

        if (!image) {
            g_output_stream_write(bos, error_header, strlen(error_header), NULL, NULL);
            g_output_stream_write(bos, error_body, strlen(error_body), NULL, NULL);
            break;
        }

        image_data = g_bytes_get_data(image, &image_data_size);

        if (content_length != image_data_size) {
            content_length = image_data_size;
            g_free(response_header);
            response_header = g_strdup_printf(HTTP_RESPONSE_HEADER_TEMPLATE, 200, "OK",
                "image/bmp", content_length);
            g_buffered_output_stream_set_buffer_size(G_BUFFERED_OUTPUT_STREAM(bos),
                strlen(response_header) + content_length);
        }
        g_output_stream_write(bos, response_header, strlen(response_header), NULL, NULL);
        g_output_stream_write(bos, image_data, image_data_size, NULL, NULL);
        g_output_stream_flush(bos, NULL, NULL);

        g_bytes_unref(image);
    }

    g_free(response_header);
    g_free(error_header);
    g_object_unref(dis);
    g_object_unref(bos);

    return FALSE;
}