#include "httpd.h" #include "httpd_commands.h" #include "conf.h" #include #include GSocketService *ss = NULL; static gboolean service_incoming(GSocketService *service, GSocketConnection *connection, GObject *source_object, gpointer user_data) { GSocket *socket; GError *error = NULL; g_debug("incoming connection to service"); socket = g_socket_connection_get_socket(connection); if(socket == NULL) { g_warning("g_socket_connection_get_socket() returned NULL"); return FALSE; } GString *string = g_string_new(NULL); gboolean done = FALSE; gssize tot = 0; while(done == FALSE) { gchar buffer[0x400]; gssize len = g_socket_receive(socket, buffer, 0x400, NULL, &error); if(len == -1) { g_warning(error->message); g_error_free(error); g_string_free(string, TRUE); return FALSE; } tot += len; g_string_append_len(string, buffer, len); /* TODO: find a more sane way to stop reading */ if(string->len >= 4 && g_strcmp0(string->str + string->len - 4, "\r\n\r\n") == 0) { done = TRUE; } } g_debug("read %lu bytes", tot); g_debug("HTTP header:\n%s", string->str); /* split headers */ gchar **data = g_strsplit(string->str, "\r\n", 0); g_string_free(string, TRUE); gchar **firstline = g_strsplit(data[0], " ", 0); /* this sets the first character of the last string in * firstline to \0 (HTTP version) */ firstline[g_strv_length(firstline)-1] = '\0'; /* now join from the second string to get the request path */ gchar *path_escaped = g_strjoinv(" ", firstline + 1); gchar *path = g_uri_unescape_string(path_escaped, NULL); g_free(path_escaped); g_strfreev(firstline); for(gint i = 1; strlen(data[i]); i++) { g_debug("data[%d] = %s", i, data[i]); } g_strfreev(data); httpd_commands_handle(connection, path); g_free(path); if(g_socket_close(socket, &error) == FALSE) { g_warning(error->message); g_error_free(error); } return FALSE; } gboolean httpd_start() { gint port = conf_get_int("audist", "httpd_port"); if(port <= 0) { g_warning("invalid httpd port"); return FALSE; } ss = g_threaded_socket_service_new(10); g_socket_listener_add_inet_port((GSocketListener*)ss, port, NULL, NULL); g_signal_connect(ss, "incoming", (GCallback)service_incoming, NULL); g_socket_service_start(ss); return TRUE; } void httpd_stop() { g_socket_service_stop(ss); g_object_unref(ss); ss = NULL; }