From 737eef099ca1e34d18245c54b6ed3ba54faf1f9c Mon Sep 17 00:00:00 2001 From: Patrick Griffis Date: Mon, 27 Jul 2020 18:07:37 +0400 Subject: Replace SoupURI with GUri --- docs/reference/libsoup-3.0-docs.xml | 2 +- docs/reference/libsoup-3.0-sections.txt | 69 +- docs/reference/meson.build | 1 + examples/get.c | 29 +- examples/simple-httpd.c | 6 +- examples/simple-proxy.c | 10 +- libsoup/Soup-3.0.metadata | 3 - libsoup/auth/soup-auth-basic.c | 4 +- libsoup/auth/soup-auth-digest.c | 21 +- libsoup/auth/soup-auth-manager.c | 31 +- libsoup/auth/soup-auth-manager.h | 2 +- libsoup/auth/soup-auth-negotiate.c | 28 +- libsoup/auth/soup-auth-ntlm.c | 8 +- libsoup/auth/soup-auth.c | 13 +- libsoup/auth/soup-auth.h | 4 +- libsoup/cache/soup-cache.c | 8 +- libsoup/cookies/soup-cookie-jar.c | 74 +- libsoup/cookies/soup-cookie-jar.h | 22 +- libsoup/cookies/soup-cookie.c | 49 +- libsoup/cookies/soup-cookie.h | 4 +- libsoup/hsts/soup-hsts-enforcer.c | 49 +- libsoup/hsts/soup-hsts-enforcer.h | 2 +- libsoup/hsts/soup-hsts-policy.c | 4 +- libsoup/include/soup-installed.h | 2 +- libsoup/meson.build | 4 +- libsoup/server/soup-auth-domain-digest.c | 12 +- libsoup/server/soup-auth-domain.c | 2 +- libsoup/server/soup-server-io.c | 124 +-- libsoup/server/soup-server-message-private.h | 2 +- libsoup/server/soup-server-message.c | 34 +- libsoup/server/soup-server-message.h | 2 +- libsoup/server/soup-server.c | 81 +- libsoup/server/soup-server.h | 2 +- libsoup/soup-connection.c | 40 +- libsoup/soup-connection.h | 4 +- libsoup/soup-headers.c | 4 +- libsoup/soup-logger.c | 27 +- libsoup/soup-message-io.c | 30 +- libsoup/soup-message-private.h | 2 +- libsoup/soup-message.c | 141 ++- libsoup/soup-message.h | 14 +- libsoup/soup-misc.h | 6 - libsoup/soup-session-private.h | 1 - libsoup/soup-session.c | 192 ++-- libsoup/soup-types.h | 1 - libsoup/soup-uri-utils-private.h | 37 + libsoup/soup-uri-utils.c | 498 +++++++++ libsoup/soup-uri-utils.h | 35 + libsoup/soup-uri.c | 1462 ------------------------- libsoup/soup-uri.h | 143 --- libsoup/soup.h | 3 +- libsoup/websocket/soup-websocket-connection.c | 14 +- libsoup/websocket/soup-websocket-connection.h | 4 +- meson.build | 8 +- tests/auth-test.c | 48 +- tests/cache-test.c | 40 +- tests/chunk-io-test.c | 4 +- tests/coding-test.c | 12 +- tests/connection-test.c | 30 +- tests/context-test.c | 6 +- tests/continue-test.c | 23 +- tests/cookies-test.c | 82 +- tests/forms-test.c | 39 +- tests/hsts-db-test.c | 27 +- tests/hsts-test.c | 27 +- tests/misc-test.c | 66 +- tests/multipart-test.c | 6 +- tests/no-ssl-test.c | 32 +- tests/ntlm-test.c | 25 +- tests/proxy-test.c | 52 +- tests/range-test.c | 6 +- tests/redirect-test.c | 27 +- tests/request-body-test.c | 13 +- tests/samesite-test.c | 12 +- tests/server-auth-test.c | 22 +- tests/server-test.c | 130 +-- tests/session-test.c | 25 +- tests/sniffing-test.c | 56 +- tests/socket-test.c | 8 +- tests/ssl-test.c | 13 +- tests/streaming-test.c | 18 +- tests/test-utils.c | 40 +- tests/test-utils.h | 5 +- tests/timeout-test.c | 31 +- tests/uri-parsing-test.c | 586 +--------- tests/websocket-test.c | 12 +- 86 files changed, 1729 insertions(+), 3168 deletions(-) create mode 100644 libsoup/soup-uri-utils-private.h create mode 100644 libsoup/soup-uri-utils.c create mode 100644 libsoup/soup-uri-utils.h delete mode 100644 libsoup/soup-uri.c delete mode 100644 libsoup/soup-uri.h diff --git a/docs/reference/libsoup-3.0-docs.xml b/docs/reference/libsoup-3.0-docs.xml index 4532a678..88a6e0f8 100644 --- a/docs/reference/libsoup-3.0-docs.xml +++ b/docs/reference/libsoup-3.0-docs.xml @@ -28,7 +28,6 @@ - @@ -84,6 +83,7 @@ Utility API + diff --git a/docs/reference/libsoup-3.0-sections.txt b/docs/reference/libsoup-3.0-sections.txt index 904e0b6c..41df03bf 100644 --- a/docs/reference/libsoup-3.0-sections.txt +++ b/docs/reference/libsoup-3.0-sections.txt @@ -511,61 +511,6 @@ SOUP_AUTH_MANAGER_GET_CLASS soup_auth_manager_get_type -
-soup-uri -SoupURI -SoupURI -soup_uri_new_with_base -soup_uri_new -soup_uri_to_string - -soup_uri_copy -soup_uri_copy_host -soup_uri_equal -soup_uri_host_equal -soup_uri_host_hash -soup_uri_free - -soup_uri_encode -soup_uri_decode -soup_uri_normalize -soup_uri_decode_data_uri - -SOUP_URI_SCHEME_HTTP -SOUP_URI_SCHEME_HTTPS -SOUP_URI_SCHEME_DATA -SOUP_URI_SCHEME_FILE -SOUP_URI_SCHEME_FTP -SOUP_URI_SCHEME_RESOURCE -SOUP_URI_SCHEME_WS -SOUP_URI_SCHEME_WSS -soup_uri_uses_default_port -SOUP_URI_IS_VALID -SOUP_URI_VALID_FOR_HTTP - -soup_uri_set_scheme -soup_uri_get_scheme -soup_uri_set_user -soup_uri_get_user -soup_uri_set_password -soup_uri_get_password -soup_uri_set_host -soup_uri_get_host -soup_uri_set_port -soup_uri_get_port -soup_uri_set_path -soup_uri_get_path -soup_uri_set_query -soup_uri_set_query_from_form -soup_uri_set_query_from_fields -soup_uri_get_query -soup_uri_set_fragment -soup_uri_get_fragment - -SOUP_TYPE_URI -soup_uri_get_type -
-
soup-date-utils SoupDateFormat @@ -575,6 +520,20 @@ soup_date_time_to_string soup_date_time_is_past
+
+soup-uri-utils +soup_uri_equal + +SOUP_HTTP_URI_FLAGS + +soup_uri_decode_data_uri + +soup_uri_get_port_with_default + +soup_uri_copy_with_query_from_form +soup_uri_copy_with_query_from_fields +
+
soup-form SoupForm diff --git a/docs/reference/meson.build b/docs/reference/meson.build index 960f6128..36a064d4 100644 --- a/docs/reference/meson.build +++ b/docs/reference/meson.build @@ -32,6 +32,7 @@ ignore_headers = [ 'soup-private-enum-types.h', 'soup-server-message-private.h', 'soup-message-io-data.h', + 'soup-uri-utils-private.h', ] mkdb_args = [ diff --git a/examples/get.c b/examples/get.c index a03404d9..377cf854 100644 --- a/examples/get.c +++ b/examples/get.c @@ -39,7 +39,7 @@ get_url (const char *url) soup_session_queue_message (session, msg, finished, loop); g_main_loop_run (loop); - name = soup_message_get_uri (msg)->path; + name = g_uri_get_path (soup_message_get_uri (msg)); if (!debug) { if (soup_message_get_status (msg) == SOUP_STATUS_SSL_FAILED) { @@ -57,17 +57,18 @@ get_url (const char *url) header = soup_message_headers_get_one (soup_message_get_response_headers (msg), "Location"); if (header) { - SoupURI *uri; + GUri *uri; char *uri_string; if (!debug && !quiet) g_print (" -> %s\n", header); - uri = soup_uri_new_with_base (soup_message_get_uri (msg), header); - uri_string = soup_uri_to_string (uri, FALSE); + uri = g_uri_parse_relative (soup_message_get_uri (msg), header, SOUP_HTTP_URI_FLAGS, NULL); + g_assert (uri != NULL); + uri_string = g_uri_to_string (uri); get_url (uri_string); g_free (uri_string); - soup_uri_free (uri); + g_uri_unref (uri); } } else if (!head && SOUP_STATUS_IS_SUCCESSFUL (soup_message_get_status (msg))) { if (output_file_path) { @@ -190,7 +191,7 @@ main (int argc, char **argv) { GOptionContext *opts; const char *url; - SoupURI *proxy_uri, *parsed; + GUri *proxy_uri, *parsed; GError *error = NULL; SoupLogger *logger = NULL; char *help; @@ -216,12 +217,12 @@ main (int argc, char **argv) g_option_context_free (opts); url = argv[1]; - parsed = soup_uri_new (url); + parsed = g_uri_parse (url, SOUP_HTTP_URI_FLAGS, &error); if (!parsed) { - g_printerr ("Could not parse '%s' as a URL\n", url); + g_printerr ("Could not parse '%s' as a URL: %s\n", url, error->message); exit (1); } - soup_uri_free (parsed); + g_uri_unref (parsed); session = g_object_new (SOUP_TYPE_SESSION, "user-agent", "get ", @@ -258,10 +259,12 @@ main (int argc, char **argv) if (proxy) { GProxyResolver *resolver; - proxy_uri = soup_uri_new (proxy); + GError *error; + proxy_uri = g_uri_parse (proxy, SOUP_HTTP_URI_FLAGS, &error); if (!proxy_uri) { - g_printerr ("Could not parse '%s' as URI\n", - proxy); + g_printerr ("Could not parse '%s' as URI: %s\n", + proxy, error->message); + g_error_free (error); exit (1); } @@ -269,7 +272,7 @@ main (int argc, char **argv) g_object_set (G_OBJECT (session), "proxy-resolver", resolver, NULL); - soup_uri_free (proxy_uri); + g_uri_unref (proxy_uri); g_object_unref (resolver); } diff --git a/examples/simple-httpd.c b/examples/simple-httpd.c index 3c5b534b..f468ce18 100644 --- a/examples/simple-httpd.c +++ b/examples/simple-httpd.c @@ -93,7 +93,7 @@ do_get (SoupServer *server, SoupMessage *msg, const char *path) if (!slash || slash[1]) { char *redir_uri; - redir_uri = g_strdup_printf ("%s/", soup_message_get_uri (msg)->path); + redir_uri = g_strdup_printf ("%s/", g_uri_get_path (soup_message_get_uri (msg))); soup_message_set_redirect (msg, SOUP_STATUS_MOVED_PERMANENTLY, redir_uri); g_free (redir_uri); @@ -287,10 +287,10 @@ main (int argc, char **argv) uris = soup_server_get_uris (server); for (u = uris; u; u = u->next) { - str = soup_uri_to_string (u->data, FALSE); + str = g_uri_to_string (u->data); g_print ("Listening on %s\n", str); g_free (str); - soup_uri_free (u->data); + g_uri_unref (u->data); } g_slist_free (uris); diff --git a/examples/simple-proxy.c b/examples/simple-proxy.c index eb0433bb..d625c06b 100644 --- a/examples/simple-proxy.c +++ b/examples/simple-proxy.c @@ -209,7 +209,7 @@ static void try_tunnel (SoupServer *server, SoupMessage *msg, SoupClientContext *context) { Tunnel *tunnel; - SoupURI *dest_uri; + GUri *dest_uri; GSocketClient *sclient; soup_server_pause_message (server, msg); @@ -221,7 +221,7 @@ try_tunnel (SoupServer *server, SoupMessage *msg, SoupClientContext *context) dest_uri = soup_message_get_uri (msg); sclient = g_socket_client_new (); - g_socket_client_connect_to_host_async (sclient, dest_uri->host, dest_uri->port, + g_socket_client_connect_to_host_async (sclient, g_uri_get_host (dest_uri), g_uri_get_port (dest_uri), NULL, tunnel_connected_cb, tunnel); g_object_unref (sclient); } @@ -284,7 +284,7 @@ server_callback (SoupServer *server, SoupMessage *msg, SoupMessage *msg2; char *uristr; - uristr = soup_uri_to_string (soup_message_get_uri (msg), FALSE); + uristr = g_uri_to_string (soup_message_get_uri (msg)); g_print ("[%p] %s %s HTTP/1.%d\n", msg, soup_message_get_method (msg), uristr, soup_message_get_http_version (msg)); @@ -398,10 +398,10 @@ main (int argc, char **argv) uris = soup_server_get_uris (server); for (u = uris; u; u = u->next) { - str = soup_uri_to_string (u->data, FALSE); + str = g_uri_to_string (u->data); g_print ("Listening on %s\n", str); g_free (str); - soup_uri_free (u->data); + g_uri_unref (u->data); } g_slist_free (uris); diff --git a/libsoup/Soup-3.0.metadata b/libsoup/Soup-3.0.metadata index b2e58984..f8c245d4 100644 --- a/libsoup/Soup-3.0.metadata +++ b/libsoup/Soup-3.0.metadata @@ -29,9 +29,6 @@ Session .get_features type_arguments="weak Soup.SessionFeature" .send_async.cancellable#parameter default=null Session*.new_with_options skip=false -URI - .set_query_from_fields skip=false -// uri_host_*.* type="Soup.URI" // Not enough GIR information MessageBody.data type="uint8[]" array_length_field="length" diff --git a/libsoup/auth/soup-auth-basic.c b/libsoup/auth/soup-auth-basic.c index db13124c..e9aa346b 100644 --- a/libsoup/auth/soup-auth-basic.c +++ b/libsoup/auth/soup-auth-basic.c @@ -70,11 +70,11 @@ soup_auth_basic_update (SoupAuth *auth, SoupMessage *msg, } static GSList * -soup_auth_basic_get_protection_space (SoupAuth *auth, SoupURI *source_uri) +soup_auth_basic_get_protection_space (SoupAuth *auth, GUri *source_uri) { char *space, *p; - space = g_strdup (source_uri->path); + space = g_strdup (g_uri_get_path (source_uri)); /* Strip filename component */ p = strrchr (space, '/'); diff --git a/libsoup/auth/soup-auth-digest.c b/libsoup/auth/soup-auth-digest.c index f81dfdca..76922929 100644 --- a/libsoup/auth/soup-auth-digest.c +++ b/libsoup/auth/soup-auth-digest.c @@ -186,12 +186,12 @@ soup_auth_digest_update (SoupAuth *auth, SoupMessage *msg, } static GSList * -soup_auth_digest_get_protection_space (SoupAuth *auth, SoupURI *source_uri) +soup_auth_digest_get_protection_space (SoupAuth *auth, GUri *source_uri) { SoupAuthDigest *auth_digest = SOUP_AUTH_DIGEST (auth); SoupAuthDigestPrivate *priv = soup_auth_digest_get_instance_private (auth_digest); GSList *space = NULL; - SoupURI *uri; + GUri *uri; char **dvec, *d, *dir, *slash; int dix; @@ -208,15 +208,16 @@ soup_auth_digest_get_protection_space (SoupAuth *auth, SoupURI *source_uri) if (*d == '/') dir = g_strdup (d); else { - uri = soup_uri_new (d); - if (uri && uri->scheme == source_uri->scheme && - uri->port == source_uri->port && - !strcmp (uri->host, source_uri->host)) - dir = g_strdup (uri->path); + uri = g_uri_parse (d, SOUP_HTTP_URI_FLAGS, NULL); + if (uri && + g_strcmp0 (g_uri_get_scheme (uri), g_uri_get_scheme (source_uri)) == 0 && + soup_uri_get_port_with_default (uri) == soup_uri_get_port_with_default (source_uri) && + !strcmp (g_uri_get_host (uri), g_uri_get_host (source_uri))) + dir = g_strdup (g_uri_get_path (uri)); else dir = NULL; if (uri) - soup_uri_free (uri); + g_uri_unref (uri); } if (dir) { @@ -417,11 +418,11 @@ soup_auth_digest_get_authorization (SoupAuth *auth, SoupMessage *msg) char response[33], *token; char *url, *algorithm; GString *out; - SoupURI *uri; + GUri *uri; uri = soup_message_get_uri (msg); g_return_val_if_fail (uri != NULL, NULL); - url = soup_uri_to_string (uri, TRUE); + url = soup_uri_get_path_and_query (uri); soup_auth_digest_compute_response (soup_message_get_method (msg), url, priv->hex_a1, priv->qop, priv->nonce, diff --git a/libsoup/auth/soup-auth-manager.c b/libsoup/auth/soup-auth-manager.c index 9b3bde9c..3a52aa7c 100644 --- a/libsoup/auth/soup-auth-manager.c +++ b/libsoup/auth/soup-auth-manager.c @@ -79,7 +79,7 @@ typedef struct { } SoupAuthManagerPrivate; typedef struct { - SoupURI *uri; + GUri *uri; SoupPathMap *auth_realms; /* path -> scheme:realm */ GHashTable *auths; /* scheme:realm -> SoupAuth */ } SoupAuthHost; @@ -91,7 +91,7 @@ G_DEFINE_TYPE_WITH_CODE (SoupAuthManager, soup_auth_manager, G_TYPE_OBJECT, static void soup_auth_host_free (SoupAuthHost *host); static SoupAuth *record_auth_for_uri (SoupAuthManagerPrivate *priv, - SoupURI *uri, SoupAuth *auth, + GUri *uri, SoupAuth *auth, gboolean prior_auth_failed); static void @@ -402,7 +402,7 @@ check_auth (SoupMessage *msg, SoupAuth *auth) } static SoupAuthHost * -get_auth_host_for_uri (SoupAuthManagerPrivate *priv, SoupURI *uri) +get_auth_host_for_uri (SoupAuthManagerPrivate *priv, GUri *uri) { SoupAuthHost *host; @@ -423,7 +423,7 @@ soup_auth_host_free (SoupAuthHost *host) g_clear_pointer (&host->auth_realms, soup_path_map_free); g_clear_pointer (&host->auths, g_hash_table_destroy); - soup_uri_free (host->uri); + g_uri_unref (host->uri); g_slice_free (SoupAuthHost, host); } @@ -436,7 +436,7 @@ make_auto_ntlm_auth (SoupAuthManagerPrivate *priv, SoupAuthHost *host) return FALSE; auth = g_object_new (SOUP_TYPE_AUTH_NTLM, - "host", host->uri->host, + "host", g_uri_get_host (host->uri), NULL); record_auth_for_uri (priv, host->uri, auth, FALSE); g_object_unref (auth); @@ -469,7 +469,7 @@ lookup_auth (SoupAuthManagerPrivate *priv, SoupMessage *msg) SoupAuthHost *host; const char *path, *realm; SoupAuth *auth; - SoupURI *uri; + GUri *uri; /* If the message already has a ready auth, use that instead */ auth = soup_message_get_auth (msg); @@ -495,7 +495,7 @@ lookup_auth (SoupAuthManagerPrivate *priv, SoupMessage *msg) if (!host->auth_realms) return NULL; - path = uri->path; + path = g_uri_get_path (uri); if (!path) path = "/"; realm = soup_path_map_lookup (host->auth_realms, path); @@ -542,7 +542,7 @@ authenticate_auth (SoupAuthManager *manager, SoupAuth *auth, gboolean proxy, gboolean can_interact) { SoupAuthManagerPrivate *priv = soup_auth_manager_get_instance_private (manager); - SoupURI *uri; + GUri *uri; if (!soup_auth_can_authenticate (auth)) return; @@ -552,10 +552,11 @@ authenticate_auth (SoupAuthManager *manager, SoupAuth *auth, /* If a password is specified explicitly in the URI, use it * even if the auth had previously already been authenticated. */ - if (uri->password && uri->user) { - soup_auth_authenticate (auth, uri->user, uri->password); - soup_uri_set_password (uri, NULL); - soup_uri_set_user (uri, NULL); + if (g_uri_get_password (uri) && g_uri_get_user (uri)) { + soup_auth_authenticate (auth, g_uri_get_user (uri), g_uri_get_password (uri)); + GUri *new_uri = soup_uri_copy_with_credentials (uri, NULL, NULL); + soup_message_set_uri (msg, new_uri); // QUESTION: This didn't emit a signal previously + g_uri_unref (new_uri); } else if (!soup_auth_is_authenticated (auth) && can_interact) { SoupMessage *original_msg; gboolean handled; @@ -579,7 +580,7 @@ authenticate_auth (SoupAuthManager *manager, SoupAuth *auth, } static SoupAuth * -record_auth_for_uri (SoupAuthManagerPrivate *priv, SoupURI *uri, +record_auth_for_uri (SoupAuthManagerPrivate *priv, GUri *uri, SoupAuth *auth, gboolean prior_auth_failed) { SoupAuthHost *host; @@ -816,7 +817,7 @@ soup_auth_manager_request_unqueued (SoupSessionFeature *manager, /** * soup_auth_manager_use_auth: * @manager: a #SoupAuthManager - * @uri: the #SoupURI under which @auth is to be used + * @uri: the #GUri under which @auth is to be used * @auth: the #SoupAuth to use * * Records that @auth is to be used under @uri, as though a @@ -833,7 +834,7 @@ soup_auth_manager_request_unqueued (SoupSessionFeature *manager, */ void soup_auth_manager_use_auth (SoupAuthManager *manager, - SoupURI *uri, + GUri *uri, SoupAuth *auth) { SoupAuthManagerPrivate *priv = soup_auth_manager_get_instance_private (manager); diff --git a/libsoup/auth/soup-auth-manager.h b/libsoup/auth/soup-auth-manager.h index d442a43e..db5756c9 100644 --- a/libsoup/auth/soup-auth-manager.h +++ b/libsoup/auth/soup-auth-manager.h @@ -16,7 +16,7 @@ G_DECLARE_FINAL_TYPE (SoupAuthManager, soup_auth_manager, SOUP, AUTH_MANAGER, GO SOUP_AVAILABLE_IN_2_4 void soup_auth_manager_use_auth (SoupAuthManager *manager, - SoupURI *uri, + GUri *uri, SoupAuth *auth); SOUP_AVAILABLE_IN_2_58 diff --git a/libsoup/auth/soup-auth-negotiate.c b/libsoup/auth/soup-auth-negotiate.c index c022f1a9..41215690 100644 --- a/libsoup/auth/soup-auth-negotiate.c +++ b/libsoup/auth/soup-auth-negotiate.c @@ -21,7 +21,7 @@ #include "soup-message.h" #include "soup-message-private.h" #include "soup-misc.h" -#include "soup-uri.h" +#include "soup-uri-utils-private.h" /** * soup_auth_negotiate_supported: @@ -142,11 +142,11 @@ soup_auth_negotiate_free_connection_state (SoupConnectionAuth *auth, } static GSList * -soup_auth_negotiate_get_protection_space (SoupAuth *auth, SoupURI *source_uri) +soup_auth_negotiate_get_protection_space (SoupAuth *auth, GUri *source_uri) { char *space, *p; - space = g_strdup (source_uri->path); + space = g_strdup (g_uri_get_path (source_uri)); /* Strip filename component */ p = strrchr (space, '/'); @@ -399,18 +399,18 @@ check_server_response (SoupMessage *msg, gpointer auth) /* Check if scheme://host:port from message matches the given URI. */ static gint -match_base_uri (SoupURI *list_uri, SoupURI *msg_uri) +match_base_uri (GUri *list_uri, GUri *msg_uri) { - if (msg_uri->scheme != list_uri->scheme) - return 1; + if (g_strcmp0 (g_uri_get_scheme (list_uri), g_uri_get_scheme (msg_uri)) != 0) + return 1; - if (list_uri->port && (msg_uri->port != list_uri->port)) - return 1; + if (g_uri_get_port (list_uri) != -1 && g_uri_get_port (list_uri) != g_uri_get_port (msg_uri)) + return 1; - if (list_uri->host) - return !soup_host_matches_host (msg_uri->host, list_uri->host); + if (g_uri_get_host (list_uri)) + return !soup_host_matches_host (g_uri_get_host (msg_uri), g_uri_get_host (list_uri)); - return 0; + return 0; } /* Parses a comma separated list of URIS from the environment. */ @@ -433,10 +433,10 @@ parse_uris_from_env_variable (const gchar *env_variable, GSList **list) length = g_strv_length (uris); for (i = 0; i < length; i++) { - SoupURI *uri; + GUri *uri; /* If the supplied URI is valid, append it to the list */ - if ((uri = soup_uri_new (uris[i]))) + if ((uri = g_uri_parse (uris[i], SOUP_HTTP_URI_FLAGS, NULL))) *list = g_slist_prepend (*list, uri); } @@ -446,7 +446,7 @@ parse_uris_from_env_variable (const gchar *env_variable, GSList **list) static gboolean check_auth_trusted_uri (SoupConnectionAuth *auth, SoupMessage *msg) { - SoupURI *msg_uri; + GUri *msg_uri; GSList *matched = NULL; g_return_val_if_fail (auth != NULL, FALSE); diff --git a/libsoup/auth/soup-auth-ntlm.c b/libsoup/auth/soup-auth-ntlm.c index f18678e5..61b99060 100644 --- a/libsoup/auth/soup-auth-ntlm.c +++ b/libsoup/auth/soup-auth-ntlm.c @@ -307,7 +307,7 @@ soup_auth_ntlm_update_connection (SoupConnectionAuth *auth, SoupMessage *msg, SoupAuthNTLMPrivate *priv = soup_auth_ntlm_get_instance_private (auth_ntlm); SoupNTLMConnectionState *conn = state; gboolean success = TRUE; - SoupURI *uri; + GUri *uri; char *authority; /* Note that we only return FALSE if some sort of parsing error @@ -399,7 +399,7 @@ soup_auth_ntlm_update_connection (SoupConnectionAuth *auth, SoupMessage *msg, conn->state = SOUP_NTLM_RECEIVED_CHALLENGE; uri = soup_message_get_uri (msg); - authority = g_strdup_printf ("%s:%d", uri->host, uri->port); + authority = g_strdup_printf ("%s:%d", g_uri_get_host (uri), g_uri_get_port (uri)); g_object_set (G_OBJECT (auth), "realm", priv->domain, "authority", authority, @@ -410,11 +410,11 @@ soup_auth_ntlm_update_connection (SoupConnectionAuth *auth, SoupMessage *msg, } static GSList * -soup_auth_ntlm_get_protection_space (SoupAuth *auth, SoupURI *source_uri) +soup_auth_ntlm_get_protection_space (SoupAuth *auth, GUri *source_uri) { char *space, *p; - space = g_strdup (source_uri->path); + space = g_strdup (g_uri_get_path (source_uri)); /* Strip filename component */ p = strrchr (space, '/'); diff --git a/libsoup/auth/soup-auth.c b/libsoup/auth/soup-auth.c index c71b7e31..2667895b 100644 --- a/libsoup/auth/soup-auth.c +++ b/libsoup/auth/soup-auth.c @@ -263,7 +263,7 @@ soup_auth_new (GType type, SoupMessage *msg, const char *auth_header) SoupAuth *auth; GHashTable *params; const char *scheme; - SoupURI *uri; + GUri *uri; char *authority; g_return_val_if_fail (g_type_is_a (type, SOUP_TYPE_AUTH), NULL); @@ -274,7 +274,7 @@ soup_auth_new (GType type, SoupMessage *msg, const char *auth_header) if (!uri) return NULL; - authority = g_strdup_printf ("%s:%d", uri->host, uri->port); + authority = g_strdup_printf ("%s:%d", g_uri_get_host (uri), g_uri_get_port (uri)); auth = g_object_new (type, "is-for-proxy", (soup_message_get_status (msg) == SOUP_STATUS_PROXY_UNAUTHORIZED), "authority", authority, @@ -642,12 +642,15 @@ soup_auth_can_authenticate (SoupAuth *auth) * paths, which can be freed with soup_auth_free_protection_space(). **/ GSList * -soup_auth_get_protection_space (SoupAuth *auth, SoupURI *source_uri) +soup_auth_get_protection_space (SoupAuth *auth, GUri *source_uri) { g_return_val_if_fail (SOUP_IS_AUTH (auth), NULL); - g_return_val_if_fail (source_uri != NULL, NULL); + g_return_val_if_fail (SOUP_URI_IS_VALID (source_uri), NULL); - return SOUP_AUTH_GET_CLASS (auth)->get_protection_space (auth, source_uri); + GUri *source_uri_normalized = soup_uri_copy_with_normalized_flags (source_uri); + GSList *ret = SOUP_AUTH_GET_CLASS (auth)->get_protection_space (auth, source_uri_normalized); + g_uri_unref (source_uri_normalized); + return ret; } /** diff --git a/libsoup/auth/soup-auth.h b/libsoup/auth/soup-auth.h index 606127b5..9a467f47 100644 --- a/libsoup/auth/soup-auth.h +++ b/libsoup/auth/soup-auth.h @@ -25,7 +25,7 @@ struct _SoupAuthClass { GHashTable *auth_header); GSList * (*get_protection_space) (SoupAuth *auth, - SoupURI *source_uri); + GUri *source_uri); void (*authenticate) (SoupAuth *auth, const char *username, @@ -89,7 +89,7 @@ char *soup_auth_get_authorization (SoupAuth *auth, SOUP_AVAILABLE_IN_2_4 GSList *soup_auth_get_protection_space (SoupAuth *auth, - SoupURI *source_uri); + GUri *source_uri); SOUP_AVAILABLE_IN_2_4 void soup_auth_free_protection_space (SoupAuth *auth, GSList *space); diff --git a/libsoup/cache/soup-cache.c b/libsoup/cache/soup-cache.c index d5c4354b..cd0ab5de 100644 --- a/libsoup/cache/soup-cache.c +++ b/libsoup/cache/soup-cache.c @@ -215,7 +215,7 @@ get_cacheability (SoupCache *cache, SoupMessage *msg) } /* Section 13.9 */ - if ((soup_message_get_uri (msg))->query && + if ((g_uri_get_query (soup_message_get_uri (msg))) && !soup_message_headers_get_one (soup_message_get_response_headers (msg), "Expires") && !has_max_age) return SOUP_CACHE_UNCACHEABLE; @@ -470,7 +470,7 @@ soup_cache_entry_new (SoupCache *cache, SoupMessage *msg, time_t request_time, t entry->being_validated = FALSE; entry->status_code = soup_message_get_status (msg); entry->response_time = response_time; - entry->uri = soup_uri_to_string (soup_message_get_uri (msg), FALSE); + entry->uri = g_uri_to_string_partial (soup_message_get_uri (msg), G_URI_HIDE_PASSWORD); /* Headers */ entry->headers = soup_message_headers_new (SOUP_MESSAGE_HEADERS_RESPONSE); @@ -667,7 +667,7 @@ soup_cache_entry_lookup (SoupCache *cache, guint32 key; char *uri = NULL; - uri = soup_uri_to_string (soup_message_get_uri (msg), FALSE); + uri = g_uri_to_string_partial (soup_message_get_uri (msg), G_URI_HIDE_PASSWORD); key = get_cache_key_from_uri ((const char *) uri); entry = g_hash_table_lookup (priv->cache, GUINT_TO_POINTER (key)); @@ -1367,7 +1367,7 @@ SoupMessage * soup_cache_generate_conditional_request (SoupCache *cache, SoupMessage *original) { SoupMessage *msg; - SoupURI *uri; + GUri *uri; SoupCacheEntry *entry; const char *last_modified, *etag; GList *disabled_features, *f; diff --git a/libsoup/cookies/soup-cookie-jar.c b/libsoup/cookies/soup-cookie-jar.c index 5df110c0..3d09dab2 100644 --- a/libsoup/cookies/soup-cookie-jar.c +++ b/libsoup/cookies/soup-cookie-jar.c @@ -279,9 +279,9 @@ compare_cookies (gconstpointer a, gconstpointer b, gpointer jar) static gboolean cookie_is_valid_for_same_site_policy (SoupCookie *cookie, gboolean is_safe_method, - SoupURI *uri, - SoupURI *top_level, - SoupURI *cookie_uri, + GUri *uri, + GUri *top_level, + GUri *cookie_uri, gboolean is_top_level_navigation, gboolean for_http) { @@ -300,14 +300,14 @@ cookie_is_valid_for_same_site_policy (SoupCookie *cookie, if (is_top_level_navigation && cookie_uri == NULL) return FALSE; - return soup_host_matches_host (soup_uri_get_host (cookie_uri ? cookie_uri : top_level), soup_uri_get_host (uri)); + return soup_host_matches_host (g_uri_get_host (cookie_uri ? cookie_uri : top_level), g_uri_get_host (uri)); } static GSList * get_cookies (SoupCookieJar *jar, - SoupURI *uri, - SoupURI *top_level, - SoupURI *site_for_cookies, + GUri *uri, + GUri *top_level, + GUri *site_for_cookies, gboolean is_safe_method, gboolean for_http, gboolean is_top_level_navigation, @@ -317,19 +317,20 @@ get_cookies (SoupCookieJar *jar, GSList *cookies, *domain_cookies; char *domain, *cur, *next_domain; GSList *new_head, *cookies_to_remove = NULL, *p; + const char *host = g_uri_get_host (uri); priv = soup_cookie_jar_get_instance_private (jar); - if (!uri->host || !uri->host[0]) + if (!host || !host[0]) return NULL; /* The logic here is a little weird, but the plan is that if - * uri->host is "www.foo.com", we will end up looking up + * host is "www.foo.com", we will end up looking up * cookies for ".www.foo.com", "www.foo.com", ".foo.com", and * ".com", in that order. (Logic stolen from Mozilla.) */ cookies = NULL; - domain = cur = g_strdup_printf (".%s", uri->host); + domain = cur = g_strdup_printf (".%s", host); next_domain = domain + 1; do { new_head = domain_cookies = g_hash_table_lookup (priv->domains, cur); @@ -373,7 +374,7 @@ get_cookies (SoupCookieJar *jar, /** * soup_cookie_jar_get_cookies: * @jar: a #SoupCookieJar - * @uri: a #SoupURI + * @uri: a #GUri * @for_http: whether or not the return value is being passed directly * to an HTTP operation * @@ -394,7 +395,7 @@ get_cookies (SoupCookieJar *jar, * Since: 2.24 **/ char * -soup_cookie_jar_get_cookies (SoupCookieJar *jar, SoupURI *uri, +soup_cookie_jar_get_cookies (SoupCookieJar *jar, GUri *uri, gboolean for_http) { GSList *cookies; @@ -420,7 +421,7 @@ soup_cookie_jar_get_cookies (SoupCookieJar *jar, SoupURI *uri, /** * soup_cookie_jar_get_cookie_list: * @jar: a #SoupCookieJar - * @uri: a #SoupURI + * @uri: a #GUri * @for_http: whether or not the return value is being passed directly * to an HTTP operation * @@ -441,7 +442,7 @@ soup_cookie_jar_get_cookies (SoupCookieJar *jar, SoupURI *uri, * Since: 2.40 **/ GSList * -soup_cookie_jar_get_cookie_list (SoupCookieJar *jar, SoupURI *uri, gboolean for_http) +soup_cookie_jar_get_cookie_list (SoupCookieJar *jar, GUri *uri, gboolean for_http) { g_return_val_if_fail (SOUP_IS_COOKIE_JAR (jar), NULL); g_return_val_if_fail (uri != NULL, NULL); @@ -452,9 +453,9 @@ soup_cookie_jar_get_cookie_list (SoupCookieJar *jar, SoupURI *uri, gboolean for_ /** * soup_cookie_jar_get_cookie_list_with_same_site_info: * @jar: a #SoupCookieJar - * @uri: a #SoupURI - * @top_level: (nullable): a #SoupURI for the top level document - * @site_for_cookies: (nullable): a #SoupURI indicating the origin to get cookies for + * @uri: a #GUri + * @top_level: (nullable): a #GUri for the top level document + * @site_for_cookies: (nullable): a #GUri indicating the origin to get cookies for * @for_http: whether or not the return value is being passed directly * to an HTTP operation * @is_safe_method: if the HTTP method is safe, as defined by RFC 7231, ignored when @for_http is %FALSE @@ -473,9 +474,9 @@ soup_cookie_jar_get_cookie_list (SoupCookieJar *jar, SoupURI *uri, gboolean for_ */ GSList * soup_cookie_jar_get_cookie_list_with_same_site_info (SoupCookieJar *jar, - SoupURI *uri, - SoupURI *top_level, - SoupURI *site_for_cookies, + GUri *uri, + GUri *top_level, + GUri *site_for_cookies, gboolean for_http, gboolean is_safe_method, gboolean is_top_level_navigation) @@ -500,19 +501,24 @@ normalize_cookie_domain (const char *domain) static gboolean incoming_cookie_is_third_party (SoupCookieJar *jar, SoupCookie *cookie, - SoupURI *first_party, + GUri *first_party, SoupCookieJarAcceptPolicy policy) { SoupCookieJarPrivate *priv; const char *normalized_cookie_domain; const char *cookie_base_domain; const char *first_party_base_domain; + const char *first_party_host; if (policy != SOUP_COOKIE_JAR_ACCEPT_NO_THIRD_PARTY && policy != SOUP_COOKIE_JAR_ACCEPT_GRANDFATHERED_THIRD_PARTY) return FALSE; - if (first_party == NULL || first_party->host == NULL) + if (first_party == NULL) + return TRUE; + + first_party_host = g_uri_get_host (first_party); + if (first_party_host == NULL) return TRUE; normalized_cookie_domain = normalize_cookie_domain (soup_cookie_get_domain (cookie)); @@ -520,9 +526,9 @@ incoming_cookie_is_third_party (SoupCookieJar *jar, if (cookie_base_domain == NULL) cookie_base_domain = soup_cookie_get_domain (cookie); - first_party_base_domain = soup_tld_get_base_domain (first_party->host, NULL); + first_party_base_domain = soup_tld_get_base_domain (first_party_host, NULL); if (first_party_base_domain == NULL) - first_party_base_domain = first_party->host; + first_party_base_domain = first_party_host; if (soup_host_matches_host (cookie_base_domain, first_party_base_domain)) return FALSE; @@ -562,7 +568,7 @@ incoming_cookie_is_third_party (SoupCookieJar *jar, * Since: 2.68 **/ void -soup_cookie_jar_add_cookie_full (SoupCookieJar *jar, SoupCookie *cookie, SoupURI *uri, SoupURI *first_party) +soup_cookie_jar_add_cookie_full (SoupCookieJar *jar, SoupCookie *cookie, GUri *uri, GUri *first_party) { SoupCookieJarPrivate *priv; GSList *old_cookies, *oc, *last = NULL; @@ -685,7 +691,7 @@ soup_cookie_jar_add_cookie (SoupCookieJar *jar, SoupCookie *cookie) * Since: 2.40 **/ void -soup_cookie_jar_add_cookie_with_first_party (SoupCookieJar *jar, SoupURI *first_party, SoupCookie *cookie) +soup_cookie_jar_add_cookie_with_first_party (SoupCookieJar *jar, GUri *first_party, SoupCookie *cookie) { g_return_if_fail (first_party != NULL); @@ -711,7 +717,7 @@ soup_cookie_jar_add_cookie_with_first_party (SoupCookieJar *jar, SoupURI *first_ * Since: 2.24 **/ void -soup_cookie_jar_set_cookie (SoupCookieJar *jar, SoupURI *uri, +soup_cookie_jar_set_cookie (SoupCookieJar *jar, GUri *uri, const char *cookie) { SoupCookie *soup_cookie; @@ -721,7 +727,7 @@ soup_cookie_jar_set_cookie (SoupCookieJar *jar, SoupURI *uri, g_return_if_fail (uri != NULL); g_return_if_fail (cookie != NULL); - if (!uri->host) + if (!g_uri_get_host (uri)) return; priv = soup_cookie_jar_get_instance_private (jar); @@ -754,8 +760,8 @@ soup_cookie_jar_set_cookie (SoupCookieJar *jar, SoupURI *uri, **/ void soup_cookie_jar_set_cookie_with_first_party (SoupCookieJar *jar, - SoupURI *uri, - SoupURI *first_party, + GUri *uri, + GUri *first_party, const char *cookie) { SoupCookie *soup_cookie; @@ -765,7 +771,7 @@ soup_cookie_jar_set_cookie_with_first_party (SoupCookieJar *jar, g_return_if_fail (first_party != NULL); g_return_if_fail (cookie != NULL); - if (!uri->host) + if (!g_uri_get_host (uri)) return; soup_cookie = soup_cookie_parse (cookie, uri); @@ -780,7 +786,7 @@ process_set_cookie_header (SoupMessage *msg, gpointer user_data) SoupCookieJar *jar = user_data; SoupCookieJarPrivate *priv = soup_cookie_jar_get_instance_private (jar); GSList *new_cookies, *nc; - SoupURI *first_party, *uri; + GUri *first_party, *uri; if (priv->accept_policy == SOUP_COOKIE_JAR_ACCEPT_NEVER) return; @@ -936,7 +942,7 @@ soup_cookie_jar_delete_cookie (SoupCookieJar *jar, * is loaded from that page reject any cookie that it could try to * set. For libsoup to be able to tell apart first party cookies from * the rest, the application must call soup_message_set_first_party() - * on each outgoing #SoupMessage, setting the #SoupURI of the main + * on each outgoing #SoupMessage, setting the #GUri of the main * document. If no first party is set in a message when this policy is * in effect, cookies will be assumed to be third party by default. * @SOUP_COOKIE_JAR_ACCEPT_GRANDFATHERED_THIRD_PARTY: accept all cookies @@ -949,7 +955,7 @@ soup_cookie_jar_delete_cookie (SoupCookieJar *jar, * set unless it already has a cookie in the cookie jar. For libsoup to * be able to tell apart first party cookies from the rest, the * application must call soup_message_set_first_party() on each outgoing - * #SoupMessage, setting the #SoupURI of the main document. If no first + * #SoupMessage, setting the #GUri of the main document. If no first * party is set in a message when this policy is in effect, cookies will * be assumed to be third party by default. Since 2.72. * diff --git a/libsoup/cookies/soup-cookie-jar.h b/libsoup/cookies/soup-cookie-jar.h index 7c4b4142..c12b3455 100644 --- a/libsoup/cookies/soup-cookie-jar.h +++ b/libsoup/cookies/soup-cookie-jar.h @@ -39,42 +39,42 @@ SOUP_AVAILABLE_IN_2_24 SoupCookieJar * soup_cookie_jar_new (void); SOUP_AVAILABLE_IN_2_24 char * soup_cookie_jar_get_cookies (SoupCookieJar *jar, - SoupURI *uri, + GUri *uri, gboolean for_http); SOUP_AVAILABLE_IN_2_40 GSList * soup_cookie_jar_get_cookie_list (SoupCookieJar *jar, - SoupURI *uri, + GUri *uri, gboolean for_http); SOUP_AVAILABLE_IN_2_70 GSList * soup_cookie_jar_get_cookie_list_with_same_site_info ( SoupCookieJar *jar, - SoupURI *uri, - SoupURI *top_level, - SoupURI *site_for_cookies, + GUri *uri, + GUri *top_level, + GUri *site_for_cookies, gboolean for_http, gboolean is_safe_method, gboolean is_top_level_navigation); SOUP_AVAILABLE_IN_2_24 void soup_cookie_jar_set_cookie (SoupCookieJar *jar, - SoupURI *uri, + GUri *uri, const char *cookie); SOUP_AVAILABLE_IN_2_30 void soup_cookie_jar_set_cookie_with_first_party (SoupCookieJar *jar, - SoupURI *uri, - SoupURI *first_party, + GUri *uri, + GUri *first_party, const char *cookie); SOUP_AVAILABLE_IN_2_26 void soup_cookie_jar_add_cookie (SoupCookieJar *jar, SoupCookie *cookie); SOUP_AVAILABLE_IN_2_40 void soup_cookie_jar_add_cookie_with_first_party (SoupCookieJar *jar, - SoupURI *first_party, + GUri *first_party, SoupCookie *cookie); SOUP_AVAILABLE_IN_2_68 void soup_cookie_jar_add_cookie_full (SoupCookieJar *jar, SoupCookie *cookie, - SoupURI *uri, - SoupURI *first_party); + GUri *uri, + GUri *first_party); SOUP_AVAILABLE_IN_2_26 void soup_cookie_jar_delete_cookie (SoupCookieJar *jar, SoupCookie *cookie); diff --git a/libsoup/cookies/soup-cookie.c b/libsoup/cookies/soup-cookie.c index 03ccc4a0..859150bb 100644 --- a/libsoup/cookies/soup-cookie.c +++ b/libsoup/cookies/soup-cookie.c @@ -173,13 +173,13 @@ parse_date (const char **val_p) } static SoupCookie * -parse_one_cookie (const char *header, SoupURI *origin) +parse_one_cookie (const char *header, GUri *origin) { const char *start, *end, *p; gboolean has_value; SoupCookie *cookie; - g_return_val_if_fail (origin == NULL || origin->host, NULL); + g_return_val_if_fail (origin == NULL || SOUP_URI_IS_VALID (origin), NULL); cookie = g_slice_new0 (SoupCookie); @@ -289,12 +289,12 @@ parse_one_cookie (const char *header, SoupURI *origin) if (origin) { /* Sanity-check domain */ if (cookie->domain) { - if (!soup_cookie_domain_matches (cookie, origin->host)) { + if (!soup_cookie_domain_matches (cookie, g_uri_get_host (origin))) { soup_cookie_free (cookie); return NULL; } } else - cookie->domain = g_strdup (origin->host); + cookie->domain = g_strdup (g_uri_get_host (origin)); /* The original cookie spec didn't say that pages * could only set cookies for paths they were under. @@ -305,16 +305,21 @@ parse_one_cookie (const char *header, SoupURI *origin) */ if (!cookie->path) { + GUri *normalized_origin = soup_uri_copy_with_normalized_flags (origin); char *slash; + const char *origin_path = g_uri_get_path (normalized_origin); - slash = strrchr (origin->path, '/'); - if (!slash || slash == origin->path) + slash = strrchr (origin_path, '/'); + if (!slash || slash == origin_path) cookie->path = g_strdup ("/"); else { - cookie->path = g_strndup (origin->path, - slash - origin->path); + cookie->path = g_strndup (origin_path, + slash - origin_path); } + + g_uri_unref (normalized_origin); } + } else if (!cookie->path) { cookie->path = g_strdup ("/"); } @@ -411,7 +416,7 @@ soup_cookie_new (const char *name, const char *value, * Since: 2.24 **/ SoupCookie * -soup_cookie_parse (const char *cookie, SoupURI *origin) +soup_cookie_parse (const char *cookie, GUri *origin) { return parse_one_cookie (cookie, origin); } @@ -904,7 +909,7 @@ soup_cookie_free (SoupCookie *cookie) GSList * soup_cookies_from_response (SoupMessage *msg) { - SoupURI *origin; + GUri *origin; const char *name, *value; SoupCookie *cookie; GSList *cookies = NULL; @@ -1073,7 +1078,7 @@ soup_cookies_to_cookie_header (GSList *cookies) /** * soup_cookie_applies_to_uri: * @cookie: a #SoupCookie - * @uri: a #SoupURI + * @uri: a #GUri * * Tests if @cookie should be sent to @uri. * @@ -1087,28 +1092,32 @@ soup_cookies_to_cookie_header (GSList *cookies) * Since: 2.24 **/ gboolean -soup_cookie_applies_to_uri (SoupCookie *cookie, SoupURI *uri) +soup_cookie_applies_to_uri (SoupCookie *cookie, GUri *uri) { int plen; + g_return_val_if_fail (SOUP_URI_IS_VALID (uri), FALSE); + if (cookie->secure && !soup_uri_is_https (uri, NULL)) return FALSE; if (cookie->expires && soup_date_time_is_past (cookie->expires)) return FALSE; - /* uri->path is required to be non-NULL */ - g_return_val_if_fail (uri->path != NULL, FALSE); - plen = strlen (cookie->path); if (plen == 0) return TRUE; - if (strncmp (cookie->path, uri->path, plen) != 0) - return FALSE; - if (cookie->path[plen - 1] != '/' && - uri->path[plen] && uri->path[plen] != '/') - return FALSE; + GUri *normalized_uri = soup_uri_copy_with_normalized_flags (uri); + const char *uri_path = g_uri_get_path (normalized_uri); + if (strncmp (cookie->path, uri_path, plen) != 0 || + (cookie->path[plen - 1] != '/' && uri_path[plen] && + uri_path[plen] != '/')) { + g_uri_unref (normalized_uri); + return FALSE; + } + + g_uri_unref (normalized_uri); return TRUE; } diff --git a/libsoup/cookies/soup-cookie.h b/libsoup/cookies/soup-cookie.h index 88735ac8..c5b5bd8f 100644 --- a/libsoup/cookies/soup-cookie.h +++ b/libsoup/cookies/soup-cookie.h @@ -44,7 +44,7 @@ SoupCookie *soup_cookie_new (const char *name, int max_age); SOUP_AVAILABLE_IN_2_24 SoupCookie *soup_cookie_parse (const char *header, - SoupURI *origin); + GUri *origin); SOUP_AVAILABLE_IN_2_24 SoupCookie *soup_cookie_copy (SoupCookie *cookie); @@ -100,7 +100,7 @@ char *soup_cookie_to_cookie_header (SoupCookie *cookie); SOUP_AVAILABLE_IN_2_24 gboolean soup_cookie_applies_to_uri (SoupCookie *cookie, - SoupURI *uri); + GUri *uri); SOUP_AVAILABLE_IN_2_24 gboolean soup_cookie_equal (SoupCookie *cookie1, SoupCookie *cookie2); diff --git a/libsoup/hsts/soup-hsts-enforcer.c b/libsoup/hsts/soup-hsts-enforcer.c index 9e024de9..8925f5ac 100644 --- a/libsoup/hsts/soup-hsts-enforcer.c +++ b/libsoup/hsts/soup-hsts-enforcer.c @@ -466,7 +466,7 @@ soup_hsts_enforcer_process_sts_header (SoupHSTSEnforcer *hsts_enforcer, SoupMessage *msg) { SoupHSTSPolicy *policy; - SoupURI *uri; + GUri *uri; uri = soup_message_get_uri (msg); @@ -487,24 +487,39 @@ got_sts_header_cb (SoupMessage *msg, gpointer user_data) soup_hsts_enforcer_process_sts_header (hsts_enforcer, msg); } +static GUri * +copy_uri_with_new_scheme (GUri *uri, const char *scheme, int port) +{ + return g_uri_build_with_user ( + g_uri_get_flags (uri), + scheme, + g_uri_get_user (uri), + g_uri_get_password (uri), + g_uri_get_auth_params (uri), + g_uri_get_host (uri), + port, + g_uri_get_path (uri), + g_uri_get_query (uri), + g_uri_get_fragment (uri) + ); +} + static void rewrite_message_uri_to_https (SoupMessage *msg) { - SoupURI *uri; - guint original_port; + GUri *uri, *new_uri; + int port; - uri = soup_uri_copy (soup_message_get_uri (msg)); - - original_port = soup_uri_get_port (uri); - /* This will unconditionally rewrite the port to 443. */ - soup_uri_set_scheme (uri, SOUP_URI_SCHEME_HTTPS); + uri = soup_message_get_uri (msg); + port = soup_uri_get_port_with_default (uri); /* From the RFC: "If the URI contains an explicit port component that is not equal to "80", the port component value MUST be preserved;" */ - if (original_port != 80) - soup_uri_set_port (uri, original_port); + if (port == 80) + port = 443; - soup_message_set_uri (msg, uri); - soup_uri_free (uri); + new_uri = copy_uri_with_new_scheme (uri, "https", port); + soup_message_set_uri (msg, new_uri); + g_uri_unref (new_uri); } static void @@ -525,19 +540,17 @@ on_sts_known_host_message_starting (SoupMessage *msg, SoupHSTSEnforcer *hsts_enf static void preprocess_request (SoupHSTSEnforcer *enforcer, SoupMessage *msg) { - SoupURI *uri; - const char *scheme; + GUri *uri; const char *host; char *canonicalized = NULL; uri = soup_message_get_uri (msg); - host = soup_uri_get_host (uri); + host = g_uri_get_host (uri); if (g_hostname_is_ip_address (host)) return; - scheme = soup_uri_get_scheme (uri); - if (scheme == SOUP_URI_SCHEME_HTTP) { + if (soup_uri_is_http (uri, NULL)) { if (g_hostname_is_ascii_encoded (host)) { canonicalized = g_hostname_to_unicode (host); if (!canonicalized) @@ -551,7 +564,7 @@ preprocess_request (SoupHSTSEnforcer *enforcer, SoupMessage *msg) g_signal_emit (enforcer, signals[HSTS_ENFORCED], 0, msg); } g_free (canonicalized); - } else if (scheme == SOUP_URI_SCHEME_HTTPS) { + } else if (soup_uri_is_https (uri, NULL)) { soup_message_add_header_handler (msg, "got-headers", "Strict-Transport-Security", G_CALLBACK (got_sts_header_cb), diff --git a/libsoup/hsts/soup-hsts-enforcer.h b/libsoup/hsts/soup-hsts-enforcer.h index 1010a4ce..adba626f 100644 --- a/libsoup/hsts/soup-hsts-enforcer.h +++ b/libsoup/hsts/soup-hsts-enforcer.h @@ -21,7 +21,7 @@ G_DECLARE_DERIVABLE_TYPE (SoupHSTSEnforcer, soup_hsts_enforcer, SOUP, HSTS_ENFOR * whether changes made to it will be lost when the underlying #SoupSession is finished. * @has_valid_policy: The @has_valid_policy function is called to check whether there is a valid * policy for the given domain. This method should return %TRUE for #SoupHSTSEnforcer to - * change the scheme of the #SoupURI in the #SoupMessage to HTTPS. Implementations might want to + * change the scheme of the #GUri in the #SoupMessage to HTTPS. Implementations might want to * chain up to the @has_valid_policy in the parent class to check, for instance, for runtime * policies. * @changed: The class closure for the #SoupHSTSEnforcer::changed signal. diff --git a/libsoup/hsts/soup-hsts-policy.c b/libsoup/hsts/soup-hsts-policy.c index f17eebbe..e78d7fda 100644 --- a/libsoup/hsts/soup-hsts-policy.c +++ b/libsoup/hsts/soup-hsts-policy.c @@ -274,7 +274,7 @@ soup_hsts_policy_new_from_response (SoupMessage *msg) soup_message_headers_iter_init (&iter, soup_message_get_response_headers (msg)); while (soup_message_headers_iter_next (&iter, &name, &value)) { - SoupURI *uri; + GUri *uri; GHashTable *params; const char *max_age_str; char *endptr; @@ -307,7 +307,7 @@ soup_hsts_policy_new_from_response (SoupMessage *msg) if (include_subdomains_value) goto out; - policy = soup_hsts_policy_new (uri->host, max_age, include_subdomains); + policy = soup_hsts_policy_new (g_uri_get_host (uri), max_age, include_subdomains); out: soup_header_free_param_list (params); return policy; diff --git a/libsoup/include/soup-installed.h b/libsoup/include/soup-installed.h index 426e0dd8..2714a5ab 100644 --- a/libsoup/include/soup-installed.h +++ b/libsoup/include/soup-installed.h @@ -40,7 +40,7 @@ extern "C" { #include #include #include -#include +#include #include #include #include diff --git a/libsoup/meson.build b/libsoup/meson.build index 531ff87b..e7950317 100644 --- a/libsoup/meson.build +++ b/libsoup/meson.build @@ -73,7 +73,7 @@ soup_sources = [ 'soup-socket-properties.c', 'soup-status.c', 'soup-tld.c', - 'soup-uri.c', + 'soup-uri-utils.c', 'soup-version.c', ] @@ -127,7 +127,7 @@ soup_introspection_headers = [ 'soup-status.h', 'soup-tld.h', 'soup-types.h', - 'soup-uri.h', + 'soup-uri-utils.h', ] soup_installed_headers = soup_introspection_headers diff --git a/libsoup/server/soup-auth-domain-digest.c b/libsoup/server/soup-auth-domain-digest.c index 1bce5770..29ef583c 100644 --- a/libsoup/server/soup-auth-domain-digest.c +++ b/libsoup/server/soup-auth-domain-digest.c @@ -207,7 +207,7 @@ check_hex_urp (SoupAuthDomain *domain, const char *nonce, *nc, *cnonce, *response; char hex_a1[33], computed_response[33]; int nonce_count; - SoupURI *dig_uri, *req_uri; + GUri *dig_uri, *req_uri; msg_username = g_hash_table_lookup (params, "username"); if (!msg_username || strcmp (msg_username, username) != 0) @@ -219,19 +219,19 @@ check_hex_urp (SoupAuthDomain *domain, return FALSE; req_uri = soup_server_message_get_uri (msg); - dig_uri = soup_uri_new (uri); + dig_uri = g_uri_parse (uri, SOUP_HTTP_URI_FLAGS, NULL); if (dig_uri) { if (!soup_uri_equal (dig_uri, req_uri)) { - soup_uri_free (dig_uri); + g_uri_unref (dig_uri); return FALSE; } - soup_uri_free (dig_uri); + g_uri_unref (dig_uri); } else { char *req_path; char *dig_path; - req_path = soup_uri_to_string (req_uri, TRUE); - dig_path = soup_uri_decode (uri); + req_path = soup_uri_get_path_and_query (req_uri); + dig_path = g_uri_unescape_string (uri, NULL); if (strcmp (dig_path, req_path) != 0) { g_free (req_path); diff --git a/libsoup/server/soup-auth-domain.c b/libsoup/server/soup-auth-domain.c index 3add8df5..5606f818 100644 --- a/libsoup/server/soup-auth-domain.c +++ b/libsoup/server/soup-auth-domain.c @@ -507,7 +507,7 @@ soup_auth_domain_covers (SoupAuthDomain *domain, const char *path; if (!priv->proxy) { - path = soup_server_message_get_uri (msg)->path; + path = g_uri_get_path (soup_server_message_get_uri (msg)); if (!soup_path_map_lookup (priv->paths, path)) return FALSE; } diff --git a/libsoup/server/soup-server-io.c b/libsoup/server/soup-server-io.c index 8db0ecdb..3e99acd7 100644 --- a/libsoup/server/soup-server-io.c +++ b/libsoup/server/soup-server-io.c @@ -516,26 +516,31 @@ io_write (SoupServerMessage *msg, return TRUE; } -static SoupURI * +static GUri * parse_connect_authority (const char *req_path) { - SoupURI *uri; - char *fake_uri; - - fake_uri = g_strdup_printf ("http://%s", req_path); - uri = soup_uri_new (fake_uri); - g_free (fake_uri); - - if (uri->user || uri->password || - uri->query || uri->fragment || - !uri->host || - (uri->port == 0) || - (strcmp (uri->path, "/") != 0)) { - soup_uri_free (uri); + GUri *uri; + char *fake_uri; + + fake_uri = g_strdup_printf ("http://%s", req_path); + uri = g_uri_parse (fake_uri, SOUP_HTTP_URI_FLAGS, NULL); + g_free (fake_uri); + + if (!uri) + return NULL; + + if (g_uri_get_user (uri) || + g_uri_get_password (uri) || + g_uri_get_query (uri) || + g_uri_get_fragment (uri) || + !g_uri_get_host (uri) || + g_uri_get_port (uri) <= 0 || + strcmp (g_uri_get_path (uri), "/") != 0) { + g_uri_unref (uri); return NULL; } - return uri; + return uri; } static guint @@ -550,7 +555,7 @@ parse_headers (SoupServerMessage *msg, SoupSocket *sock; const char *req_host; guint status; - SoupURI *uri; + GUri *uri; SoupMessageHeaders *request_headers; request_headers = soup_server_message_get_request_headers (msg); @@ -585,54 +590,51 @@ parse_headers (SoupServerMessage *msg, sock = soup_server_message_get_soup_socket (msg); - if (!strcmp (req_path, "*") && req_host) { - /* Eg, "OPTIONS * HTTP/1.1" */ - url = g_strdup_printf ("%s://%s", - soup_socket_is_ssl (sock) ? "https" : "http", - req_host); - uri = soup_uri_new (url); - if (uri) - soup_uri_set_path (uri, "*"); - g_free (url); - } else if (soup_server_message_get_method (msg) == SOUP_METHOD_CONNECT) { - /* Authority */ - uri = parse_connect_authority (req_path); - } else if (*req_path != '/') { - /* Absolute URI */ - uri = soup_uri_new (req_path); - } else if (req_host) { - url = g_strdup_printf ("%s://%s%s", - soup_socket_is_ssl (sock) ? "https" : "http", - req_host, req_path); - uri = soup_uri_new (url); - g_free (url); - } else if (soup_server_message_get_http_version (msg) == SOUP_HTTP_1_0) { - /* No Host header, no AbsoluteUri */ - GInetSocketAddress *addr = soup_socket_get_local_address (sock); + if (!strcmp (req_path, "*") && req_host) { + /* Eg, "OPTIONS * HTTP/1.1" */ + 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); + g_free (url); + } else if (soup_server_message_get_method (msg) == SOUP_METHOD_CONNECT) { + /* Authority */ + uri = parse_connect_authority (req_path); + } else if (*req_path != '/') { + /* Absolute URI */ + uri = g_uri_parse (req_path, SOUP_HTTP_URI_FLAGS, NULL); + } else if (req_host) { + url = g_strdup_printf ("%s://%s%s", + soup_socket_is_ssl (sock) ? "https" : "http", + req_host, req_path); + uri = g_uri_parse (url, SOUP_HTTP_URI_FLAGS, NULL); + g_free (url); + } else if (soup_server_message_get_http_version (msg) == SOUP_HTTP_1_0) { + /* No Host header, no AbsoluteUri */ + GInetSocketAddress *addr = soup_socket_get_local_address (sock); GInetAddress *inet_addr = g_inet_socket_address_get_address (addr); char *local_ip = g_inet_address_to_string (inet_addr); + int port = g_inet_socket_address_get_port (addr); + if (port == 0) + port = -1; + + uri = g_uri_build (SOUP_HTTP_URI_FLAGS, + soup_socket_is_ssl (sock) ? "https" : "http", + NULL, local_ip, port, req_path, NULL, NULL); + g_free (local_ip); + } else + uri = NULL; + + g_free (req_path); + + if (!uri || !g_uri_get_host (uri)) { + if (uri) + g_uri_unref (uri); + return SOUP_STATUS_BAD_REQUEST; + } - uri = soup_uri_new (NULL); - soup_uri_set_scheme (uri, soup_socket_is_ssl (sock) ? - SOUP_URI_SCHEME_HTTPS : - SOUP_URI_SCHEME_HTTP); - soup_uri_set_host (uri, local_ip); - soup_uri_set_port (uri, g_inet_socket_address_get_port (addr)); - soup_uri_set_path (uri, req_path); - g_free (local_ip); - } else - uri = NULL; - - g_free (req_path); - - if (!uri || !uri->host) { - if (uri) - soup_uri_free (uri); - return SOUP_STATUS_BAD_REQUEST; - } - - soup_server_message_set_uri (msg, uri); - soup_uri_free (uri); + soup_server_message_set_uri (msg, uri); + g_uri_unref (uri); return SOUP_STATUS_OK; } diff --git a/libsoup/server/soup-server-message-private.h b/libsoup/server/soup-server-message-private.h index 057b058d..a4904653 100644 --- a/libsoup/server/soup-server-message-private.h +++ b/libsoup/server/soup-server-message-private.h @@ -12,7 +12,7 @@ SoupServerMessage *soup_server_message_new (SoupSocket *sock); void soup_server_message_set_uri (SoupServerMessage *msg, - SoupURI *uri); + GUri *uri); void soup_server_message_set_method (SoupServerMessage *msg, const char *method); SoupSocket *soup_server_message_get_soup_socket (SoupServerMessage *msg); diff --git a/libsoup/server/soup-server-message.c b/libsoup/server/soup-server-message.c index 9d4c3324..04baff66 100644 --- a/libsoup/server/soup-server-message.c +++ b/libsoup/server/soup-server-message.c @@ -59,7 +59,7 @@ struct _SoupServerMessage { guint status_code; char *reason_phrase; - SoupURI *uri; + GUri *uri; SoupMessageBody *request_body; SoupMessageHeaders *request_headers; @@ -124,7 +124,7 @@ soup_server_message_finalize (GObject *object) g_clear_object (&msg->gsock); g_clear_pointer (&msg->remote_ip, g_free); - g_clear_pointer (&msg->uri, soup_uri_free); + g_clear_pointer (&msg->uri, g_uri_unref); g_free (msg->reason_phrase); soup_message_body_free (msg->request_body); @@ -337,11 +337,11 @@ soup_server_message_new (SoupSocket *sock) void soup_server_message_set_uri (SoupServerMessage *msg, - SoupURI *uri) + GUri *uri) { if (msg->uri) - soup_uri_free (msg->uri); - msg->uri = soup_uri_copy (uri); + g_uri_unref (msg->uri); + msg->uri = soup_uri_copy_with_normalized_flags (uri); } SoupSocket * @@ -654,9 +654,9 @@ soup_server_message_set_status (SoupServerMessage *msg, * * Get @msg's URI. * - * Returns: (transfer none): a #SoupURI + * Returns: (transfer none): a #GUri */ -SoupURI * +GUri * soup_server_message_get_uri (SoupServerMessage *msg) { g_return_val_if_fail (SOUP_IS_SERVER_MESSAGE (msg), NULL); @@ -720,20 +720,20 @@ soup_server_message_set_redirect (SoupServerMessage *msg, guint status_code, const char *redirect_uri) { - SoupURI *location; - char *location_str; + GUri *location; + char *location_str; g_return_if_fail (SOUP_IS_SERVER_MESSAGE (msg)); - location = soup_uri_new_with_base (soup_server_message_get_uri (msg), redirect_uri); - g_return_if_fail (location != NULL); + location = g_uri_parse_relative (soup_server_message_get_uri (msg), redirect_uri, SOUP_HTTP_URI_FLAGS, NULL); + g_return_if_fail (location != NULL); - soup_server_message_set_status (msg, status_code, NULL); - location_str = soup_uri_to_string (location, FALSE); - soup_message_headers_replace (msg->response_headers, "Location", - location_str); - g_free (location_str); - soup_uri_free (location); + soup_server_message_set_status (msg, status_code, NULL); + location_str = g_uri_to_string (location); + soup_message_headers_replace (msg->response_headers, "Location", + location_str); + g_free (location_str); + g_uri_unref (location); } /** diff --git a/libsoup/server/soup-server-message.h b/libsoup/server/soup-server-message.h index 5102648e..7d29b2c2 100644 --- a/libsoup/server/soup-server-message.h +++ b/libsoup/server/soup-server-message.h @@ -46,7 +46,7 @@ void soup_server_message_set_status (SoupServerMessage guint status_code, const char *reason_phrase); SOUP_AVAILABLE_IN_ALL -SoupURI *soup_server_message_get_uri (SoupServerMessage *msg); +GUri *soup_server_message_get_uri (SoupServerMessage *msg); SOUP_AVAILABLE_IN_ALL void soup_server_message_set_response (SoupServerMessage *msg, diff --git a/libsoup/server/soup-server.c b/libsoup/server/soup-server.c index 40056c5e..bbc10627 100644 --- a/libsoup/server/soup-server.c +++ b/libsoup/server/soup-server.c @@ -223,7 +223,7 @@ soup_server_init (SoupServer *server) priv->handlers = soup_path_map_new ((GDestroyNotify)free_handler); priv->http_aliases = g_new (char *, 2); - priv->http_aliases[0] = (char *)g_intern_string ("*"); + priv->http_aliases[0] = g_strdup ("*"); priv->http_aliases[1] = NULL; priv->websocket_extension_types = g_ptr_array_new_with_free_func ((GDestroyNotify)g_type_class_unref); @@ -260,16 +260,16 @@ soup_server_finalize (GObject *object) g_clear_pointer (&priv->loop, g_main_loop_unref); - g_free (priv->http_aliases); - g_free (priv->https_aliases); + g_strfreev (priv->http_aliases); + g_strfreev (priv->https_aliases); g_ptr_array_free (priv->websocket_extension_types, TRUE); G_OBJECT_CLASS (soup_server_parent_class)->finalize (object); } -/* priv->http_aliases and priv->https_aliases are stored as arrays of - * *interned* strings, so we can't just use g_strdupv() to set them. +/* priv->http_aliases and priv->https_aliases are stored as lower-case strings, + * so we can't just use g_strdupv() to set them. */ static void set_aliases (char ***variable, char **value) @@ -277,7 +277,7 @@ set_aliases (char ***variable, char **value) int len, i; if (*variable) - g_free (*variable); + g_strfreev (*variable); if (!value) { *variable = NULL; @@ -287,7 +287,7 @@ set_aliases (char ***variable, char **value) len = g_strv_length (value); *variable = g_new (char *, len + 1); for (i = 0; i < len; i++) - (*variable)[i] = (char *)g_intern_string (value[i]); + (*variable)[i] = g_ascii_strdown (value[i], -1); (*variable)[i] = NULL; } @@ -726,10 +726,10 @@ get_handler (SoupServer *server, SoupServerMessage *msg) { SoupServerPrivate *priv = soup_server_get_instance_private (server); - SoupURI *uri; + GUri *uri; uri = soup_server_message_get_uri (msg); - return soup_path_map_lookup (priv->handlers, NORMALIZED_PATH (uri->path)); + return soup_path_map_lookup (priv->handlers, NORMALIZED_PATH (g_uri_get_path (uri))); } static void @@ -739,7 +739,7 @@ call_handler (SoupServer *server, gboolean early) { GHashTable *form_data_set; - SoupURI *uri; + GUri *uri; if (early && !handler->early_callback) return; @@ -750,18 +750,18 @@ call_handler (SoupServer *server, return; uri = soup_server_message_get_uri (msg); - if (uri->query) - form_data_set = soup_form_decode (uri->query); + if (g_uri_get_query (uri)) + form_data_set = soup_form_decode (g_uri_get_query (uri)); else form_data_set = NULL; if (early) { (*handler->early_callback) (server, msg, - uri->path, form_data_set, + g_uri_get_path (uri), form_data_set, handler->early_user_data); } else { (*handler->callback) (server, msg, - uri->path, form_data_set, + g_uri_get_path (uri), form_data_set, handler->user_data); } @@ -769,13 +769,30 @@ call_handler (SoupServer *server, g_hash_table_unref (form_data_set); } +static GUri * +uri_set_path (GUri *uri, const char *path) +{ + return g_uri_build_with_user ( + g_uri_get_flags (uri) ^ G_URI_FLAGS_ENCODED_PATH, + g_uri_get_scheme (uri), + g_uri_get_user (uri), + g_uri_get_password (uri), + g_uri_get_auth_params (uri), + g_uri_get_host (uri), + g_uri_get_port (uri), + path, + g_uri_get_query (uri), + g_uri_get_fragment (uri) + ); +} + static void got_headers (SoupServer *server, SoupServerMessage *msg) { SoupServerPrivate *priv = soup_server_get_instance_private (server); SoupServerHandler *handler; - SoupURI *uri; + GUri *uri; GDateTime *date; char *date_string; SoupAuthDomain *domain; @@ -805,10 +822,10 @@ got_headers (SoupServer *server, return; } - if (!priv->raw_paths) { + if (!priv->raw_paths && g_uri_get_flags (uri) & G_URI_FLAGS_ENCODED_PATH) { char *decoded_path; - decoded_path = soup_uri_decode (uri->path); + decoded_path = g_uri_unescape_string (g_uri_get_path (uri), NULL); if (strstr (decoded_path, "/../") || g_str_has_suffix (decoded_path, "/..") @@ -826,7 +843,8 @@ got_headers (SoupServer *server, return; } - soup_uri_set_path (uri, decoded_path); + uri = uri_set_path (uri, decoded_path); + soup_server_message_set_uri (msg, uri); g_free (decoded_path); } @@ -870,7 +888,7 @@ static void complete_websocket_upgrade (SoupServer *server, SoupServerMessage *msg) { - SoupURI *uri = soup_server_message_get_uri (msg); + GUri *uri = soup_server_message_get_uri (msg); SoupServerHandler *handler; GIOStream *stream; SoupWebsocketConnection *conn; @@ -889,7 +907,7 @@ complete_websocket_upgrade (SoupServer *server, handler->websocket_extensions = NULL; g_object_unref (stream); - (*handler->websocket_callback) (server, msg, uri->path, conn, + (*handler->websocket_callback) (server, msg, g_uri_get_path (uri), conn, handler->websocket_user_data); g_object_unref (conn); g_object_unref (msg); @@ -1491,8 +1509,8 @@ soup_server_listen_socket (SoupServer *server, GSocket *socket, * ::, rather than actually returning separate URIs * for each interface on the system. * - * Return value: (transfer full) (element-type Soup.URI): a list of - * #SoupURIs, which you must free when you are done with it. + * Return value: (transfer full) (element-type GUri): a list of + * #GUris, which you must free when you are done with it. * * Since: 2.48 */ @@ -1505,7 +1523,8 @@ soup_server_get_uris (SoupServer *server) GInetSocketAddress *addr; GInetAddress *inet_addr; char *ip; - SoupURI *uri; + int port; + GUri *uri; gpointer creds; g_return_val_if_fail (SOUP_IS_SERVER (server), NULL); @@ -1516,13 +1535,15 @@ soup_server_get_uris (SoupServer *server) addr = soup_socket_get_local_address (listener); inet_addr = g_inet_socket_address_get_address (addr); ip = g_inet_address_to_string (inet_addr); + port = g_inet_socket_address_get_port (addr); g_object_get (G_OBJECT (listener), "ssl-creds", &creds, NULL); - uri = soup_uri_new (NULL); - soup_uri_set_scheme (uri, creds ? "https" : "http"); - soup_uri_set_host (uri, ip); - soup_uri_set_port (uri, g_inet_socket_address_get_port (addr)); - soup_uri_set_path (uri, "/"); + if (port == 0) + port = -1; + + uri = g_uri_build (SOUP_HTTP_URI_FLAGS, + creds ? "https" : "http", + NULL, ip, port, "/", NULL, NULL); uris = g_slist_prepend (uris, uri); @@ -1551,9 +1572,7 @@ soup_server_get_uris (SoupServer *server) * server is serving resources in some non-POSIX-filesystem namespace, * you may want to distinguish those as two distinct paths. In that * case, you can set the SoupServer:raw-paths property when creating - * the #SoupServer, and it will leave those characters undecoded. (You - * may want to call soup_uri_normalize() to decode any percent-encoded - * characters that you aren't handling specially.) + * the #SoupServer, and it will leave those characters undecoded. * * @query contains the query component of the Request-URI parsed * according to the rules for HTML form handling. Although this is the diff --git a/libsoup/server/soup-server.h b/libsoup/server/soup-server.h index e1143694..1eb7f0db 100644 --- a/libsoup/server/soup-server.h +++ b/libsoup/server/soup-server.h @@ -6,7 +6,7 @@ #pragma once #include "soup-types.h" -#include "soup-uri.h" +#include "soup-uri-utils.h" #include "soup-websocket-connection.h" G_BEGIN_DECLS diff --git a/libsoup/soup-connection.c b/libsoup/soup-connection.c index f3b3acf7..9597097b 100644 --- a/libsoup/soup-connection.c +++ b/libsoup/soup-connection.c @@ -27,7 +27,7 @@ typedef struct { GIOStream *iostream; SoupSocketProperties *socket_props; - SoupURI *remote_uri, *proxy_uri; + GUri *remote_uri, *proxy_uri; gboolean ssl; SoupMessage *current_msg; @@ -80,8 +80,8 @@ soup_connection_finalize (GObject *object) { SoupConnectionPrivate *priv = soup_connection_get_instance_private (SOUP_CONNECTION (object)); - g_clear_pointer (&priv->remote_uri, soup_uri_free); - g_clear_pointer (&priv->proxy_uri, soup_uri_free); + g_clear_pointer (&priv->remote_uri, g_uri_unref); + g_clear_pointer (&priv->proxy_uri, g_uri_unref); g_clear_pointer (&priv->socket_props, soup_socket_properties_unref); g_clear_object (&priv->remote_connectable); g_clear_object (&priv->current_msg); @@ -216,7 +216,7 @@ soup_connection_class_init (SoupConnectionClass *connection_class) g_param_spec_boxed ("remote-uri", "Remote URI", "The URI of the HTTP server", - SOUP_TYPE_URI, + G_TYPE_URI, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); g_object_class_install_property ( @@ -314,7 +314,7 @@ current_msg_got_body (SoupMessage *msg, gpointer user_data) soup_connection_event (conn, G_SOCKET_CLIENT_PROXY_NEGOTIATED, NULL); /* We're now effectively no longer proxying */ - g_clear_pointer (&priv->proxy_uri, soup_uri_free); + g_clear_pointer (&priv->proxy_uri, g_uri_unref); } priv->reusable = soup_message_is_keepalive (msg); @@ -476,8 +476,14 @@ soup_connection_connected (SoupConnection *conn, if (addr && G_IS_PROXY_ADDRESS (addr)) { GProxyAddress *paddr = G_PROXY_ADDRESS (addr); - if (strcmp (g_proxy_address_get_protocol (paddr), "http") == 0) - priv->proxy_uri = soup_uri_new (g_proxy_address_get_uri (paddr)); + if (strcmp (g_proxy_address_get_protocol (paddr), "http") == 0) { + GError *error = NULL; + priv->proxy_uri = g_uri_parse (g_proxy_address_get_uri (paddr), SOUP_HTTP_URI_FLAGS, &error); + if (error) { + g_warning ("Failed to parse proxy URI %s: %s", g_proxy_address_get_uri (paddr), error->message); + g_error_free (error); + } + } } g_clear_object (&addr); @@ -597,9 +603,9 @@ soup_connection_connect_async (SoupConnection *conn, /* Set the protocol to ensure correct proxy resolution. */ priv->remote_connectable = g_object_new (G_TYPE_NETWORK_ADDRESS, - "hostname", priv->remote_uri->host, - "port", priv->remote_uri->port, - "scheme", priv->remote_uri->scheme, + "hostname", g_uri_get_host (priv->remote_uri), + "port", soup_uri_get_port_with_default (priv->remote_uri), + "scheme", g_uri_get_scheme (priv->remote_uri), NULL); priv->cancellable = cancellable ? g_object_ref (cancellable) : g_cancellable_new (); @@ -640,11 +646,11 @@ soup_connection_connect (SoupConnection *conn, /* Set the protocol to ensure correct proxy resolution. */ priv->remote_connectable = - g_object_new (G_TYPE_NETWORK_ADDRESS, - "hostname", priv->remote_uri->host, - "port", priv->remote_uri->port, - "scheme", priv->remote_uri->scheme, - NULL); + g_object_new (G_TYPE_NETWORK_ADDRESS, + "hostname", g_uri_get_host (priv->remote_uri), + "port", soup_uri_get_port_with_default (priv->remote_uri), + "scheme", g_uri_get_scheme (priv->remote_uri), + NULL); priv->cancellable = cancellable ? g_object_ref (cancellable) : g_cancellable_new (); @@ -887,7 +893,7 @@ soup_connection_steal_iostream (SoupConnection *conn) return iostream; } -SoupURI * +GUri * soup_connection_get_remote_uri (SoupConnection *conn) { SoupConnectionPrivate *priv = soup_connection_get_instance_private (conn); @@ -897,7 +903,7 @@ soup_connection_get_remote_uri (SoupConnection *conn) return priv->remote_uri; } -SoupURI * +GUri * soup_connection_get_proxy_uri (SoupConnection *conn) { SoupConnectionPrivate *priv = soup_connection_get_instance_private (conn); diff --git a/libsoup/soup-connection.h b/libsoup/soup-connection.h index c372a731..505866ee 100644 --- a/libsoup/soup-connection.h +++ b/libsoup/soup-connection.h @@ -51,8 +51,8 @@ void soup_connection_disconnect (SoupConnection *conn); GSocket *soup_connection_get_socket (SoupConnection *conn); GIOStream *soup_connection_get_iostream (SoupConnection *conn); GIOStream *soup_connection_steal_iostream (SoupConnection *conn); -SoupURI *soup_connection_get_remote_uri (SoupConnection *conn); -SoupURI *soup_connection_get_proxy_uri (SoupConnection *conn); +GUri *soup_connection_get_remote_uri (SoupConnection *conn); +GUri *soup_connection_get_proxy_uri (SoupConnection *conn); gboolean soup_connection_is_via_proxy (SoupConnection *conn); gboolean soup_connection_is_tunnelled (SoupConnection *conn); gboolean soup_connection_get_tls_info (SoupConnection *conn, diff --git a/libsoup/soup-headers.c b/libsoup/soup-headers.c index c0fd1888..917d5e75 100644 --- a/libsoup/soup-headers.c +++ b/libsoup/soup-headers.c @@ -696,7 +696,7 @@ decode_rfc5987 (char *encoded_string) if (!q) return FALSE; - decoded = soup_uri_decode (q + 1); + decoded = g_uri_unescape_string (q + 1, NULL); if (iso_8859_1) { char *utf8 = g_convert_with_fallback (decoded, -1, "UTF-8", "iso-8859-1", "_", @@ -910,7 +910,7 @@ append_param_rfc5987 (GString *string, g_string_append (string, name); g_string_append (string, "*=UTF-8''"); - encoded = soup_uri_encode (value, " *'%()<>@,;:\\\"/[]?="); + encoded = g_uri_escape_string (value, "*'%()<>@,;:\\\"/[]?=", FALSE); g_string_append (string, encoded); g_free (encoded); } diff --git a/libsoup/soup-logger.c b/libsoup/soup-logger.c index 63b5a78c..d22212f6 100644 --- a/libsoup/soup-logger.c +++ b/libsoup/soup-logger.c @@ -509,7 +509,7 @@ print_request (SoupLogger *logger, SoupMessage *msg, SoupMessageHeadersIter iter; const char *name, *value; char *socket_dbg; - SoupURI *uri; + GUri *uri; if (priv->request_filter) { log_level = priv->request_filter (logger, msg, @@ -524,14 +524,15 @@ print_request (SoupLogger *logger, SoupMessage *msg, if (soup_message_get_method (msg) == SOUP_METHOD_CONNECT) { soup_logger_print (logger, SOUP_LOGGER_LOG_MINIMAL, '>', "CONNECT %s:%u HTTP/1.%d", - uri->host, uri->port, + g_uri_get_host (uri), g_uri_get_port (uri), soup_message_get_http_version (msg)); } else { soup_logger_print (logger, SOUP_LOGGER_LOG_MINIMAL, '>', "%s %s%s%s HTTP/1.%d", - soup_message_get_method (msg), uri->path, - uri->query ? "?" : "", - uri->query ? uri->query : "", + soup_message_get_method (msg), + g_uri_get_path (uri), + g_uri_get_query (uri) ? "?" : "", + g_uri_get_query (uri) ? g_uri_get_query (uri) : "", soup_message_get_http_version (msg)); } @@ -559,21 +560,19 @@ print_request (SoupLogger *logger, SoupMessage *msg, return; if (!soup_message_headers_get_one (soup_message_get_request_headers (msg), "Host")) { - char *uri_host; + char *uri_host = (char*)g_uri_get_host (uri); - if (strchr (uri->host, ':')) - uri_host = g_strdup_printf ("[%s]", uri->host); - else if (g_hostname_is_non_ascii (uri->host)) - uri_host = g_hostname_to_ascii (uri->host); - else - uri_host = uri->host; + if (strchr (uri_host, ':')) + uri_host = g_strdup_printf ("[%s]", uri_host); + else if (g_hostname_is_non_ascii (uri_host)) + uri_host = g_hostname_to_ascii (uri_host); soup_logger_print (logger, SOUP_LOGGER_LOG_HEADERS, '>', "Host: %s%c%u", uri_host, soup_uri_uses_default_port (uri) ? '\0' : ':', - uri->port); + g_uri_get_port (uri)); - if (uri_host != uri->host) + if (uri_host != g_uri_get_host (uri)) g_free (uri_host); } soup_message_headers_iter_init (&iter, soup_message_get_request_headers (msg)); diff --git a/libsoup/soup-message-io.c b/libsoup/soup-message-io.c index 997d0306..dfc57c11 100644 --- a/libsoup/soup-message-io.c +++ b/libsoup/soup-message-io.c @@ -258,31 +258,33 @@ write_headers (SoupMessage *msg, SoupConnection *conn, SoupEncoding *encoding) { - SoupURI *uri = soup_message_get_uri (msg); + GUri *uri = soup_message_get_uri (msg); char *uri_host; char *uri_string; SoupMessageHeadersIter iter; const char *name, *value; - if (strchr (uri->host, ':')) - uri_host = g_strdup_printf ("[%.*s]", (int) strcspn (uri->host, "%"), uri->host); - else if (g_hostname_is_non_ascii (uri->host)) - uri_host = g_hostname_to_ascii (uri->host); - else - uri_host = uri->host; + uri_host = (char*)g_uri_get_host (uri); + if (strchr (uri_host, ':')) + uri_host = g_strdup_printf ("[%.*s]", (int) strcspn (uri_host, "%"), uri_host); + else if (g_hostname_is_non_ascii (uri_host)) + uri_host = g_hostname_to_ascii (uri_host); if (soup_message_get_method (msg) == SOUP_METHOD_CONNECT) { /* CONNECT URI is hostname:port for tunnel destination */ - uri_string = g_strdup_printf ("%s:%d", uri_host, uri->port); + uri_string = g_strdup_printf ("%s:%d", uri_host, g_uri_get_port (uri)); } else { gboolean proxy = soup_connection_is_via_proxy (conn); /* Proxy expects full URI to destination. Otherwise * just the path. */ - uri_string = soup_uri_to_string (uri, !proxy); + if (!proxy) + uri_string = soup_uri_get_path_and_query (uri); + else + uri_string = g_uri_to_string (uri); - if (proxy && uri->fragment) { + if (proxy && g_uri_get_fragment (uri)) { /* Strip fragment */ char *fragment = strchr (uri_string, '#'); if (fragment) @@ -300,11 +302,11 @@ write_headers (SoupMessage *msg, uri_host); } else { g_string_append_printf (header, "Host: %s:%d\r\n", - uri_host, uri->port); + uri_host, g_uri_get_port (uri)); } } g_free (uri_string); - if (uri_host != uri->host) + if (uri_host != g_uri_get_host (uri)) g_free (uri_host); *encoding = soup_message_headers_get_encoding (soup_message_get_request_headers (msg)); @@ -756,8 +758,8 @@ io_run_until (SoupMessage *msg, gboolean blocking, /* Allow profiling of network requests. */ if (io->read_state == SOUP_MESSAGE_IO_STATE_DONE && io->write_state == SOUP_MESSAGE_IO_STATE_DONE) { - SoupURI *uri = soup_message_get_uri (msg); - char *uri_str = soup_uri_to_string (uri, FALSE); + GUri *uri = soup_message_get_uri (msg); + char *uri_str = g_uri_to_string_partial (uri, G_URI_HIDE_PASSWORD); const gchar *last_modified = soup_message_headers_get_one (soup_message_get_request_headers (msg), "Last-Modified"); const gchar *etag = soup_message_headers_get_one (soup_message_get_request_headers (msg), "ETag"); diff --git a/libsoup/soup-message-private.h b/libsoup/soup-message-private.h index 7d69f347..769d6da7 100644 --- a/libsoup/soup-message-private.h +++ b/libsoup/soup-message-private.h @@ -41,7 +41,7 @@ SoupAuth *soup_message_get_auth (SoupMessage *msg); void soup_message_set_proxy_auth (SoupMessage *msg, SoupAuth *auth); SoupAuth *soup_message_get_proxy_auth (SoupMessage *msg); -SoupURI *soup_message_get_uri_for_auth (SoupMessage *msg); +GUri *soup_message_get_uri_for_auth (SoupMessage *msg); /* I/O */ void soup_message_io_run (SoupMessage *msg, diff --git a/libsoup/soup-message.c b/libsoup/soup-message.c index 1a63bf79..55716c98 100644 --- a/libsoup/soup-message.c +++ b/libsoup/soup-message.c @@ -74,15 +74,15 @@ typedef struct { SoupHTTPVersion http_version, orig_http_version; - SoupURI *uri; + GUri *uri; SoupAuth *auth, *proxy_auth; SoupConnection *connection; GHashTable *disabled_features; - SoupURI *first_party; - SoupURI *site_for_cookies; + GUri *first_party; + GUri *site_for_cookies; GTlsCertificate *tls_certificate; GTlsCertificateFlags tls_certificate_errors; @@ -160,9 +160,9 @@ soup_message_finalize (GObject *object) soup_client_message_io_data_free (priv->io_data); - g_clear_pointer (&priv->uri, soup_uri_free); - g_clear_pointer (&priv->first_party, soup_uri_free); - g_clear_pointer (&priv->site_for_cookies, soup_uri_free); + g_clear_pointer (&priv->uri, g_uri_unref); + g_clear_pointer (&priv->first_party, g_uri_unref); + g_clear_pointer (&priv->site_for_cookies, g_uri_unref); g_clear_object (&priv->auth); g_clear_object (&priv->proxy_auth); @@ -598,7 +598,7 @@ soup_message_class_init (SoupMessageClass *message_class) g_param_spec_boxed ("uri", "URI", "The message's Request-URI", - SOUP_TYPE_URI, + G_TYPE_URI, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); g_object_class_install_property ( @@ -638,7 +638,7 @@ soup_message_class_init (SoupMessageClass *message_class) /** * SoupMessage:first-party: * - * The #SoupURI loaded in the application when the message was + * The #GUri loaded in the application when the message was * queued. * * Since: 2.30 @@ -648,7 +648,7 @@ soup_message_class_init (SoupMessageClass *message_class) g_param_spec_boxed ("first-party", "First party", "The URI loaded in the application when the message was requested.", - SOUP_TYPE_URI, + G_TYPE_URI, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); /** @@ -663,7 +663,7 @@ soup_message_class_init (SoupMessageClass *message_class) g_param_spec_boxed ("site-for-cookies", "Site for cookies", "The URI for the site to compare cookies against", - SOUP_TYPE_URI, + G_TYPE_URI, G_PARAM_READWRITE)); /** * SoupMessage:is-top-level-navigation: @@ -759,35 +759,35 @@ SoupMessage * soup_message_new (const char *method, const char *uri_string) { SoupMessage *msg; - SoupURI *uri; + GUri *uri; g_return_val_if_fail (method != NULL, NULL); g_return_val_if_fail (uri_string != NULL, NULL); - uri = soup_uri_new (uri_string); + uri = g_uri_parse (uri_string, SOUP_HTTP_URI_FLAGS, NULL); if (!uri) return NULL; - if (!uri->host) { - soup_uri_free (uri); + if (!g_uri_get_host (uri)) { + g_uri_unref (uri); return NULL; } msg = soup_message_new_from_uri (method, uri); - soup_uri_free (uri); + g_uri_unref (uri); return msg; } /** * soup_message_new_from_uri: * @method: the HTTP method for the created request - * @uri: the destination endpoint (as a #SoupURI) + * @uri: the destination endpoint (as a #GUri) * * Creates a new empty #SoupMessage, which will connect to @uri * * Return value: the new #SoupMessage */ SoupMessage * -soup_message_new_from_uri (const char *method, SoupURI *uri) +soup_message_new_from_uri (const char *method, GUri *uri) { return g_object_new (SOUP_TYPE_MESSAGE, "method", method, @@ -795,6 +795,23 @@ soup_message_new_from_uri (const char *method, SoupURI *uri) NULL); } +static GUri * +copy_uri_with_new_query (GUri *uri, const char *query) +{ + return g_uri_build_with_user ( + g_uri_get_flags (uri), + g_uri_get_scheme (uri), + g_uri_get_user (uri), + g_uri_get_password (uri), + g_uri_get_auth_params (uri), + g_uri_get_host (uri), + g_uri_get_port (uri), + g_uri_get_path (uri), + query, + g_uri_get_fragment (uri) + ); +} + /** * soup_message_new_from_encoded_form: * @method: the HTTP method for the created request (GET, POST or PUT) @@ -818,23 +835,23 @@ soup_message_new_from_encoded_form (const char *method, char *encoded_form) { SoupMessage *msg = NULL; - SoupURI *uri; + GUri *uri; g_return_val_if_fail (method != NULL, NULL); g_return_val_if_fail (uri_string != NULL, NULL); g_return_val_if_fail (encoded_form != NULL, NULL); - uri = soup_uri_new (uri_string); - if (!uri || !uri->host) { + uri = g_uri_parse (uri_string, SOUP_HTTP_URI_FLAGS, NULL); + if (!uri || !g_uri_get_host (uri)) { g_free (encoded_form); - soup_uri_free (uri); + g_clear_pointer (&uri, g_uri_unref); return NULL; } if (strcmp (method, "GET") == 0) { - g_free (uri->query); - uri->query = encoded_form; - msg = soup_message_new_from_uri (method, uri); + GUri *new_uri = copy_uri_with_new_query (uri, encoded_form); + msg = soup_message_new_from_uri (method, new_uri); + g_uri_unref (new_uri); } else if (strcmp (method, "POST") == 0 || strcmp (method, "PUT") == 0) { GBytes *body; @@ -846,7 +863,7 @@ soup_message_new_from_encoded_form (const char *method, g_free (encoded_form); } - soup_uri_free (uri); + g_uri_unref (uri); return msg; } @@ -867,15 +884,15 @@ soup_message_new_from_multipart (const char *uri_string, SoupMultipart *multipart) { SoupMessage *msg = NULL; - SoupURI *uri; + GUri *uri; GBytes *body = NULL; g_return_val_if_fail (uri_string != NULL, NULL); g_return_val_if_fail (multipart != NULL, NULL); - uri = soup_uri_new (uri_string); - if (!uri || !uri->host) { - soup_uri_free (uri); + uri = g_uri_parse (uri_string, SOUP_HTTP_URI_FLAGS, NULL); + if (!uri || !g_uri_get_host (uri)) { + g_clear_pointer (&uri, g_uri_unref); return NULL; } @@ -885,6 +902,7 @@ soup_message_new_from_multipart (const char *uri_string, soup_message_headers_get_content_type (soup_message_get_request_headers (msg), NULL), body); g_bytes_unref (body); + g_uri_unref (uri); return msg; } @@ -1213,7 +1231,7 @@ soup_message_get_proxy_auth (SoupMessage *msg) return priv->proxy_auth; } -SoupURI * +GUri * soup_message_get_uri_for_auth (SoupMessage *msg) { SoupMessagePrivate *priv = soup_message_get_instance_private (msg); @@ -1554,23 +1572,24 @@ soup_message_is_keepalive (SoupMessage *msg) /** * soup_message_set_uri: * @msg: a #SoupMessage - * @uri: the new #SoupURI + * @uri: the new #GUri * * Sets @msg's URI to @uri. If @msg has already been sent and you want * to re-send it with the new URI, you need to call * soup_session_requeue_message(). **/ void -soup_message_set_uri (SoupMessage *msg, SoupURI *uri) +soup_message_set_uri (SoupMessage *msg, GUri *uri) { SoupMessagePrivate *priv; g_return_if_fail (SOUP_IS_MESSAGE (msg)); + g_return_if_fail (SOUP_URI_IS_VALID (uri)); priv = soup_message_get_instance_private (msg); if (priv->uri) - soup_uri_free (priv->uri); - priv->uri = soup_uri_copy (uri); + g_uri_unref (priv->uri); + priv->uri = soup_uri_copy_with_normalized_flags (uri); g_object_notify (G_OBJECT (msg), "uri"); } @@ -1583,7 +1602,7 @@ soup_message_set_uri (SoupMessage *msg, SoupURI *uri) * * Return value: (transfer none): the URI @msg is targeted for. **/ -SoupURI * +GUri * soup_message_get_uri (SoupMessage *msg) { SoupMessagePrivate *priv; @@ -1748,13 +1767,13 @@ soup_message_get_disabled_features (SoupMessage *msg) * soup_message_get_first_party: * @msg: a #SoupMessage * - * Gets @msg's first-party #SoupURI + * Gets @msg's first-party #GUri * - * Returns: (transfer none): the @msg's first party #SoupURI + * Returns: (transfer none): the @msg's first party #GUri * * Since: 2.30 **/ -SoupURI * +GUri * soup_message_get_first_party (SoupMessage *msg) { SoupMessagePrivate *priv; @@ -1768,9 +1787,9 @@ soup_message_get_first_party (SoupMessage *msg) /** * soup_message_set_first_party: * @msg: a #SoupMessage - * @first_party: the #SoupURI for the @msg's first party + * @first_party: the #GUri for the @msg's first party * - * Sets @first_party as the main document #SoupURI for @msg. For + * Sets @first_party as the main document #GUri for @msg. For * details of when and how this is used refer to the documentation for * #SoupCookieJarAcceptPolicy. * @@ -1778,23 +1797,27 @@ soup_message_get_first_party (SoupMessage *msg) **/ void soup_message_set_first_party (SoupMessage *msg, - SoupURI *first_party) + GUri *first_party) { SoupMessagePrivate *priv; + GUri *first_party_normalized; g_return_if_fail (SOUP_IS_MESSAGE (msg)); - g_return_if_fail (first_party != NULL); + g_return_if_fail (SOUP_URI_IS_VALID (first_party)); priv = soup_message_get_instance_private (msg); + first_party_normalized = soup_uri_copy_with_normalized_flags (first_party); if (priv->first_party) { - if (soup_uri_equal (priv->first_party, first_party)) - return; + if (soup_uri_equal (priv->first_party, first_party_normalized)) { + g_uri_unref (first_party_normalized); + return; + } - soup_uri_free (priv->first_party); + g_uri_unref (priv->first_party); } - priv->first_party = soup_uri_copy (first_party); + priv->first_party = g_steal_pointer (&first_party_normalized); g_object_notify (G_OBJECT (msg), "first-party"); } @@ -1802,13 +1825,13 @@ soup_message_set_first_party (SoupMessage *msg, * soup_message_get_site_for_cookies: * @msg: a #SoupMessage * - * Gets @msg's site for cookies #SoupURI + * Gets @msg's site for cookies #GUri * - * Returns: (transfer none): the @msg's site for cookies #SoupURI + * Returns: (transfer none): the @msg's site for cookies #GUri * * Since: 2.70 **/ -SoupURI * +GUri * soup_message_get_site_for_cookies (SoupMessage *msg) { SoupMessagePrivate *priv; @@ -1822,7 +1845,7 @@ soup_message_get_site_for_cookies (SoupMessage *msg) /** * soup_message_set_site_for_cookies: * @msg: a #SoupMessage - * @site_for_cookies: (nullable): the #SoupURI for the @msg's site for cookies + * @site_for_cookies: (nullable): the #GUri for the @msg's site for cookies * * Sets @site_for_cookies as the policy URL for same-site cookies for @msg. * @@ -1837,25 +1860,27 @@ soup_message_get_site_for_cookies (SoupMessage *msg) **/ void soup_message_set_site_for_cookies (SoupMessage *msg, - SoupURI *site_for_cookies) + GUri *site_for_cookies) { SoupMessagePrivate *priv; + GUri *site_for_cookies_normalized; g_return_if_fail (SOUP_IS_MESSAGE (msg)); + g_return_if_fail (SOUP_URI_IS_VALID (site_for_cookies)); priv = soup_message_get_instance_private (msg); - - if (priv->site_for_cookies == site_for_cookies) - return; + site_for_cookies_normalized = soup_uri_copy_with_normalized_flags (site_for_cookies); if (priv->site_for_cookies) { - if (site_for_cookies && soup_uri_equal (priv->site_for_cookies, site_for_cookies)) - return; + if (soup_uri_equal (priv->site_for_cookies, site_for_cookies_normalized)) { + g_uri_unref (site_for_cookies_normalized); + return; + } - soup_uri_free (priv->site_for_cookies); + g_uri_unref (priv->site_for_cookies); } - priv->site_for_cookies = site_for_cookies ? soup_uri_copy (site_for_cookies) : NULL; + priv->site_for_cookies = g_steal_pointer (&site_for_cookies_normalized); g_object_notify (G_OBJECT (msg), "site-for-cookies"); } diff --git a/libsoup/soup-message.h b/libsoup/soup-message.h index f4fb6c4f..de3c7a7d 100644 --- a/libsoup/soup-message.h +++ b/libsoup/soup-message.h @@ -22,7 +22,7 @@ SoupMessage *soup_message_new (const char *method, const char *uri_string); SOUP_AVAILABLE_IN_2_4 SoupMessage *soup_message_new_from_uri (const char *method, - SoupURI *uri); + GUri *uri); SOUP_AVAILABLE_IN_ALL SoupMessage *soup_message_new_from_encoded_form (const char *method, @@ -53,20 +53,20 @@ SOUP_AVAILABLE_IN_2_4 gboolean soup_message_is_keepalive (SoupMessage *msg); SOUP_AVAILABLE_IN_2_4 -SoupURI *soup_message_get_uri (SoupMessage *msg); +GUri *soup_message_get_uri (SoupMessage *msg); SOUP_AVAILABLE_IN_2_4 void soup_message_set_uri (SoupMessage *msg, - SoupURI *uri); + GUri *uri); SOUP_AVAILABLE_IN_2_30 -SoupURI *soup_message_get_first_party (SoupMessage *msg); +GUri *soup_message_get_first_party (SoupMessage *msg); SOUP_AVAILABLE_IN_2_30 void soup_message_set_first_party (SoupMessage *msg, - SoupURI *first_party); + GUri *first_party); SOUP_AVAILABLE_IN_2_70 -SoupURI *soup_message_get_site_for_cookies (SoupMessage *msg); +GUri *soup_message_get_site_for_cookies (SoupMessage *msg); SOUP_AVAILABLE_IN_2_70 void soup_message_set_site_for_cookies (SoupMessage *msg, - SoupURI *site_for_cookies); + GUri *site_for_cookies); SOUP_AVAILABLE_IN_2_70 void soup_message_set_is_top_level_navigation (SoupMessage *msg, gboolean is_top_level_navigation); diff --git a/libsoup/soup-misc.h b/libsoup/soup-misc.h index 2e3b457e..ec1c0e86 100644 --- a/libsoup/soup-misc.h +++ b/libsoup/soup-misc.h @@ -46,12 +46,6 @@ extern const char soup_char_attributes[]; #define soup_char_is_uri_unreserved(ch) (!(soup_char_attributes[(guchar)ch] & (SOUP_CHAR_URI_PERCENT_ENCODED | SOUP_CHAR_URI_GEN_DELIMS | SOUP_CHAR_URI_SUB_DELIMS))) #define soup_char_is_token(ch) (!(soup_char_attributes[(guchar)ch] & (SOUP_CHAR_HTTP_SEPARATOR | SOUP_CHAR_HTTP_CTL))) -char *soup_uri_decoded_copy (const char *str, int length, int *decoded_length); -char *soup_uri_to_string_internal (SoupURI *uri, gboolean just_path_and_query, - gboolean include_password, gboolean force_port); -gboolean soup_uri_is_http (SoupURI *uri, char **aliases); -gboolean soup_uri_is_https (SoupURI *uri, char **aliases); - /* At some point it might be possible to mark additional methods * safe or idempotent... */ diff --git a/libsoup/soup-session-private.h b/libsoup/soup-session-private.h index 851e36cd..06f86961 100644 --- a/libsoup/soup-session-private.h +++ b/libsoup/soup-session-private.h @@ -7,7 +7,6 @@ #define __SOUP_SESSION_PRIVATE_H__ 1 #include "soup-session.h" -#include "soup-uri.h" G_BEGIN_DECLS diff --git a/libsoup/soup-session.c b/libsoup/soup-session.c index 7fbb242f..604251fa 100644 --- a/libsoup/soup-session.c +++ b/libsoup/soup-session.c @@ -71,7 +71,7 @@ */ typedef struct { - SoupURI *uri; + GUri *uri; GNetworkAddress *addr; GSList *connections; /* CONTAINS: SoupConnection */ @@ -101,7 +101,7 @@ typedef struct { GProxyResolver *proxy_resolver; gboolean proxy_use_default; - SoupURI *proxy_uri; + GUri *proxy_uri; SoupSocketProperties *socket_props; @@ -298,10 +298,10 @@ soup_session_finalize (GObject *object) g_hash_table_destroy (priv->features_cache); g_clear_object (&priv->proxy_resolver); - g_clear_pointer (&priv->proxy_uri, soup_uri_free); + g_clear_pointer (&priv->proxy_uri, g_uri_unref); - g_free (priv->http_aliases); - g_free (priv->https_aliases); + g_strfreev (priv->http_aliases); + g_strfreev (priv->https_aliases); g_clear_pointer (&priv->socket_props, soup_socket_properties_unref); @@ -382,43 +382,40 @@ set_use_system_ca_file (SoupSession *session, gboolean use_system_ca_file) g_clear_object (&system_default); } -/* priv->http_aliases and priv->https_aliases are stored as arrays of - * *interned* strings, so we can't just use g_strdupv() to set them. +/* priv->http_aliases and priv->https_aliases are normalized to be lower-case + * so we can't just use g_strdupv() to set them. */ static void set_aliases (char ***variable, char **value) { int len, i; - if (*variable) - g_free (*variable); + g_clear_pointer (variable, g_strfreev); - if (!value) { - *variable = NULL; + if (!value) return; - } len = g_strv_length (value); *variable = g_new (char *, len + 1); for (i = 0; i < len; i++) - (*variable)[i] = (char *)g_intern_string (value[i]); + (*variable)[i] = g_ascii_strdown (value[i], -1); (*variable)[i] = NULL; } static void -set_proxy_resolver (SoupSession *session, SoupURI *uri, +set_proxy_resolver (SoupSession *session, GUri *uri, GProxyResolver *g_resolver) { SoupSessionPrivate *priv = soup_session_get_instance_private (session); g_clear_object (&priv->proxy_resolver); - g_clear_pointer (&priv->proxy_uri, soup_uri_free); + g_clear_pointer (&priv->proxy_uri, g_uri_unref); priv->proxy_use_default = FALSE; if (uri) { char *uri_string; - priv->proxy_uri = soup_uri_copy (uri); - uri_string = soup_uri_to_string_internal (uri, FALSE, TRUE, TRUE); + priv->proxy_uri = soup_uri_copy_with_normalized_flags (uri); + uri_string = g_uri_to_string (uri); priv->proxy_resolver = g_simple_proxy_resolver_new (uri_string, NULL); g_free (uri_string); } else if (g_resolver) @@ -640,50 +637,71 @@ soup_session_new_with_options (const char *optname1, static guint soup_host_uri_hash (gconstpointer key) { - const SoupURI *uri = key; + GUri *uri = (GUri*)key; - g_return_val_if_fail (uri != NULL && uri->host != NULL, 0); + g_return_val_if_fail (uri != NULL && g_uri_get_host (uri) != NULL, 0); - return uri->port + soup_str_case_hash (uri->host); + return g_uri_get_port (uri) + soup_str_case_hash (g_uri_get_host (uri)); } static gboolean soup_host_uri_equal (gconstpointer v1, gconstpointer v2) { - const SoupURI *one = v1; - const SoupURI *two = v2; + GUri *one = (GUri*)v1; + GUri *two = (GUri*)v2; g_return_val_if_fail (one != NULL && two != NULL, one == two); - g_return_val_if_fail (one->host != NULL && two->host != NULL, one->host == two->host); - if (one->port != two->port) + const char *one_host = g_uri_get_host (one); + const char *two_host = g_uri_get_host (two); + g_return_val_if_fail (one_host != NULL && two_host != NULL, one_host == two_host); + + if (g_uri_get_port (one) != g_uri_get_port (two)) return FALSE; - return g_ascii_strcasecmp (one->host, two->host) == 0; + return g_ascii_strcasecmp (one_host, two_host) == 0; +} + +static GUri * +copy_uri_with_new_scheme (GUri *uri, const char *scheme) +{ + return g_uri_build_with_user ( + g_uri_get_flags (uri), + scheme, + g_uri_get_user (uri), + g_uri_get_password (uri), + g_uri_get_auth_params (uri), + g_uri_get_host (uri), + g_uri_get_port (uri), + g_uri_get_path (uri), + g_uri_get_query (uri), + g_uri_get_fragment (uri) + ); } static SoupSessionHost * -soup_session_host_new (SoupSession *session, SoupURI *uri) +soup_session_host_new (SoupSession *session, GUri *uri) { SoupSessionHost *host; + const char *scheme = g_uri_get_scheme (uri); host = g_slice_new0 (SoupSessionHost); - host->uri = soup_uri_copy_host (uri); - if (host->uri->scheme != SOUP_URI_SCHEME_HTTP && - host->uri->scheme != SOUP_URI_SCHEME_HTTPS) { + if (g_strcmp0 (scheme, "http") && + g_strcmp0 (scheme, "https")) { SoupSessionPrivate *priv = soup_session_get_instance_private (session); - if (soup_uri_is_https (host->uri, priv->https_aliases)) - host->uri->scheme = SOUP_URI_SCHEME_HTTPS; + if (soup_uri_is_https (uri, priv->https_aliases)) + host->uri = copy_uri_with_new_scheme (uri, "https"); else - host->uri->scheme = SOUP_URI_SCHEME_HTTP; - } + host->uri = copy_uri_with_new_scheme (uri, "http"); + } else + host->uri = g_uri_ref (uri); host->addr = g_object_new (G_TYPE_NETWORK_ADDRESS, - "hostname", host->uri->host, - "port", host->uri->port, - "scheme", host->uri->scheme, + "hostname", g_uri_get_host (host->uri), + "port", soup_uri_get_port_with_default (host->uri), + "scheme", g_uri_get_scheme (host->uri), NULL); host->keep_alive_src = NULL; host->session = session; @@ -693,12 +711,12 @@ soup_session_host_new (SoupSession *session, SoupURI *uri) /* Requires conn_lock to be locked */ static SoupSessionHost * -get_host_for_uri (SoupSession *session, SoupURI *uri) +get_host_for_uri (SoupSession *session, GUri *uri) { SoupSessionPrivate *priv = soup_session_get_instance_private (session); SoupSessionHost *host; gboolean https; - SoupURI *uri_tmp = NULL; + GUri *uri_tmp = NULL; https = soup_uri_is_https (uri, priv->https_aliases); if (https) @@ -708,14 +726,12 @@ get_host_for_uri (SoupSession *session, SoupURI *uri) if (host) return host; - if (uri->scheme != SOUP_URI_SCHEME_HTTP && - uri->scheme != SOUP_URI_SCHEME_HTTPS) { - uri = uri_tmp = soup_uri_copy (uri); - uri->scheme = https ? SOUP_URI_SCHEME_HTTPS : SOUP_URI_SCHEME_HTTP; + if (!soup_uri_is_http (uri, NULL) && !soup_uri_is_https (uri, NULL)) { + uri = uri_tmp = copy_uri_with_new_scheme (uri, https ? "https" : "http"); } host = soup_session_host_new (session, uri); if (uri_tmp) - soup_uri_free (uri_tmp); + g_uri_unref (uri_tmp); if (https) g_hash_table_insert (priv->https_hosts, host->uri, host); @@ -742,7 +758,7 @@ free_host (SoupSessionHost *host) g_source_unref (host->keep_alive_src); } - soup_uri_free (host->uri); + g_uri_unref (host->uri); g_object_unref (host->addr); g_slice_free (SoupSessionHost, host); } @@ -761,20 +777,23 @@ free_host (SoupSessionHost *host) soup_message_get_status (msg) == SOUP_STATUS_FOUND) && \ SOUP_METHOD_IS_SAFE (soup_message_get_method (msg))) -static inline SoupURI * +static inline GUri * redirection_uri (SoupMessage *msg) { const char *new_loc; - SoupURI *new_uri; + GUri *new_uri; new_loc = soup_message_headers_get_one (soup_message_get_response_headers (msg), "Location"); if (!new_loc) return NULL; - new_uri = soup_uri_new_with_base (soup_message_get_uri (msg), new_loc); - if (!new_uri || !new_uri->host) { - if (new_uri) - soup_uri_free (new_uri); + + new_uri = g_uri_parse_relative (soup_message_get_uri (msg), new_loc, SOUP_HTTP_URI_FLAGS, NULL); + if (!new_uri) + return NULL; + + if (!g_uri_get_host (new_uri)) { + g_uri_unref (new_uri); return NULL; } @@ -798,7 +817,7 @@ gboolean soup_session_would_redirect (SoupSession *session, SoupMessage *msg) { SoupSessionPrivate *priv = soup_session_get_instance_private (session); - SoupURI *new_uri; + GUri *new_uri; /* It must have an appropriate status code and method */ if (!SOUP_SESSION_WOULD_REDIRECT_AS_GET (session, msg) && @@ -811,14 +830,14 @@ soup_session_would_redirect (SoupSession *session, SoupMessage *msg) new_uri = redirection_uri (msg); if (!new_uri) return FALSE; - if (!new_uri->host || !*new_uri->host || + if (!g_uri_get_host (new_uri) || !*g_uri_get_host (new_uri) || (!soup_uri_is_http (new_uri, priv->http_aliases) && !soup_uri_is_https (new_uri, priv->https_aliases))) { - soup_uri_free (new_uri); + g_uri_unref (new_uri); return FALSE; } - soup_uri_free (new_uri); + g_uri_unref (new_uri); return TRUE; } @@ -849,7 +868,7 @@ soup_session_would_redirect (SoupSession *session, SoupMessage *msg) gboolean soup_session_redirect_message (SoupSession *session, SoupMessage *msg) { - SoupURI *new_uri; + GUri *new_uri; new_uri = redirection_uri (msg); if (!new_uri) @@ -867,7 +886,7 @@ soup_session_redirect_message (SoupSession *session, SoupMessage *msg) } soup_message_set_uri (msg, new_uri); - soup_uri_free (new_uri); + g_uri_unref (new_uri); soup_session_requeue_message (session, msg); return TRUE; @@ -1033,6 +1052,7 @@ free_unused_host (gpointer user_data) { SoupSessionHost *host = (SoupSessionHost *) user_data; SoupSessionPrivate *priv = soup_session_get_instance_private (host->session); + GUri *uri = host->uri; g_mutex_lock (&priv->conn_lock); @@ -1047,10 +1067,10 @@ free_unused_host (gpointer user_data) /* This will free the host in addition to removing it from the * hash table */ - if (host->uri->scheme == SOUP_URI_SCHEME_HTTPS) - g_hash_table_remove (priv->https_hosts, host->uri); + if (soup_uri_is_https (uri, NULL)) + g_hash_table_remove (priv->https_hosts, uri); else - g_hash_table_remove (priv->http_hosts, host->uri); + g_hash_table_remove (priv->http_hosts, uri); g_mutex_unlock (&priv->conn_lock); return FALSE; @@ -1169,7 +1189,7 @@ soup_session_set_item_status (SoupSession *session, guint status_code, GError *error) { - SoupURI *uri = NULL; + GUri *uri = NULL; switch (status_code) { case SOUP_STATUS_CANT_RESOLVE: @@ -1197,10 +1217,10 @@ soup_session_set_item_status (SoupSession *session, if (error) soup_message_set_status_full (item->msg, status_code, error->message); - else if (uri && uri->host) { + else if (uri && g_uri_get_host (uri)) { char *msg = g_strdup_printf ("%s (%s)", soup_status_get_phrase (status_code), - uri->host); + g_uri_get_host (uri)); soup_message_set_status_full (item->msg, status_code, msg); g_free (msg); } else @@ -1355,7 +1375,7 @@ tunnel_connect (SoupMessageQueueItem *item) { SoupSession *session = item->session; SoupMessageQueueItem *tunnel_item; - SoupURI *uri; + GUri *uri; SoupMessage *msg; item->state = SOUP_MESSAGE_TUNNELING; @@ -3370,8 +3390,9 @@ soup_session_read_uri_async (SoupSession *session, { SoupSessionPrivate *priv; GTask *task; - SoupURI *soup_uri; + GUri *soup_uri; SoupMessage *msg; + GError *error = NULL; SessionGetAsyncData *data; g_return_if_fail (SOUP_IS_SESSION (session)); @@ -3380,13 +3401,15 @@ soup_session_read_uri_async (SoupSession *session, task = g_task_new (session, cancellable, callback, user_data); g_task_set_priority (task, io_priority); - soup_uri = soup_uri_new (uri); + soup_uri = g_uri_parse (uri, SOUP_HTTP_URI_FLAGS, &error); if (!soup_uri) { g_task_return_new_error (task, SOUP_SESSION_ERROR, SOUP_SESSION_ERROR_BAD_URI, - _("Could not parse URI “%s”"), - uri); + _("Could not parse URI “%s”: %s"), + uri, + error->message); + g_error_free (error); g_object_unref (task); return; } @@ -3399,21 +3422,21 @@ soup_session_read_uri_async (SoupSession *session, SOUP_SESSION_ERROR, SOUP_SESSION_ERROR_UNSUPPORTED_URI_SCHEME, _("Unsupported URI scheme “%s”"), - soup_uri->scheme); + g_uri_get_scheme (soup_uri)); g_object_unref (task); - soup_uri_free (soup_uri); + g_uri_unref (soup_uri); return; } - if (!SOUP_URI_VALID_FOR_HTTP (soup_uri)) { + if (!SOUP_URI_IS_VALID (soup_uri)) { g_task_return_new_error (task, SOUP_SESSION_ERROR, SOUP_SESSION_ERROR_BAD_URI, _("Invalid “%s” URI: %s"), - soup_uri->scheme, + g_uri_get_scheme (soup_uri), uri); g_object_unref (task); - soup_uri_free (soup_uri); + g_uri_unref (soup_uri); return; } @@ -3431,7 +3454,7 @@ soup_session_read_uri_async (SoupSession *session, (GAsyncReadyCallback)http_input_stream_ready_cb, task); g_object_unref (msg); - soup_uri_free (soup_uri); + g_uri_unref (soup_uri); } /** @@ -3504,21 +3527,24 @@ soup_session_read_uri (SoupSession *session, GError **error) { SoupSessionPrivate *priv; - SoupURI *soup_uri; + GUri *soup_uri; SoupMessage *msg; GInputStream *stream; + GError *internal_error = NULL; SessionGetAsyncData data = { 0, NULL }; g_return_val_if_fail (SOUP_IS_SESSION (session), NULL); g_return_val_if_fail (uri != NULL, NULL); - soup_uri = soup_uri_new (uri); + soup_uri = g_uri_parse (uri, SOUP_HTTP_URI_FLAGS, &internal_error); if (!soup_uri) { g_set_error (error, SOUP_SESSION_ERROR, SOUP_SESSION_ERROR_BAD_URI, - _("Could not parse URI “%s”"), - uri); + _("Could not parse URI “%s”: %s"), + uri, + internal_error->message); + g_error_free (internal_error); return NULL; } @@ -3531,20 +3557,20 @@ soup_session_read_uri (SoupSession *session, SOUP_SESSION_ERROR, SOUP_SESSION_ERROR_UNSUPPORTED_URI_SCHEME, _("Unsupported URI scheme “%s”"), - soup_uri->scheme); - soup_uri_free (soup_uri); + g_uri_get_scheme (soup_uri)); + g_uri_unref (soup_uri); return NULL; } - if (!SOUP_URI_VALID_FOR_HTTP (soup_uri)) { + if (!SOUP_URI_IS_VALID (soup_uri)) { g_set_error (error, SOUP_SESSION_ERROR, SOUP_SESSION_ERROR_BAD_URI, _("Invalid “%s” URI: %s"), - soup_uri->scheme, + g_uri_get_scheme (soup_uri), uri); - soup_uri_free (soup_uri); + g_uri_unref (soup_uri); return NULL; } @@ -3565,7 +3591,7 @@ soup_session_read_uri (SoupSession *session, } g_free (data.content_type); - soup_uri_free (soup_uri); + g_uri_unref (soup_uri); return stream; } diff --git a/libsoup/soup-types.h b/libsoup/soup-types.h index 48c598a3..62375361 100644 --- a/libsoup/soup-types.h +++ b/libsoup/soup-types.h @@ -27,7 +27,6 @@ typedef struct _SoupServerMessage SoupServerMessage; typedef struct _SoupSession SoupSession; typedef struct _SoupSessionFeature SoupSessionFeature; typedef struct _SoupSocket SoupSocket; -typedef struct _SoupURI SoupURI; typedef struct _SoupWebsocketConnection SoupWebsocketConnection; typedef struct _SoupWebsocketExtension SoupWebsocketExtension; diff --git a/libsoup/soup-uri-utils-private.h b/libsoup/soup-uri-utils-private.h new file mode 100644 index 00000000..ed137f90 --- /dev/null +++ b/libsoup/soup-uri-utils-private.h @@ -0,0 +1,37 @@ +/* + * Copyright 1999-2002 Ximian, Inc. + * Copyright 2020 Igalia, S.L. + */ + + +#pragma once + +#include "soup-uri-utils.h" + +G_BEGIN_DECLS + +gboolean soup_uri_is_http (GUri *uri, + char **aliases); + +gboolean soup_uri_is_https (GUri *uri, + char **aliases); + +gboolean soup_uri_uses_default_port (GUri *uri); + +GUri *soup_uri_copy_with_credentials (GUri *uri, + const char *username, + const char *password); + +char *soup_uri_get_path_and_query (GUri *uri); + +GUri *soup_uri_copy_host (GUri *uri); + +guint soup_uri_host_hash (gconstpointer key); + +gboolean soup_uri_host_equal (gconstpointer v1, gconstpointer v2); + +GUri *soup_uri_copy_with_normalized_flags (GUri *uri); + +#define SOUP_URI_IS_VALID(x) (x && g_uri_get_host(x) && g_uri_get_host(x)[0]) + +G_END_DECLS diff --git a/libsoup/soup-uri-utils.c b/libsoup/soup-uri-utils.c new file mode 100644 index 00000000..de843ae1 --- /dev/null +++ b/libsoup/soup-uri-utils.c @@ -0,0 +1,498 @@ +/* soup-uri-utils.c + * + * Copyright 2020 Igalia S.L. + * Copyright 1999-2003 Ximian, Inc. + * + * This file is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This file is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program. If not, see . + * + * SPDX-License-Identifier: LGPL-2.0-or-later + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include + +#include + +#include "soup-uri-utils.h" +#include "soup.h" +#include "soup-misc.h" + +/** + * SECTION:soup-uri-utils + * @section_id: SoupURIUtils + * @title: URI Utilities + * @short_description: Functions to help working with #GUri and HTTP + * + * Utility functions and defines to help working with URIs. + */ + +/** + * SOUP_HTTP_URI_FLAGS: + * + * The set of #GUriFlags libsoup expects all #GUri to use. + */ + +static inline int +soup_scheme_default_port (const char *scheme) +{ + if (!g_strcmp0 (scheme, "http") || + !g_strcmp0 (scheme, "ws")) + return 80; + else if (!g_strcmp0 (scheme, "https") || + !g_strcmp0 (scheme, "wss")) + return 443; + else if (!g_strcmp0 (scheme, "ftp")) + return 21; + else + return -1; +} + +static inline gboolean +parts_equal (const char *one, const char *two, gboolean insensitive) +{ + if (!one && !two) + return TRUE; + if (!one || !two) + return FALSE; + return insensitive ? !g_ascii_strcasecmp (one, two) : !strcmp (one, two); +} + +static inline gboolean +path_equal (const char *one, const char *two) +{ + if (one[0] == '\0') + one = "/"; + if (two[0] == '\0') + two = "/"; + + return !strcmp (one, two); +} + +/** + * soup_uri_get_port_with_default: + * @uri: A #GUri + * + * If @uri has a port of `-1` this will return the default + * port for the sheme it uses if known. + * + * Returns: The port to use with the @uri or `-1` if unknown. + */ +int +soup_uri_get_port_with_default (GUri *uri) +{ + int port = g_uri_get_port (uri); + if (port != -1) + return port; + + return soup_scheme_default_port (g_uri_get_scheme (uri)); +} + +static gboolean +flags_equal (GUriFlags flags1, GUriFlags flags2) +{ + /* We only care about flags that affect the contents which these do */ + static const GUriFlags normalization_flags = (G_URI_FLAGS_ENCODED | G_URI_FLAGS_ENCODED_FRAGMENT | + G_URI_FLAGS_ENCODED_PATH | G_URI_FLAGS_ENCODED_QUERY | + G_URI_FLAGS_SCHEME_NORMALIZE); + + return (flags1 & normalization_flags) == (flags2 & normalization_flags); +} + +/** + * soup_uri_equal: + * @uri1: a #GUri + * @uri2: another #GUri + * + * Tests whether or not @uri1 and @uri2 are equal in all parts + * + * Returns: %TRUE if equal otherwise %FALSE + **/ +gboolean +soup_uri_equal (GUri *uri1, GUri *uri2) +{ + g_return_val_if_fail (uri1 != NULL, FALSE); + g_return_val_if_fail (uri2 != NULL, FALSE); + + if (!flags_equal (g_uri_get_flags (uri1), g_uri_get_flags (uri2)) || + g_strcmp0 (g_uri_get_scheme (uri1), g_uri_get_scheme (uri2)) || + soup_uri_get_port_with_default (uri1) != soup_uri_get_port_with_default (uri2) || + !parts_equal (g_uri_get_user (uri1), g_uri_get_user (uri2), FALSE) || + !parts_equal (g_uri_get_password (uri1), g_uri_get_password (uri2), FALSE) || + !parts_equal (g_uri_get_host (uri1), g_uri_get_host (uri2), TRUE) || + !path_equal (g_uri_get_path (uri1), g_uri_get_path (uri2)) || + !parts_equal (g_uri_get_query (uri1), g_uri_get_query (uri2), FALSE) || + !parts_equal (g_uri_get_fragment (uri1), g_uri_get_fragment (uri2), FALSE)) { + return FALSE; + } + + return TRUE; +} + +char * +soup_uri_get_path_and_query (GUri *uri) +{ + g_return_val_if_fail (uri != NULL, NULL); + + return g_uri_join_with_user (SOUP_HTTP_URI_FLAGS, + NULL, NULL, NULL, NULL, NULL, -1, + g_uri_get_path (uri), + g_uri_get_query (uri), + NULL); +} + +/** + * soup_uri_uses_default_port: + * @uri: a #GUri + * + * Tests if @uri uses the default port for its scheme. (Eg, 80 for + * http.) (This only works for http, https and ftp; libsoup does not know + * the default ports of other protocols.) + * + * Returns: %TRUE or %FALSE + **/ +gboolean +soup_uri_uses_default_port (GUri *uri) +{ + g_return_val_if_fail (uri != NULL, FALSE); + + if (g_uri_get_port (uri) == -1) + return TRUE; + + if (g_uri_get_scheme (uri)) + return g_uri_get_port (uri) == soup_scheme_default_port (g_uri_get_scheme (uri)); + + return FALSE; +} + +static GUri * +soup_uri_copy_with_query (GUri *uri, const char *query) +{ + return g_uri_build_with_user ( + g_uri_get_flags (uri) | G_URI_FLAGS_ENCODED_QUERY, + g_uri_get_scheme (uri), + g_uri_get_user (uri), + g_uri_get_password (uri), + g_uri_get_auth_params (uri), + g_uri_get_host (uri), + g_uri_get_port (uri), + g_uri_get_path (uri), + query, + g_uri_get_fragment (uri) + ); +} + +/** + * soup_uri_copy_with_query_from_form: + * @uri: a #GUri + * @form: (element-type utf8 utf8): a #GHashTable containing HTML form + * information + * + * Sets @uri's query to the result of encoding @form according to the + * HTML form rules. See soup_form_encode_hash() for more information. + * + * Returns: (transfer full): A new #GUri + **/ +GUri * +soup_uri_copy_with_query_from_form (GUri *uri, GHashTable *form) +{ + g_return_val_if_fail (uri != NULL, NULL); + + char *query = soup_form_encode_hash (form); + GUri *new_uri = soup_uri_copy_with_query (uri, query); + g_free (query); + return new_uri; +} + +/** + * soup_uri_copy_with_query_from_fields: + * @uri: a #GUri + * @first_field: name of the first form field to encode into query + * @...: value of @first_field, followed by additional field names + * and values, terminated by %NULL. + * + * Sets @uri's query to the result of encoding the given form fields + * and values according to the * HTML form rules. See + * soup_form_encode() for more information. + * + * Returns: (transfer full): A new #GUri + **/ +GUri * +soup_uri_copy_with_query_from_fields (GUri *uri, + const char *first_field, + ...) +{ + va_list args; + + g_return_val_if_fail (uri != NULL, NULL); + + va_start (args, first_field); + char *query = soup_form_encode_valist (first_field, args); + va_end (args); + + GUri *new_uri = soup_uri_copy_with_query (uri, query); + g_free (query); + return new_uri; +} + +GUri * +soup_uri_copy_host (GUri *uri) +{ + g_return_val_if_fail (uri != NULL, NULL); + + return g_uri_build (g_uri_get_flags (uri), + g_uri_get_scheme (uri), NULL, + g_uri_get_host (uri), + g_uri_get_port (uri), + "/", NULL, NULL); +} + +/** + * soup_uri_host_hash: + * @key: (type GUri): a #GUri with a non-%NULL @host member + * + * Hashes @key, considering only the scheme, host, and port. + * + * Returns: A hash + */ +guint +soup_uri_host_hash (gconstpointer key) +{ + GUri *uri = (GUri*)key; + const char *host; + + g_return_val_if_fail (uri != NULL, 0); + + host = g_uri_get_host (uri); + + g_return_val_if_fail (host != NULL, 0); + + return soup_str_case_hash (g_uri_get_scheme (uri)) + + g_uri_get_port (uri) + + soup_str_case_hash (host); +} + +/** + * soup_uri_host_equal: + * @v1: (type GUri): a #GUri with a non-%NULL @host member + * @v2: (type GUri): a #GUri with a non-%NULL @host member + * + * Compares @v1 and @v2, considering only the scheme, host, and port. + * + * Returns: %TRUE if the URIs are equal in scheme, host, and port. + */ +gboolean +soup_uri_host_equal (gconstpointer v1, gconstpointer v2) +{ + GUri *one = (GUri*)v1; + GUri *two = (GUri*)v2; + const char *one_host, *two_host; + int one_port, two_port; + + g_return_val_if_fail (one != NULL && two != NULL, one == two); + + one_host = g_uri_get_host (one); + two_host = g_uri_get_host (two); + + g_return_val_if_fail (one_host != NULL && two_host != NULL, one_host == two_host); + + if (one == two) + return TRUE; + if (g_strcmp0 (g_uri_get_scheme (one), g_uri_get_scheme (two)) != 0) + return FALSE; + + one_port = g_uri_get_port (one); + two_port = g_uri_get_port (two); + + if (one_port == -1 && g_uri_get_scheme (one)) + one_port = soup_scheme_default_port (g_uri_get_scheme (one)); + if (two_port == -1 && g_uri_get_scheme (two)) + two_port = soup_scheme_default_port (g_uri_get_scheme (two)); + + if (one_port != two_port) + return FALSE; + + return g_ascii_strcasecmp (one_host, two_host) == 0; +} + +gboolean +soup_uri_is_https (GUri *uri, char **aliases) +{ + g_return_val_if_fail (uri != NULL, FALSE); + + const char *scheme = g_uri_get_scheme (uri); + + if (G_UNLIKELY (scheme == NULL)) + return FALSE; + + if (strcmp (scheme, "https") == 0 || + strcmp (scheme, "wss") == 0) + return TRUE; + else if (!aliases) + return FALSE; + + for (int i = 0; aliases[i]; i++) { + if (strcmp (scheme, aliases[i]) == 0) + return TRUE; + } + + return FALSE; +} + +gboolean +soup_uri_is_http (GUri *uri, char **aliases) +{ + g_return_val_if_fail (uri != NULL, FALSE); + + const char *scheme = g_uri_get_scheme (uri); + + if (G_UNLIKELY (scheme == NULL)) + return FALSE; + + if (strcmp (scheme, "http") == 0 || + strcmp (scheme, "ws") == 0) + return TRUE; + else if (!aliases) + return FALSE; + + for (int i = 0; aliases[i]; i++) { + if (strcmp (scheme, aliases[i]) == 0) + return TRUE; + } + + return FALSE; +} + +#define BASE64_INDICATOR ";base64" +#define BASE64_INDICATOR_LEN (sizeof (";base64") - 1) + +/** + * soup_uri_decode_data_uri: + * @uri: a data URI, in string form + * @content_type: (out) (nullable) (transfer full): location to store content type, or %NULL + * + * Decodes the given data URI and returns its contents and @content_type. + * + * Returns: (transfer full): a #GBytes with the contents of @uri, + * or %NULL if @uri is not a valid data URI + */ +GBytes * +soup_uri_decode_data_uri (const char *uri, + char **content_type) +{ + GUri *soup_uri; + const char *comma, *start, *end; + gboolean base64 = FALSE; + char *uri_string; + GBytes *bytes; + + g_return_val_if_fail (uri != NULL, NULL); + + soup_uri = g_uri_parse (uri, SOUP_HTTP_URI_FLAGS, NULL); + if (!soup_uri) + return NULL; + + if (g_strcmp0 (g_uri_get_scheme (soup_uri), "data") || g_uri_get_host (soup_uri) != NULL) + return NULL; + + if (content_type) + *content_type = NULL; + + uri_string = g_uri_to_string (soup_uri); + g_uri_unref (soup_uri); + + start = uri_string + 5; + comma = strchr (start, ','); + if (comma && comma != start) { + /* Deal with MIME type / params */ + if (comma >= start + BASE64_INDICATOR_LEN && !g_ascii_strncasecmp (comma - BASE64_INDICATOR_LEN, BASE64_INDICATOR, BASE64_INDICATOR_LEN)) { + end = comma - BASE64_INDICATOR_LEN; + base64 = TRUE; + } else + end = comma; + + if (end != start && content_type) + *content_type = g_uri_unescape_segment (start, end, NULL); + } + + if (content_type && !*content_type) + *content_type = g_strdup ("text/plain;charset=US-ASCII"); + + if (comma) + start = comma + 1; + + if (*start) { + bytes = g_uri_unescape_bytes (start, -1, NULL, NULL); + + if (base64 && bytes) { + gsize content_length; + GByteArray *unescaped_array = g_bytes_unref_to_array (bytes); + g_base64_decode_inplace ((gchar*)unescaped_array->data, &content_length); + unescaped_array->len = content_length; + bytes = g_byte_array_free_to_bytes (unescaped_array); + } + } else { + bytes = g_bytes_new_static (NULL, 0); + } + g_free (uri_string); + + return bytes; +} + +GUri * +soup_uri_copy_with_credentials (GUri *uri, const char *username, const char *password) +{ + g_return_val_if_fail (uri != NULL, NULL); + + return g_uri_build_with_user ( + g_uri_get_flags (uri) | G_URI_FLAGS_HAS_PASSWORD, + g_uri_get_scheme (uri), + username, password, + g_uri_get_auth_params (uri), + g_uri_get_host (uri), + g_uri_get_port (uri), + g_uri_get_path (uri), + g_uri_get_query (uri), + g_uri_get_fragment (uri) + ); +} + +GUri * +soup_uri_copy_with_normalized_flags (GUri *uri) +{ + GUriFlags flags = g_uri_get_flags (uri); + + /* We require its encoded (hostname encoding optional) */ + if (((flags & (G_URI_FLAGS_ENCODED_PATH | G_URI_FLAGS_ENCODED_QUERY | G_URI_FLAGS_ENCODED_FRAGMENT)) || + (flags & G_URI_FLAGS_ENCODED)) && + /* And has scheme-based normalization */ + (flags & G_URI_FLAGS_SCHEME_NORMALIZE)) + return g_uri_ref (uri); + + return g_uri_build_with_user ( + g_uri_get_flags (uri) | SOUP_HTTP_URI_FLAGS, + g_uri_get_scheme (uri), + g_uri_get_user (uri), + g_uri_get_password (uri), + g_uri_get_auth_params (uri), + g_uri_get_host (uri), + g_uri_get_port (uri), + g_uri_get_path (uri), + g_uri_get_query (uri), + g_uri_get_fragment (uri) + ); +} diff --git a/libsoup/soup-uri-utils.h b/libsoup/soup-uri-utils.h new file mode 100644 index 00000000..8b436180 --- /dev/null +++ b/libsoup/soup-uri-utils.h @@ -0,0 +1,35 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ + +/* + * Copyright 1999-2002 Ximian, Inc. + */ + + +#pragma once + +#include "soup-types.h" + +G_BEGIN_DECLS + +SOUP_AVAILABLE_IN_ALL +GBytes *soup_uri_decode_data_uri (const char *uri, + char **content_type); + +SOUP_AVAILABLE_IN_ALL +gboolean soup_uri_equal (GUri *uri1, GUri *uri2); + +SOUP_AVAILABLE_IN_ALL +GUri *soup_uri_copy_with_query_from_form (GUri *uri, + GHashTable *form); + +SOUP_AVAILABLE_IN_ALL +GUri *soup_uri_copy_with_query_from_fields (GUri *uri, + const char *first_field, + ...) G_GNUC_NULL_TERMINATED; + +SOUP_AVAILABLE_IN_ALL +int soup_uri_get_port_with_default (GUri *uri); + +#define SOUP_HTTP_URI_FLAGS (G_URI_FLAGS_HAS_PASSWORD | G_URI_FLAGS_ENCODED_PATH | G_URI_FLAGS_ENCODED_QUERY | G_URI_FLAGS_ENCODED_FRAGMENT | G_URI_FLAGS_SCHEME_NORMALIZE) + +G_END_DECLS diff --git a/libsoup/soup-uri.c b/libsoup/soup-uri.c deleted file mode 100644 index dd27553f..00000000 --- a/libsoup/soup-uri.c +++ /dev/null @@ -1,1462 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* soup-uri.c : utility functions to parse URLs */ - -/* - * Copyright 1999-2003 Ximian, Inc. - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include - -#include "soup-uri.h" -#include "soup.h" -#include "soup-misc.h" - -/** - * SECTION:soup-uri - * @short_description: URIs - * - * A #SoupURI represents a (parsed) URI. - * - * Many applications will not need to use #SoupURI directly at all; on - * the client side, soup_message_new() takes a stringified URI, and on - * the server side, the path and query components are provided for you - * in the server callback. - **/ - -/** - * SoupURI: - * @scheme: the URI scheme (eg, "http") - * @user: a username, or %NULL - * @password: a password, or %NULL - * @host: the hostname or IP address, or %NULL - * @port: the port number on @host - * @path: the path on @host - * @query: a query for @path, or %NULL - * @fragment: a fragment identifier within @path, or %NULL - * - * A #SoupURI represents a (parsed) URI. #SoupURI supports RFC 3986 - * (URI Generic Syntax), and can parse any valid URI. However, libsoup - * only uses "http" and "https" URIs internally; You can use - * SOUP_URI_VALID_FOR_HTTP() to test if a #SoupURI is a valid HTTP - * URI. - * - * @scheme will always be set in any URI. It is an interned string and - * is always all lowercase. (If you parse a URI with a non-lowercase - * scheme, it will be converted to lowercase.) The macros - * %SOUP_URI_SCHEME_HTTP and %SOUP_URI_SCHEME_HTTPS provide the - * interned values for "http" and "https" and can be compared against - * URI @scheme values. - * - * @user and @password are parsed as defined in the older URI specs - * (ie, separated by a colon; RFC 3986 only talks about a single - * "userinfo" field). Note that @password is not included in the - * output of soup_uri_to_string(). libsoup does not normally use these - * fields; authentication is handled via #SoupSession signals. - * - * @host contains the hostname, and @port the port specified in the - * URI. If the URI doesn't contain a hostname, @host will be %NULL, - * and if it doesn't specify a port, @port may be 0. However, for - * "http" and "https" URIs, @host is guaranteed to be non-%NULL - * (trying to parse an http URI with no @host will return %NULL), and - * @port will always be non-0 (because libsoup knows the default value - * to use when it is not specified in the URI). - * - * @path is always non-%NULL. For http/https URIs, @path will never be - * an empty string either; if the input URI has no path, the parsed - * #SoupURI will have a @path of "/". - * - * @query and @fragment are optional for all URI types. - * soup_form_decode() may be useful for parsing @query. - * - * Note that @path, @query, and @fragment may contain - * %-encoded characters. soup_uri_new() calls - * soup_uri_normalize() on them, but not soup_uri_decode(). This is - * necessary to ensure that soup_uri_to_string() will generate a URI - * that has exactly the same meaning as the original. (In theory, - * #SoupURI should leave @user, @password, and @host partially-encoded - * as well, but this would be more annoying than useful.) - **/ - -/** - * SOUP_URI_IS_VALID: - * @uri: a #SoupURI - * - * Tests whether @uri is a valid #SoupURI; that is, that it is non-%NULL - * and its @scheme and @path members are also non-%NULL. - * - * This macro does not check whether http and https URIs have a non-%NULL - * @host member. - * - * Return value: %TRUE if @uri is valid for use. - * - * Since: 2.38 - **/ - -/** - * SOUP_URI_VALID_FOR_HTTP: - * @uri: a #SoupURI - * - * Tests if @uri is a valid #SoupURI for HTTP communication; that is, if - * it can be used to construct a #SoupMessage. - * - * Return value: %TRUE if @uri is a valid "http" or "https" URI. - * - * Since: 2.24 - **/ - -/** - * SOUP_URI_SCHEME_HTTP: - * - * "http" as an interned string; you can compare this directly to a - * #SoupURI's scheme field using - * ==. - */ -/** - * SOUP_URI_SCHEME_HTTPS: - * - * "https" as an interned string; you can compare this directly to a - * #SoupURI's scheme field using - * ==. - */ -/** - * SOUP_URI_SCHEME_FTP: - * - * "ftp" as an interned string; you can compare this directly to a - * #SoupURI's scheme field using - * ==. - * - * Since: 2.30 - */ -/** - * SOUP_URI_SCHEME_FILE: - * - * "file" as an interned string; you can compare this directly to a - * #SoupURI's scheme field using - * ==. - * - * Since: 2.30 - */ -/** - * SOUP_URI_SCHEME_DATA: - * - * "data" as an interned string; you can compare this directly to a - * #SoupURI's scheme field using - * ==. - * - * Since: 2.30 - */ -/** - * SOUP_URI_SCHEME_RESOURCE: - * - * "data" as an interned string; you can compare this directly to a - * #SoupURI's scheme field using - * ==. - * - * Since: 2.42 - */ -/** - * SOUP_URI_SCHEME_WS: - * - * "ws" (WebSocket) as an interned string; you can compare this - * directly to a #SoupURI's scheme field using - * ==. - * - * Since: 2.50 - */ -/** - * SOUP_URI_SCHEME_WSS: - * - * "wss" (WebSocket over TLS) as an interned string; you can compare - * this directly to a #SoupURI's scheme field using - * ==. - * - * Since: 2.50 - */ - -static void append_uri_encoded (GString *str, const char *in, const char *extra_enc_chars); -static char *uri_normalized_copy (const char *str, int length, const char *unescape_extra); - -gpointer _SOUP_URI_SCHEME_HTTP, _SOUP_URI_SCHEME_HTTPS; -gpointer _SOUP_URI_SCHEME_WS, _SOUP_URI_SCHEME_WSS; -gpointer _SOUP_URI_SCHEME_FTP; -gpointer _SOUP_URI_SCHEME_FILE, _SOUP_URI_SCHEME_DATA, _SOUP_URI_SCHEME_RESOURCE; - -static inline const char * -soup_uri_parse_scheme (const char *scheme, int len) -{ - if (len == 4 && !g_ascii_strncasecmp (scheme, "http", len)) { - return SOUP_URI_SCHEME_HTTP; - } else if (len == 5 && !g_ascii_strncasecmp (scheme, "https", len)) { - return SOUP_URI_SCHEME_HTTPS; - } else if (len == 8 && !g_ascii_strncasecmp (scheme, "resource", len)) { - return SOUP_URI_SCHEME_RESOURCE; - } else if (len == 2 && !g_ascii_strncasecmp (scheme, "ws", len)) { - return SOUP_URI_SCHEME_WS; - } else if (len == 3 && !g_ascii_strncasecmp (scheme, "wss", len)) { - return SOUP_URI_SCHEME_WSS; - } else { - char *lower_scheme; - - lower_scheme = g_ascii_strdown (scheme, len); - scheme = g_intern_static_string (lower_scheme); - if (scheme != (const char *)lower_scheme) - g_free (lower_scheme); - return scheme; - } -} - -static inline guint -soup_scheme_default_port (const char *scheme) -{ - if (scheme == SOUP_URI_SCHEME_HTTP || scheme == SOUP_URI_SCHEME_WS) - return 80; - else if (scheme == SOUP_URI_SCHEME_HTTPS || scheme == SOUP_URI_SCHEME_WSS) - return 443; - else if (scheme == SOUP_URI_SCHEME_FTP) - return 21; - else - return 0; -} - -/** - * soup_uri_new_with_base: (constructor) - * @base: a base URI - * @uri_string: the URI - * - * Parses @uri_string relative to @base. - * - * Returns: a parsed #SoupURI. - **/ -SoupURI * -soup_uri_new_with_base (SoupURI *base, const char *uri_string) -{ - SoupURI *uri, fixed_base; - const char *end, *hash, *colon, *at, *path, *question; - const char *p, *hostend; - gboolean remove_dot_segments = TRUE; - int len; - - g_return_val_if_fail (uri_string != NULL, NULL); - - /* Allow a %NULL path in @base, for compatibility */ - if (base && base->scheme && !base->path) { - g_warn_if_fail (SOUP_URI_IS_VALID (base)); - - memcpy (&fixed_base, base, sizeof (SoupURI)); - fixed_base.path = ""; - base = &fixed_base; - } - - g_return_val_if_fail (base == NULL || SOUP_URI_IS_VALID (base), NULL); - - /* First some cleanup steps (which are supposed to all be no-ops, - * but...). Skip initial whitespace, strip out internal tabs and - * line breaks, and ignore trailing whitespace. - */ - while (g_ascii_isspace (*uri_string)) - uri_string++; - - len = strcspn (uri_string, "\t\n\r"); - if (uri_string[len]) { - char *clean = g_malloc (strlen (uri_string) + 1), *d; - const char *s; - - for (s = uri_string, d = clean; *s; s++) { - if (*s != '\t' && *s != '\n' && *s != '\r') - *d++ = *s; - } - *d = '\0'; - - uri = soup_uri_new_with_base (base, clean); - g_free (clean); - return uri; - } - end = uri_string + len; - while (end > uri_string && g_ascii_isspace (end[-1])) - end--; - - uri = g_slice_new0 (SoupURI); - - /* Find fragment. */ - hash = strchr (uri_string, '#'); - if (hash) { - uri->fragment = uri_normalized_copy (hash + 1, end - hash + 1, - NULL); - end = hash; - } - - /* Find scheme */ - p = uri_string; - while (p < end && (g_ascii_isalpha (*p) || - (p > uri_string && (g_ascii_isdigit (*p) || - *p == '.' || - *p == '+' || - *p == '-')))) - p++; - - if (p > uri_string && *p == ':') { - uri->scheme = soup_uri_parse_scheme (uri_string, p - uri_string); - uri_string = p + 1; - } - - if (uri_string == end && !base && !uri->fragment) { - uri->path = g_strdup (""); - return uri; - } - - /* Check for authority */ - if (strncmp (uri_string, "//", 2) == 0) { - uri_string += 2; - - path = uri_string + strcspn (uri_string, "/?#"); - if (path > end) - path = end; - at = strchr (uri_string, '@'); - if (at && at < path) { - colon = strchr (uri_string, ':'); - if (colon && colon < at) { - uri->password = soup_uri_decoded_copy (colon + 1, - at - colon - 1, NULL); - } else { - uri->password = NULL; - colon = at; - } - - uri->user = soup_uri_decoded_copy (uri_string, - colon - uri_string, NULL); - uri_string = at + 1; - } else - uri->user = uri->password = NULL; - - /* Find host and port. */ - if (*uri_string == '[') { - const char *pct; - - uri_string++; - hostend = strchr (uri_string, ']'); - if (!hostend || hostend > path) { - soup_uri_free (uri); - return NULL; - } - if (*(hostend + 1) == ':') - colon = hostend + 1; - else - colon = NULL; - - pct = memchr (uri_string, '%', hostend - uri_string); - if (!pct || (pct[1] == '2' && pct[2] == '5')) { - uri->host = soup_uri_decoded_copy (uri_string, - hostend - uri_string, NULL); - } else - uri->host = g_strndup (uri_string, hostend - uri_string); - } else { - colon = memchr (uri_string, ':', path - uri_string); - hostend = colon ? colon : path; - uri->host = soup_uri_decoded_copy (uri_string, - hostend - uri_string, NULL); - } - - if (colon && colon != path - 1) { - char *portend; - uri->port = strtoul (colon + 1, &portend, 10); - if (portend != (char *)path) { - soup_uri_free (uri); - return NULL; - } - } - - uri_string = path; - } - - /* Find query */ - question = memchr (uri_string, '?', end - uri_string); - if (question) { - uri->query = uri_normalized_copy (question + 1, - end - (question + 1), - NULL); - end = question; - } - - if (end != uri_string) { - uri->path = uri_normalized_copy (uri_string, end - uri_string, - NULL); - } - - /* Apply base URI. This is spelled out in RFC 3986. */ - if (base && !uri->scheme && uri->host) - uri->scheme = base->scheme; - else if (base && !uri->scheme) { - uri->scheme = base->scheme; - uri->user = g_strdup (base->user); - uri->password = g_strdup (base->password); - uri->host = g_strdup (base->host); - uri->port = base->port; - - if (!uri->path) { - uri->path = g_strdup (base->path); - if (!uri->query) - uri->query = g_strdup (base->query); - remove_dot_segments = FALSE; - } else if (*uri->path != '/') { - char *newpath, *last; - - last = strrchr (base->path, '/'); - if (last) { - newpath = g_strdup_printf ("%.*s%s", - (int)(last + 1 - base->path), - base->path, - uri->path); - } else - newpath = g_strdup_printf ("/%s", uri->path); - - g_free (uri->path); - uri->path = newpath; - } - } - - if (remove_dot_segments && uri->path && *uri->path) { - char *p, *q; - - /* Remove "./" where "." is a complete segment. */ - for (p = uri->path + 1; *p; ) { - if (*(p - 1) == '/' && - *p == '.' && *(p + 1) == '/') - memmove (p, p + 2, strlen (p + 2) + 1); - else - p++; - } - /* Remove "." at end. */ - if (p > uri->path + 2 && - *(p - 1) == '.' && *(p - 2) == '/') - *(p - 1) = '\0'; - - /* Remove "/../" where != ".." */ - for (p = uri->path + 1; *p; ) { - if (!strncmp (p, "../", 3)) { - p += 3; - continue; - } - q = strchr (p + 1, '/'); - if (!q) - break; - if (strncmp (q, "/../", 4) != 0) { - p = q + 1; - continue; - } - memmove (p, q + 4, strlen (q + 4) + 1); - p = uri->path + 1; - } - /* Remove "/.." at end where != ".." */ - q = strrchr (uri->path, '/'); - if (q && q != uri->path && !strcmp (q, "/..")) { - p = q - 1; - while (p > uri->path && *p != '/') - p--; - if (strncmp (p, "/../", 4) != 0) - *(p + 1) = 0; - } - - /* Remove extraneous initial "/.."s */ - while (!strncmp (uri->path, "/../", 4)) - memmove (uri->path, uri->path + 3, strlen (uri->path) - 2); - if (!strcmp (uri->path, "/..")) - uri->path[1] = '\0'; - } - - /* HTTP-specific stuff */ - if (uri->scheme == SOUP_URI_SCHEME_HTTP || - uri->scheme == SOUP_URI_SCHEME_HTTPS) { - if (!uri->path) - uri->path = g_strdup ("/"); - if (!SOUP_URI_VALID_FOR_HTTP (uri)) { - soup_uri_free (uri); - return NULL; - } - } - - if (uri->scheme == SOUP_URI_SCHEME_FTP) { - if (!uri->host) { - soup_uri_free (uri); - return NULL; - } - } - - if (!uri->port) - uri->port = soup_scheme_default_port (uri->scheme); - if (!uri->path) - uri->path = g_strdup (""); - - return uri; -} - -/** - * soup_uri_new: - * @uri_string: (allow-none): a URI - * - * Parses an absolute URI. - * - * You can also pass %NULL for @uri_string if you want to get back an - * "empty" #SoupURI that you can fill in by hand. (You will need to - * call at least soup_uri_set_scheme() and soup_uri_set_path(), since - * those fields are required.) - * - * Return value: (nullable): a #SoupURI, or %NULL if the given string - * was found to be invalid. - **/ -SoupURI * -soup_uri_new (const char *uri_string) -{ - SoupURI *uri; - - if (!uri_string) - return g_slice_new0 (SoupURI); - - uri = soup_uri_new_with_base (NULL, uri_string); - if (!uri) - return NULL; - if (!SOUP_URI_IS_VALID (uri)) { - soup_uri_free (uri); - return NULL; - } - - return uri; -} - - -char * -soup_uri_to_string_internal (SoupURI *uri, gboolean just_path_and_query, - gboolean include_password, gboolean force_port) -{ - GString *str; - char *return_result; - - g_return_val_if_fail (uri != NULL, NULL); - g_warn_if_fail (SOUP_URI_IS_VALID (uri)); - - str = g_string_sized_new (40); - - if (uri->scheme && !just_path_and_query) - g_string_append_printf (str, "%s:", uri->scheme); - if (uri->host && !just_path_and_query) { - g_string_append (str, "//"); - if (uri->user) { - append_uri_encoded (str, uri->user, ":;@?/"); - if (uri->password && include_password) { - g_string_append_c (str, ':'); - append_uri_encoded (str, uri->password, ";@?/"); - } - g_string_append_c (str, '@'); - } - if (strchr (uri->host, ':')) { - const char *pct; - - g_string_append_c (str, '['); - pct = strchr (uri->host, '%'); - if (pct) { - g_string_append_printf (str, "%.*s%%25%s", - (int) (pct - uri->host), - uri->host, pct + 1); - } else - g_string_append (str, uri->host); - g_string_append_c (str, ']'); - } else - append_uri_encoded (str, uri->host, ":/"); - if (uri->port && (force_port || uri->port != soup_scheme_default_port (uri->scheme))) - g_string_append_printf (str, ":%u", uri->port); - if (!uri->path && (uri->query || uri->fragment)) - g_string_append_c (str, '/'); - else if ((!uri->path || !*uri->path) && - (uri->scheme == SOUP_URI_SCHEME_HTTP || - uri->scheme == SOUP_URI_SCHEME_HTTPS)) - g_string_append_c (str, '/'); - } - - if (uri->path && *uri->path) - g_string_append (str, uri->path); - else if (just_path_and_query) - g_string_append_c (str, '/'); - - if (uri->query) { - g_string_append_c (str, '?'); - g_string_append (str, uri->query); - } - if (uri->fragment && !just_path_and_query) { - g_string_append_c (str, '#'); - g_string_append (str, uri->fragment); - } - - return_result = str->str; - g_string_free (str, FALSE); - - return return_result; -} - -/** - * soup_uri_to_string: - * @uri: a #SoupURI - * @just_path_and_query: if %TRUE, output just the path and query portions - * - * Returns a string representing @uri. - * - * If @just_path_and_query is %TRUE, this concatenates the path and query - * together. That is, it constructs the string that would be needed in - * the Request-Line of an HTTP request for @uri. - * - * Note that the output will never contain a password, even if @uri - * does. - * - * Return value: a string representing @uri, which the caller must free. - **/ -char * -soup_uri_to_string (SoupURI *uri, gboolean just_path_and_query) -{ - return soup_uri_to_string_internal (uri, just_path_and_query, FALSE, FALSE); -} - -/** - * soup_uri_copy: - * @uri: a #SoupURI - * - * Copies @uri - * - * Return value: a copy of @uri, which must be freed with soup_uri_free() - **/ -SoupURI * -soup_uri_copy (SoupURI *uri) -{ - SoupURI *dup; - - g_return_val_if_fail (uri != NULL, NULL); - g_warn_if_fail (SOUP_URI_IS_VALID (uri)); - - dup = g_slice_new0 (SoupURI); - dup->scheme = uri->scheme; - dup->user = g_strdup (uri->user); - dup->password = g_strdup (uri->password); - dup->host = g_strdup (uri->host); - dup->port = uri->port; - dup->path = g_strdup (uri->path); - dup->query = g_strdup (uri->query); - dup->fragment = g_strdup (uri->fragment); - - return dup; -} - -static inline gboolean -parts_equal (const char *one, const char *two, gboolean insensitive) -{ - if (!one && !two) - return TRUE; - if (!one || !two) - return FALSE; - return insensitive ? !g_ascii_strcasecmp (one, two) : !strcmp (one, two); -} - -/** - * soup_uri_equal: - * @uri1: a #SoupURI - * @uri2: another #SoupURI - * - * Tests whether or not @uri1 and @uri2 are equal in all parts - * - * Return value: %TRUE or %FALSE - **/ -gboolean -soup_uri_equal (SoupURI *uri1, SoupURI *uri2) -{ - g_return_val_if_fail (uri1 != NULL, FALSE); - g_return_val_if_fail (uri2 != NULL, FALSE); - g_warn_if_fail (SOUP_URI_IS_VALID (uri1)); - g_warn_if_fail (SOUP_URI_IS_VALID (uri2)); - - if (uri1->scheme != uri2->scheme || - uri1->port != uri2->port || - !parts_equal (uri1->user, uri2->user, FALSE) || - !parts_equal (uri1->password, uri2->password, FALSE) || - !parts_equal (uri1->host, uri2->host, TRUE) || - !parts_equal (uri1->path, uri2->path, FALSE) || - !parts_equal (uri1->query, uri2->query, FALSE) || - !parts_equal (uri1->fragment, uri2->fragment, FALSE)) - return FALSE; - - return TRUE; -} - -/** - * soup_uri_free: - * @uri: a #SoupURI - * - * Frees @uri. - **/ -void -soup_uri_free (SoupURI *uri) -{ - g_return_if_fail (uri != NULL); - - g_free (uri->user); - g_free (uri->password); - g_free (uri->host); - g_free (uri->path); - g_free (uri->query); - g_free (uri->fragment); - - g_slice_free (SoupURI, uri); -} - -static void -append_uri_encoded (GString *str, const char *in, const char *extra_enc_chars) -{ - const unsigned char *s = (const unsigned char *)in; - - while (*s) { - if (soup_char_is_uri_percent_encoded (*s) || - soup_char_is_uri_gen_delims (*s) || - (extra_enc_chars && strchr (extra_enc_chars, *s))) - g_string_append_printf (str, "%%%02X", (int)*s++); - else - g_string_append_c (str, *s++); - } -} - -/** - * soup_uri_encode: - * @part: a URI part - * @escape_extra: (allow-none): additional reserved characters to - * escape (or %NULL) - * - * This %-encodes the given URI part and returns the escaped - * version in allocated memory, which the caller must free when it is - * done. - * - * Return value: the encoded URI part - **/ -char * -soup_uri_encode (const char *part, const char *escape_extra) -{ - GString *str; - char *encoded; - - g_return_val_if_fail (part != NULL, NULL); - - str = g_string_new (NULL); - append_uri_encoded (str, part, escape_extra); - encoded = str->str; - g_string_free (str, FALSE); - - return encoded; -} - -#define XDIGIT(c) ((c) <= '9' ? (c) - '0' : ((c) & 0x4F) - 'A' + 10) -#define HEXCHAR(s) ((XDIGIT (s[1]) << 4) + XDIGIT (s[2])) - -/* length must be set (e.g. from strchr()) such that [part, part + length] - * contains no nul bytes */ -char * -soup_uri_decoded_copy (const char *part, int length, int *decoded_length) -{ - unsigned char *s, *d; - char *decoded; - - g_return_val_if_fail (part != NULL, NULL); - - decoded = g_strndup (part, length); - s = d = (unsigned char *)decoded; - do { - if (*s == '%') { - if (s[1] == '\0' || - s[2] == '\0' || - !g_ascii_isxdigit (s[1]) || - !g_ascii_isxdigit (s[2])) { - *d++ = *s; - continue; - } - *d++ = HEXCHAR (s); - s += 2; - } else - *d++ = *s; - } while (*s++); - - if (decoded_length) - *decoded_length = d - (unsigned char *)decoded - 1; - - return decoded; -} - -/** - * soup_uri_decode: - * @part: a URI part - * - * Fully %-decodes @part. - * - * In the past, this would return %NULL if @part contained invalid - * percent-encoding, but now it just ignores the problem (as - * soup_uri_new() already did). - * - * Return value: the decoded URI part. - */ -char * -soup_uri_decode (const char *part) -{ - g_return_val_if_fail (part != NULL, NULL); - - return soup_uri_decoded_copy (part, strlen (part), NULL); -} - -/* length must be set (e.g. from strchr()) such that [part, part + length] - * contains no nul bytes */ -static char * -uri_normalized_copy (const char *part, int length, - const char *unescape_extra) -{ - unsigned char *s, *d, c; - char *normalized = g_strndup (part, length); - gboolean need_fixup = FALSE; - - if (!unescape_extra) - unescape_extra = ""; - - s = d = (unsigned char *)normalized; - while (*s) { - if (*s == '%') { - if (s[1] == '\0' || - s[2] == '\0' || - !g_ascii_isxdigit (s[1]) || - !g_ascii_isxdigit (s[2])) { - *d++ = *s++; - continue; - } - - c = HEXCHAR (s); - if (soup_char_is_uri_unreserved (c) || - (c && strchr (unescape_extra, c))) { - *d++ = c; - s += 3; - } else { - /* We leave it unchanged. We used to uppercase percent-encoded - * triplets but we do not do it any more as RFC3986 Section 6.2.2.1 - * says that they only SHOULD be case normalized. - */ - *d++ = *s++; - *d++ = *s++; - *d++ = *s++; - } - } else { - if (!g_ascii_isgraph (*s) && - !strchr (unescape_extra, *s)) - need_fixup = TRUE; - *d++ = *s++; - } - } - *d = '\0'; - - if (need_fixup) { - GString *fixed; - - fixed = g_string_new (NULL); - s = (guchar *)normalized; - while (*s) { - if (g_ascii_isgraph (*s) || - strchr (unescape_extra, *s)) - g_string_append_c (fixed, *s); - else - g_string_append_printf (fixed, "%%%02X", (int)*s); - s++; - } - g_free (normalized); - normalized = g_string_free (fixed, FALSE); - } - - return normalized; -} - -/** - * soup_uri_normalize: - * @part: a URI part - * @unescape_extra: (allow-none): reserved characters to unescape (or %NULL) - * - * %-decodes any "unreserved" characters (or characters in - * @unescape_extra) in @part, and %-encodes any non-ASCII - * characters, spaces, and non-printing characters in @part. - * - * "Unreserved" characters are those that are not allowed to be used - * for punctuation according to the URI spec. For example, letters are - * unreserved, so soup_uri_normalize() will turn - * http://example.com/foo/b%61r into - * http://example.com/foo/bar, which is guaranteed - * to mean the same thing. However, "/" is "reserved", so - * http://example.com/foo%2Fbar would not - * be changed, because it might mean something different to the - * server. - * - * In the past, this would return %NULL if @part contained invalid - * percent-encoding, but now it just ignores the problem (as - * soup_uri_new() already did). - * - * Return value: the normalized URI part - */ -char * -soup_uri_normalize (const char *part, const char *unescape_extra) -{ - g_return_val_if_fail (part != NULL, NULL); - - return uri_normalized_copy (part, strlen (part), unescape_extra); -} - - -/** - * soup_uri_uses_default_port: - * @uri: a #SoupURI - * - * Tests if @uri uses the default port for its scheme. (Eg, 80 for - * http.) (This only works for http, https and ftp; libsoup does not know - * the default ports of other protocols.) - * - * Return value: %TRUE or %FALSE - **/ -gboolean -soup_uri_uses_default_port (SoupURI *uri) -{ - g_return_val_if_fail (uri != NULL, FALSE); - g_warn_if_fail (SOUP_URI_IS_VALID (uri)); - - return uri->port == soup_scheme_default_port (uri->scheme); -} - -/** - * soup_uri_get_scheme: - * @uri: a #SoupURI - * - * Gets @uri's scheme. - * - * Return value: @uri's scheme. - * - * Since: 2.32 - **/ -const char * -soup_uri_get_scheme (SoupURI *uri) -{ - g_return_val_if_fail (uri != NULL, NULL); - - return uri->scheme; -} - -/** - * soup_uri_set_scheme: - * @uri: a #SoupURI - * @scheme: the URI scheme - * - * Sets @uri's scheme to @scheme. This will also set @uri's port to - * the default port for @scheme, if known. - **/ -void -soup_uri_set_scheme (SoupURI *uri, const char *scheme) -{ - g_return_if_fail (uri != NULL); - g_return_if_fail (scheme != NULL); - - uri->scheme = soup_uri_parse_scheme (scheme, strlen (scheme)); - uri->port = soup_scheme_default_port (uri->scheme); -} - -/** - * soup_uri_get_user: - * @uri: a #SoupURI - * - * Gets @uri's user. - * - * Return value: @uri's user. - * - * Since: 2.32 - **/ -const char * -soup_uri_get_user (SoupURI *uri) -{ - g_return_val_if_fail (uri != NULL, NULL); - - return uri->user; -} - -/** - * soup_uri_set_user: - * @uri: a #SoupURI - * @user: (allow-none): the username, or %NULL - * - * Sets @uri's user to @user. - **/ -void -soup_uri_set_user (SoupURI *uri, const char *user) -{ - g_return_if_fail (uri != NULL); - - g_free (uri->user); - uri->user = g_strdup (user); -} - -/** - * soup_uri_get_password: - * @uri: a #SoupURI - * - * Gets @uri's password. - * - * Return value: @uri's password. - * - * Since: 2.32 - **/ -const char * -soup_uri_get_password (SoupURI *uri) -{ - g_return_val_if_fail (uri != NULL, NULL); - - return uri->password; -} - -/** - * soup_uri_set_password: - * @uri: a #SoupURI - * @password: (allow-none): the password, or %NULL - * - * Sets @uri's password to @password. - **/ -void -soup_uri_set_password (SoupURI *uri, const char *password) -{ - g_return_if_fail (uri != NULL); - - g_free (uri->password); - uri->password = g_strdup (password); -} - -/** - * soup_uri_get_host: - * @uri: a #SoupURI - * - * Gets @uri's host. - * - * Return value: @uri's host. - * - * Since: 2.32 - **/ -const char * -soup_uri_get_host (SoupURI *uri) -{ - g_return_val_if_fail (uri != NULL, NULL); - - return uri->host; -} - -/** - * soup_uri_set_host: - * @uri: a #SoupURI - * @host: (allow-none): the hostname or IP address, or %NULL - * - * Sets @uri's host to @host. - * - * If @host is an IPv6 IP address, it should not include the brackets - * required by the URI syntax; they will be added automatically when - * converting @uri to a string. - * - * http and https URIs should not have a %NULL @host. - **/ -void -soup_uri_set_host (SoupURI *uri, const char *host) -{ - g_return_if_fail (uri != NULL); - - g_free (uri->host); - uri->host = g_strdup (host); -} - -/** - * soup_uri_get_port: - * @uri: a #SoupURI - * - * Gets @uri's port. - * - * Return value: @uri's port. - * - * Since: 2.32 - **/ -guint -soup_uri_get_port (SoupURI *uri) -{ - g_return_val_if_fail (uri != NULL, 0); - - return uri->port; -} - -/** - * soup_uri_set_port: - * @uri: a #SoupURI - * @port: the port, or 0 - * - * Sets @uri's port to @port. If @port is 0, @uri will not have an - * explicitly-specified port. - **/ -void -soup_uri_set_port (SoupURI *uri, guint port) -{ - g_return_if_fail (uri != NULL); - - uri->port = port; -} - -/** - * soup_uri_get_path: - * @uri: a #SoupURI - * - * Gets @uri's path. - * - * Return value: @uri's path. - * - * Since: 2.32 - **/ -const char * -soup_uri_get_path (SoupURI *uri) -{ - g_return_val_if_fail (uri != NULL, NULL); - - return uri->path; -} - -/** - * soup_uri_set_path: - * @uri: a #SoupURI - * @path: the non-%NULL path - * - * Sets @uri's path to @path. - **/ -void -soup_uri_set_path (SoupURI *uri, const char *path) -{ - g_return_if_fail (uri != NULL); - - /* We allow a NULL path for compatibility, but warn about it. */ - if (!path) { - g_warn_if_fail (path != NULL); - path = ""; - } - - g_free (uri->path); - uri->path = g_strdup (path); -} - -/** - * soup_uri_get_query: - * @uri: a #SoupURI - * - * Gets @uri's query. - * - * Return value: @uri's query. - * - * Since: 2.32 - **/ -const char * -soup_uri_get_query (SoupURI *uri) -{ - g_return_val_if_fail (uri != NULL, NULL); - - return uri->query; -} - -/** - * soup_uri_set_query: - * @uri: a #SoupURI - * @query: (allow-none): the query - * - * Sets @uri's query to @query. - **/ -void -soup_uri_set_query (SoupURI *uri, const char *query) -{ - g_return_if_fail (uri != NULL); - - g_free (uri->query); - uri->query = g_strdup (query); -} - -/** - * soup_uri_set_query_from_form: - * @uri: a #SoupURI - * @form: (element-type utf8 utf8): a #GHashTable containing HTML form - * information - * - * Sets @uri's query to the result of encoding @form according to the - * HTML form rules. See soup_form_encode_hash() for more information. - **/ -void -soup_uri_set_query_from_form (SoupURI *uri, GHashTable *form) -{ - g_return_if_fail (uri != NULL); - - g_free (uri->query); - uri->query = soup_form_encode_hash (form); -} - -/** - * soup_uri_set_query_from_fields: - * @uri: a #SoupURI - * @first_field: name of the first form field to encode into query - * @...: value of @first_field, followed by additional field names - * and values, terminated by %NULL. - * - * Sets @uri's query to the result of encoding the given form fields - * and values according to the * HTML form rules. See - * soup_form_encode() for more information. - **/ -void -soup_uri_set_query_from_fields (SoupURI *uri, - const char *first_field, - ...) -{ - va_list args; - - g_return_if_fail (uri != NULL); - - g_free (uri->query); - va_start (args, first_field); - uri->query = soup_form_encode_valist (first_field, args); - va_end (args); -} - -/** - * soup_uri_get_fragment: - * @uri: a #SoupURI - * - * Gets @uri's fragment. - * - * Return value: @uri's fragment. - * - * Since: 2.32 - **/ -const char * -soup_uri_get_fragment (SoupURI *uri) -{ - g_return_val_if_fail (uri != NULL, NULL); - - return uri->fragment; -} - -/** - * soup_uri_set_fragment: - * @uri: a #SoupURI - * @fragment: (allow-none): the fragment - * - * Sets @uri's fragment to @fragment. - **/ -void -soup_uri_set_fragment (SoupURI *uri, const char *fragment) -{ - g_return_if_fail (uri != NULL); - - g_free (uri->fragment); - uri->fragment = g_strdup (fragment); -} - -/** - * soup_uri_copy_host: - * @uri: a #SoupURI - * - * Makes a copy of @uri, considering only the protocol, host, and port - * - * Return value: the new #SoupURI - * - * Since: 2.28 - **/ -SoupURI * -soup_uri_copy_host (SoupURI *uri) -{ - SoupURI *dup; - - g_return_val_if_fail (uri != NULL, NULL); - g_warn_if_fail (SOUP_URI_IS_VALID (uri)); - - dup = soup_uri_new (NULL); - dup->scheme = uri->scheme; - dup->host = g_strdup (uri->host); - dup->port = uri->port; - dup->path = g_strdup (""); - - return dup; -} - -/** - * soup_uri_host_hash: - * @key: (type Soup.URI): a #SoupURI with a non-%NULL @host member - * - * Hashes @key, considering only the scheme, host, and port. - * - * Return value: a hash - * - * Since: 2.28 - **/ -guint -soup_uri_host_hash (gconstpointer key) -{ - const SoupURI *uri = key; - - g_return_val_if_fail (uri != NULL && uri->host != NULL, 0); - g_warn_if_fail (SOUP_URI_IS_VALID (uri)); - - return GPOINTER_TO_UINT (uri->scheme) + uri->port + - soup_str_case_hash (uri->host); -} - -/** - * soup_uri_host_equal: - * @v1: (type Soup.URI): a #SoupURI with a non-%NULL @host member - * @v2: (type Soup.URI): a #SoupURI with a non-%NULL @host member - * - * Compares @v1 and @v2, considering only the scheme, host, and port. - * - * Return value: whether or not the URIs are equal in scheme, host, - * and port. - * - * Since: 2.28 - **/ -gboolean -soup_uri_host_equal (gconstpointer v1, gconstpointer v2) -{ - const SoupURI *one = v1; - const SoupURI *two = v2; - - g_return_val_if_fail (one != NULL && two != NULL, one == two); - g_return_val_if_fail (one->host != NULL && two->host != NULL, one->host == two->host); - g_warn_if_fail (SOUP_URI_IS_VALID (one)); - g_warn_if_fail (SOUP_URI_IS_VALID (two)); - - if (one->scheme != two->scheme) - return FALSE; - if (one->port != two->port) - return FALSE; - - return g_ascii_strcasecmp (one->host, two->host) == 0; -} - -gboolean -soup_uri_is_http (SoupURI *uri, char **aliases) -{ - int i; - - if (uri->scheme == SOUP_URI_SCHEME_HTTP || - uri->scheme == SOUP_URI_SCHEME_WS) - return TRUE; - else if (uri->scheme == SOUP_URI_SCHEME_HTTPS || - uri->scheme == SOUP_URI_SCHEME_WSS) - return FALSE; - else if (!aliases) - return FALSE; - - for (i = 0; aliases[i]; i++) { - if (uri->scheme == aliases[i]) - return TRUE; - } - - return FALSE; -} - -gboolean -soup_uri_is_https (SoupURI *uri, char **aliases) -{ - int i; - - if (uri->scheme == SOUP_URI_SCHEME_HTTPS || - uri->scheme == SOUP_URI_SCHEME_WSS) - return TRUE; - else if (uri->scheme == SOUP_URI_SCHEME_HTTP || - uri->scheme == SOUP_URI_SCHEME_WS) - return FALSE; - else if (!aliases) - return FALSE; - - for (i = 0; aliases[i]; i++) { - if (uri->scheme == aliases[i]) - return TRUE; - } - - return FALSE; -} - -#define BASE64_INDICATOR ";base64" -#define BASE64_INDICATOR_LEN (sizeof (";base64") - 1) - -/** - * soup_uri_decode_data_uri: - * @uri: a data URI, in string form - * @content_type: (out) (nullable) (transfer full): location to store content type, or %NULL - * - * Decodes the given data URI and returns its contents and @content_type. - * - * Returns: (transfer full): a #GBytes with the contents of @uri, - * or %NULL if @uri is not a valid data URI - */ -GBytes * -soup_uri_decode_data_uri (const char *uri, - char **content_type) -{ - SoupURI *soup_uri; - const char *comma, *start, *end; - gboolean base64 = FALSE; - char *uri_string; - GBytes *bytes; - - g_return_val_if_fail (uri != NULL, NULL); - - soup_uri = soup_uri_new (uri); - if (!soup_uri) - return NULL; - - if (soup_uri->scheme != SOUP_URI_SCHEME_DATA || soup_uri->host != NULL) - return NULL; - - if (content_type) - *content_type = NULL; - - uri_string = soup_uri_to_string (soup_uri, FALSE); - soup_uri_free (soup_uri); - - start = uri_string + 5; - comma = strchr (start, ','); - if (comma && comma != start) { - /* Deal with MIME type / params */ - if (comma >= start + BASE64_INDICATOR_LEN && !g_ascii_strncasecmp (comma - BASE64_INDICATOR_LEN, BASE64_INDICATOR, BASE64_INDICATOR_LEN)) { - end = comma - BASE64_INDICATOR_LEN; - base64 = TRUE; - } else - end = comma; - - if (end != start && content_type) - *content_type = soup_uri_decoded_copy (start, end - start, NULL); - } - - if (content_type && !*content_type) - *content_type = g_strdup ("text/plain;charset=US-ASCII"); - - if (comma) - start = comma + 1; - - if (*start) { - gsize content_length; - int decoded_length = 0; - guchar *buffer = (guchar *) soup_uri_decoded_copy (start, strlen (start), - &decoded_length); - - if (base64) - buffer = g_base64_decode_inplace ((gchar*)buffer, &content_length); - else - content_length = decoded_length; - - bytes = g_bytes_new_take (buffer, content_length); - } else { - bytes = g_bytes_new_static (NULL, 0); - } - g_free (uri_string); - - return bytes; -} - -G_DEFINE_BOXED_TYPE (SoupURI, soup_uri, soup_uri_copy, soup_uri_free) diff --git a/libsoup/soup-uri.h b/libsoup/soup-uri.h deleted file mode 100644 index ea24a53c..00000000 --- a/libsoup/soup-uri.h +++ /dev/null @@ -1,143 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Copyright 1999-2002 Ximian, Inc. - */ - - -#pragma once - -#include "soup-types.h" - -G_BEGIN_DECLS - -struct _SoupURI { - const char *scheme; - - char *user; - char *password; - - char *host; - guint port; - - char *path; - char *query; - - char *fragment; -}; - -SOUP_AVAILABLE_IN_2_4 -GType soup_uri_get_type (void); -#define SOUP_TYPE_URI (soup_uri_get_type ()) - -#define SOUP_URI_SCHEME_HTTP _SOUP_ATOMIC_INTERN_STRING (_SOUP_URI_SCHEME_HTTP, "http") -#define SOUP_URI_SCHEME_HTTPS _SOUP_ATOMIC_INTERN_STRING (_SOUP_URI_SCHEME_HTTPS, "https") -#define SOUP_URI_SCHEME_FTP _SOUP_ATOMIC_INTERN_STRING (_SOUP_URI_SCHEME_FTP, "ftp") -#define SOUP_URI_SCHEME_FILE _SOUP_ATOMIC_INTERN_STRING (_SOUP_URI_SCHEME_FILE, "file") -#define SOUP_URI_SCHEME_DATA _SOUP_ATOMIC_INTERN_STRING (_SOUP_URI_SCHEME_DATA, "data") -#define SOUP_URI_SCHEME_RESOURCE _SOUP_ATOMIC_INTERN_STRING (_SOUP_URI_SCHEME_RESOURCE, "resource") -#define SOUP_URI_SCHEME_WS _SOUP_ATOMIC_INTERN_STRING (_SOUP_URI_SCHEME_WS, "ws") -#define SOUP_URI_SCHEME_WSS _SOUP_ATOMIC_INTERN_STRING (_SOUP_URI_SCHEME_WSS, "wss") - -SOUP_VAR gpointer _SOUP_URI_SCHEME_HTTP, _SOUP_URI_SCHEME_HTTPS; -SOUP_VAR gpointer _SOUP_URI_SCHEME_FTP; -SOUP_VAR gpointer _SOUP_URI_SCHEME_FILE, _SOUP_URI_SCHEME_DATA, _SOUP_URI_SCHEME_RESOURCE; -SOUP_VAR gpointer _SOUP_URI_SCHEME_WS, _SOUP_URI_SCHEME_WSS; - -SOUP_AVAILABLE_IN_2_4 -SoupURI *soup_uri_new_with_base (SoupURI *base, - const char *uri_string); -SOUP_AVAILABLE_IN_2_4 -SoupURI *soup_uri_new (const char *uri_string); - -SOUP_AVAILABLE_IN_2_4 -char *soup_uri_to_string (SoupURI *uri, - gboolean just_path_and_query); - -SOUP_AVAILABLE_IN_2_4 -SoupURI *soup_uri_copy (SoupURI *uri); - -SOUP_AVAILABLE_IN_2_4 -gboolean soup_uri_equal (SoupURI *uri1, - SoupURI *uri2); - -SOUP_AVAILABLE_IN_2_4 -void soup_uri_free (SoupURI *uri); - -SOUP_AVAILABLE_IN_2_4 -char *soup_uri_encode (const char *part, - const char *escape_extra); -SOUP_AVAILABLE_IN_2_4 -char *soup_uri_decode (const char *part); -SOUP_AVAILABLE_IN_2_4 -char *soup_uri_normalize (const char *part, - const char *unescape_extra); -SOUP_AVAILABLE_IN_ALL -GBytes *soup_uri_decode_data_uri (const char *uri, - char **content_type); - -SOUP_AVAILABLE_IN_2_4 -gboolean soup_uri_uses_default_port (SoupURI *uri); - -SOUP_AVAILABLE_IN_2_32 -const char *soup_uri_get_scheme (SoupURI *uri); -SOUP_AVAILABLE_IN_2_4 -void soup_uri_set_scheme (SoupURI *uri, - const char *scheme); -SOUP_AVAILABLE_IN_2_32 -const char *soup_uri_get_user (SoupURI *uri); -SOUP_AVAILABLE_IN_2_4 -void soup_uri_set_user (SoupURI *uri, - const char *user); -SOUP_AVAILABLE_IN_2_32 -const char *soup_uri_get_password (SoupURI *uri); -SOUP_AVAILABLE_IN_2_4 -void soup_uri_set_password (SoupURI *uri, - const char *password); -SOUP_AVAILABLE_IN_2_32 -const char *soup_uri_get_host (SoupURI *uri); -SOUP_AVAILABLE_IN_2_4 -void soup_uri_set_host (SoupURI *uri, - const char *host); -SOUP_AVAILABLE_IN_2_32 -guint soup_uri_get_port (SoupURI *uri); -SOUP_AVAILABLE_IN_2_4 -void soup_uri_set_port (SoupURI *uri, - guint port); -SOUP_AVAILABLE_IN_2_32 -const char *soup_uri_get_path (SoupURI *uri); -SOUP_AVAILABLE_IN_2_4 -void soup_uri_set_path (SoupURI *uri, - const char *path); -SOUP_AVAILABLE_IN_2_32 -const char *soup_uri_get_query (SoupURI *uri); -SOUP_AVAILABLE_IN_2_4 -void soup_uri_set_query (SoupURI *uri, - const char *query); -SOUP_AVAILABLE_IN_2_4 -void soup_uri_set_query_from_form (SoupURI *uri, - GHashTable *form); -SOUP_AVAILABLE_IN_2_4 -void soup_uri_set_query_from_fields (SoupURI *uri, - const char *first_field, - ...) G_GNUC_NULL_TERMINATED; -SOUP_AVAILABLE_IN_2_32 -const char *soup_uri_get_fragment (SoupURI *uri); -SOUP_AVAILABLE_IN_2_4 -void soup_uri_set_fragment (SoupURI *uri, - const char *fragment); - -SOUP_AVAILABLE_IN_2_28 -SoupURI *soup_uri_copy_host (SoupURI *uri); -SOUP_AVAILABLE_IN_2_28 -guint soup_uri_host_hash (gconstpointer key); -SOUP_AVAILABLE_IN_2_28 -gboolean soup_uri_host_equal (gconstpointer v1, - gconstpointer v2); - -#define SOUP_URI_IS_VALID(uri) ((uri) && (uri)->scheme && (uri)->path) -#define SOUP_URI_VALID_FOR_HTTP(uri) ((uri) && ((uri)->scheme == SOUP_URI_SCHEME_HTTP || (uri)->scheme == SOUP_URI_SCHEME_HTTPS) && (uri)->host && (uri)->path) - -G_DEFINE_AUTOPTR_CLEANUP_FUNC(SoupURI, soup_uri_free) - -G_END_DECLS diff --git a/libsoup/soup.h b/libsoup/soup.h index 9e7c863a..d813163b 100644 --- a/libsoup/soup.h +++ b/libsoup/soup.h @@ -43,7 +43,8 @@ extern "C" { #include "soup-socket.h" #include "soup-status.h" #include "soup-tld.h" -#include "soup-uri.h" +#include "soup-uri-utils.h" +#include "soup-uri-utils-private.h" #include "soup-version.h" #include "websocket/soup-websocket.h" #include "websocket/soup-websocket-connection.h" diff --git a/libsoup/websocket/soup-websocket-connection.c b/libsoup/websocket/soup-websocket-connection.c index 325a0b96..1262f290 100644 --- a/libsoup/websocket/soup-websocket-connection.c +++ b/libsoup/websocket/soup-websocket-connection.c @@ -25,7 +25,7 @@ #include "soup-websocket-connection.h" #include "soup-enum-types.h" #include "soup-io-stream.h" -#include "soup-uri.h" +#include "soup-uri-utils-private.h" #include "soup-websocket-extension.h" /* @@ -120,7 +120,7 @@ struct _SoupWebsocketConnection { typedef struct { GIOStream *io_stream; SoupWebsocketConnectionType connection_type; - SoupURI *uri; + GUri *uri; char *origin; char *protocol; guint64 max_incoming_payload_size; @@ -1391,7 +1391,7 @@ soup_websocket_connection_set_property (GObject *object, case PROP_URI: g_return_if_fail (priv->uri == NULL); - priv->uri = g_value_dup_boxed (value); + priv->uri = soup_uri_copy_with_normalized_flags (g_value_get_boxed (value)); break; case PROP_ORIGIN: @@ -1462,7 +1462,7 @@ soup_websocket_connection_finalize (GObject *object) g_byte_array_free (priv->message_data, TRUE); if (priv->uri) - soup_uri_free (priv->uri); + g_uri_unref (priv->uri); g_free (priv->origin); g_free (priv->protocol); @@ -1532,7 +1532,7 @@ soup_websocket_connection_class_init (SoupWebsocketConnectionClass *klass) g_param_spec_boxed ("uri", "URI", "The WebSocket URI", - SOUP_TYPE_URI, + G_TYPE_URI, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); @@ -1753,7 +1753,7 @@ soup_websocket_connection_class_init (SoupWebsocketConnectionClass *klass) */ SoupWebsocketConnection * soup_websocket_connection_new (GIOStream *stream, - SoupURI *uri, + GUri *uri, SoupWebsocketConnectionType type, const char *origin, const char *protocol, @@ -1826,7 +1826,7 @@ soup_websocket_connection_get_connection_type (SoupWebsocketConnection *self) * * Since: 2.50 */ -SoupURI * +GUri * soup_websocket_connection_get_uri (SoupWebsocketConnection *self) { SoupWebsocketConnectionPrivate *priv = soup_websocket_connection_get_instance_private (self); diff --git a/libsoup/websocket/soup-websocket-connection.h b/libsoup/websocket/soup-websocket-connection.h index 6bd11bbd..d537168d 100644 --- a/libsoup/websocket/soup-websocket-connection.h +++ b/libsoup/websocket/soup-websocket-connection.h @@ -31,7 +31,7 @@ G_DECLARE_FINAL_TYPE (SoupWebsocketConnection, soup_websocket_connection, SOUP, SOUP_AVAILABLE_IN_ALL SoupWebsocketConnection *soup_websocket_connection_new (GIOStream *stream, - SoupURI *uri, + GUri *uri, SoupWebsocketConnectionType type, const char *origin, const char *protocol, @@ -44,7 +44,7 @@ SOUP_AVAILABLE_IN_2_50 SoupWebsocketConnectionType soup_websocket_connection_get_connection_type (SoupWebsocketConnection *self); SOUP_AVAILABLE_IN_2_50 -SoupURI * soup_websocket_connection_get_uri (SoupWebsocketConnection *self); +GUri * soup_websocket_connection_get_uri (SoupWebsocketConnection *self); SOUP_AVAILABLE_IN_2_50 const char * soup_websocket_connection_get_origin (SoupWebsocketConnection *self); diff --git a/meson.build b/meson.build index 1650cf6b..fe1f95af 100644 --- a/meson.build +++ b/meson.build @@ -76,7 +76,7 @@ endif add_project_arguments(common_flags, language : 'c') -glib_required_version = '>= 2.58' +glib_required_version = '>= 2.67.0' glib_dep = dependency('glib-2.0', version : glib_required_version, fallback: ['glib', 'libglib_dep']) gobject_dep = dependency('gobject-2.0', version : glib_required_version, @@ -86,6 +86,12 @@ gio_dep = dependency('gio-2.0', version : glib_required_version, glib_deps = [glib_dep, gobject_dep, gio_dep] +# Added in 2.67.x cycle, remove after 2.68.0 +cc.has_header_symbol('glib.h', 'G_URI_FLAGS_SCHEME_NORMALIZE', + dependencies: glib_dep, + required: true, +) + sqlite_dep = dependency('sqlite3', required: false) # Fallback check for sqlite, not all platforms ship pkg-config file diff --git a/tests/auth-test.c b/tests/auth-test.c index 3c89932c..a018ad3c 100644 --- a/tests/auth-test.c +++ b/tests/auth-test.c @@ -791,7 +791,7 @@ select_auth_authenticate (SoupMessage *msg, } static void -select_auth_test_one (SoupURI *uri, +select_auth_test_one (GUri *uri, gboolean disable_digest, const char *password, const char *first_headers, const char *first_response, const char *second_headers, const char *second_response, @@ -881,7 +881,7 @@ do_select_auth_test (void) { SoupServer *server; SoupAuthDomain *basic_auth_domain, *digest_auth_domain; - SoupURI *uri; + GUri *uri; g_test_bug ("562339"); @@ -977,7 +977,7 @@ do_select_auth_test (void) g_object_unref (basic_auth_domain); g_object_unref (digest_auth_domain); - soup_uri_free (uri); + g_uri_unref (uri); soup_test_server_quit_unref (server); } @@ -1036,7 +1036,7 @@ do_auth_close_test (void) { SoupServer *server; SoupAuthDomain *basic_auth_domain; - SoupURI *uri; + GUri *uri, *tmp; AuthCloseData acd; GBytes *body; @@ -1045,7 +1045,9 @@ do_auth_close_test (void) server_callback, NULL, NULL); uri = soup_test_server_get_uri (server, "http", NULL); - soup_uri_set_path (uri, "/close"); + tmp = g_uri_parse_relative (uri, "/close", SOUP_HTTP_URI_FLAGS, NULL); + g_uri_unref (uri); + uri = g_steal_pointer (&tmp); basic_auth_domain = soup_auth_domain_basic_new ( "realm", "auth-test", @@ -1062,7 +1064,7 @@ do_auth_close_test (void) acd.msg = soup_message_new_from_uri ("GET", uri); g_signal_connect (acd.msg, "authenticate", G_CALLBACK (auth_close_authenticate), &acd); - soup_uri_free (uri); + g_uri_unref (uri); body = soup_test_session_async_send (acd.session, acd.msg); soup_test_assert_message_status (acd.msg, SOUP_STATUS_OK); @@ -1160,7 +1162,7 @@ do_disappearing_auth_test (void) { SoupServer *server; SoupAuthDomain *auth_domain; - SoupURI *uri; + GUri *uri; SoupMessage *msg; SoupSession *session; int counter; @@ -1201,7 +1203,7 @@ do_disappearing_auth_test (void) soup_test_session_abort_unref (session); g_object_unref (auth_domain); - soup_uri_free (uri); + g_uri_unref (uri); soup_test_server_quit_unref (server); } @@ -1248,36 +1250,37 @@ do_batch_tests (gconstpointer data) SoupSession *session; SoupMessage *msg; char *expected, *uristr; - SoupURI *base; + GUri *base; int i; SOUP_TEST_SKIP_IF_NO_APACHE; session = soup_test_session_new (NULL); - base = soup_uri_new (base_uri); + base = g_uri_parse (base_uri, SOUP_HTTP_URI_FLAGS, NULL); for (i = 0; current_tests[i].url; i++) { - SoupURI *soup_uri = soup_uri_new_with_base (base, current_tests[i].url); + GUri *soup_uri = g_uri_parse_relative (base, current_tests[i].url, SOUP_HTTP_URI_FLAGS, NULL); debug_printf (1, "Test %d: %s\n", i + 1, current_tests[i].explanation); if (current_tests[i].url_auth) { gchar *username = g_strdup_printf ("user%c", current_tests[i].provided[0]); gchar *password = g_strdup_printf ("realm%c", current_tests[i].provided[0]); - soup_uri_set_user (soup_uri, username); - soup_uri_set_password (soup_uri, password); + GUri *tmp = soup_uri_copy_with_credentials (soup_uri, username, password); + g_uri_unref (soup_uri); + soup_uri = tmp; g_free (username); g_free (password); } msg = soup_message_new_from_uri (SOUP_METHOD_GET, soup_uri); - soup_uri_free (soup_uri); + g_uri_unref (soup_uri); if (!msg) { g_printerr ("auth-test: Could not parse URI\n"); exit (1); } - uristr = soup_uri_to_string (soup_message_get_uri (msg), FALSE); + uristr = g_uri_to_string (soup_message_get_uri (msg)); debug_printf (1, " GET %s\n", uristr); g_free (uristr); @@ -1304,7 +1307,7 @@ do_batch_tests (gconstpointer data) g_object_unref (msg); } - soup_uri_free (base); + g_uri_unref (base); soup_test_session_abort_unref (session); } @@ -1338,7 +1341,7 @@ do_message_do_not_use_auth_cache_test (void) SoupSession *session; SoupAuthManager *manager; SoupMessage *msg; - SoupURI *soup_uri; + GUri *soup_uri, *auth_uri; char *uri; SOUP_TEST_SKIP_IF_NO_APACHE; @@ -1355,15 +1358,16 @@ do_message_do_not_use_auth_cache_test (void) /* Passing credentials in the URI should always authenticate * no matter whether the cache is used or not */ - soup_uri = soup_uri_new (uri); - soup_uri_set_user (soup_uri, "user1"); - soup_uri_set_password (soup_uri, "realm1"); - msg = soup_message_new_from_uri (SOUP_METHOD_GET, soup_uri); + soup_uri = g_uri_parse (uri, SOUP_HTTP_URI_FLAGS, NULL); + auth_uri = soup_uri_copy_with_credentials (soup_uri, "user1", "realm1"); + + msg = soup_message_new_from_uri (SOUP_METHOD_GET, auth_uri); soup_message_add_flags (msg, SOUP_MESSAGE_DO_NOT_USE_AUTH_CACHE); soup_test_session_send_message (session, msg); soup_test_assert_message_status (msg, SOUP_STATUS_OK); g_object_unref (msg); - soup_uri_free (soup_uri); + g_uri_unref (soup_uri); + g_uri_unref (auth_uri); manager = SOUP_AUTH_MANAGER (soup_session_get_feature (session, SOUP_TYPE_AUTH_MANAGER)); diff --git a/tests/cache-test.c b/tests/cache-test.c index 85d66829..0a86ef87 100644 --- a/tests/cache-test.c +++ b/tests/cache-test.c @@ -120,7 +120,7 @@ is_network_stream (GInputStream *stream) } static char *do_request (SoupSession *session, - SoupURI *base_uri, + GUri *base_uri, const char *method, const char *path, SoupMessageHeaders *response_headers, @@ -142,7 +142,7 @@ copy_headers (const char *name, static char * do_request (SoupSession *session, - SoupURI *base_uri, + GUri *base_uri, const char *method, const char *path, SoupMessageHeaders *response_headers, @@ -150,7 +150,7 @@ do_request (SoupSession *session, { SoupMessage *msg; GInputStream *stream; - SoupURI *uri; + GUri *uri; va_list ap; const char *header, *value; char buf[256]; @@ -160,9 +160,9 @@ do_request (SoupSession *session, last_request_validated = last_request_hit_network = FALSE; last_request_unqueued = FALSE; - uri = soup_uri_new_with_base (base_uri, path); + uri = g_uri_parse_relative (base_uri, path, SOUP_HTTP_URI_FLAGS, NULL); msg = soup_message_new_from_uri (method, uri); - soup_uri_free (uri); + g_uri_unref (uri); va_start (ap, response_headers); while ((header = va_arg (ap, const char *))) { @@ -217,23 +217,23 @@ do_request (SoupSession *session, static void do_request_with_cancel (SoupSession *session, - SoupURI *base_uri, + GUri *base_uri, const char *method, const char *path, SoupTestRequestFlags flags) { SoupMessage *msg; GInputStream *stream; - SoupURI *uri; + GUri *uri; GError *error = NULL; GCancellable *cancellable; last_request_validated = last_request_hit_network = last_request_unqueued = FALSE; cancelled_requests = 0; - uri = soup_uri_new_with_base (base_uri, path); + uri = g_uri_parse_relative (base_uri, path, SOUP_HTTP_URI_FLAGS, NULL); msg = soup_message_new_from_uri (method, uri); - soup_uri_free (uri); + g_uri_unref (uri); cancellable = flags & SOUP_TEST_REQUEST_CANCEL_CANCELLABLE ? g_cancellable_new () : NULL; stream = soup_test_request_send (session, msg, cancellable, flags, &error); if (stream) { @@ -259,7 +259,7 @@ message_starting (SoupMessage *msg, gpointer data) soup_message_headers_get_one (soup_message_get_request_headers (msg), "If-None-Match")) { debug_printf (2, " Conditional request for %s\n", - soup_message_get_uri (msg)->path); + g_uri_get_path (soup_message_get_uri (msg))); last_request_validated = TRUE; } } @@ -285,7 +285,7 @@ request_unqueued (SoupSession *session, SoupMessage *msg, static void do_basics_test (gconstpointer data) { - SoupURI *base_uri = (SoupURI *)data; + GUri *base_uri = (GUri *)data; SoupSession *session; SoupCache *cache; char *cache_dir; @@ -475,7 +475,7 @@ do_basics_test (gconstpointer data) static void do_cancel_test (gconstpointer data) { - SoupURI *base_uri = (SoupURI *)data; + GUri *base_uri = (GUri *)data; SoupSession *session; SoupCache *cache; char *cache_dir; @@ -565,13 +565,13 @@ base_stream_unreffed (gpointer loop, GObject *ex_base_stream) static void do_refcounting_test (gconstpointer data) { - SoupURI *base_uri = (SoupURI *)data; + GUri *base_uri = (GUri *)data; SoupSession *session; SoupCache *cache; char *cache_dir; SoupMessage *msg; GInputStream *stream, *base_stream; - SoupURI *uri; + GUri *uri; GError *error = NULL; guint flags; GMainLoop *loop; @@ -587,9 +587,9 @@ do_refcounting_test (gconstpointer data) last_request_validated = last_request_hit_network = FALSE; cancelled_requests = 0; - uri = soup_uri_new_with_base (base_uri, "/1"); + uri = g_uri_parse_relative (base_uri, "/1", SOUP_HTTP_URI_FLAGS, NULL); msg = soup_message_new_from_uri ("GET", uri); - soup_uri_free (uri); + g_uri_unref (uri); flags = SOUP_TEST_REQUEST_CANCEL_AFTER_SEND_FINISH | SOUP_TEST_REQUEST_CANCEL_MESSAGE; stream = soup_test_request_send (session, msg, NULL, flags, &error); @@ -624,7 +624,7 @@ do_refcounting_test (gconstpointer data) static void do_headers_test (gconstpointer data) { - SoupURI *base_uri = (SoupURI *)data; + GUri *base_uri = (GUri *)data; SoupSession *session; SoupMessageHeaders *headers; SoupCache *cache; @@ -702,7 +702,7 @@ count_cached_resources_in_dir (const char *cache_dir) static void do_leaks_test (gconstpointer data) { - SoupURI *base_uri = (SoupURI *)data; + GUri *base_uri = (GUri *)data; SoupSession *session; SoupCache *cache; char *cache_dir; @@ -761,7 +761,7 @@ int main (int argc, char **argv) { SoupServer *server; - SoupURI *base_uri; + GUri *base_uri; int ret; test_init (argc, argv, NULL); @@ -778,7 +778,7 @@ main (int argc, char **argv) ret = g_test_run (); - soup_uri_free (base_uri); + g_uri_unref (base_uri); soup_test_server_quit_unref (server); test_cleanup (); diff --git a/tests/chunk-io-test.c b/tests/chunk-io-test.c index 98df3ce5..62af7a64 100644 --- a/tests/chunk-io-test.c +++ b/tests/chunk-io-test.c @@ -10,7 +10,7 @@ force_io_streams_init (void) { SoupServer *server; SoupSession *session; - SoupURI *base_uri; + GUri *base_uri; SoupMessage *msg; /* Poke libsoup enough to cause SoupBodyInputStream and @@ -27,7 +27,7 @@ force_io_streams_init (void) g_object_unref (msg); soup_test_session_abort_unref (session); - soup_uri_free (base_uri); + g_uri_unref (base_uri); soup_test_server_quit_unref (server); } diff --git a/tests/coding-test.c b/tests/coding-test.c index d25dbd0d..0a1d553c 100644 --- a/tests/coding-test.c +++ b/tests/coding-test.c @@ -6,8 +6,8 @@ #include "test-utils.h" -SoupServer *server; -SoupURI *base_uri; +static SoupServer *server; +static GUri *base_uri; static void server_callback (SoupServer *server, @@ -161,11 +161,11 @@ setup_coding_test (CodingTestData *data, gconstpointer test_data) { CodingTestType test_type = GPOINTER_TO_INT (test_data); SoupMessage *msg; - SoupURI *uri; + GUri *uri; data->session = soup_test_session_new (NULL); - uri = soup_uri_new_with_base (base_uri, "/mbox"); + uri = g_uri_parse_relative (base_uri, "/mbox", SOUP_HTTP_URI_FLAGS, NULL); if (test_type & CODING_TEST_EMPTY) data->response = g_bytes_new_static (NULL, 0); @@ -176,7 +176,7 @@ setup_coding_test (CodingTestData *data, gconstpointer test_data) } data->msg = soup_message_new_from_uri ("GET", uri); - soup_uri_free (uri); + g_uri_unref (uri); if (test_type & CODING_TEST_NO_DECODER) soup_session_remove_feature_by_type (data->session, SOUP_TYPE_CONTENT_DECODER); @@ -373,7 +373,7 @@ main (int argc, char **argv) ret = g_test_run (); - soup_uri_free (base_uri); + g_uri_unref (base_uri); soup_test_server_quit_unref (server); test_cleanup (); diff --git a/tests/connection-test.c b/tests/connection-test.c index 834d5fb3..480b34c9 100644 --- a/tests/connection-test.c +++ b/tests/connection-test.c @@ -11,9 +11,9 @@ #include -SoupServer *server; -SoupURI *base_uri; -GMutex server_mutex; +static SoupServer *server; +static GUri *base_uri; +static GMutex server_mutex; static void forget_close (SoupServerMessage *msg, @@ -183,7 +183,7 @@ do_content_length_framing_test (void) { SoupSession *session; SoupMessage *msg; - SoupURI *request_uri; + GUri *request_uri; goffset declared_length; GBytes *body; @@ -192,7 +192,7 @@ do_content_length_framing_test (void) session = soup_test_session_new (NULL); debug_printf (1, " Content-Length larger than message body length\n"); - request_uri = soup_uri_new_with_base (base_uri, "/content-length/long"); + request_uri = g_uri_parse_relative (base_uri, "/content-length/long", SOUP_HTTP_URI_FLAGS, NULL); msg = soup_message_new_from_uri ("GET", request_uri); body = soup_test_session_send (session, msg, NULL, NULL); @@ -203,12 +203,12 @@ do_content_length_framing_test (void) (gulong)declared_length, (char *)g_bytes_get_data (body, NULL)); g_assert_cmpint (g_bytes_get_size (body), <, declared_length); - soup_uri_free (request_uri); + g_uri_unref (request_uri); g_bytes_unref (body); g_object_unref (msg); debug_printf (1, " Server claims 'Connection: close' but doesn't\n"); - request_uri = soup_uri_new_with_base (base_uri, "/content-length/noclose"); + request_uri = g_uri_parse_relative (base_uri, "/content-length/noclose", SOUP_HTTP_URI_FLAGS, NULL); msg = soup_message_new_from_uri ("GET", request_uri); body = soup_test_session_send (session, msg, NULL, NULL); @@ -217,7 +217,7 @@ do_content_length_framing_test (void) declared_length = soup_message_headers_get_content_length (soup_message_get_response_headers (msg)); g_assert_cmpint (g_bytes_get_size (body), ==, declared_length); - soup_uri_free (request_uri); + g_uri_unref (request_uri); g_bytes_unref (body); g_object_unref (msg); @@ -264,7 +264,7 @@ do_timeout_test_for_session (SoupSession *session) { SoupMessage *msg; GSocket *sockets[4] = { NULL, NULL, NULL, NULL }; - SoupURI *timeout_uri; + GUri *timeout_uri; int i; GBytes *body; @@ -273,9 +273,9 @@ do_timeout_test_for_session (SoupSession *session) &sockets); debug_printf (1, " First message\n"); - timeout_uri = soup_uri_new_with_base (base_uri, "/timeout-persistent"); + timeout_uri = g_uri_parse_relative (base_uri, "/timeout-persistent", SOUP_HTTP_URI_FLAGS, NULL); msg = soup_message_new_from_uri ("GET", timeout_uri); - soup_uri_free (timeout_uri); + g_uri_unref (timeout_uri); body = soup_test_session_send (session, msg, NULL, NULL); soup_test_assert_message_status (msg, SOUP_STATUS_OK); @@ -331,7 +331,7 @@ do_persistent_connection_timeout_test_with_cancellation (void) SoupSession *session; SoupMessage *msg; GSocket *sockets[4] = { NULL, NULL, NULL, NULL }; - SoupURI *timeout_uri; + GUri *timeout_uri; GCancellable *cancellable; GInputStream *response; int i; @@ -344,10 +344,10 @@ do_persistent_connection_timeout_test_with_cancellation (void) &sockets); debug_printf (1, " First message\n"); - timeout_uri = soup_uri_new_with_base (base_uri, "/timeout-persistent"); + timeout_uri = g_uri_parse_relative (base_uri, "/timeout-persistent", SOUP_HTTP_URI_FLAGS, NULL); msg = soup_message_new_from_uri ("GET", timeout_uri); cancellable = g_cancellable_new (); - soup_uri_free (timeout_uri); + g_uri_unref (timeout_uri); response = soup_session_send (session, msg, cancellable, NULL); soup_test_assert_message_status (msg, SOUP_STATUS_OK); @@ -941,7 +941,7 @@ main (int argc, char **argv) ret = g_test_run (); - soup_uri_free (base_uri); + g_uri_unref (base_uri); soup_test_server_quit_unref (server); test_cleanup (); diff --git a/tests/context-test.c b/tests/context-test.c index f6b761fc..9ffe279f 100644 --- a/tests/context-test.c +++ b/tests/context-test.c @@ -321,7 +321,7 @@ int main (int argc, char **argv) { SoupServer *server; - SoupURI *uri; + GUri *uri; int ret; test_init (argc, argv, NULL); @@ -329,8 +329,8 @@ main (int argc, char **argv) server = soup_test_server_new (SOUP_TEST_SERVER_IN_THREAD); soup_server_add_handler (server, NULL, server_callback, NULL, NULL); uri = soup_test_server_get_uri (server, "http", NULL); - base_uri = soup_uri_to_string (uri, FALSE); - soup_uri_free (uri); + base_uri = g_uri_to_string (uri); + g_uri_unref (uri); g_test_add_func ("/context/blocking/thread-default", do_test1); g_test_add_func ("/context/nested/thread-default", do_test2); diff --git a/tests/continue-test.c b/tests/continue-test.c index edd9786d..4fc662b2 100644 --- a/tests/continue-test.c +++ b/tests/continue-test.c @@ -10,7 +10,7 @@ #define MAX_POST_LENGTH (sizeof (SHORT_BODY)) -static SoupURI *base_uri; +static GUri *base_uri; static GSList *events; static void @@ -89,7 +89,7 @@ do_message (const char *path, gboolean long_body, SoupSession *session; SoupMessage *msg; const char *body; - SoupURI *uri; + GUri *uri, *msg_uri; va_list ap; const char *expected_event; char *actual_event; @@ -97,14 +97,15 @@ do_message (const char *path, gboolean long_body, GBytes *request_body; GBytes *response_body; - uri = soup_uri_copy (base_uri); - if (auth) { - soup_uri_set_user (uri, "user"); - soup_uri_set_password (uri, "pass"); - } - soup_uri_set_path (uri, path); - msg = soup_message_new_from_uri ("POST", uri); - soup_uri_free (uri); + if (auth) + uri = soup_uri_copy_with_credentials (base_uri, "user", "pass"); + else + uri = g_uri_ref (base_uri); + + msg_uri = g_uri_parse_relative (uri, path, SOUP_HTTP_URI_FLAGS, NULL); + msg = soup_message_new_from_uri ("POST", msg_uri); + g_uri_unref (uri); + g_uri_unref (msg_uri); body = long_body ? LONG_BODY : SHORT_BODY; request_body = g_bytes_new_static (body, strlen (body)); @@ -558,7 +559,7 @@ main (int argc, char **argv) ret = g_test_run (); soup_test_server_quit_unref (server); - soup_uri_free (base_uri); + g_uri_unref (base_uri); test_cleanup (); diff --git a/tests/cookies-test.c b/tests/cookies-test.c index fe215469..43cafc5e 100644 --- a/tests/cookies-test.c +++ b/tests/cookies-test.c @@ -5,10 +5,8 @@ #include "test-utils.h" -SoupServer *server; -SoupURI *first_party_uri, *third_party_uri; -const char *first_party = "http://127.0.0.1/"; -const char *third_party = "http://localhost/"; +static SoupServer *server; +static GUri *first_party_uri, *third_party_uri; static void server_callback (SoupServer *server, @@ -60,7 +58,7 @@ do_cookies_accept_policy_test (void) { SoupSession *session; SoupMessage *msg; - SoupURI *uri; + GUri *uri; SoupCookieJar *jar; GSList *l, *p; int i; @@ -76,26 +74,26 @@ do_cookies_accept_policy_test (void) * test_server, so let's swap first and third party here * to simulate a cookie coming from a third party. */ - uri = soup_uri_new_with_base (first_party_uri, "/foo.jpg"); + uri = g_uri_parse_relative (first_party_uri, "/foo.jpg", SOUP_HTTP_URI_FLAGS, NULL); msg = soup_message_new_from_uri ("GET", uri); soup_message_set_first_party (msg, third_party_uri); soup_test_session_send_message (session, msg); - soup_uri_free (uri); + g_uri_unref (uri); g_object_unref (msg); - uri = soup_uri_new_with_base (first_party_uri, "/index.html"); + uri = g_uri_parse_relative (first_party_uri, "/index.html", SOUP_HTTP_URI_FLAGS, NULL); msg = soup_message_new_from_uri ("GET", uri); soup_message_set_first_party (msg, first_party_uri); soup_test_session_send_message (session, msg); - soup_uri_free (uri); + g_uri_unref (uri); g_object_unref (msg); - + if (validResults[i].try_third_party_again) { - uri = soup_uri_new_with_base (first_party_uri, "/foo.jpg"); - msg = soup_message_new_from_uri ("GET", uri); + uri = g_uri_parse_relative (first_party_uri, "/foo.jpg", SOUP_HTTP_URI_FLAGS, NULL); + msg = soup_message_new_from_uri ("GET", uri); soup_message_set_first_party (msg, third_party_uri); soup_test_session_send_message (session, msg); - soup_uri_free (uri); + g_uri_unref (uri); g_object_unref (msg); } @@ -118,18 +116,18 @@ do_cookies_subdomain_policy_test (void) { SoupCookieJar *jar; GSList *cookies; - SoupURI *uri1; - SoupURI *uri2; - SoupURI *uri3; + GUri *uri1; + GUri *uri2; + GUri *uri3; g_test_bug ("792130"); /* Only the base domain should be considered when deciding * whether a cookie is a third-party cookie. */ - uri1 = soup_uri_new ("https://www.gnome.org"); - uri2 = soup_uri_new ("https://foundation.gnome.org"); - uri3 = soup_uri_new ("https://www.gnome.org."); + uri1 = g_uri_parse ("https://www.gnome.org", SOUP_HTTP_URI_FLAGS, NULL); + uri2 = g_uri_parse ("https://foundation.gnome.org", SOUP_HTTP_URI_FLAGS, NULL); + uri3 = g_uri_parse ("https://www.gnome.org.", SOUP_HTTP_URI_FLAGS, NULL); /* We can't check subdomains with a test server running on * localhost, so we'll just check the cookie jar API itself. @@ -239,9 +237,9 @@ do_cookies_subdomain_policy_test (void) g_assert_cmpint (g_slist_length (cookies), ==, 7); g_slist_free_full (cookies, (GDestroyNotify)soup_cookie_free); - soup_uri_free (uri1); - soup_uri_free (uri2); - soup_uri_free (uri3); + g_uri_unref (uri1); + g_uri_unref (uri2); + g_uri_unref (uri3); g_object_unref (jar); } @@ -250,11 +248,11 @@ do_cookies_strict_secure_test (void) { SoupCookieJar *jar; GSList *cookies; - SoupURI *insecure_uri; - SoupURI *secure_uri; + GUri *insecure_uri; + GUri *secure_uri; - insecure_uri = soup_uri_new ("http://gnome.org"); - secure_uri = soup_uri_new ("https://gnome.org"); + insecure_uri = g_uri_parse ("http://gnome.org", SOUP_HTTP_URI_FLAGS, NULL); + secure_uri = g_uri_parse ("https://gnome.org", SOUP_HTTP_URI_FLAGS, NULL); jar = soup_cookie_jar_new (); /* Set a cookie from secure origin */ @@ -283,8 +281,8 @@ do_cookies_strict_secure_test (void) g_assert_cmpint (g_slist_length (cookies), ==, 2); g_slist_free_full (cookies, (GDestroyNotify)soup_cookie_free); - soup_uri_free (insecure_uri); - soup_uri_free (secure_uri); + g_uri_unref (insecure_uri); + g_uri_unref (secure_uri); g_object_unref (jar); } @@ -373,18 +371,18 @@ static void do_get_cookies_empty_host_test (void) { SoupCookieJar *jar; - SoupURI *uri; + GUri *uri; char *cookies; jar = soup_cookie_jar_new (); - uri = soup_uri_new ("file:///whatever.html"); + uri = g_uri_parse ("file:///whatever.html", SOUP_HTTP_URI_FLAGS, NULL); cookies = soup_cookie_jar_get_cookies (jar, uri, FALSE); g_assert_null (cookies); g_object_unref (jar); - soup_uri_free (uri); + g_uri_unref (uri); } static void @@ -400,12 +398,12 @@ do_remove_feature_test (void) { SoupSession *session; SoupMessage *msg; - SoupURI *uri; + GUri *uri; GMainLoop *loop; session = soup_test_session_new (NULL); soup_session_add_feature_by_type (session, SOUP_TYPE_COOKIE_JAR); - uri = soup_uri_new_with_base (first_party_uri, "/index.html"); + uri = g_uri_parse_relative (first_party_uri, "/index.html", SOUP_HTTP_URI_FLAGS, NULL); msg = soup_message_new_from_uri ("GET", uri); soup_message_set_first_party (msg, first_party_uri); @@ -418,13 +416,13 @@ do_remove_feature_test (void) g_main_loop_unref (loop); g_object_unref (msg); - soup_uri_free (uri); + g_uri_unref (uri); } int main (int argc, char **argv) { - SoupURI *server_uri; + GUri *server_uri; int ret; test_init (argc, argv, NULL); @@ -433,10 +431,10 @@ main (int argc, char **argv) soup_server_add_handler (server, NULL, server_callback, NULL, NULL); server_uri = soup_test_server_get_uri (server, "http", NULL); - first_party_uri = soup_uri_new (first_party); - third_party_uri = soup_uri_new (third_party); - soup_uri_set_port (first_party_uri, server_uri->port); - soup_uri_set_port (third_party_uri, server_uri->port); + first_party_uri = g_uri_build (SOUP_HTTP_URI_FLAGS, "http", NULL, "127.0.0.1", + g_uri_get_port (server_uri), "/", NULL, NULL); + third_party_uri = g_uri_build (SOUP_HTTP_URI_FLAGS, "http", NULL, "localhost", + g_uri_get_port (server_uri), "/", NULL, NULL); g_test_add_func ("/cookies/accept-policy", do_cookies_accept_policy_test); g_test_add_func ("/cookies/accept-policy-subdomains", do_cookies_subdomain_policy_test); @@ -448,9 +446,9 @@ main (int argc, char **argv) ret = g_test_run (); - soup_uri_free (first_party_uri); - soup_uri_free (third_party_uri); - soup_uri_free (server_uri); + g_uri_unref (first_party_uri); + g_uri_unref (third_party_uri); + g_uri_unref (server_uri); soup_test_server_quit_unref (server); test_cleanup (); diff --git a/tests/forms-test.c b/tests/forms-test.c index cd0c8b96..803181fa 100644 --- a/tests/forms-test.c +++ b/tests/forms-test.c @@ -413,7 +413,7 @@ md5_post_callback (SoupServer *server, const char *fmt; char *filename, *md5sum, *redirect_uri; GBytes *file; - SoupURI *uri; + GUri *uri; SoupMultipart *multipart; GBytes *body; SoupMessageHeaders *request_headers; @@ -438,18 +438,17 @@ md5_post_callback (SoupServer *server, md5sum = g_compute_checksum_for_bytes (G_CHECKSUM_MD5, file); g_bytes_unref (file); - uri = soup_uri_copy (soup_server_message_get_uri (msg)); - soup_uri_set_query_from_fields (uri, - "file", filename ? filename : "", - "md5sum", md5sum, - "fmt", fmt ? fmt : "html", - NULL); - redirect_uri = soup_uri_to_string (uri, FALSE); + uri = soup_uri_copy_with_query_from_fields (soup_server_message_get_uri (msg), + "file", filename ? filename : "", + "md5sum", md5sum, + "fmt", fmt ? fmt : "html", + NULL); + redirect_uri = g_uri_to_string (uri); soup_server_message_set_redirect (msg, SOUP_STATUS_SEE_OTHER, redirect_uri); g_free (redirect_uri); - soup_uri_free (uri); + g_uri_unref (uri); g_free (md5sum); g_free (filename); g_hash_table_destroy (params); @@ -488,7 +487,7 @@ main (int argc, char **argv) { GMainLoop *loop; SoupServer *server; - SoupURI *base_uri, *uri; + GUri *base_uri, *uri; int ret = 0; test_init (argc, argv, no_test_entry); @@ -503,28 +502,28 @@ main (int argc, char **argv) loop = g_main_loop_new (NULL, TRUE); if (run_tests) { - uri = soup_uri_new_with_base (base_uri, "/hello"); - g_test_add_data_func_full ("/forms/hello/curl", soup_uri_to_string (uri, FALSE), do_hello_tests_curl, g_free); - g_test_add_data_func_full ("/forms/hello/libsoup", soup_uri_to_string (uri, FALSE), do_hello_tests_libsoup, g_free); - soup_uri_free (uri); + uri = g_uri_parse_relative (base_uri, "/hello", SOUP_HTTP_URI_FLAGS, NULL); + g_test_add_data_func_full ("/forms/hello/curl", g_uri_to_string (uri), do_hello_tests_curl, g_free); + g_test_add_data_func_full ("/forms/hello/libsoup", g_uri_to_string (uri), do_hello_tests_libsoup, g_free); + g_uri_unref (uri); - uri = soup_uri_new_with_base (base_uri, "/md5"); - g_test_add_data_func_full ("/forms/md5/curl", soup_uri_to_string (uri, FALSE), do_md5_test_curl, g_free); - g_test_add_data_func_full ("/forms/md5/libsoup", soup_uri_to_string (uri, FALSE), do_md5_test_libsoup, g_free); - soup_uri_free (uri); + uri = g_uri_parse_relative (base_uri, "/md5", SOUP_HTTP_URI_FLAGS, NULL); + g_test_add_data_func_full ("/forms/md5/curl", g_uri_to_string (uri), do_md5_test_curl, g_free); + g_test_add_data_func_full ("/forms/md5/libsoup", g_uri_to_string (uri), do_md5_test_libsoup, g_free); + g_uri_unref (uri); g_test_add_func ("/forms/decode", do_form_decode_test); ret = g_test_run (); } else { - g_print ("Listening on port %d\n", base_uri->port); + g_print ("Listening on port %d\n", g_uri_get_port (base_uri)); g_main_loop_run (loop); } g_main_loop_unref (loop); soup_test_server_quit_unref (server); - soup_uri_free (base_uri); + g_uri_unref (base_uri); if (run_tests) test_cleanup (); diff --git a/tests/hsts-db-test.c b/tests/hsts-db-test.c index f69d9267..176ad029 100644 --- a/tests/hsts-db-test.c +++ b/tests/hsts-db-test.c @@ -6,8 +6,8 @@ #define DB_FILE "hsts-db.sqlite" -SoupURI *http_uri; -SoupURI *https_uri; +GUri *http_uri; +GUri *https_uri; /* This server pseudo-implements the HSTS spec in order to allow us to test the Soup HSTS feature. @@ -25,13 +25,11 @@ server_callback (SoupServer *server, response_headers = soup_server_message_get_response_headers (msg); if (strcmp (server_protocol, "http") == 0) { - char *uri_string; - SoupURI *uri = soup_uri_new ("https://localhost"); - soup_uri_set_path (uri, path); - uri_string = soup_uri_to_string (uri, FALSE); + GUri *uri = g_uri_build (SOUP_HTTP_URI_FLAGS, "https", NULL, "localhost", -1, path, NULL, NULL); + char *uri_string = g_uri_to_string (uri); fprintf (stderr, "server is redirecting to HTTPS\n"); soup_server_message_set_redirect (msg, SOUP_STATUS_MOVED_PERMANENTLY, uri_string); - soup_uri_free (uri); + g_uri_unref (uri); g_free (uri_string); } else if (strcmp (server_protocol, "https") == 0) { soup_server_message_set_status (msg, SOUP_STATUS_OK, NULL); @@ -82,12 +80,15 @@ session_get_uri (SoupSession *session, const char *uri, SoupStatus expected_stat static void rewrite_message_uri (SoupMessage *msg) { - if (soup_uri_get_scheme (soup_message_get_uri (msg)) == SOUP_URI_SCHEME_HTTP) - soup_uri_set_port (soup_message_get_uri (msg), soup_uri_get_port (http_uri)); - else if (soup_uri_get_scheme (soup_message_get_uri (msg)) == SOUP_URI_SCHEME_HTTPS) - soup_uri_set_port (soup_message_get_uri (msg), soup_uri_get_port (https_uri)); + GUri *new_uri; + if (soup_uri_is_http (soup_message_get_uri (msg), NULL)) + new_uri = soup_test_uri_set_port (soup_message_get_uri (msg), g_uri_get_port (http_uri)); + else if (soup_uri_is_https (soup_message_get_uri (msg), NULL)) + new_uri = soup_test_uri_set_port (soup_message_get_uri (msg), g_uri_get_port (https_uri)); else g_assert_not_reached(); + soup_message_set_uri (msg, new_uri); + g_uri_unref (new_uri); } static void @@ -190,11 +191,11 @@ main (int argc, char **argv) ret = g_test_run (); - soup_uri_free (http_uri); + g_uri_unref (http_uri); soup_test_server_quit_unref (server); if (tls_available) { - soup_uri_free (https_uri); + g_uri_unref (https_uri); soup_test_server_quit_unref (https_server); } diff --git a/tests/hsts-test.c b/tests/hsts-test.c index 1dbd71cb..dad4dcf0 100644 --- a/tests/hsts-test.c +++ b/tests/hsts-test.c @@ -6,8 +6,8 @@ #include "test-utils.h" -SoupURI *http_uri; -SoupURI *https_uri; +GUri *http_uri; +GUri *https_uri; /* This server pseudo-implements the HSTS spec in order to allow us to test the Soup HSTS feature. @@ -31,12 +31,10 @@ server_callback (SoupServer *server, "max-age=31536000"); soup_server_message_set_status (msg, SOUP_STATUS_OK, NULL); } else { - char *uri_string; - SoupURI *uri = soup_uri_new ("https://localhost"); - soup_uri_set_path (uri, path); - uri_string = soup_uri_to_string (uri, FALSE); + GUri *uri = g_uri_build (SOUP_HTTP_URI_FLAGS, "https", NULL, "localhost", -1, path, NULL, NULL); + char *uri_string = g_uri_to_string (uri); soup_server_message_set_redirect (msg, SOUP_STATUS_MOVED_PERMANENTLY, uri_string); - soup_uri_free (uri); + g_uri_unref (uri); g_free (uri_string); } } else if (strcmp (server_protocol, "https") == 0) { @@ -128,12 +126,15 @@ session_get_uri (SoupSession *session, const char *uri, SoupStatus expected_stat static void rewrite_message_uri (SoupMessage *msg) { - if (soup_uri_get_scheme (soup_message_get_uri (msg)) == SOUP_URI_SCHEME_HTTP) - soup_uri_set_port (soup_message_get_uri (msg), soup_uri_get_port (http_uri)); - else if (soup_uri_get_scheme (soup_message_get_uri (msg)) == SOUP_URI_SCHEME_HTTPS) - soup_uri_set_port (soup_message_get_uri (msg), soup_uri_get_port (https_uri)); + GUri *new_uri; + if (soup_uri_is_http (soup_message_get_uri (msg), NULL)) + new_uri = soup_test_uri_set_port (soup_message_get_uri (msg), g_uri_get_port (http_uri)); + else if (soup_uri_is_https (soup_message_get_uri (msg), NULL)) + new_uri = soup_test_uri_set_port (soup_message_get_uri (msg), g_uri_get_port (https_uri)); else g_assert_not_reached(); + soup_message_set_uri (msg, new_uri); + g_uri_unref (new_uri); } static void @@ -604,11 +605,11 @@ main (int argc, char **argv) ret = g_test_run (); - soup_uri_free (http_uri); + g_uri_unref (http_uri); soup_test_server_quit_unref (server); if (tls_available) { - soup_uri_free (https_uri); + g_uri_unref (https_uri); soup_test_server_quit_unref (https_server); } diff --git a/tests/misc-test.c b/tests/misc-test.c index 1a45a20c..a9df51ae 100644 --- a/tests/misc-test.c +++ b/tests/misc-test.c @@ -8,7 +8,7 @@ #include "soup-session-private.h" SoupServer *server, *ssl_server; -SoupURI *base_uri, *ssl_base_uri; +GUri *base_uri, *ssl_base_uri; static gboolean auth_callback (SoupAuthDomain *auth_domain, SoupMessage *msg, @@ -36,7 +36,7 @@ server_callback (SoupServer *server, SoupMessageHeaders *request_headers; SoupMessageHeaders *response_headers; const char *method = soup_server_message_get_method (msg); - SoupURI *uri = soup_server_message_get_uri (msg); + GUri *uri = soup_server_message_get_uri (msg); const char *server_protocol = data; if (method != SOUP_METHOD_GET && method != SOUP_METHOD_POST) { @@ -53,24 +53,24 @@ server_callback (SoupServer *server, response_headers = soup_server_message_get_response_headers (msg); if (!strcmp (path, "/alias-redirect")) { - SoupURI *redirect_uri; + GUri *redirect_uri; char *redirect_string; const char *redirect_protocol; + int redirect_port; redirect_protocol = soup_message_headers_get_one (request_headers, "X-Redirect-Protocol"); - - redirect_uri = soup_uri_copy (uri); - soup_uri_set_scheme (redirect_uri, "foo"); if (!g_strcmp0 (redirect_protocol, "https")) - soup_uri_set_port (redirect_uri, ssl_base_uri->port); + redirect_port = g_uri_get_port (ssl_base_uri); else - soup_uri_set_port (redirect_uri, base_uri->port); - soup_uri_set_path (redirect_uri, "/alias-redirected"); - redirect_string = soup_uri_to_string (redirect_uri, FALSE); + redirect_port = g_uri_get_port (base_uri); + + redirect_uri = g_uri_build (SOUP_HTTP_URI_FLAGS, "foo", NULL, g_uri_get_host (uri), redirect_port, + "/alias-redirected", NULL, NULL); + redirect_string = g_uri_to_string (redirect_uri); soup_server_message_set_redirect (msg, SOUP_STATUS_FOUND, redirect_string); g_free (redirect_string); - soup_uri_free (redirect_uri); + g_uri_unref (redirect_uri); return; } else if (!strcmp (path, "/alias-redirected")) { soup_server_message_set_status (msg, SOUP_STATUS_OK, NULL); @@ -90,9 +90,9 @@ server_callback (SoupServer *server, } soup_server_message_set_status (msg, SOUP_STATUS_OK, NULL); - if (!strcmp (uri->host, "foo")) { + if (!strcmp (g_uri_get_host (uri), "foo")) { soup_server_message_set_response (msg, "text/plain", - SOUP_MEMORY_STATIC, "foo-index", 9); + SOUP_MEMORY_STATIC, "foo-index", 9); return; } else { soup_server_message_set_response (msg, "text/plain", @@ -205,7 +205,7 @@ do_callback_unref_test (void) SoupSession *session; SoupMessage *one, *two; GMainLoop *loop; - SoupURI *bad_uri; + GUri *bad_uri; g_test_bug ("533473"); @@ -227,7 +227,7 @@ do_callback_unref_test (void) g_signal_connect (two, "finished", G_CALLBACK (cu_two_completed), loop); g_object_add_weak_pointer (G_OBJECT (two), (gpointer *)&two); - soup_uri_free (bad_uri); + g_uri_unref (bad_uri); soup_session_send_async (session, one, G_PRIORITY_DEFAULT, NULL, NULL, NULL); soup_session_send_async (session, two, G_PRIORITY_DEFAULT, NULL, NULL, NULL); @@ -296,7 +296,7 @@ do_msg_reuse_test (void) { SoupSession *session; SoupMessage *msg; - SoupURI *uri; + GUri *uri; guint *signal_ids, n_signal_ids; g_test_bug ("559054"); @@ -313,23 +313,19 @@ do_msg_reuse_test (void) ensure_no_signal_handlers (msg, signal_ids, n_signal_ids); debug_printf (1, " Redirect message\n"); - uri = soup_uri_new_with_base (base_uri, "/redirect"); + uri = g_uri_parse_relative (base_uri, "/redirect", SOUP_HTTP_URI_FLAGS, NULL); soup_message_set_uri (msg, uri); - soup_uri_free (uri); + g_uri_unref (uri); soup_test_session_async_send (session, msg); g_assert_true (soup_uri_equal (soup_message_get_uri (msg), base_uri)); ensure_no_signal_handlers (msg, signal_ids, n_signal_ids); debug_printf (1, " Auth message\n"); - uri = soup_uri_new_with_base (base_uri, "/auth"); + uri = g_uri_parse_relative (base_uri, "/auth", SOUP_HTTP_URI_FLAGS, NULL); soup_message_set_uri (msg, uri); - soup_uri_free (uri); + g_uri_unref (uri); soup_test_session_async_send (session, msg); soup_test_assert_message_status (msg, SOUP_STATUS_OK); - ensure_no_signal_handlers (msg, signal_ids, n_signal_ids); - - /* One last try to make sure the auth stuff got cleaned up */ - debug_printf (1, " Last message\n"); soup_message_set_uri (msg, base_uri); soup_test_session_async_send (session, msg); ensure_no_signal_handlers (msg, signal_ids, n_signal_ids); @@ -507,12 +503,12 @@ static void do_cancel_while_reading_test_for_session (SoupSession *session) { SoupMessage *msg; - SoupURI *uri; + GUri *uri; gboolean done = FALSE; - uri = soup_uri_new_with_base (base_uri, "/slow"); + uri = g_uri_parse_relative (base_uri, "/slow", SOUP_HTTP_URI_FLAGS, NULL); msg = soup_message_new_from_uri ("GET", uri); - soup_uri_free (uri); + g_uri_unref (uri); g_object_set_data (G_OBJECT (msg), "session", session); g_object_ref (msg); @@ -551,13 +547,13 @@ do_cancel_while_reading_req_test_for_session (SoupSession *session, guint flags) { SoupMessage *msg; - SoupURI *uri; + GUri *uri; GCancellable *cancellable; GError *error = NULL; - uri = soup_uri_new_with_base (base_uri, "/slow"); + uri = g_uri_parse_relative (base_uri, "/slow", SOUP_HTTP_URI_FLAGS, NULL); msg = soup_message_new_from_uri ("GET", uri); - soup_uri_free (uri); + g_uri_unref (uri); cancellable = g_cancellable_new (); soup_test_request_send (session, msg, cancellable, flags, &error); @@ -616,14 +612,14 @@ do_aliases_test_for_session (SoupSession *session, const char *redirect_protocol) { SoupMessage *msg; - SoupURI *uri; + GUri *uri; const char *redirected_protocol; - uri = soup_uri_new_with_base (base_uri, "/alias-redirect"); + uri = g_uri_parse_relative (base_uri, "/alias-redirect", SOUP_HTTP_URI_FLAGS, NULL); msg = soup_message_new_from_uri ("GET", uri); if (redirect_protocol) soup_message_headers_append (soup_message_get_request_headers (msg), "X-Redirect-Protocol", redirect_protocol); - soup_uri_free (uri); + g_uri_unref (uri); soup_test_session_send_message (session, msg); redirected_protocol = soup_message_headers_get_one (soup_message_get_response_headers (msg), "X-Redirected-Protocol"); @@ -756,11 +752,11 @@ main (int argc, char **argv) ret = g_test_run (); - soup_uri_free (base_uri); + g_uri_unref (base_uri); soup_test_server_quit_unref (server); if (tls_available) { - soup_uri_free (ssl_base_uri); + g_uri_unref (ssl_base_uri); soup_test_server_quit_unref (ssl_server); } diff --git a/tests/multipart-test.c b/tests/multipart-test.c index 8450972d..c6c3b0e5 100644 --- a/tests/multipart-test.c +++ b/tests/multipart-test.c @@ -25,7 +25,7 @@ typedef enum { char *buffer; SoupSession *session; char *base_uri_string; -SoupURI *base_uri; +GUri *base_uri; SoupMultipartInputStream *multipart; unsigned passes; GMainLoop *loop; @@ -484,7 +484,7 @@ main (int argc, char **argv) server = soup_test_server_new (SOUP_TEST_SERVER_DEFAULT); soup_server_add_handler (server, NULL, server_callback, NULL, NULL); base_uri = soup_test_server_get_uri (server, "http", NULL); - base_uri_string = soup_uri_to_string (base_uri, FALSE); + base_uri_string = g_uri_to_string (base_uri); /* FIXME: I had to raise the number of connections allowed here, otherwise I * was hitting the limit, which indicates some connections are not dying. @@ -501,7 +501,7 @@ main (int argc, char **argv) ret = g_test_run (); - soup_uri_free (base_uri); + g_uri_unref (base_uri); g_free (base_uri_string); g_free (buffer); diff --git a/tests/no-ssl-test.c b/tests/no-ssl-test.c index 76bec5d3..a5b9442d 100644 --- a/tests/no-ssl-test.c +++ b/tests/no-ssl-test.c @@ -3,7 +3,7 @@ #include "test-utils.h" static void -do_ssl_test_for_session (SoupSession *session, SoupURI *uri) +do_ssl_test_for_session (SoupSession *session, GUri *uri) { SoupMessage *msg; @@ -20,7 +20,7 @@ do_ssl_test_for_session (SoupSession *session, SoupURI *uri) static void do_ssl_tests (gconstpointer data) { - SoupURI *uri = (SoupURI *)data; + GUri *uri = (GUri *)data; SoupSession *session; g_test_bug ("700518"); @@ -43,12 +43,30 @@ server_handler (SoupServer *server, "ok\r\n", 4); } +static GUri * +uri_set_scheme (GUri *uri, const char *scheme) +{ + GUri *new_uri = g_uri_build_with_user ( + g_uri_get_flags (uri), + scheme, + g_uri_get_user (uri), + g_uri_get_password (uri), + g_uri_get_auth_params (uri), + g_uri_get_host (uri), + g_uri_get_port (uri), + g_uri_get_path (uri), + g_uri_get_query (uri), + g_uri_get_fragment (uri) + ); + g_uri_unref (uri); + return new_uri; +} + int main (int argc, char **argv) { SoupServer *server; - SoupURI *uri; - guint port; + GUri *uri; int ret; /* Force this test to use the dummy TLS backend */ @@ -63,15 +81,13 @@ main (int argc, char **argv) server = soup_test_server_new (TRUE); soup_server_add_handler (server, NULL, server_handler, NULL, NULL); uri = soup_test_server_get_uri (server, "http", NULL); - port = uri->port; - soup_uri_set_scheme (uri, SOUP_URI_SCHEME_HTTPS); - soup_uri_set_port (uri, port); + uri = uri_set_scheme (uri, "https"); g_test_add_data_func ("/no-ssl/request-error", uri, do_ssl_tests); ret = g_test_run (); - soup_uri_free (uri); + g_uri_unref (uri); soup_test_server_quit_unref (server); test_cleanup (); diff --git a/tests/ntlm-test.c b/tests/ntlm-test.c index d5b3f33e..a40ebd37 100644 --- a/tests/ntlm-test.c +++ b/tests/ntlm-test.c @@ -43,7 +43,7 @@ static const char *state_name[] = { typedef struct { SoupServer *server; GHashTable *connections; - SoupURI *uri; + GUri *uri; gboolean ntlmssp; gboolean ntlmv2; } TestServer; @@ -200,7 +200,7 @@ static void teardown_server (TestServer *ts, gconstpointer test_data) { - soup_uri_free (ts->uri); + g_uri_unref (ts->uri); soup_test_server_quit_unref (ts->server); g_hash_table_destroy (ts->connections); } @@ -318,7 +318,7 @@ response_check (SoupMessage *msg, gpointer user_data) static void do_message (SoupSession *session, - SoupURI *base_uri, + GUri *base_uri, const char *path, const char *user, gboolean get_ntlm_prompt, @@ -327,14 +327,14 @@ do_message (SoupSession *session, gboolean do_basic, guint status_code) { - SoupURI *uri; + GUri *uri; SoupMessage *msg; GBytes *body; NTLMState state = { FALSE, FALSE, FALSE, FALSE }; - uri = soup_uri_new_with_base (base_uri, path); + uri = g_uri_parse_relative (base_uri, path, SOUP_HTTP_URI_FLAGS, NULL); msg = soup_message_new_from_uri ("GET", uri); - soup_uri_free (uri); + g_uri_unref (uri); if (user) { g_signal_connect (msg, "authenticate", @@ -413,7 +413,7 @@ do_message (SoupSession *session, } static void -do_ntlm_round (SoupURI *base_uri, gboolean use_ntlm, +do_ntlm_round (GUri *base_uri, gboolean use_ntlm, const char *user, gboolean use_builtin_ntlm) { SoupSession *session; @@ -662,7 +662,7 @@ do_retrying_test (TestServer *ts, { SoupSession *session; SoupMessage *msg; - SoupURI *uri; + GUri *uri; GBytes *body; gboolean retried = FALSE; @@ -675,11 +675,11 @@ do_retrying_test (TestServer *ts, session = soup_test_session_new (NULL); soup_session_add_feature_by_type (session, SOUP_TYPE_AUTH_NTLM); - uri = soup_uri_new_with_base (ts->uri, "/alice"); + uri = g_uri_parse_relative (ts->uri, "/alice", SOUP_HTTP_URI_FLAGS, NULL); msg = soup_message_new_from_uri ("GET", uri); g_signal_connect (msg, "authenticate", G_CALLBACK (retry_test_authenticate), &retried); - soup_uri_free (uri); + g_uri_unref (uri); body = soup_test_session_send (session, msg, NULL, NULL); @@ -696,11 +696,12 @@ do_retrying_test (TestServer *ts, session = soup_test_session_new (NULL); soup_session_add_feature_by_type (session, SOUP_TYPE_AUTH_NTLM); retried = FALSE; - uri = soup_uri_new_with_base (ts->uri, "/bob"); + + uri = g_uri_parse_relative (ts->uri, "/bob", SOUP_HTTP_URI_FLAGS, NULL); msg = soup_message_new_from_uri ("GET", uri); g_signal_connect (msg, "authenticate", G_CALLBACK (retry_test_authenticate), &retried); - soup_uri_free (uri); + g_uri_unref (uri); body = soup_test_session_send (session, msg, NULL, NULL); diff --git a/tests/proxy-test.c b/tests/proxy-test.c index 7689b99a..4d0f5a58 100644 --- a/tests/proxy-test.c +++ b/tests/proxy-test.c @@ -59,10 +59,10 @@ authenticate (SoupMessage *msg, g_free (uri); g_assert_true (found); } else { - SoupURI *uri = soup_message_get_uri (msg); + GUri *uri = soup_message_get_uri (msg); char *authority; - authority = g_strdup_printf ("%s:%d", uri->host, uri->port); + authority = g_strdup_printf ("%s:%d", g_uri_get_host (uri), g_uri_get_port (uri)); g_assert_cmpstr (authority, ==, soup_auth_get_authority (auth)); g_free (authority); } @@ -154,18 +154,21 @@ do_proxy_test (SoupProxyTest *test) g_test_bug (test->bugref); if (!strncmp (test->url, "http", 4)) { - SoupURI *uri; - guint port; + GUri *http_uri, *https_uri; + int port; http_url = g_strdup (test->url); - uri = soup_uri_new (test->url); - port = uri->port; - soup_uri_set_scheme (uri, "https"); - if (port) - soup_uri_set_port (uri, port + 1); - https_url = soup_uri_to_string (uri, FALSE); - soup_uri_free (uri); + http_uri = g_uri_parse (test->url, SOUP_HTTP_URI_FLAGS, NULL); + port = g_uri_get_port (http_uri); + if (port != -1) + port += 1; + https_uri = g_uri_build (SOUP_HTTP_URI_FLAGS, "https", NULL, g_uri_get_host (http_uri), + port, g_uri_get_path (http_uri), + g_uri_get_query (http_uri), g_uri_get_fragment (http_uri)); + https_url = g_uri_to_string (https_uri); + g_uri_unref (http_uri); + g_uri_unref (https_uri); } else { http_url = g_strconcat (HTTP_SERVER, test->url, NULL); https_url = g_strconcat (HTTPS_SERVER, test->url, NULL); @@ -202,17 +205,17 @@ server_callback (SoupServer *server, GHashTable *query, gpointer data) { - SoupURI *uri = soup_server_message_get_uri (msg); + GUri *uri = soup_server_message_get_uri (msg); - soup_server_message_set_status (msg, uri->fragment ? SOUP_STATUS_BAD_REQUEST : SOUP_STATUS_OK, NULL); + soup_server_message_set_status (msg, g_uri_get_fragment (uri) ? SOUP_STATUS_BAD_REQUEST : SOUP_STATUS_OK, NULL); } static void do_proxy_fragment_test (gconstpointer data) { - SoupURI *base_uri = (SoupURI *)data; + GUri *base_uri = (GUri *)data; SoupSession *session; - SoupURI *req_uri; + GUri *req_uri; SoupMessage *msg; SOUP_TEST_SKIP_IF_NO_APACHE; @@ -220,9 +223,9 @@ do_proxy_fragment_test (gconstpointer data) session = soup_test_session_new ("proxy-resolver", proxy_resolvers[SIMPLE_PROXY], NULL); - req_uri = soup_uri_new_with_base (base_uri, "/#foo"); + req_uri = g_uri_parse_relative (base_uri, "/#foo", SOUP_HTTP_URI_FLAGS, NULL); msg = soup_message_new_from_uri (SOUP_METHOD_GET, req_uri); - soup_uri_free (req_uri); + g_uri_unref (req_uri); soup_test_session_send_message (session, msg); soup_test_assert_message_status (msg, SOUP_STATUS_OK); @@ -235,7 +238,7 @@ static void do_proxy_redirect_test (void) { SoupSession *session; - SoupURI *req_uri, *new_uri; + GUri *base_uri, *req_uri, *new_uri; SoupMessage *msg; g_test_bug ("631368"); @@ -246,17 +249,18 @@ do_proxy_redirect_test (void) session = soup_test_session_new ("proxy-resolver", proxy_resolvers[SIMPLE_PROXY], NULL); - req_uri = soup_uri_new (HTTPS_SERVER); - soup_uri_set_path (req_uri, "/redirected"); + base_uri = g_uri_parse (HTTPS_SERVER, SOUP_HTTP_URI_FLAGS, NULL); + req_uri = g_uri_parse_relative (base_uri, "/redirected", SOUP_HTTP_URI_FLAGS, NULL); msg = soup_message_new_from_uri (SOUP_METHOD_GET, req_uri); soup_message_headers_append (soup_message_get_request_headers (msg), "Connection", "close"); soup_test_session_send_message (session, msg); new_uri = soup_message_get_uri (msg); - soup_test_assert (strcmp (req_uri->path, new_uri->path) != 0, + soup_test_assert (strcmp (g_uri_get_path (req_uri), g_uri_get_path (new_uri)) != 0, "message was not redirected"); - soup_uri_free (req_uri); + g_uri_unref (req_uri); + g_uri_unref (base_uri); soup_test_assert_message_status (msg, SOUP_STATUS_OK); @@ -340,7 +344,7 @@ int main (int argc, char **argv) { SoupServer *server; - SoupURI *base_uri; + GUri *base_uri; char *path; int i, ret; @@ -368,7 +372,7 @@ main (int argc, char **argv) ret = g_test_run (); - soup_uri_free (base_uri); + g_uri_unref (base_uri); soup_test_server_quit_unref (server); for (i = 0; i < 3; i++) g_object_unref (proxy_resolvers[i]); diff --git a/tests/range-test.c b/tests/range-test.c index 39eb8353..cc050720 100644 --- a/tests/range-test.c +++ b/tests/range-test.c @@ -364,7 +364,7 @@ do_libsoup_range_test (void) { SoupSession *session; SoupServer *server; - SoupURI *base_uri; + GUri *base_uri; char *base_uri_str; session = soup_test_session_new (NULL); @@ -372,9 +372,9 @@ do_libsoup_range_test (void) server = soup_test_server_new (SOUP_TEST_SERVER_DEFAULT); soup_server_add_handler (server, NULL, server_handler, NULL, NULL); base_uri = soup_test_server_get_uri (server, "http", NULL); - base_uri_str = soup_uri_to_string (base_uri, FALSE); + base_uri_str = g_uri_to_string (base_uri); do_range_test (session, base_uri_str, TRUE, TRUE); - soup_uri_free (base_uri); + g_uri_unref (base_uri); g_free (base_uri_str); soup_test_server_quit_unref (server); diff --git a/tests/redirect-test.c b/tests/redirect-test.c index 46c931ee..615da0fe 100644 --- a/tests/redirect-test.c +++ b/tests/redirect-test.c @@ -5,7 +5,7 @@ #include "test-utils.h" -SoupURI *base_uri; +GUri *base_uri; char *server2_uri; SoupSession *async_session; @@ -143,9 +143,9 @@ static void restarted (SoupMessage *msg, gpointer user_data) { TestRequest **treq = user_data; - SoupURI *uri = soup_message_get_uri (msg); + GUri *uri = soup_message_get_uri (msg); - debug_printf (2, " %s %s\n", soup_message_get_method (msg), uri->path); + debug_printf (2, " %s %s\n", soup_message_get_method (msg), g_uri_get_path (uri)); if ((*treq)->method && !(*treq)->repeat) (*treq)++; @@ -154,13 +154,13 @@ restarted (SoupMessage *msg, gpointer user_data) "Expected to be done"); g_assert_cmpstr (soup_message_get_method (msg), ==, (*treq)->method); - g_assert_cmpstr (uri->path, ==, (*treq)->path); + g_assert_cmpstr (g_uri_get_path (uri), ==, (*treq)->path); } static void do_message_api_test (SoupSession *session, TestCase *test) { - SoupURI *uri; + GUri *uri; SoupMessage *msg; GBytes *body; TestRequest *treq; @@ -168,9 +168,9 @@ do_message_api_test (SoupSession *session, TestCase *test) if (test->bugref) g_test_bug (test->bugref); - uri = soup_uri_new_with_base (base_uri, test->requests[0].path); - msg = soup_message_new_from_uri (test->requests[0].method, uri); - soup_uri_free (uri); + uri = g_uri_parse_relative (base_uri, test->requests[0].path, SOUP_HTTP_URI_FLAGS | G_URI_FLAGS_PARSE_RELAXED, NULL); + msg = soup_message_new_from_uri (test->requests[0].method, uri); + g_uri_unref (uri); if (soup_message_get_method (msg) == SOUP_METHOD_POST) { GBytes *request_body; @@ -314,7 +314,7 @@ main (int argc, char **argv) { GMainLoop *loop; SoupServer *server, *server2; - SoupURI *uri2; + GUri *uri2, *uri2_with_path; char *path; int n, ret; @@ -329,9 +329,10 @@ main (int argc, char **argv) soup_server_add_handler (server2, NULL, server2_callback, NULL, NULL); uri2 = soup_test_server_get_uri (server2, "http", NULL); - soup_uri_set_path (uri2, "/on-server2"); - server2_uri = soup_uri_to_string (uri2, FALSE); - soup_uri_free (uri2); + uri2_with_path = g_uri_parse_relative (uri2, "/on-server2", SOUP_HTTP_URI_FLAGS, NULL); + g_uri_unref (uri2); + server2_uri = g_uri_to_string (uri2_with_path); + g_uri_unref (uri2_with_path); loop = g_main_loop_new (NULL, TRUE); @@ -348,7 +349,7 @@ main (int argc, char **argv) ret = g_test_run (); g_main_loop_unref (loop); - soup_uri_free (base_uri); + g_uri_unref (base_uri); soup_test_server_quit_unref (server); g_free (server2_uri); soup_test_server_quit_unref (server2); diff --git a/tests/request-body-test.c b/tests/request-body-test.c index 26c56fc6..b2b6335b 100644 --- a/tests/request-body-test.c +++ b/tests/request-body-test.c @@ -8,7 +8,7 @@ #include "soup-message-private.h" static SoupSession *session; -static SoupURI *base_uri; +static GUri *base_uri; typedef struct { SoupSession *session; @@ -89,16 +89,16 @@ static void do_request_test (gconstpointer data) { RequestTestFlags flags = GPOINTER_TO_UINT (data); - SoupURI *uri; + GUri *uri; PutTestData ptd; SoupMessage *msg; const char *client_md5, *server_md5; GChecksum *check; if (flags & RESTART) - uri = soup_uri_new_with_base (base_uri, "/redirect"); + uri = g_uri_parse_relative (base_uri, "/redirect", SOUP_HTTP_URI_FLAGS, NULL); else - uri = soup_uri_copy (base_uri); + uri = g_uri_ref (base_uri); ptd.session = session; check = setup_request_body (&ptd, flags); @@ -133,8 +133,7 @@ do_request_test (gconstpointer data) g_clear_object (&ptd.stream); g_object_unref (msg); g_checksum_free (check); - - soup_uri_free (uri); + g_uri_unref (uri); } static void @@ -203,7 +202,7 @@ main (int argc, char **argv) soup_test_session_abort_unref (session); - soup_uri_free (base_uri); + g_uri_unref (base_uri); g_main_loop_unref (loop); soup_test_server_quit_unref (server); diff --git a/tests/samesite-test.c b/tests/samesite-test.c index 0b081b2b..aed12aa0 100644 --- a/tests/samesite-test.c +++ b/tests/samesite-test.c @@ -3,8 +3,8 @@ #include "test-utils.h" typedef struct { - SoupURI *origin_uri; - SoupURI *cross_uri; + GUri *origin_uri; + GUri *cross_uri; SoupCookieJar *jar; GSList *cookies; } SameSiteFixture; @@ -15,8 +15,8 @@ same_site_setup (SameSiteFixture *fixture, { SoupCookie *cookie_none, *cookie_lax, *cookie_strict; - fixture->origin_uri = soup_uri_new ("http://127.0.0.1"); - fixture->cross_uri = soup_uri_new ("http://localhost"); + fixture->origin_uri = g_uri_parse ("http://127.0.0.1", SOUP_HTTP_URI_FLAGS, NULL); + fixture->cross_uri = g_uri_parse ("http://localhost", SOUP_HTTP_URI_FLAGS, NULL); fixture->jar = soup_cookie_jar_new (); cookie_none = soup_cookie_new ("none", "1", "127.0.0.1", "/", 1000); @@ -35,8 +35,8 @@ same_site_teardown (SameSiteFixture *fixture, gconstpointer data) { g_object_unref (fixture->jar); - soup_uri_free (fixture->origin_uri); - soup_uri_free (fixture->cross_uri); + g_uri_unref (fixture->origin_uri); + g_uri_unref (fixture->cross_uri); g_slist_free_full (fixture->cookies, (GDestroyNotify) soup_cookie_free); } diff --git a/tests/server-auth-test.c b/tests/server-auth-test.c index 0d57c88c..41985a77 100644 --- a/tests/server-auth-test.c +++ b/tests/server-auth-test.c @@ -5,7 +5,7 @@ #include "test-utils.h" -static SoupURI *base_uri; +static GUri *base_uri; static struct { gboolean client_sent_basic, client_sent_digest; @@ -23,26 +23,24 @@ curl_exited (GPid pid, int status, gpointer data) } static void -do_test (SoupURI *base_uri, const char *path, +do_test (GUri *base_uri, const char *path, gboolean good_user, gboolean good_password, gboolean offer_basic, gboolean offer_digest, gboolean client_sends_basic, gboolean client_sends_digest, gboolean server_requests_basic, gboolean server_requests_digest, gboolean success) { - SoupURI *uri; + GUri *uri; char *uri_str; GPtrArray *args; GPid pid; gboolean done; - /* We build the URI this way to avoid having soup_uri_new() - normalize the path, hence losing the encoded characters in - tests 4. and 5. below. */ - uri = soup_uri_copy (base_uri); - soup_uri_set_path (uri, path); - uri_str = soup_uri_to_string (uri, FALSE); - soup_uri_free (uri); + /* Note that we purposefully do not pass G_URI_FLAGS_ENCODED_PATH here which would lose + the encoded characters in tests 4. and 5. below. */ + uri = g_uri_parse_relative (base_uri, path, G_URI_FLAGS_NONE, NULL); + uri_str = g_uri_to_string (uri); + g_uri_unref (uri); args = g_ptr_array_new (); g_ptr_array_add (args, "curl"); @@ -399,11 +397,11 @@ main (int argc, char **argv) ret = g_test_run (); } else { - g_print ("Listening on port %d\n", base_uri->port); + g_print ("Listening on port %d\n", g_uri_get_port (base_uri)); g_main_loop_run (loop); ret = 0; } - soup_uri_free (base_uri); + g_uri_unref (base_uri); g_main_loop_unref (loop); soup_test_server_quit_unref (server); diff --git a/tests/server-test.c b/tests/server-test.c index c0a73e9c..9cc16612 100644 --- a/tests/server-test.c +++ b/tests/server-test.c @@ -9,7 +9,7 @@ typedef struct { SoupServer *server; - SoupURI *base_uri, *ssl_base_uri; + GUri *base_uri, *ssl_base_uri; GSList *handlers; } ServerData; @@ -90,8 +90,8 @@ server_teardown (ServerData *sd, gconstpointer test_data) g_slist_free_full (sd->handlers, g_free); g_clear_pointer (&sd->server, soup_test_server_quit_unref); - g_clear_pointer (&sd->base_uri, soup_uri_free); - g_clear_pointer (&sd->ssl_base_uri, soup_uri_free); + g_clear_pointer (&sd->base_uri, g_uri_unref); + g_clear_pointer (&sd->ssl_base_uri, g_uri_unref); } static void @@ -126,14 +126,16 @@ do_star_test (ServerData *sd, gconstpointer test_data) { SoupSession *session; SoupMessage *msg; - SoupURI *star_uri; + 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 = soup_uri_copy (sd->base_uri); - soup_uri_set_path (star_uri, "*"); + 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); @@ -158,11 +160,11 @@ do_star_test (ServerData *sd, gconstpointer test_data) g_object_unref (msg); soup_test_session_abort_unref (session); - soup_uri_free (star_uri); + g_uri_unref (star_uri); } static void -do_one_server_aliases_test (SoupURI *uri, +do_one_server_aliases_test (GUri *uri, const char *alias, gboolean succeed) { @@ -175,18 +177,18 @@ do_one_server_aliases_test (SoupURI *uri, GString *req; static char buf[1024]; - debug_printf (1, " %s via %s\n", alias, uri->scheme); + debug_printf (1, " %s via %s\n", alias, g_uri_get_scheme (uri)); /* There's no way to make libsoup's client side send an absolute * URI (to a non-proxy server), so we have to fake this. */ client = g_socket_client_new (); - if (uri->scheme == SOUP_URI_SCHEME_HTTPS) { + if (soup_uri_is_https (uri, NULL)) { g_socket_client_set_tls (client, TRUE); g_socket_client_set_tls_validation_flags (client, 0); } - addr = g_network_address_new (uri->host, uri->port); + addr = g_network_address_new (g_uri_get_host (uri), g_uri_get_port (uri)); conn = g_socket_client_connect (client, addr, NULL, &error); g_object_unref (addr); @@ -202,9 +204,9 @@ do_one_server_aliases_test (SoupURI *uri, req = g_string_new (NULL); g_string_append_printf (req, "GET %s://%s:%d HTTP/1.1\r\n", - alias, uri->host, uri->port); + alias, g_uri_get_host (uri), g_uri_get_port (uri)); g_string_append_printf (req, "Host: %s:%d\r\n", - uri->host, uri->port); + g_uri_get_host (uri), g_uri_get_port (uri)); g_string_append (req, "Connection: close\r\n\r\n"); if (!g_output_stream_write_all (out, req->str, req->len, NULL, NULL, &error)) { @@ -268,80 +270,80 @@ do_dot_dot_test (ServerData *sd, gconstpointer test_data) { SoupSession *session; SoupMessage *msg; - SoupURI *uri; + GUri *uri; g_test_bug ("667635"); session = soup_test_session_new (NULL); - uri = soup_uri_new_with_base (sd->base_uri, "/..%2ftest"); + uri = g_uri_parse_relative (sd->base_uri, "/..%2ftest", SOUP_HTTP_URI_FLAGS, NULL); msg = soup_message_new_from_uri ("GET", uri); - soup_uri_free (uri); + g_uri_unref (uri); soup_test_session_send_message (session, msg); soup_test_assert_message_status (msg, SOUP_STATUS_BAD_REQUEST); g_object_unref (msg); - uri = soup_uri_new_with_base (sd->base_uri, "/%2e%2e%2ftest"); + uri = g_uri_parse_relative (sd->base_uri, "/%2e%2e%2ftest", SOUP_HTTP_URI_FLAGS, NULL); msg = soup_message_new_from_uri ("GET", uri); - soup_uri_free (uri); + g_uri_unref (uri); soup_test_session_send_message (session, msg); soup_test_assert_message_status (msg, SOUP_STATUS_BAD_REQUEST); g_object_unref (msg); #ifdef G_OS_WIN32 - uri = soup_uri_new_with_base (sd->base_uri, "\\..%5Ctest"); + uri = g_uri_parse_relative (sd->base_uri, "\\..%5Ctest", SOUP_HTTP_URI_FLAGS, NULL); msg = soup_message_new_from_uri ("GET", uri); - soup_uri_free (uri); + g_uri_unref (uri); soup_test_session_send_message (session, msg); soup_test_assert_message_status (msg, SOUP_STATUS_BAD_REQUEST); g_object_unref (msg); - uri = soup_uri_new_with_base (sd->base_uri, "\\../test"); + uri = g_uri_parse_relative (sd->base_uri, "\\../test", SOUP_HTTP_URI_FLAGS, NULL); msg = soup_message_new_from_uri ("GET", uri); - soup_uri_free (uri); + g_uri_unref (uri); soup_test_session_send_message (session, msg); soup_test_assert_message_status (msg, SOUP_STATUS_BAD_REQUEST); g_object_unref (msg); - uri = soup_uri_new_with_base (sd->base_uri, "%5C..%2ftest"); + uri = g_uri_parse_relative (sd->base_uri, "%5C..%2ftest", SOUP_HTTP_URI_FLAGS, NULL); msg = soup_message_new_from_uri ("GET", uri); - soup_uri_free (uri); + g_uri_unref (uri); soup_test_session_send_message (session, msg); soup_test_assert_message_status (msg, SOUP_STATUS_BAD_REQUEST); g_object_unref (msg); - uri = soup_uri_new_with_base (sd->base_uri, "/..\\test"); + uri = g_uri_parse_relative (sd->base_uri, "/..\\test", SOUP_HTTP_URI_FLAGS, NULL); msg = soup_message_new_from_uri ("GET", uri); - soup_uri_free (uri); + g_uri_unref (uri); soup_test_session_send_message (session, msg); soup_test_assert_message_status (msg, SOUP_STATUS_BAD_REQUEST); g_object_unref (msg); - uri = soup_uri_new_with_base (sd->base_uri, "%2f..%5Ctest"); + uri = g_uri_parse_relative (sd->base_uri, "%2f..%5Ctest", SOUP_HTTP_URI_FLAGS, NULL); msg = soup_message_new_from_uri ("GET", uri); - soup_uri_free (uri); + g_uri_unref (uri); soup_test_session_send_message (session, msg); soup_test_assert_message_status (msg, SOUP_STATUS_BAD_REQUEST); g_object_unref (msg); - uri = soup_uri_new_with_base (sd->base_uri, "\\%2e%2e%5ctest"); + uri = g_uri_parse_relative (sd->base_uri, "\\%2e%2e%5ctest", SOUP_HTTP_URI_FLAGS, NULL); msg = soup_message_new_from_uri ("GET", uri); - soup_uri_free (uri); + g_uri_unref (uri); soup_test_session_send_message (session, msg); soup_test_assert_message_status (msg, SOUP_STATUS_BAD_REQUEST); g_object_unref (msg); - uri = soup_uri_new_with_base (sd->base_uri, "\\..%%35%63..%%35%63test"); + uri = g_uri_parse_relative (sd->base_uri, "\\..%%35%63..%%35%63test", SOUP_HTTP_URI_FLAGS, NULL); msg = soup_message_new_from_uri ("GET", uri); - soup_uri_free (uri); + g_uri_unref (uri); soup_test_session_send_message (session, msg); soup_test_assert_message_status (msg, SOUP_STATUS_BAD_REQUEST); @@ -430,20 +432,20 @@ multi_server_callback (SoupServer *server, { GSocketAddress *addr; GInetSocketAddress *iaddr; - SoupURI *uri; + GUri *uri; char *uristr, *addrstr; addr = soup_server_message_get_local_address (msg); iaddr = G_INET_SOCKET_ADDRESS (addr); uri = soup_server_message_get_uri (msg); - uristr = soup_uri_to_string (uri, FALSE); + uristr = g_uri_to_string (uri); addrstr = g_inet_address_to_string (g_inet_socket_address_get_address (iaddr)); - g_assert_cmpstr (addrstr, ==, uri->host); + g_assert_cmpstr (addrstr, ==, g_uri_get_host (uri)); g_free (addrstr); - g_assert_cmpint (g_inet_socket_address_get_port (iaddr), ==, uri->port); + g_assert_cmpint (g_inet_socket_address_get_port (iaddr), ==, g_uri_get_port (uri)); /* FIXME ssl */ @@ -453,7 +455,7 @@ multi_server_callback (SoupServer *server, } static void -do_multi_test (ServerData *sd, SoupURI *uri1, SoupURI *uri2) +do_multi_test (ServerData *sd, GUri *uri1, GUri *uri2) { char *uristr; SoupSession *session; @@ -464,7 +466,7 @@ do_multi_test (ServerData *sd, SoupURI *uri1, SoupURI *uri2) session = soup_test_session_new (NULL); - uristr = soup_uri_to_string (uri1, FALSE); + uristr = g_uri_to_string (uri1); msg = soup_message_new ("GET", uristr); body = soup_test_session_async_send (session, msg); soup_test_assert_message_status (msg, SOUP_STATUS_OK); @@ -473,7 +475,7 @@ do_multi_test (ServerData *sd, SoupURI *uri1, SoupURI *uri2) g_object_unref (msg); g_free (uristr); - uristr = soup_uri_to_string (uri2, FALSE); + uristr = g_uri_to_string (uri2); msg = soup_message_new ("GET", uristr); body = soup_test_session_async_send (session, msg); soup_test_assert_message_status (msg, SOUP_STATUS_OK); @@ -484,15 +486,15 @@ do_multi_test (ServerData *sd, SoupURI *uri1, SoupURI *uri2) soup_test_session_abort_unref (session); - soup_uri_free (uri1); - soup_uri_free (uri2); + g_uri_unref (uri1); + g_uri_unref (uri2); } static void do_multi_port_test (ServerData *sd, gconstpointer test_data) { GSList *uris; - SoupURI *uri1, *uri2; + GUri *uri1, *uri2; GError *error = NULL; sd->server = soup_test_server_new (SOUP_TEST_SERVER_NO_DEFAULT_LISTENER); @@ -514,7 +516,7 @@ do_multi_port_test (ServerData *sd, gconstpointer test_data) uri2 = uris->next->data; g_slist_free (uris); - g_assert_cmpint (uri1->port, !=, uri2->port); + g_assert_cmpint (g_uri_get_port (uri1), !=, g_uri_get_port (uri2)); do_multi_test (sd, uri1, uri2); } @@ -523,7 +525,7 @@ static void do_multi_scheme_test (ServerData *sd, gconstpointer test_data) { GSList *uris; - SoupURI *uri1, *uri2; + GUri *uri1, *uri2; GError *error = NULL; SOUP_TEST_SKIP_IF_NO_TLS; @@ -549,7 +551,7 @@ do_multi_scheme_test (ServerData *sd, gconstpointer test_data) uri2 = uris->next->data; g_slist_free (uris); - g_assert_cmpstr (uri1->scheme, !=, uri2->scheme); + g_assert_cmpstr (g_uri_get_scheme (uri1), !=, g_uri_get_scheme (uri2)); do_multi_test (sd, uri1, uri2); } @@ -558,7 +560,7 @@ static void do_multi_family_test (ServerData *sd, gconstpointer test_data) { GSList *uris; - SoupURI *uri1, *uri2; + GUri *uri1, *uri2; GError *error = NULL; sd->server = soup_test_server_new (SOUP_TEST_SERVER_NO_DEFAULT_LISTENER); @@ -589,8 +591,8 @@ do_multi_family_test (ServerData *sd, gconstpointer test_data) uri2 = uris->next->data; g_slist_free (uris); - g_assert_cmpstr (uri1->host, !=, uri2->host); - g_assert_cmpint (uri1->port, ==, uri2->port); + g_assert_cmpstr (g_uri_get_host (uri1), !=, g_uri_get_host (uri2)); + g_assert_cmpint (g_uri_get_port (uri1), ==, g_uri_get_port (uri2)); do_multi_test (sd, uri1, uri2); } @@ -602,7 +604,7 @@ do_gsocket_import_test (void) GSocketAddress *gaddr; SoupServer *server; GSList *listeners; - SoupURI *uri; + GUri *uri; SoupSession *session; SoupMessage *msg; GBytes *body; @@ -653,7 +655,7 @@ do_gsocket_import_test (void) soup_test_session_abort_unref (session); - soup_uri_free (uri); + g_uri_unref (uri); soup_test_server_quit_unref (server); g_assert_false (g_socket_is_connected (gsock)); @@ -667,7 +669,7 @@ do_fd_import_test (void) GSocketAddress *gaddr; SoupServer *server; GSList *listeners; - SoupURI *uri; + GUri *uri; SoupSession *session; SoupMessage *msg; GBytes *body; @@ -719,7 +721,7 @@ do_fd_import_test (void) soup_test_session_abort_unref (session); - soup_uri_free (uri); + g_uri_unref (uri); soup_test_server_quit_unref (server); /* @server should have closed our socket, note the specific error isn't reliable */ @@ -1051,7 +1053,7 @@ do_early_respond_test (ServerData *sd, gconstpointer test_data) { SoupSession *session; SoupMessage *msg; - SoupURI *uri2; + GUri *uri2; GBytes *body; server_add_early_handler (sd, NULL, early_respond_callback, NULL, NULL); @@ -1065,14 +1067,14 @@ do_early_respond_test (ServerData *sd, gconstpointer test_data) g_object_unref (msg); /* The early handler will ignore this one */ - uri2 = soup_uri_new_with_base (sd->base_uri, "/subdir"); + uri2 = g_uri_parse_relative (sd->base_uri, "/subdir", SOUP_HTTP_URI_FLAGS, NULL); msg = soup_message_new_from_uri ("GET", uri2); body = soup_test_session_send (session, msg, NULL, NULL); soup_test_assert_message_status (msg, SOUP_STATUS_OK); g_assert_cmpmem ("index", sizeof ("index") - 1, g_bytes_get_data (body, NULL), g_bytes_get_size (body)); g_bytes_unref (body); g_object_unref (msg); - soup_uri_free (uri2); + g_uri_unref (uri2); soup_test_session_abort_unref (session); } @@ -1092,7 +1094,7 @@ do_early_multi_test (ServerData *sd, gconstpointer test_data) { SoupSession *session; SoupMessage *msg; - SoupURI *uri; + GUri *uri; GBytes *body; struct { const char *path; @@ -1123,9 +1125,9 @@ do_early_multi_test (ServerData *sd, gconstpointer test_data) session = soup_test_session_new (NULL); for (i = 0; i < G_N_ELEMENTS (multi_tests); i++) { - uri = soup_uri_new_with_base (sd->base_uri, multi_tests[i].path); + uri = g_uri_parse_relative (sd->base_uri, multi_tests[i].path, SOUP_HTTP_URI_FLAGS, NULL); msg = soup_message_new_from_uri ("GET", uri); - soup_uri_free (uri); + g_uri_unref (uri); body = soup_test_session_send (session, msg, NULL, NULL); @@ -1359,7 +1361,7 @@ proxy_server_callback (SoupServer *server, gpointer data) { GSocketClient *sclient; - SoupURI *dest_uri; + GUri *dest_uri; Tunnel *tunnel; if (soup_server_message_get_method (msg) != SOUP_METHOD_CONNECT) { @@ -1375,7 +1377,7 @@ proxy_server_callback (SoupServer *server, dest_uri = soup_server_message_get_uri (msg); sclient = g_socket_client_new (); - g_socket_client_connect_to_host_async (sclient, dest_uri->host, dest_uri->port, + g_socket_client_connect_to_host_async (sclient, g_uri_get_host (dest_uri), g_uri_get_port (dest_uri), NULL, tunnel_connected_cb, tunnel); g_object_unref (sclient); } @@ -1386,7 +1388,7 @@ do_steal_connect_test (ServerData *sd, gconstpointer test_data) SoupServer *proxy; SoupSession *session; SoupMessage *msg; - SoupURI *proxy_uri; + GUri *proxy_uri; char *proxy_uri_str; GProxyResolver *resolver; const char *handled_by; @@ -1394,8 +1396,8 @@ do_steal_connect_test (ServerData *sd, gconstpointer test_data) SOUP_TEST_SKIP_IF_NO_TLS; proxy = soup_test_server_new (SOUP_TEST_SERVER_IN_THREAD); - proxy_uri = soup_test_server_get_uri (proxy, SOUP_URI_SCHEME_HTTP, "127.0.0.1"); - proxy_uri_str = soup_uri_to_string (proxy_uri, FALSE); + proxy_uri = soup_test_server_get_uri (proxy, "http", "127.0.0.1"); + proxy_uri_str = g_uri_to_string (proxy_uri); soup_server_add_handler (proxy, NULL, proxy_server_callback, NULL, NULL); resolver = g_simple_proxy_resolver_new (proxy_uri_str, NULL); @@ -1413,7 +1415,7 @@ do_steal_connect_test (ServerData *sd, gconstpointer test_data) soup_test_server_quit_unref (proxy); g_object_unref (resolver); - soup_uri_free (proxy_uri); + g_uri_unref (proxy_uri); g_free (proxy_uri_str); } diff --git a/tests/session-test.c b/tests/session-test.c index 2d0c73b2..1ae68b5f 100644 --- a/tests/session-test.c +++ b/tests/session-test.c @@ -2,7 +2,7 @@ #include "test-utils.h" -static SoupURI *base_uri; +static GUri *base_uri; static gboolean server_processed_message; static gboolean timeout; static GMainLoop *loop; @@ -72,17 +72,16 @@ do_test_for_session (SoupSession *session, SoupMessage *msg; gboolean finished, local_timeout; guint timeout_id; - SoupURI *timeout_uri; + GUri *timeout_uri; GBytes *body; debug_printf (1, " queue_message\n"); debug_printf (2, " requesting timeout\n"); - timeout_uri = soup_uri_new_with_base (base_uri, "/request-timeout"); + timeout_uri = g_uri_parse_relative (base_uri, "/request-timeout", SOUP_HTTP_URI_FLAGS, NULL); msg = soup_message_new_from_uri ("GET", timeout_uri); - soup_uri_free (timeout_uri); body = soup_test_session_send (session, msg, NULL, NULL); g_bytes_unref (body); - g_object_unref (msg); + g_uri_unref (timeout_uri); msg = soup_message_new_from_uri ("GET", base_uri); server_processed_message = timeout = finished = FALSE; @@ -210,14 +209,14 @@ do_priority_tests (void) expected_priorities[2] = SOUP_MESSAGE_PRIORITY_LOW; for (i = 0; i < 3; i++) { - SoupURI *msg_uri; + GUri *msg_uri; SoupMessage *msg; char buf[5]; g_snprintf (buf, sizeof (buf), "%d", i); - msg_uri = soup_uri_new_with_base (base_uri, buf); + msg_uri = g_uri_parse_relative (base_uri, buf, SOUP_HTTP_URI_FLAGS, NULL); msg = soup_message_new_from_uri ("GET", msg_uri); - soup_uri_free (msg_uri); + g_uri_unref (msg_uri); soup_message_set_priority (msg, priorities[i]); g_signal_connect (msg, "finished", @@ -433,7 +432,7 @@ load_uri_bytes_async_ready_cb (SoupSession *session, static void do_read_uri_test (gconstpointer data) { - SoupURI *uri; + GUri *uri; char *uri_string; SoupSession *session; GBytes *body = NULL; @@ -443,8 +442,8 @@ do_read_uri_test (gconstpointer data) session = soup_test_session_new (NULL); - uri = soup_uri_new_with_base (base_uri, "/index.txt"); - uri_string = soup_uri_to_string (uri, FALSE); + uri = g_uri_parse_relative (base_uri, "/index.txt", SOUP_HTTP_URI_FLAGS, NULL); + uri_string = g_uri_to_string (uri); if (flags & SYNC) { if (flags & STREAM) { @@ -500,7 +499,7 @@ do_read_uri_test (gconstpointer data) g_bytes_unref (body); g_free (content_type); g_free (uri_string); - soup_uri_free (uri); + g_uri_unref (uri); soup_test_session_abort_unref (session); } @@ -567,7 +566,7 @@ main (int argc, char **argv) ret = g_test_run (); - soup_uri_free (base_uri); + g_uri_unref (base_uri); soup_test_server_quit_unref (server); test_cleanup (); diff --git a/tests/sniffing-test.c b/tests/sniffing-test.c index 792e8c63..0bcc3bea 100644 --- a/tests/sniffing-test.c +++ b/tests/sniffing-test.c @@ -6,7 +6,7 @@ #include "test-utils.h" SoupSession *session; -SoupURI *base_uri; +GUri *base_uri; static void server_callback (SoupServer *server, @@ -91,7 +91,6 @@ server_callback (SoupServer *server, if (g_str_has_prefix (path, "/type/")) { char **components = g_strsplit (path, "/", 4); - char *ptr; char *base_name = g_path_get_basename (path); @@ -100,7 +99,7 @@ server_callback (SoupServer *server, g_free (base_name); /* Hack to allow passing type in the URI */ - ptr = g_strrstr (components[2], "_"); + char *ptr = g_strrstr (components[2], "_"); *ptr = '/'; soup_message_headers_append (response_headers, @@ -160,12 +159,29 @@ got_headers (SoupMessage *msg) g_object_set_data (G_OBJECT (msg), "got-headers", GINT_TO_POINTER (TRUE)); } +static GUri * +uri_set_query (GUri *uri, const char *query) +{ + GUri *new_uri = g_uri_build ( + g_uri_get_flags (uri), + g_uri_get_scheme (uri), + NULL, + g_uri_get_host (uri), + g_uri_get_port (uri), + g_uri_get_path (uri), + query, + g_uri_get_fragment (uri) + ); + g_uri_unref (uri); + return new_uri; +} + static void do_signals_test (gboolean should_content_sniff, gboolean chunked_encoding, gboolean empty_response) { - SoupURI *uri = soup_uri_new_with_base (base_uri, "/mbox"); + GUri *uri = g_uri_parse_relative (base_uri, "/mbox", SOUP_HTTP_URI_FLAGS, NULL); SoupMessage *msg = soup_message_new_from_uri ("GET", uri); GBytes *expected; GError *error = NULL; @@ -177,15 +193,15 @@ do_signals_test (gboolean should_content_sniff, empty_response ? "" : "!"); if (chunked_encoding) - soup_uri_set_query (uri, "chunked=yes"); + uri = uri_set_query (uri, "chunked=yes"); if (empty_response) { - if (uri->query) { - char *tmp = uri->query; - uri->query = g_strdup_printf ("%s&empty_response=yes", tmp); - g_free (tmp); + if (g_uri_get_query (uri)) { + char *new_query = g_strdup_printf ("%s&empty_response=yes", g_uri_get_query (uri)); + uri = uri_set_query (uri, new_query); + g_free (new_query); } else - soup_uri_set_query (uri, "empty_response=yes"); + uri = uri_set_query (uri, "empty_response=yes"); } soup_message_set_uri (msg, uri); @@ -216,11 +232,11 @@ do_signals_test (gboolean should_content_sniff, //g_message ("|||body (%zu): %s", g_bytes_get_size (body), (char*)g_bytes_get_data (body, NULL)); //g_message ("|||expected (%zu): %s", g_bytes_get_size (expected), (char*)g_bytes_get_data (expected, NULL)); g_assert_true (g_bytes_equal (body, expected)); - } + } g_bytes_unref (expected); g_bytes_unref (body); - soup_uri_free (uri); + g_uri_unref (uri); g_object_unref (msg); } @@ -271,14 +287,14 @@ sniffing_content_sniffed (SoupMessage *msg, const char *content_type, static void test_sniffing (const char *path, const char *expected_type) { - SoupURI *uri; + GUri *uri; SoupMessage *msg; GBytes *body; char *sniffed_type = NULL; char *uri_string; GError *error = NULL; - uri = soup_uri_new_with_base (base_uri, path); + uri = g_uri_parse_relative (base_uri, path, SOUP_HTTP_URI_FLAGS, NULL); msg = soup_message_new_from_uri ("GET", uri); g_signal_connect (msg, "content-sniffed", @@ -291,7 +307,7 @@ test_sniffing (const char *path, const char *expected_type) g_object_unref (msg); sniffed_type = NULL; - uri_string = soup_uri_to_string (uri, FALSE); + uri_string = g_uri_to_string (uri); body = soup_session_load_uri_bytes (session, uri_string, NULL, &sniffed_type, &error); g_assert_no_error (error); g_assert_cmpstr (sniffed_type, ==, expected_type); @@ -299,7 +315,7 @@ test_sniffing (const char *path, const char *expected_type) g_free (uri_string); g_bytes_unref (body); - soup_uri_free (uri); + g_uri_unref (uri); } static void @@ -319,14 +335,14 @@ static void test_disabled (gconstpointer data) { const char *path = data; - SoupURI *uri; + GUri *uri; SoupMessage *msg; GBytes *body; char *sniffed_type = NULL; g_test_bug ("574773"); - uri = soup_uri_new_with_base (base_uri, path); + uri = g_uri_parse_relative (base_uri, path, SOUP_HTTP_URI_FLAGS, NULL); msg = soup_message_new_from_uri ("GET", uri); g_assert_false (soup_message_is_feature_disabled (msg, SOUP_TYPE_CONTENT_SNIFFER)); @@ -341,7 +357,7 @@ test_disabled (gconstpointer data) g_assert_null (sniffed_type); g_bytes_unref (body); g_object_unref (msg); - soup_uri_free (uri); + g_uri_unref (uri); } int @@ -518,7 +534,7 @@ main (int argc, char **argv) ret = g_test_run (); - soup_uri_free (base_uri); + g_uri_unref (base_uri); soup_test_session_abort_unref (session); soup_test_server_quit_unref (server); diff --git a/tests/socket-test.c b/tests/socket-test.c index f3fc039a..5e6c1b4f 100644 --- a/tests/socket-test.c +++ b/tests/socket-test.c @@ -120,7 +120,7 @@ static void do_socket_from_fd_client_test (void) { SoupServer *server; - SoupURI *uri; + GUri *uri; GSocket *gsock; SoupSocket *sock; GInetSocketAddress *local, *remote; @@ -137,7 +137,7 @@ do_socket_from_fd_client_test (void) &error); g_assert_no_error (error); - gaddr = g_inet_socket_address_new_from_string ("127.0.0.1", uri->port); + gaddr = g_inet_socket_address_new_from_string ("127.0.0.1", g_uri_get_port (uri)); g_socket_connect (gsock, gaddr, NULL, &error); g_object_unref (gaddr); g_assert_no_error (error); @@ -164,7 +164,7 @@ do_socket_from_fd_client_test (void) assert_host_equals (local, "127.0.0.1"); g_assert_cmpint (g_inet_socket_address_get_port (local), ==, g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (gaddr))); assert_host_equals (remote, "127.0.0.1"); - g_assert_cmpint (g_inet_socket_address_get_port (remote), ==, uri->port); + g_assert_cmpint (g_inet_socket_address_get_port (remote), ==, g_uri_get_port (uri)); g_object_unref (local); g_object_unref (remote); @@ -174,7 +174,7 @@ do_socket_from_fd_client_test (void) g_object_unref (gsock); soup_test_server_quit_unref (server); - soup_uri_free (uri); + g_uri_unref (uri); } static void diff --git a/tests/ssl-test.c b/tests/ssl-test.c index f1952d8b..53b3441a 100644 --- a/tests/ssl-test.c +++ b/tests/ssl-test.c @@ -2,7 +2,7 @@ #include "test-utils.h" -SoupURI *uri; +GUri *uri; typedef struct { const char *name; @@ -193,7 +193,7 @@ do_tls_interaction_test (void) SoupMessage *msg; GBytes *body; GTlsInteraction *interaction; - SoupURI *test_uri; + GUri *test_uri; GError *error = NULL; SOUP_TEST_SKIP_IF_NO_TLS; @@ -209,8 +209,9 @@ do_tls_interaction_test (void) g_signal_connect (service, "run", G_CALLBACK (got_connection), NULL); g_socket_service_start (service); - test_uri = soup_uri_new ("https://127.0.0.1"); - soup_uri_set_port (test_uri, g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (bound_address))); + test_uri = g_uri_build (SOUP_HTTP_URI_FLAGS, "https", NULL, "127.0.0.1", + g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (bound_address)), + "/", NULL, NULL); g_object_unref (bound_address); session = soup_test_session_new (NULL); @@ -236,7 +237,7 @@ do_tls_interaction_test (void) g_bytes_unref (body); g_object_unref (msg); - soup_uri_free (test_uri); + g_uri_unref (test_uri); soup_test_session_abort_unref (session); g_socket_service_stop (service); @@ -282,7 +283,7 @@ main (int argc, char **argv) ret = g_test_run (); if (tls_available) { - soup_uri_free (uri); + g_uri_unref (uri); soup_test_server_quit_unref (server); } diff --git a/tests/streaming-test.c b/tests/streaming-test.c index 264e352a..cfec948b 100644 --- a/tests/streaming-test.c +++ b/tests/streaming-test.c @@ -82,16 +82,16 @@ server_callback (SoupServer *server, } static void -do_request (SoupSession *session, SoupURI *base_uri, char *path) +do_request (SoupSession *session, GUri *base_uri, char *path) { - SoupURI *uri; + GUri *uri; SoupMessage *msg; GBytes *body; char *md5; - uri = soup_uri_new_with_base (base_uri, path); + uri = g_uri_parse_relative (base_uri, path, SOUP_HTTP_URI_FLAGS, NULL); msg = soup_message_new_from_uri ("GET", uri); - soup_uri_free (uri); + g_uri_unref (uri); body = soup_test_session_async_send (session, msg); @@ -111,7 +111,7 @@ do_request (SoupSession *session, SoupURI *base_uri, char *path) static void do_chunked_test (gconstpointer data) { - SoupURI *base_uri = (SoupURI *)data; + GUri *base_uri = (GUri *)data; SoupSession *session; session = soup_test_session_new (NULL); @@ -122,7 +122,7 @@ do_chunked_test (gconstpointer data) static void do_content_length_test (gconstpointer data) { - SoupURI *base_uri = (SoupURI *)data; + GUri *base_uri = (GUri *)data; SoupSession *session; session = soup_test_session_new (NULL); @@ -133,7 +133,7 @@ do_content_length_test (gconstpointer data) static void do_eof_test (gconstpointer data) { - SoupURI *base_uri = (SoupURI *)data; + GUri *base_uri = (GUri *)data; SoupSession *session; g_test_bug ("572153"); @@ -148,7 +148,7 @@ main (int argc, char **argv) { GMainLoop *loop; SoupServer *server; - SoupURI *base_uri; + GUri *base_uri; int ret; test_init (argc, argv, NULL); @@ -170,7 +170,7 @@ main (int argc, char **argv) ret = g_test_run (); - soup_uri_free (base_uri); + g_uri_unref (base_uri); g_main_loop_unref (loop); g_free (full_response_md5); diff --git a/tests/test-utils.c b/tests/test-utils.c index 09094752..a057e0ed 100644 --- a/tests/test-utils.c +++ b/tests/test-utils.c @@ -459,36 +459,36 @@ soup_test_server_new (SoupTestServerOptions options) return server; } -static SoupURI * +static GUri * find_server_uri (SoupServer *server, const char *scheme, const char *host) { GSList *uris, *u; - SoupURI *uri, *ret_uri = NULL; + GUri *uri, *ret_uri = NULL; uris = soup_server_get_uris (server); for (u = uris; u; u = u->next) { uri = u->data; - if (scheme && strcmp (uri->scheme, scheme) != 0) + if (scheme && strcmp (g_uri_get_scheme (uri), scheme) != 0) continue; - if (host && strcmp (uri->host, host) != 0) + if (host && strcmp (g_uri_get_host (uri), host) != 0) continue; - ret_uri = soup_uri_copy (uri); + ret_uri = g_uri_ref (uri); break; } - g_slist_free_full (uris, (GDestroyNotify)soup_uri_free); + g_slist_free_full (uris, (GDestroyNotify)g_uri_unref); return ret_uri; } -static SoupURI * +static GUri * add_listener (SoupServer *server, const char *scheme, const char *host) { SoupServerListenOptions options = 0; GError *error = NULL; - if (!g_strcmp0 (scheme, SOUP_URI_SCHEME_HTTPS)) + if (!g_strcmp0 (scheme, "https")) options |= SOUP_SERVER_LISTEN_HTTPS; if (!g_strcmp0 (host, "127.0.0.1")) options |= SOUP_SERVER_LISTEN_IPV4_ONLY; @@ -509,7 +509,7 @@ typedef struct { const char *scheme; const char *host; - SoupURI *uri; + GUri *uri; } AddListenerData; static gboolean @@ -525,12 +525,12 @@ add_listener_in_thread (gpointer user_data) return FALSE; } -SoupURI * +GUri * soup_test_server_get_uri (SoupServer *server, const char *scheme, const char *host) { - SoupURI *uri; + GUri *uri; GMainLoop *loop; uri = find_server_uri (server, scheme, host); @@ -896,3 +896,21 @@ soup_test_assert (gboolean expr, const char *fmt, ...) } } #endif + +GUri * +soup_test_uri_set_port (GUri *uri, int port) +{ + GUri *new_uri = g_uri_build_with_user ( + g_uri_get_flags (uri), + g_uri_get_scheme (uri), + g_uri_get_user (uri), + g_uri_get_password (uri), + g_uri_get_auth_params (uri), + g_uri_get_host (uri), + port, + g_uri_get_path (uri), + g_uri_get_query (uri), + g_uri_get_fragment (uri) + ); + return new_uri; +} diff --git a/tests/test-utils.h b/tests/test-utils.h index e44051f3..20b0b98d 100644 --- a/tests/test-utils.h +++ b/tests/test-utils.h @@ -65,7 +65,7 @@ typedef enum { } SoupTestServerOptions; SoupServer *soup_test_server_new (SoupTestServerOptions options); -SoupURI *soup_test_server_get_uri (SoupServer *server, +GUri *soup_test_server_get_uri (SoupServer *server, const char *scheme, const char *host); void soup_test_server_quit_unref (SoupServer *server); @@ -92,6 +92,9 @@ GBytes *soup_test_load_resource (const char *name, GBytes *soup_test_get_index (void); +GUri *soup_test_uri_set_port (GUri *uri, + int port); + #ifdef G_HAVE_ISO_VARARGS #define soup_test_assert(expr, ...) \ G_STMT_START { \ diff --git a/tests/timeout-test.c b/tests/timeout-test.c index 411f09cf..3d713757 100644 --- a/tests/timeout-test.c +++ b/tests/timeout-test.c @@ -24,7 +24,7 @@ request_started_cb (SoupSession *session, SoupMessage *msg, gpointer user_data) } static void -do_message_to_session (SoupSession *session, SoupURI *uri, +do_message_to_session (SoupSession *session, GUri *uri, const char *comment, guint expected_status) { SoupMessage *msg; @@ -55,8 +55,8 @@ static void do_msg_tests_for_session (SoupSession *timeout_session, SoupSession *idle_session, SoupSession *plain_session, - SoupURI *fast_uri, - SoupURI *slow_uri) + GUri *fast_uri, + GUri *slow_uri) { GSocket *ret, *idle_first = NULL, *idle_second; GSocket *plain_first = NULL, *plain_second; @@ -107,16 +107,15 @@ static void do_async_timeout_tests (gconstpointer data) { SoupSession *timeout_session, *idle_session, *plain_session; - SoupURI *fast_uri = (SoupURI *)data; - SoupURI *slow_uri = soup_uri_new_with_base (fast_uri, "/slow"); + GUri *fast_uri = (GUri *)data; + GUri *slow_uri = g_uri_parse_relative (fast_uri, "/slow", SOUP_HTTP_URI_FLAGS, NULL); gboolean extra_slow; g_test_skip ("FIXME"); return; - if (fast_uri->scheme == SOUP_URI_SCHEME_HTTPS) { + if (soup_uri_is_https (fast_uri, NULL)) { SOUP_TEST_SKIP_IF_NO_TLS; - extra_slow = slow_https; } else extra_slow = FALSE; @@ -138,21 +137,21 @@ do_async_timeout_tests (gconstpointer data) soup_test_session_abort_unref (idle_session); soup_test_session_abort_unref (plain_session); - soup_uri_free (slow_uri); + g_uri_unref (slow_uri); } static void do_sync_timeout_tests (gconstpointer data) { SoupSession *timeout_session, *plain_session; - SoupURI *fast_uri = (SoupURI *)data; - SoupURI *slow_uri = soup_uri_new_with_base (fast_uri, "/slow"); + GUri *fast_uri = (GUri *)data; + GUri *slow_uri = g_uri_parse_relative (fast_uri, "/slow", SOUP_HTTP_URI_FLAGS, NULL); gboolean extra_slow; g_test_skip ("FIXME"); return; - if (fast_uri->scheme == SOUP_URI_SCHEME_HTTPS) { + if (soup_uri_is_https (fast_uri, NULL)) { SOUP_TEST_SKIP_IF_NO_TLS; extra_slow = slow_https; @@ -167,7 +166,7 @@ do_sync_timeout_tests (gconstpointer data) soup_test_session_abort_unref (timeout_session); soup_test_session_abort_unref (plain_session); - soup_uri_free (slow_uri); + g_uri_unref (slow_uri); } static gboolean @@ -205,7 +204,7 @@ int main (int argc, char **argv) { SoupServer *server, *https_server = NULL; - SoupURI *uri, *https_uri = NULL; + GUri *uri, *https_uri = NULL; int ret; test_init (argc, argv, NULL); @@ -239,7 +238,7 @@ main (int argc, char **argv) slow_https = FALSE; } } else - https_uri = soup_uri_new ("https://fail."); + https_uri = g_uri_parse ("https://fail.", SOUP_HTTP_URI_FLAGS, NULL); g_test_add_data_func ("/timeout/http/async", uri, do_async_timeout_tests); g_test_add_data_func ("/timeout/http/sync", uri, do_sync_timeout_tests); @@ -248,8 +247,8 @@ main (int argc, char **argv) ret = g_test_run (); - soup_uri_free (uri); - soup_uri_free (https_uri); + g_uri_unref (uri); + g_uri_unref (https_uri); soup_test_server_quit_unref (server); if (https_server) soup_test_server_quit_unref (https_server); diff --git a/tests/uri-parsing-test.c b/tests/uri-parsing-test.c index 9acadf7c..8d5c0109 100644 --- a/tests/uri-parsing-test.c +++ b/tests/uri-parsing-test.c @@ -3,573 +3,47 @@ #include "test-utils.h" static struct { - const char *uri_string, *result, *bugref; - const SoupURI bits; -} abs_tests[] = { - { "foo:", "foo:", NULL, - { "foo", NULL, NULL, NULL, 0, "", NULL, NULL } }, - { "file:/dev/null", "file:/dev/null", NULL, - { "file", NULL, NULL, NULL, 0, "/dev/null", NULL, NULL } }, - { "file:///dev/null", "file:///dev/null", NULL, - { "file", NULL, NULL, "", 0, "/dev/null", NULL, NULL } }, - { "ftp://user@host/path", "ftp://user@host/path", NULL, - { "ftp", "user", NULL, "host", 21, "/path", NULL, NULL } }, - { "ftp://user@host:9999/path", "ftp://user@host:9999/path", NULL, - { "ftp", "user", NULL, "host", 9999, "/path", NULL, NULL } }, - { "ftp://user:password@host/path", "ftp://user@host/path", NULL, - { "ftp", "user", "password", "host", 21, "/path", NULL, NULL } }, - { "ftp://user:password@host:9999/path", "ftp://user@host:9999/path", NULL, - { "ftp", "user", "password", "host", 9999, "/path", NULL, NULL } }, - { "ftp://user:password@host", "ftp://user@host", NULL, - { "ftp", "user", "password", "host", 21, "", NULL, NULL } }, - { "http://us%65r@host", "http://user@host/", NULL, - { "http", "user", NULL, "host", 80, "/", NULL, NULL } }, - { "http://us%40r@host", "http://us%40r@host/", NULL, - { "http", "us\x40r", NULL, "host", 80, "/", NULL, NULL } }, - { "http://us%3ar@host", "http://us%3Ar@host/", NULL, - { "http", "us\x3ar", NULL, "host", 80, "/", NULL, NULL } }, - { "http://us%2fr@host", "http://us%2Fr@host/", NULL, - { "http", "us\x2fr", NULL, "host", 80, "/", NULL, NULL } }, - { "http://us%3fr@host", "http://us%3Fr@host/", NULL, - { "http", "us\x3fr", NULL, "host", 80, "/", NULL, NULL } }, - { "http://host?query", "http://host/?query", NULL, - { "http", NULL, NULL, "host", 80, "/", "query", NULL } }, - { "http://host/path?query=http%3A%2F%2Fhost%2Fpath%3Fchildparam%3Dchildvalue¶m=value", - "http://host/path?query=http%3A%2F%2Fhost%2Fpath%3Fchildparam%3Dchildvalue¶m=value", NULL, - { "http", NULL, NULL, "host", 80, "/path", "query=http%3A%2F%2Fhost%2Fpath%3Fchildparam%3Dchildvalue¶m=value", NULL } }, - { "http://control-chars/%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F", - "http://control-chars/%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F", NULL, - { "http", NULL, NULL, "control-chars", 80, "/%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F", NULL, NULL } }, - { "http://space/%20", - "http://space/%20", NULL, - { "http", NULL, NULL, "space", 80, "/%20", NULL, NULL } }, - { "http://delims/%3C%3E%23%25%22", - "http://delims/%3C%3E%23%25%22", NULL, - { "http", NULL, NULL, "delims", 80, "/%3C%3E%23%25%22", NULL, NULL } }, - { "http://unwise-chars/%7B%7D%7C%5C%5E%5B%5D%60", - "http://unwise-chars/%7B%7D%7C%5C%5E%5B%5D%60", NULL, - { "http", NULL, NULL, "unwise-chars", 80, "/%7B%7D%7C%5C%5E%5B%5D%60", NULL, NULL } }, - - /* From RFC 2732 */ - { "http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:80/index.html", - "http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]/index.html", NULL, - { "http", NULL, NULL, "FEDC:BA98:7654:3210:FEDC:BA98:7654:3210", 80, "/index.html", NULL, NULL } }, - { "http://[1080:0:0:0:8:800:200C:417A]/index.html", - "http://[1080:0:0:0:8:800:200C:417A]/index.html", NULL, - { "http", NULL, NULL, "1080:0:0:0:8:800:200C:417A", 80, "/index.html", NULL, NULL } }, - { "http://[3ffe:2a00:100:7031::1]", - "http://[3ffe:2a00:100:7031::1]/", NULL, - { "http", NULL, NULL, "3ffe:2a00:100:7031::1", 80, "/", NULL, NULL } }, - { "http://[1080::8:800:200C:417A]/foo", - "http://[1080::8:800:200C:417A]/foo", NULL, - { "http", NULL, NULL, "1080::8:800:200C:417A", 80, "/foo", NULL, NULL } }, - { "http://[::192.9.5.5]/ipng", - "http://[::192.9.5.5]/ipng", NULL, - { "http", NULL, NULL, "::192.9.5.5", 80, "/ipng", NULL, NULL } }, - { "http://[::FFFF:129.144.52.38]:80/index.html", - "http://[::FFFF:129.144.52.38]/index.html", NULL, - { "http", NULL, NULL, "::FFFF:129.144.52.38", 80, "/index.html", NULL, NULL } }, - { "http://[2010:836B:4179::836B:4179]", - "http://[2010:836B:4179::836B:4179]/", NULL, - { "http", NULL, NULL, "2010:836B:4179::836B:4179", 80, "/", NULL, NULL } }, - - /* Try to recover certain kinds of invalid URIs */ - { "http://host/path with spaces", - "http://host/path%20with%20spaces", "566530", - { "http", NULL, NULL, "host", 80, "/path%20with%20spaces", NULL, NULL } }, - { " http://host/path", "http://host/path", "594405", - { "http", NULL, NULL, "host", 80, "/path", NULL, NULL } }, - { "http://host/path ", "http://host/path", "594405", - { "http", NULL, NULL, "host", 80, "/path", NULL, NULL } }, - { "http://host ", "http://host/", "594405", - { "http", NULL, NULL, "host", 80, "/", NULL, NULL } }, - { "http://host:999 ", "http://host:999/", "594405", - { "http", NULL, NULL, "host", 999, "/", NULL, NULL } }, - { "http://host/pa\nth", "http://host/path", "594405", - { "http", NULL, NULL, "host", 80, "/path", NULL, NULL } }, - { "http:\r\n//host/path", "http://host/path", "594405", - { "http", NULL, NULL, "host", 80, "/path", NULL, NULL } }, - { "http://\thost/path", "http://host/path", "594405", - { "http", NULL, NULL, "host", 80, "/path", NULL, NULL } }, - - /* 0-length is different from not-present */ - { "http://host/path?", "http://host/path?", "594405", - { "http", NULL, NULL, "host", 80, "/path", "", NULL } }, - { "http://host/path#", "http://host/path#", "594405", - { "http", NULL, NULL, "host", 80, "/path", NULL, "" } }, - - /* ignore bad %-encoding */ - { "http://host/path%", "http://host/path%", "590524", - { "http", NULL, NULL, "host", 80, "/path%", NULL, NULL } }, - { "http://h%ost/path", "http://h%25ost/path", "590524", - { "http", NULL, NULL, "h%ost", 80, "/path", NULL, NULL } }, - { "http://host/path%%", "http://host/path%%", "590524", - { "http", NULL, NULL, "host", 80, "/path%%", NULL, NULL } }, - { "http://host/path%%%", "http://host/path%%%", "590524", - { "http", NULL, NULL, "host", 80, "/path%%%", NULL, NULL } }, - { "http://host/path%/x/", "http://host/path%/x/", "590524", - { "http", NULL, NULL, "host", 80, "/path%/x/", NULL, NULL } }, - { "http://host/path%0x/", "http://host/path%0x/", "590524", - { "http", NULL, NULL, "host", 80, "/path%0x/", NULL, NULL } }, - { "http://host/path%ax", "http://host/path%ax", "590524", - { "http", NULL, NULL, "host", 80, "/path%ax", NULL, NULL } }, - - /* %-encode non-ASCII characters */ - { "http://host/p\xc3\xa4th/", "http://host/p%C3%A4th/", "662806", - { "http", NULL, NULL, "host", 80, "/p%C3%A4th/", NULL, NULL } }, - - { "HTTP:////////////////", "http:////////////////", "667637", - { "http", NULL, NULL, "", 80, "//////////////", NULL, NULL } }, - - { "http://@host", "http://@host/", NULL, - { "http", "", NULL, "host", 80, "/", NULL, NULL } }, - { "http://:@host", "http://@host/", NULL, - { "http", "", "", "host", 80, "/", NULL, NULL } }, - - { "http://host/keep%00nuls", "http://host/keep%00nuls", NULL, - { "http", NULL, NULL, "host", 80, "/keep%00nuls", NULL, NULL } }, - - /* scheme parsing */ - { "foo0://host/path", "foo0://host/path", "703776", - { "foo0", NULL, NULL, "host", 0, "/path", NULL, NULL } }, - { "f0.o://host/path", "f0.o://host/path", "703776", - { "f0.o", NULL, NULL, "host", 0, "/path", NULL, NULL } }, - { "http++://host/path", "http++://host/path", "703776", - { "http++", NULL, NULL, "host", 0, "/path", NULL, NULL } }, - { "http-ish://host/path", "http-ish://host/path", "703776", - { "http-ish", NULL, NULL, "host", 0, "/path", NULL, NULL } }, - { "99http://host/path", NULL, "703776", - { NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL } }, - { ".http://host/path", NULL, "703776", - { NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL } }, - { "+http://host/path", NULL, "703776", - { NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL } }, - - /* IPv6 scope ID parsing (both correct and incorrect) */ - { "http://[fe80::dead:beef%em1]/", "http://[fe80::dead:beef%25em1]/", NULL, - { "http", NULL, NULL, "fe80::dead:beef%em1", 80, "/", NULL, NULL } }, - { "http://[fe80::dead:beef%25em1]/", "http://[fe80::dead:beef%25em1]/", NULL, - { "http", NULL, NULL, "fe80::dead:beef%em1", 80, "/", NULL, NULL } }, - { "http://[fe80::dead:beef%10]/", "http://[fe80::dead:beef%2510]/", NULL, - { "http", NULL, NULL, "fe80::dead:beef%10", 80, "/", NULL, NULL } }, - - /* ".." past top */ - { "http://example.com/..", "http://example.com/", "785042", - { "http", NULL, NULL, "example.com", 80, "/", NULL, NULL } }, -}; -static int num_abs_tests = G_N_ELEMENTS(abs_tests); - -/* From RFC 3986. */ -static const char *base = "http://a/b/c/d;p?q"; -static struct { - const char *uri_string, *result; - const SoupURI bits; -} rel_tests[] = { - { "g:h", "g:h", - { "g", NULL, NULL, NULL, 0, "h", NULL, NULL } }, - { "g", "http://a/b/c/g", - { "http", NULL, NULL, "a", 80, "/b/c/g", NULL, NULL } }, - { "./g", "http://a/b/c/g", - { "http", NULL, NULL, "a", 80, "/b/c/g", NULL, NULL } }, - { "g/", "http://a/b/c/g/", - { "http", NULL, NULL, "a", 80, "/b/c/g/", NULL, NULL } }, - { "/g", "http://a/g", - { "http", NULL, NULL, "a", 80, "/g", NULL, NULL } }, - { "//g", "http://g/", - { "http", NULL, NULL, "g", 80, "/", NULL, NULL } }, - { "?y", "http://a/b/c/d;p?y", - { "http", NULL, NULL, "a", 80, "/b/c/d;p", "y", NULL } }, - { "g?y", "http://a/b/c/g?y", - { "http", NULL, NULL, "a", 80, "/b/c/g", "y", NULL } }, - { "#s", "http://a/b/c/d;p?q#s", - { "http", NULL, NULL, "a", 80, "/b/c/d;p", "q", "s" } }, - { "g#s", "http://a/b/c/g#s", - { "http", NULL, NULL, "a", 80, "/b/c/g", NULL, "s" } }, - { "g?y#s", "http://a/b/c/g?y#s", - { "http", NULL, NULL, "a", 80, "/b/c/g", "y", "s" } }, - { ";x", "http://a/b/c/;x", - { "http", NULL, NULL, "a", 80, "/b/c/;x", NULL, NULL } }, - { "g;x", "http://a/b/c/g;x", - { "http", NULL, NULL, "a", 80, "/b/c/g;x", NULL, NULL } }, - { "g;x?y#s", "http://a/b/c/g;x?y#s", - { "http", NULL, NULL, "a", 80, "/b/c/g;x", "y", "s" } }, - { ".", "http://a/b/c/", - { "http", NULL, NULL, "a", 80, "/b/c/", NULL, NULL } }, - { "./", "http://a/b/c/", - { "http", NULL, NULL, "a", 80, "/b/c/", NULL, NULL } }, - { "..", "http://a/b/", - { "http", NULL, NULL, "a", 80, "/b/", NULL, NULL } }, - { "../", "http://a/b/", - { "http", NULL, NULL, "a", 80, "/b/", NULL, NULL } }, - { "../g", "http://a/b/g", - { "http", NULL, NULL, "a", 80, "/b/g", NULL, NULL } }, - { "../..", "http://a/", - { "http", NULL, NULL, "a", 80, "/", NULL, NULL } }, - { "../../", "http://a/", - { "http", NULL, NULL, "a", 80, "/", NULL, NULL } }, - { "../../g", "http://a/g", - { "http", NULL, NULL, "a", 80, "/g", NULL, NULL } }, - { "", "http://a/b/c/d;p?q", - { "http", NULL, NULL, "a", 80, "/b/c/d;p", "q", NULL } }, - { "../../../g", "http://a/g", - { "http", NULL, NULL, "a", 80, "/g", NULL, NULL } }, - { "../../../../g", "http://a/g", - { "http", NULL, NULL, "a", 80, "/g", NULL, NULL } }, - { "/./g", "http://a/g", - { "http", NULL, NULL, "a", 80, "/g", NULL, NULL } }, - { "/../g", "http://a/g", - { "http", NULL, NULL, "a", 80, "/g", NULL, NULL } }, - { "g.", "http://a/b/c/g.", - { "http", NULL, NULL, "a", 80, "/b/c/g.", NULL, NULL } }, - { ".g", "http://a/b/c/.g", - { "http", NULL, NULL, "a", 80, "/b/c/.g", NULL, NULL } }, - { "g..", "http://a/b/c/g..", - { "http", NULL, NULL, "a", 80, "/b/c/g..", NULL, NULL } }, - { "..g", "http://a/b/c/..g", - { "http", NULL, NULL, "a", 80, "/b/c/..g", NULL, NULL } }, - { "./../g", "http://a/b/g", - { "http", NULL, NULL, "a", 80, "/b/g", NULL, NULL } }, - { "./g/.", "http://a/b/c/g/", - { "http", NULL, NULL, "a", 80, "/b/c/g/", NULL, NULL } }, - { "g/./h", "http://a/b/c/g/h", - { "http", NULL, NULL, "a", 80, "/b/c/g/h", NULL, NULL } }, - { "g/../h", "http://a/b/c/h", - { "http", NULL, NULL, "a", 80, "/b/c/h", NULL, NULL } }, - { "g;x=1/./y", "http://a/b/c/g;x=1/y", - { "http", NULL, NULL, "a", 80, "/b/c/g;x=1/y", NULL, NULL } }, - { "g;x=1/../y", "http://a/b/c/y", - { "http", NULL, NULL, "a", 80, "/b/c/y", NULL, NULL } }, - { "g?y/./x", "http://a/b/c/g?y/./x", - { "http", NULL, NULL, "a", 80, "/b/c/g", "y/./x", NULL } }, - { "g?y/../x", "http://a/b/c/g?y/../x", - { "http", NULL, NULL, "a", 80, "/b/c/g", "y/../x", NULL } }, - { "g#s/./x", "http://a/b/c/g#s/./x", - { "http", NULL, NULL, "a", 80, "/b/c/g", NULL, "s/./x" } }, - { "g#s/../x", "http://a/b/c/g#s/../x", - { "http", NULL, NULL, "a", 80, "/b/c/g", NULL, "s/../x" } }, - - /* RFC 3986 notes that some old parsers will parse this as - * a relative URL ("http://a/b/c/g"), but it should be - * interpreted as absolute. libsoup should parse it - * correctly as being absolute, but then reject it since it's - * an http URL with no host. - */ - { "http:g", NULL, { NULL } } -}; -static int num_rel_tests = G_N_ELEMENTS(rel_tests); - -static struct { - const char *one, *two, *bugref; + const char *one, *two; + gboolean equal; + GUriFlags flags_one, flags_two; } eq_tests[] = { - { "example://a/b/c/%7Bfoo%7D", "eXAMPLE://a/./b/../b/%63/%7Bfoo%7D", "628728" }, - { "http://example.com", "http://example.com/", NULL }, + // NOTE: GUri doesn't remove dot segments from absolute URIs + // { "example://a/b/c/%7Bfoo%7D", "eXAMPLE://a/./b/../b/%63/%7Bfoo%7D", "628728" }, + { "http://example.com", "http://example.com/", TRUE, + SOUP_HTTP_URI_FLAGS, SOUP_HTTP_URI_FLAGS }, /* From RFC 2616 */ - { "http://abc.com:80/~smith/home.html", "http://abc.com:80/~smith/home.html", NULL }, - { "http://abc.com:80/~smith/home.html", "http://ABC.com/%7Esmith/home.html", NULL }, - { "http://abc.com:80/~smith/home.html", "http://ABC.com:/%7esmith/home.html", NULL }, + { "http://abc.com:80/~smith/home.html", "http://abc.com:80/~smith/home.html", TRUE, + SOUP_HTTP_URI_FLAGS, SOUP_HTTP_URI_FLAGS }, + { "http://abc.com:80/~smith/home.html", "http://ABC.com/%7Esmith/home.html", TRUE, + SOUP_HTTP_URI_FLAGS, SOUP_HTTP_URI_FLAGS }, + { "http://abc.com:80/~smith/home.html", "http://ABC.com:/%7esmith/home.html", TRUE, + SOUP_HTTP_URI_FLAGS, SOUP_HTTP_URI_FLAGS }, + /* Test flags affecting comparisons */ + { "http://example.com/%2F", "http://example.com/%2F", FALSE, + G_URI_FLAGS_ENCODED_PATH, G_URI_FLAGS_NONE }, + { "http://example.com/%2F", "http://example.com/%2F", TRUE, + G_URI_FLAGS_PARSE_RELAXED, G_URI_FLAGS_NONE }, + { "http://example.com/%2F", "http://example.com/%2F", TRUE, + G_URI_FLAGS_PARSE_RELAXED, G_URI_FLAGS_HAS_PASSWORD }, }; static int num_eq_tests = G_N_ELEMENTS(eq_tests); -static void -do_uri (SoupURI *base_uri, const char *base_str, - const char *in_uri, const char *out_uri, - const SoupURI *bits) -{ - SoupURI *uri; - char *uri_string; - - if (base_uri) { - debug_printf (1, "<%s> + <%s> = <%s>\n", base_str, in_uri, - out_uri ? out_uri : "ERR"); - uri = soup_uri_new_with_base (base_uri, in_uri); - } else { - debug_printf (1, "<%s> => <%s>\n", in_uri, - out_uri ? out_uri : "ERR"); - uri = soup_uri_new (in_uri); - } - - if (!uri) { - g_assert_null (out_uri); - return; - } - - if (bits != NULL) { - g_assert_cmpstr (uri->scheme, ==, bits->scheme); - g_assert_cmpstr (uri->user, ==, bits->user); - g_assert_cmpstr (uri->password, ==, bits->password); - g_assert_cmpstr (uri->host, ==, bits->host); - g_assert_cmpuint (uri->port, ==, bits->port); - g_assert_cmpstr (uri->path, ==, bits->path); - g_assert_cmpstr (uri->query, ==, bits->query); - g_assert_cmpstr (uri->fragment, ==, bits->fragment); - } - - uri_string = soup_uri_to_string (uri, FALSE); - soup_uri_free (uri); - - g_assert_cmpstr (uri_string, ==, out_uri); - g_free (uri_string); -} - -static void -do_absolute_uri_tests (void) -{ - int i; - - for (i = 0; i < num_abs_tests; i++) { - if (abs_tests[i].bugref) - g_test_bug (abs_tests[i].bugref); - do_uri (NULL, NULL, abs_tests[i].uri_string, - abs_tests[i].result, &abs_tests[i].bits); - } -} - -static void -do_relative_uri_tests (void) -{ - SoupURI *base_uri; - char *uri_string; - int i; - - base_uri = soup_uri_new (base); - if (!base_uri) { - g_printerr ("Could not parse %s!\n", base); - exit (1); - } - - uri_string = soup_uri_to_string (base_uri, FALSE); - g_assert_cmpstr (uri_string, ==, base); - g_free (uri_string); - - for (i = 0; i < num_rel_tests; i++) { - do_uri (base_uri, base, rel_tests[i].uri_string, - rel_tests[i].result, &rel_tests[i].bits); - } - soup_uri_free (base_uri); -} - static void do_equality_tests (void) { - SoupURI *uri1, *uri2; + GUri *uri1, *uri2; int i; for (i = 0; i < num_eq_tests; i++) { - if (eq_tests[i].bugref) - g_test_bug (eq_tests[i].bugref); - - uri1 = soup_uri_new (eq_tests[i].one); - uri2 = soup_uri_new (eq_tests[i].two); - - debug_printf (1, "<%s> == <%s>\n", eq_tests[i].one, eq_tests[i].two); - g_assert_true (soup_uri_equal (uri1, uri2)); + uri1 = g_uri_parse (eq_tests[i].one, eq_tests[i].flags_one, NULL); + uri2 = g_uri_parse (eq_tests[i].two, eq_tests[i].flags_two, NULL); - soup_uri_free (uri1); - soup_uri_free (uri2); - } -} - -static void -do_soup_uri_null_tests (void) -{ - SoupURI *uri, *uri2; - char *uri_string; - - g_test_bug ("667637"); - g_test_bug ("670431"); - - uri = soup_uri_new (NULL); - g_assert_false (SOUP_URI_IS_VALID (uri)); - g_assert_false (SOUP_URI_VALID_FOR_HTTP (uri)); - - /* This implicitly also verifies that none of these methods g_warn */ - g_assert_null (soup_uri_get_scheme (uri)); - g_assert_null (soup_uri_get_user (uri)); - g_assert_null (soup_uri_get_password (uri)); - g_assert_null (soup_uri_get_host (uri)); - g_assert_cmpint (soup_uri_get_port (uri), ==, 0); - g_assert_null (soup_uri_get_path (uri)); - g_assert_null (soup_uri_get_query (uri)); - g_assert_null (soup_uri_get_fragment (uri)); - - g_test_expect_message ("libsoup", G_LOG_LEVEL_CRITICAL, - "*base == NULL*"); - uri2 = soup_uri_new_with_base (uri, "/path"); - g_test_assert_expected_messages (); - g_assert_null (uri2); - - g_test_expect_message ("libsoup", G_LOG_LEVEL_WARNING, - "*SOUP_URI_IS_VALID*"); - uri_string = soup_uri_to_string (uri, FALSE); - g_test_assert_expected_messages (); - g_assert_cmpstr (uri_string, ==, ""); - g_free (uri_string); - - soup_uri_set_scheme (uri, SOUP_URI_SCHEME_HTTP); - g_assert_false (SOUP_URI_IS_VALID (uri)); - g_assert_false (SOUP_URI_VALID_FOR_HTTP (uri)); - - g_test_expect_message ("libsoup", G_LOG_LEVEL_WARNING, - "*SOUP_URI_IS_VALID*"); - uri_string = soup_uri_to_string (uri, FALSE); - g_test_assert_expected_messages (); - g_assert_cmpstr (uri_string, ==, "http:"); - g_free (uri_string); - - soup_uri_set_host (uri, "localhost"); - g_assert_false (SOUP_URI_IS_VALID (uri)); - g_assert_false (SOUP_URI_VALID_FOR_HTTP (uri)); + debug_printf (1, "<%s> %c= <%s>\n", eq_tests[i].one, eq_tests[i].equal ? '=' : '!', eq_tests[i].two); + g_assert_cmpint (soup_uri_equal (uri1, uri2), ==, eq_tests[i].equal); - g_test_expect_message ("libsoup", G_LOG_LEVEL_WARNING, - "*SOUP_URI_IS_VALID*"); - uri_string = soup_uri_to_string (uri, FALSE); - g_test_assert_expected_messages (); - g_assert_cmpstr (uri_string, ==, "http://localhost/"); - g_free (uri_string); - - g_test_expect_message ("libsoup", G_LOG_LEVEL_WARNING, - "*SOUP_URI_IS_VALID*"); - uri2 = soup_uri_new_with_base (uri, "/path"); - g_test_assert_expected_messages (); - g_assert_true (uri2 != NULL); - - if (uri2) { - uri_string = soup_uri_to_string (uri2, FALSE); - g_assert_cmpstr (uri_string, ==, "http://localhost/path"); - g_free (uri_string); - soup_uri_free (uri2); + g_uri_unref (uri1); + g_uri_unref (uri2); } - - g_test_expect_message ("libsoup", G_LOG_LEVEL_WARNING, - "*path != NULL*"); - soup_uri_set_path (uri, NULL); - g_test_assert_expected_messages (); - g_assert_cmpstr (uri->path, ==, ""); - - uri_string = soup_uri_to_string (uri, FALSE); - g_assert_cmpstr (uri_string, ==, "http://localhost/"); - g_free (uri_string); - - g_assert_true (SOUP_URI_IS_VALID (uri)); - g_assert_true (SOUP_URI_VALID_FOR_HTTP (uri)); - - soup_uri_free (uri); -} - -static struct { - const char *uri_string, *unescape_extra, *result; -} normalization_tests[] = { - { "fo%6fbar", NULL, "foobar" }, - { "foo%2fbar", NULL, "foo%2fbar" }, - { "foo%2Fbar", NULL, "foo%2Fbar" }, - { "foo%2fbar", "/", "foo/bar" }, - { "foo bar", NULL, "foo%20bar" }, - { "foo bar", " ", "foo bar" }, - { "fo\xc3\xb6" "bar", NULL, "fo%C3%B6bar" }, - { "fo\xc3\xb6 bar", " ", "fo%C3%B6 bar" }, - { "%", NULL, "%" }, -}; -static int num_normalization_tests = G_N_ELEMENTS (normalization_tests); - -static void -do_normalization_tests (void) -{ - char *normalized; - int i; - - g_test_bug ("680018"); - - for (i = 0; i < num_normalization_tests; i++) { - if (normalization_tests[i].unescape_extra) { - debug_printf (1, "<%s> unescaping <%s> => <%s>\n", - normalization_tests[i].uri_string, - normalization_tests[i].unescape_extra, - normalization_tests[i].result); - } else { - debug_printf (1, "<%s> => <%s>\n", - normalization_tests[i].uri_string, - normalization_tests[i].result); - } - - normalized = soup_uri_normalize (normalization_tests[i].uri_string, - normalization_tests[i].unescape_extra); - g_assert_cmpstr (normalized, ==, normalization_tests[i].result); - g_free (normalized); - } -} - -typedef struct { - const char *uri; - const char *mime_type; - const char *body; -} DataURITest; - -static const DataURITest data_tests[] = { - { "data:text/plain,foo%20bar", - "text/plain", - "foo bar" }, - { "data:text/plain;charset=utf-8,foo%20bar", - "text/plain;charset=utf-8", - "foo bar" }, - { "data:text/plain;base64,Zm9vIGJhcg==", - "text/plain", - "foo bar" }, - { "data:,foo%20bar", - "text/plain;charset=US-ASCII", - "foo bar" }, - { "data:;base64,Zm9vIGJhcg==", - "text/plain;charset=US-ASCII", - "foo bar" }, - { "data:,", - "text/plain;charset=US-ASCII", - "" }, - { "data:text/plain,", - "text/plain", - "" }, - { "data://text/plain,foo", - NULL, - NULL }, - { "http:text/plain,foo%20bar", - NULL, - NULL }, - { "./foo", - NULL, - NULL }, -}; - -static void -do_data_tests (void) -{ - int i; - - for (i = 0; i < G_N_ELEMENTS (data_tests); i++) { - GBytes *bytes; - char *content_type = NULL; - - bytes = soup_uri_decode_data_uri (data_tests[i].uri, &content_type); - if (!data_tests[i].body) { - g_assert_null (bytes); - g_assert_null (content_type); - - continue; - } - - g_assert_nonnull (bytes); - g_assert_cmpmem (g_bytes_get_data (bytes, NULL), g_bytes_get_size (bytes), - data_tests[i].body, strlen (data_tests[i].body)); - g_assert_cmpstr (content_type, ==, data_tests[i].mime_type); - - g_free (content_type); - g_bytes_unref (bytes); - } -} - -static void -test_uri_decode (void) -{ - gchar *decoded = soup_uri_decode ("%"); - g_assert_cmpstr (decoded, ==, "%"); - g_free (decoded); } int @@ -579,13 +53,7 @@ main (int argc, char **argv) test_init (argc, argv, NULL); - g_test_add_func ("/uri/absolute", do_absolute_uri_tests); - g_test_add_func ("/uri/relative", do_relative_uri_tests); g_test_add_func ("/uri/equality", do_equality_tests); - g_test_add_func ("/uri/null", do_soup_uri_null_tests); - g_test_add_func ("/uri/normalization", do_normalization_tests); - g_test_add_func ("/uri/data", do_data_tests); - g_test_add_func ("/uri/decode", test_uri_decode); ret = g_test_run (); diff --git a/tests/websocket-test.c b/tests/websocket-test.c index 9c9d9817..cc8b5a19 100644 --- a/tests/websocket-test.c +++ b/tests/websocket-test.c @@ -105,7 +105,7 @@ direct_connection_complete (GObject *object, { Test *test = user_data; GSocketConnection *conn; - SoupURI *uri; + GUri *uri; GError *error = NULL; GList *extensions = NULL; @@ -113,7 +113,7 @@ direct_connection_complete (GObject *object, result, &error); g_assert_no_error (error); - uri = soup_uri_new ("http://127.0.0.1/"); + uri = g_uri_parse ("http://127.0.0.1/", SOUP_HTTP_URI_FLAGS, NULL); if (test->enable_extensions) { SoupWebsocketExtension *extension; @@ -127,7 +127,7 @@ direct_connection_complete (GObject *object, SOUP_WEBSOCKET_CONNECTION_CLIENT, NULL, NULL, extensions); - soup_uri_free (uri); + g_uri_unref (uri); g_object_unref (conn); } @@ -139,7 +139,7 @@ got_connection (GSocket *listener, Test *test = user_data; GSocket *sock; GSocketConnection *conn; - SoupURI *uri; + GUri *uri; GList *extensions = NULL; GError *error = NULL; @@ -153,7 +153,7 @@ got_connection (GSocket *listener, if (test->no_server) test->raw_server = G_IO_STREAM (conn); else { - uri = soup_uri_new ("http://127.0.0.1/"); + uri = g_uri_parse ("http://127.0.0.1/", SOUP_HTTP_URI_FLAGS, NULL); if (test->enable_extensions) { SoupWebsocketExtension *extension; @@ -167,7 +167,7 @@ got_connection (GSocket *listener, SOUP_WEBSOCKET_CONNECTION_SERVER, NULL, NULL, extensions); - soup_uri_free (uri); + g_uri_unref (uri); g_object_unref (conn); } -- cgit v1.2.1