[gtk+/broadway: 17/71] Add initial http server
- From: Alexander Larsson <alexl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/broadway: 17/71] Add initial http server
- Date: Thu, 25 Nov 2010 21:16:41 +0000 (UTC)
commit ded9bc698bc822a939cad9155454e0c3e6754e3b
Author: Alexander Larsson <alexl redhat com>
Date: Thu Nov 18 13:17:23 2010 +0100
Add initial http server
gdk/broadway/gdkdisplay-broadway.c | 113 ++++++++++++++++++++++++++++++++++++
gdk/broadway/gdkdisplay-broadway.h | 1 +
2 files changed, 114 insertions(+), 0 deletions(-)
---
diff --git a/gdk/broadway/gdkdisplay-broadway.c b/gdk/broadway/gdkdisplay-broadway.c
index a2d2d27..be618cf 100644
--- a/gdk/broadway/gdkdisplay-broadway.c
+++ b/gdk/broadway/gdkdisplay-broadway.c
@@ -122,6 +122,106 @@ _gdk_input_init (GdkDisplay *display)
g_list_free (list);
}
+typedef struct {
+ GdkDisplay *display;
+ GSocketConnection *connection;
+ GDataInputStream *data;
+ GString *request;
+} HttpRequest;
+
+static void
+http_request_free (HttpRequest *request)
+{
+ g_object_unref (request->connection);
+ g_object_unref (request->data);
+ g_string_free (request->request, TRUE);
+ g_free (request);
+}
+
+static void
+send_error (HttpRequest *request,
+ int error_code,
+ const char *reason)
+{
+ char *res;
+
+ res = g_strdup_printf ("HTTP/1.0 %d %s\r\n\r\n"
+ "<html><head><title>%d %s</title></head>"
+ "<body>%s</body></html>",
+ error_code, reason,
+ error_code, reason,
+ reason);
+ /* TODO: This should really be async */
+ g_output_stream_write_all (g_io_stream_get_output_stream (G_IO_STREAM (request->connection)),
+ res, strlen (res), NULL, NULL, NULL);
+ g_free (res);
+ http_request_free (request);
+}
+
+static void
+got_request (HttpRequest *request)
+{
+ g_print ("got request:\n%s", request->request->str);
+ send_error (request, 404, "Not implemented yet");
+}
+
+static void
+got_http_request_line (GOutputStream *stream,
+ GAsyncResult *result,
+ HttpRequest *request)
+{
+ char *line;
+
+ line = g_data_input_stream_read_line_finish (G_DATA_INPUT_STREAM (stream), result, NULL, NULL);
+ if (line == NULL)
+ {
+ http_request_free (request);
+ g_printerr ("Error reading request lines\n");
+ return;
+ }
+ if (strlen (line) == 0)
+ got_request (request);
+ else
+ {
+ /* Protect against overflow in request length */
+ if (request->request->len > 1024 * 5)
+ {
+ send_error (request, 400, "Request to long");
+ }
+ else
+ {
+ g_string_append_printf (request->request, "%s\n", line);
+ g_data_input_stream_read_line_async (request->data, 0, NULL,
+ (GAsyncReadyCallback)got_http_request_line, request);
+ }
+ }
+ g_free (line);
+}
+
+static gboolean
+handle_incoming_connection (GSocketService *service,
+ GSocketConnection *connection,
+ GObject *source_object)
+{
+ HttpRequest *request;
+ GInputStream *in;
+
+ request = g_new0 (HttpRequest, 1);
+ request->connection = g_object_ref (connection);
+ request->display = (GdkDisplay *) source_object;
+ request->request = g_string_new ("");
+
+ in = g_io_stream_get_input_stream (G_IO_STREAM (connection));
+
+ request->data = g_data_input_stream_new (in);
+ /* Be tolerant of input */
+ g_data_input_stream_set_newline_type (request->data, G_DATA_STREAM_NEWLINE_TYPE_ANY);
+
+ g_data_input_stream_read_line_async (request->data, 0, NULL,
+ (GAsyncReadyCallback)got_http_request_line, request);
+ return TRUE;
+}
+
GdkDisplay *
gdk_display_open (const gchar *display_name)
{
@@ -129,6 +229,7 @@ gdk_display_open (const gchar *display_name)
GdkDisplayBroadway *display_broadway;
const char *sm_client_id;
int fd;
+ GError *error;
fd = dup(STDOUT_FILENO);
dup2(STDERR_FILENO, STDOUT_FILENO);
@@ -163,6 +264,18 @@ gdk_display_open (const gchar *display_name)
_gdk_broadway_screen_setup (display_broadway->screens[0]);
+ display_broadway->service = g_socket_service_new ();
+ if (!g_socket_listener_add_inet_port (G_SOCKET_LISTENER (display_broadway->service),
+ 8080,
+ G_OBJECT (display),
+ &error))
+ {
+ g_printerr ("Unable to listen to port %d: %s\n", 8080, error->message);
+ g_error_free (error);
+ return NULL;
+ }
+ g_signal_connect (display_broadway->service, "incoming", G_CALLBACK (handle_incoming_connection), NULL);
+
g_signal_emit_by_name (display, "opened");
g_signal_emit_by_name (gdk_display_manager_get (), "display-opened", display);
diff --git a/gdk/broadway/gdkdisplay-broadway.h b/gdk/broadway/gdkdisplay-broadway.h
index e8a43de..3317b5b 100644
--- a/gdk/broadway/gdkdisplay-broadway.h
+++ b/gdk/broadway/gdkdisplay-broadway.h
@@ -74,6 +74,7 @@ struct _GdkDisplayBroadway
/* The offscreen window that has the pointer in it (if any) */
GdkWindow *active_offscreen_window;
+ GSocketService *service;
BroadwayClient *connection;
};
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]