soup-message-server-io: fix processing of IPv6 HTTP/1.0 messages
authorDan Winship <danw@gnome.org>
Tue, 14 Feb 2012 02:38:39 +0000 (21:38 -0500)
committerDan Winship <danw@gnome.org>
Tue, 14 Feb 2012 02:38:39 +0000 (21:38 -0500)
When receiving an HTTP/1.0 message with no Host header on an IPv6
interface, SoupServer would internally generate an invalid URL and
then return 400 Bad Request. Fix, and add a test for it.

https://bugzilla.gnome.org/show_bug.cgi?id=666399

libsoup/soup-message-server-io.c
tests/misc-test.c

index 624fad6..8b07ebf 100644 (file)
@@ -82,14 +82,14 @@ parse_request_headers (SoupMessage *msg, char *headers, guint headers_len,
        } else if (priv->http_version == SOUP_HTTP_1_0) {
                /* No Host header, no AbsoluteUri */
                SoupAddress *addr = soup_socket_get_local_address (sock);
-               const char *host = soup_address_get_physical (addr);
 
-               url = g_strdup_printf ("%s://%s:%d%s",
-                                      soup_socket_is_ssl (sock) ? "https" : "http",
-                                      host, soup_address_get_port (addr),
-                                      req_path);
-               uri = soup_uri_new (url);
-               g_free (url);
+               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, soup_address_get_physical (addr));
+               soup_uri_set_port (uri, soup_address_get_port (addr));
+               soup_uri_set_path (uri, req_path);
        } else
                uri = NULL;
 
index 358031d..321d41f 100644 (file)
@@ -1222,6 +1222,56 @@ do_dot_dot_test (void)
        soup_test_session_abort_unref (session);
 }
 
+static void
+do_ipv6_test (void)
+{
+       SoupServer *ipv6_server;
+       SoupURI *ipv6_uri;
+       SoupAddress *ipv6_addr;
+       SoupSession *session;
+       SoupMessage *msg;
+
+       debug_printf (1, "\nIPv6 server test\n");
+
+       ipv6_addr = soup_address_new ("::1", SOUP_ADDRESS_ANY_PORT);
+       soup_address_resolve_sync (ipv6_addr, NULL);
+       ipv6_server = soup_server_new (SOUP_SERVER_INTERFACE, ipv6_addr,
+                                      NULL);
+       g_object_unref (ipv6_addr);
+       soup_server_add_handler (ipv6_server, NULL, server_callback, NULL, NULL);
+       soup_server_run_async (ipv6_server);
+
+       ipv6_uri = soup_uri_new ("http://[::1]/");
+       soup_uri_set_port (ipv6_uri, soup_server_get_port (ipv6_server));
+
+       session = soup_test_session_new (SOUP_TYPE_SESSION_ASYNC, NULL);
+
+       debug_printf (1, "  HTTP/1.1\n");
+       msg = soup_message_new_from_uri ("GET", ipv6_uri);
+       soup_session_send_message (session, msg);
+       if (!SOUP_STATUS_IS_SUCCESSFUL (msg->status_code)) {
+               debug_printf (1, "    request failed: %d %s\n",
+                             msg->status_code, msg->reason_phrase);
+               errors++;
+       }
+       g_object_unref (msg);
+
+       debug_printf (1, "  HTTP/1.0\n");
+       msg = soup_message_new_from_uri ("GET", ipv6_uri);
+       soup_message_set_http_version (msg, SOUP_HTTP_1_0);
+       soup_session_send_message (session, msg);
+       if (!SOUP_STATUS_IS_SUCCESSFUL (msg->status_code)) {
+               debug_printf (1, "    request failed: %d %s\n",
+                             msg->status_code, msg->reason_phrase);
+               errors++;
+       }
+       g_object_unref (msg);
+
+       soup_uri_free (ipv6_uri);
+       soup_test_session_abort_unref (session);
+       soup_test_server_quit_unref (ipv6_server);
+}
+
 int
 main (int argc, char **argv)
 {
@@ -1260,6 +1310,7 @@ main (int argc, char **argv)
        do_aliases_test ();
        do_non_persistent_connection_test ();
        do_dot_dot_test ();
+       do_ipv6_test ();
 
        soup_uri_free (base_uri);
        soup_uri_free (ssl_base_uri);