static void
server_callback (SoupServer        *server,
		 SoupMessage       *msg,
		 const char        *path,
		 GHashTable        *query,
		 SoupClientContext *client,
		 gpointer           user_data)
{
	RemoteDisplayHost *host = user_data;
	RemoteDisplayHostPrivate *priv = GET_PRIVATE (host);
	RemoteDisplayHostFile *file;

	if (!client_allowed (host, client)) {
		g_debug ("Client %s not allowed", soup_client_context_get_host (client));
		soup_message_set_status (msg, SOUP_STATUS_FORBIDDEN);
		return;
	}

	if (msg->method != SOUP_METHOD_GET &&
	    msg->method != SOUP_METHOD_HEAD) {
		g_debug ("Method is not GET or HEAD");
		soup_message_set_status (msg, SOUP_STATUS_NOT_IMPLEMENTED);
		return;
	}

	if (path == NULL || *path != '/') {
		g_debug ("Invalid path '%s'requested", path);
		soup_message_set_status (msg, SOUP_STATUS_NOT_FOUND);
		return;
	}

	file = g_hash_table_lookup (priv->files, path + 1);
	if (!file) {
		soup_message_set_status (msg, SOUP_STATUS_NOT_FOUND);
		return;
	}

	if (!file->mapped_file) {
		file->mapped_file = g_mapped_file_new (file->path, FALSE, NULL);
		if (!file->mapped_file) {
			soup_message_set_status (msg, SOUP_STATUS_NOT_FOUND);
			return;
		}
	}

	if (msg->method == SOUP_METHOD_GET) {
		soup_message_set_response (msg, file->mime_type,
					   SOUP_MEMORY_STATIC,
					   g_mapped_file_get_contents (file->mapped_file),
					   g_mapped_file_get_length (file->mapped_file));
	} else {
		soup_message_headers_set_content_type (msg->response_headers,
						       file->mime_type, NULL);

		soup_message_headers_set_content_length (msg->response_headers,
							 g_mapped_file_get_length (file->mapped_file));
	}

	soup_message_set_status(msg, SOUP_STATUS_OK);
}
Beispiel #2
0
SnraServerClient *
snra_server_client_new (SoupServer * soup, SoupMessage * msg,
                        SoupClientContext * context)
{
    SnraServerClient *client = g_object_new (SNRA_TYPE_SERVER_CLIENT, NULL);
    const gchar *accept_challenge;
    gchar *accept_reply;

    client->soup = soup;
    client->event_pipe = msg;
    client->host = g_strdup (soup_client_context_get_host (context));

    client->net_event_sig = g_signal_connect (msg, "network-event",
                            G_CALLBACK (snra_server_client_network_event), client);
    client->disco_sig = g_signal_connect (msg, "finished",
                                          G_CALLBACK (snra_server_client_disconnect), client);

    if (!is_websocket_client (client)) {
        client->type = SNRA_SERVER_CLIENT_CHUNKED;
        client->need_body_complete = TRUE;

        soup_message_headers_set_encoding (msg->response_headers,
                                           SOUP_ENCODING_CHUNKED);
        soup_message_set_status (msg, SOUP_STATUS_OK);
        return client;
    }

    /* Otherwise, it's a websocket client */
    client->type = SNRA_SERVER_CLIENT_WEBSOCKET;
    client->need_body_complete = FALSE;

    client->socket = soup_client_context_get_socket (context);
    client->in_bufptr = client->in_buf = g_new0 (gchar, 1024);
    client->in_bufsize = 1024;
    client->in_bufavail = 0;

    accept_challenge =
        soup_message_headers_get_one (msg->request_headers, "Sec-WebSocket-Key");
    accept_reply = calc_websocket_challenge_reply (accept_challenge);

    soup_message_headers_set_encoding (msg->response_headers, SOUP_ENCODING_EOF);

    soup_message_set_status (msg, SOUP_STATUS_SWITCHING_PROTOCOLS);
    soup_message_headers_replace (msg->response_headers, "Upgrade", "websocket");
    soup_message_headers_replace (msg->response_headers, "Connection", "Upgrade");
    soup_message_headers_replace (msg->response_headers, "Sec-WebSocket-Accept",
                                  accept_reply);
    soup_message_headers_replace (msg->response_headers, "Sec-WebSocket-Protocol",
                                  "aurena");

    g_free (accept_reply);

    client->wrote_info_sig = g_signal_connect (msg, "wrote-informational",
                             G_CALLBACK (snra_server_client_wrote_headers), client);

    return client;
}
Beispiel #3
0
static void trap_callback(SoupServer *server, SoupMessage *msg,
	const char *path, GHashTable *query,
	SoupClientContext *client, gpointer user_data)
{
	g_print("%s\n", path);
	rest_parse(path, NULL);
	SoupHTTPVersion version = soup_message_get_http_version(msg);
	if (version == SOUP_HTTP_1_0)
		g_print("1\n");
	if (version == SOUP_HTTP_1_1)
		g_print("1.1\n");
	g_print("%s\n", soup_client_context_get_host(client));

	trex_callback(server, msg, path, query, "http://127.0.0.1");
}
Beispiel #4
0
SnraServerClient *
snra_server_client_new_single (SoupServer * soup, SoupMessage * msg,
                               G_GNUC_UNUSED SoupClientContext * context)
{
    SnraServerClient *client = g_object_new (SNRA_TYPE_SERVER_CLIENT, NULL);

    client->soup = soup;
    client->event_pipe = msg;
    client->host = g_strdup (soup_client_context_get_host (context));

    client->net_event_sig = g_signal_connect (msg, "network-event",
                            G_CALLBACK (snra_server_client_network_event), client);
    client->disco_sig = g_signal_connect (msg, "finished",
                                          G_CALLBACK (snra_server_client_disconnect), client);

    client->type = SNRA_SERVER_CLIENT_SINGLE;
    client->need_body_complete = TRUE;

    soup_message_set_status (msg, SOUP_STATUS_OK);
    soup_server_pause_message (client->soup, msg);

    return client;
}
Beispiel #5
0
static void
korva_upnp_file_server_handle_request (SoupServer        *server,
                                       SoupMessage       *msg,
                                       const char        *path,
                                       GHashTable        *query,
                                       SoupClientContext *client,
                                       gpointer           user_data)
{
    KorvaUPnPFileServer *self = KORVA_UPNP_FILE_SERVER (user_data);
    GMatchInfo *info;
    char *id;
    GFile *file;
    KorvaUPnPHostData *data;
    ServeData *serve_data;
    SoupRange *ranges = NULL;
    int length;
    const char *content_features;
    GError *error = NULL;
    goffset size;

    if (msg->method != SOUP_METHOD_HEAD &&
        msg->method != SOUP_METHOD_GET) {
        soup_message_set_status (msg, SOUP_STATUS_METHOD_NOT_ALLOWED);

        return;
    }

    g_debug ("Got %s request for uri: %s", msg->method, path);
    soup_message_headers_foreach (msg->request_headers, print_header, NULL);

    soup_server_pause_message (server, msg);
    soup_message_set_status (msg, SOUP_STATUS_OK);

    if (!g_regex_match (self->priv->path_regex,
                        path,
                        0,
                        &info)) {
        soup_message_set_status (msg, SOUP_STATUS_NOT_FOUND);
        g_match_info_free (info);

        goto out;
    }

    id = g_match_info_fetch (info, 1);
    g_match_info_free (info);

    file = g_hash_table_lookup (self->priv->id_map, id);
    g_free (id);

    if (file == NULL) {
        soup_message_set_status (msg, SOUP_STATUS_NOT_FOUND);

        goto out;
    }

    data = g_hash_table_lookup (self->priv->host_data, file);
    if (data == NULL) {
        soup_message_set_status (msg, SOUP_STATUS_NOT_FOUND);

        goto out;
    }

    if (!korva_upnp_host_data_valid_for_peer (data, soup_client_context_get_host (client))) {
        soup_message_set_status (msg, SOUP_STATUS_NOT_FOUND);

        goto out;
    }

    serve_data = g_slice_new0 (ServeData);
    serve_data->host_data = data;
    g_object_add_weak_pointer (G_OBJECT (data), (gpointer *) &(serve_data->host_data));
    korva_upnp_host_data_add_request (data);
    size = korva_upnp_host_data_get_size (data);
    if (soup_message_headers_get_ranges (msg->request_headers, size, &ranges, &length)) {
        goffset start, end;
        start = ranges[0].start;
        end = ranges[0].end;

        if (start > size || start > end || end > size) {
            soup_message_set_status (msg, SOUP_STATUS_REQUESTED_RANGE_NOT_SATISFIABLE);
            g_slice_free (ServeData, serve_data);

            goto out;
        } else {
            soup_message_set_status (msg, SOUP_STATUS_PARTIAL_CONTENT);
            soup_message_headers_set_content_range (msg->response_headers, start, end, size);
        }
        serve_data->start = start;
        serve_data->end = end;
    } else {
        serve_data->start = 0;
        serve_data->end = size - 1;
        soup_message_set_status (msg, SOUP_STATUS_OK);
    }

    soup_message_headers_set_content_length (msg->response_headers,
                                             serve_data->end - serve_data->start + 1);
    soup_message_headers_set_content_type (msg->response_headers,
                                           korva_upnp_host_data_get_content_type (data),
                                           NULL);

    content_features = soup_message_headers_get_one (msg->request_headers,
                                                     "getContentFeatures.dlna.org");
    if (content_features != NULL && atol (content_features) == 1) {
        const GVariant *value;

        value = korva_upnp_host_data_lookup_meta_data (data, "DLNAProfile");
        if (value == NULL) {
            soup_message_headers_append (msg->response_headers,
                                         "contentFeatures.dlna.org", "*");
        } else {
            soup_message_headers_append (msg->response_headers,
                                         "contentFeatures.dlna.org",
                                         korva_upnp_host_data_get_protocol_info (data));
        }
    }

    soup_message_headers_append (msg->response_headers, "Connection", "close");

    g_debug ("Response headers:");
    soup_message_headers_foreach (msg->response_headers, print_header, NULL);

    if (g_ascii_strcasecmp (msg->method, "HEAD") == 0) {
        g_debug ("Handled HEAD request of %s: %d", path, msg->status_code);
        g_slice_free (ServeData, serve_data);

        goto out;
    }

    soup_message_headers_set_encoding (msg->response_headers, SOUP_ENCODING_CONTENT_LENGTH);
    soup_message_body_set_accumulate (msg->response_body, FALSE);

    serve_data->stream = G_INPUT_STREAM (g_file_read (file, NULL, &error));
    serve_data->server = server;
    if (error != NULL) {
        g_warning ("Failed to MMAP file %s: %s",
                   path,
                   error->message);

        g_error_free (error);
        g_slice_free (ServeData, serve_data);

        soup_message_set_status (msg, SOUP_STATUS_INTERNAL_SERVER_ERROR);

        goto out;
    }
    g_seekable_seek (G_SEEKABLE (serve_data->stream), serve_data->start, G_SEEK_SET, NULL, NULL);

    /* Drop timeout until the message is done */
    korva_upnp_host_data_cancel_timeout (data);

    g_signal_connect (msg,
                      "wrote-chunk",
                      G_CALLBACK (korva_upnp_file_server_on_wrote_chunk),
                      serve_data);
    g_signal_connect (msg,
                      "wrote-headers",
                      G_CALLBACK (korva_upnp_file_server_on_wrote_chunk),
                      serve_data);
    g_signal_connect (msg,
                      "finished",
                      G_CALLBACK (korva_upnp_file_server_on_finished),
                      serve_data);

out:
    if (ranges != NULL) {
        soup_message_headers_free_ranges (msg->request_headers, ranges);
    }

    soup_server_unpause_message (server, msg);
}
Beispiel #6
0
static void
postal_http_log_message (PostalHttp        *http,
                         SoupMessage       *message,
                         const gchar       *path,
                         SoupClientContext *client)
{
   const gchar *ip_addr;
   const gchar *version;
   GTimeVal event_time;
   struct tm tt;
   time_t t;
   gchar *epath;
   gchar *formatted = NULL;
   gchar *referrer;
   gchar *user_agent;
   gchar ftime[32];

   g_assert(POSTAL_IS_HTTP(http));
   g_assert(SOUP_IS_MESSAGE(message));
   g_assert(client);

   g_get_current_time(&event_time);
   t = (time_t)event_time.tv_sec;
   localtime_r(&t, &tt);
   strftime(ftime, sizeof ftime, "%b %d %H:%M:%S", &tt);
   ftime[31] = '\0';

   switch (soup_message_get_http_version(message)) {
   case SOUP_HTTP_1_0:
      version = "HTTP/1.0";
      break;
   case SOUP_HTTP_1_1:
      version = "HTTP/1.1";
      break;
   default:
      g_assert_not_reached();
      version = NULL;
      break;
   }

   ip_addr = soup_client_context_get_host(client);
   referrer = (gchar *)soup_message_headers_get_one(message->request_headers, "Referrer");
   user_agent = (gchar *)soup_message_headers_get_one(message->request_headers, "User-Agent");

   epath = g_strescape(path, NULL);
   referrer = g_strescape(referrer ?: "", NULL);
   user_agent = g_strescape(user_agent ?: "", NULL);

   formatted = g_strdup_printf("%s %s \"%s %s %s\" %u %"G_GSIZE_FORMAT" \"%s\" \"%s\"\n",
                               ip_addr,
                               ftime,
                               message->method,
                               epath,
                               version,
                               message->status_code,
                               message->response_body->length,
                               referrer,
                               user_agent);

   neo_logger_log(http->priv->logger,
                  &event_time,
                  NULL,
                  NULL,
                  0,
                  0,
                  0,
                  NULL,
                  formatted);

   g_free(epath);
   g_free(referrer);
   g_free(user_agent);
   g_free(formatted);
}