diff options
author | Patrick Griffis <pgriffis@igalia.com> | 2020-11-09 15:21:26 -0600 |
---|---|---|
committer | Patrick Griffis <tingping@tingping.se> | 2020-11-14 19:07:24 +0000 |
commit | ebc6e9569dc2bc9c226762ce89fd35950f8ad085 (patch) | |
tree | 14c61a8b593919927c1141978a9befefa49f8764 | |
parent | 737eef099ca1e34d18245c54b6ed3ba54faf1f9c (diff) | |
download | libsoup-ebc6e9569dc2bc9c226762ce89fd35950f8ad085.tar.gz |
Restore ability to send/recv `OPTIONS *` messages
Since GUri does not support an invalid path of just `*` we have to
handle that ourselves.
-rw-r--r-- | docs/reference/libsoup-3.0-sections.txt | 1 | ||||
-rw-r--r-- | libsoup/server/soup-server-io.c | 3 | ||||
-rw-r--r-- | libsoup/server/soup-server-message-private.h | 2 | ||||
-rw-r--r-- | libsoup/server/soup-server-message.c | 25 | ||||
-rw-r--r-- | libsoup/server/soup-server-message.h | 3 | ||||
-rw-r--r-- | libsoup/server/soup-server.c | 18 | ||||
-rw-r--r-- | libsoup/soup-message-io.c | 8 | ||||
-rw-r--r-- | libsoup/soup-message-private.h | 2 | ||||
-rw-r--r-- | libsoup/soup-message.c | 32 | ||||
-rw-r--r-- | tests/server-test.c | 18 |
10 files changed, 95 insertions, 17 deletions
diff --git a/docs/reference/libsoup-3.0-sections.txt b/docs/reference/libsoup-3.0-sections.txt index 41df03bf..f66f50fc 100644 --- a/docs/reference/libsoup-3.0-sections.txt +++ b/docs/reference/libsoup-3.0-sections.txt @@ -281,6 +281,7 @@ soup_server_message_get_socket soup_server_message_get_local_address soup_server_message_get_remote_address soup_server_message_get_remote_host +soup_server_message_is_options_ping soup_server_message_steal_connection <SUBSECTION Standard> SOUP_SERVER_MESSAGE diff --git a/libsoup/server/soup-server-io.c b/libsoup/server/soup-server-io.c index 3e99acd7..acc8f2ad 100644 --- a/libsoup/server/soup-server-io.c +++ b/libsoup/server/soup-server-io.c @@ -592,10 +592,11 @@ parse_headers (SoupServerMessage *msg, if (!strcmp (req_path, "*") && req_host) { /* Eg, "OPTIONS * HTTP/1.1" */ - url = g_strdup_printf ("%s://%s/*", + url = g_strdup_printf ("%s://%s/", soup_socket_is_ssl (sock) ? "https" : "http", req_host); uri = g_uri_parse (url, SOUP_HTTP_URI_FLAGS, NULL); + soup_server_message_set_options_ping (msg, TRUE); g_free (url); } else if (soup_server_message_get_method (msg) == SOUP_METHOD_CONNECT) { /* Authority */ diff --git a/libsoup/server/soup-server-message-private.h b/libsoup/server/soup-server-message-private.h index a4904653..55ef608c 100644 --- a/libsoup/server/soup-server-message-private.h +++ b/libsoup/server/soup-server-message-private.h @@ -40,6 +40,8 @@ void soup_server_message_finished (SoupServerMessage void soup_server_message_read_request (SoupServerMessage *msg, SoupMessageIOCompletionFn completion_cb, gpointer user_data); +void soup_server_message_set_options_ping (SoupServerMessage *msg, + gboolean is_options_ping); typedef struct _SoupServerMessageIOData SoupServerMessageIOData; void soup_server_message_io_data_free (SoupServerMessageIOData *io); diff --git a/libsoup/server/soup-server-message.c b/libsoup/server/soup-server-message.c index 04baff66..03b68724 100644 --- a/libsoup/server/soup-server-message.c +++ b/libsoup/server/soup-server-message.c @@ -68,6 +68,8 @@ struct _SoupServerMessage { SoupMessageHeaders *response_headers; SoupServerMessageIOData *io_data; + + gboolean options_ping; }; struct _SoupServerMessageClass { @@ -569,6 +571,29 @@ soup_server_message_set_method (SoupServerMessage *msg, msg->method = g_intern_string (method); } +void +soup_server_message_set_options_ping (SoupServerMessage *msg, + gboolean is_options_ping) +{ + msg->options_ping = is_options_ping; +} + +/** + * soup_server_message_is_options_ping: + * @msg: a #SoupServerMessage + * + * Gets if @msg represents an OPTIONS message with the path `*`. + * + * Returns: %TRUE if is an OPTIONS ping + */ +gboolean +soup_server_message_is_options_ping (SoupServerMessage *msg) +{ + g_return_val_if_fail (SOUP_IS_SERVER_MESSAGE (msg), FALSE); + + return msg->options_ping; +} + /** * soup_server_message_get_http_version: * @msg: a #SoupServerMessage diff --git a/libsoup/server/soup-server-message.h b/libsoup/server/soup-server-message.h index 7d29b2c2..d3f202d0 100644 --- a/libsoup/server/soup-server-message.h +++ b/libsoup/server/soup-server-message.h @@ -74,6 +74,9 @@ const char *soup_server_message_get_remote_host (SoupServerMessage SOUP_AVAILABLE_IN_ALL GIOStream *soup_server_message_steal_connection (SoupServerMessage *msg); +SOUP_AVAILABLE_IN_ALL +gboolean soup_server_message_is_options_ping (SoupServerMessage *msg); + G_END_DECLS #endif /* __SOUP_SERVER_MESSAGE_H__ */ diff --git a/libsoup/server/soup-server.c b/libsoup/server/soup-server.c index bbc10627..c49127e1 100644 --- a/libsoup/server/soup-server.c +++ b/libsoup/server/soup-server.c @@ -721,15 +721,23 @@ soup_server_get_listeners (SoupServer *server) */ #define NORMALIZED_PATH(path) ((path) && *(path) ? (path) : "/") +static const char * +get_msg_path (SoupServerMessage *msg) +{ + /* A GUri cannot hold a path of "*" so we handle that */ + if (soup_server_message_is_options_ping (msg)) + return "*"; + else + return NORMALIZED_PATH (g_uri_get_path (soup_server_message_get_uri (msg))); +} + static SoupServerHandler * get_handler (SoupServer *server, SoupServerMessage *msg) { SoupServerPrivate *priv = soup_server_get_instance_private (server); - GUri *uri; - uri = soup_server_message_get_uri (msg); - return soup_path_map_lookup (priv->handlers, NORMALIZED_PATH (g_uri_get_path (uri))); + return soup_path_map_lookup (priv->handlers, get_msg_path (msg)); } static void @@ -757,11 +765,11 @@ call_handler (SoupServer *server, if (early) { (*handler->early_callback) (server, msg, - g_uri_get_path (uri), form_data_set, + get_msg_path (msg), form_data_set, handler->early_user_data); } else { (*handler->callback) (server, msg, - g_uri_get_path (uri), form_data_set, + get_msg_path (msg), form_data_set, handler->user_data); } diff --git a/libsoup/soup-message-io.c b/libsoup/soup-message-io.c index dfc57c11..5bee9dc1 100644 --- a/libsoup/soup-message-io.c +++ b/libsoup/soup-message-io.c @@ -279,10 +279,12 @@ write_headers (SoupMessage *msg, /* Proxy expects full URI to destination. Otherwise * just the path. */ - if (!proxy) - uri_string = soup_uri_get_path_and_query (uri); - else + if (proxy) uri_string = g_uri_to_string (uri); + else if (soup_message_is_options_ping (msg)) + uri_string = g_strdup ("*"); + else + uri_string = soup_uri_get_path_and_query (uri); if (proxy && g_uri_get_fragment (uri)) { /* Strip fragment */ diff --git a/libsoup/soup-message-private.h b/libsoup/soup-message-private.h index 769d6da7..a4d1923f 100644 --- a/libsoup/soup-message-private.h +++ b/libsoup/soup-message-private.h @@ -136,4 +136,6 @@ void soup_message_set_reason_phrase (SoupMessage *ms void soup_message_set_method (SoupMessage *msg, const char *method); +gboolean soup_message_is_options_ping (SoupMessage *msg); + #endif /* __SOUP_MESSAGE_PRIVATE_H__ */ diff --git a/libsoup/soup-message.c b/libsoup/soup-message.c index 55716c98..ef16f8e6 100644 --- a/libsoup/soup-message.c +++ b/libsoup/soup-message.c @@ -90,6 +90,7 @@ typedef struct { SoupMessagePriority priority; gboolean is_top_level_navigation; + gboolean options_ping; } SoupMessagePrivate; G_DEFINE_TYPE_WITH_PRIVATE (SoupMessage, soup_message, G_TYPE_OBJECT) @@ -134,6 +135,7 @@ enum { PROP_PRIORITY, PROP_SITE_FOR_COOKIES, PROP_IS_TOP_LEVEL_NAVIGATION, + PROP_OPTIONS_PING, LAST_PROP }; @@ -219,6 +221,9 @@ soup_message_set_property (GObject *object, guint prop_id, case PROP_PRIORITY: priv->priority = g_value_get_enum (value); break; + case PROP_OPTIONS_PING: + priv->options_ping = g_value_get_boolean (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -275,6 +280,9 @@ soup_message_get_property (GObject *object, guint prop_id, case PROP_PRIORITY: g_value_set_enum (value, priv->priority); break; + case PROP_OPTIONS_PING: + g_value_set_boolean (value, priv->options_ping); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -742,6 +750,22 @@ soup_message_class_init (SoupMessageClass *message_class) SOUP_MESSAGE_PRIORITY_NORMAL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /** + * SoupMessage:options-ping: + * + * The #SoupMessage is intended to be used to send + * `OPTIONS *` to a server and the path of + * #SoupMessage:uri will be ignored. + */ + g_object_class_install_property ( + object_class, PROP_OPTIONS_PING, + g_param_spec_boolean ("options-ping", + "Options Ping", + "The message is an OPTIONS ping", + FALSE, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); } @@ -2199,3 +2223,11 @@ soup_message_set_method (SoupMessage *msg, priv->method = g_intern_string (method); } + +gboolean +soup_message_is_options_ping (SoupMessage *msg) +{ + SoupMessagePrivate *priv = soup_message_get_instance_private (msg); + + return priv->options_ping; +}
\ No newline at end of file diff --git a/tests/server-test.c b/tests/server-test.c index 9cc16612..36edb5a0 100644 --- a/tests/server-test.c +++ b/tests/server-test.c @@ -126,19 +126,18 @@ do_star_test (ServerData *sd, gconstpointer test_data) { SoupSession *session; SoupMessage *msg; - GUri *star_uri; const char *handled_by; g_test_bug ("590751"); - g_test_skip ("The literal path \"*\" is not a valid GUri"); - return; - session = soup_test_session_new (NULL); - star_uri = g_uri_parse_relative (sd->base_uri, "*", SOUP_HTTP_URI_FLAGS, NULL); debug_printf (1, " Testing with no handler\n"); - msg = soup_message_new_from_uri ("OPTIONS", star_uri); + msg = g_object_new (SOUP_TYPE_MESSAGE, + "method", SOUP_METHOD_OPTIONS, + "uri", sd->base_uri, + "options-ping", TRUE, + NULL); soup_test_session_send_message (session, msg); soup_test_assert_message_status (msg, SOUP_STATUS_NOT_FOUND); @@ -150,7 +149,11 @@ do_star_test (ServerData *sd, gconstpointer test_data) server_add_handler (sd, "*", server_star_callback, NULL, NULL); debug_printf (1, " Testing with handler\n"); - msg = soup_message_new_from_uri ("OPTIONS", star_uri); + msg = g_object_new (SOUP_TYPE_MESSAGE, + "method", SOUP_METHOD_OPTIONS, + "uri", sd->base_uri, + "options-ping", TRUE, + NULL); soup_test_session_send_message (session, msg); soup_test_assert_message_status (msg, SOUP_STATUS_OK); @@ -160,7 +163,6 @@ do_star_test (ServerData *sd, gconstpointer test_data) g_object_unref (msg); soup_test_session_abort_unref (session); - g_uri_unref (star_uri); } static void |