[libsoup/websockets-fixes-2.66: 1/5] WebSockets: handle Set-Cookie header in handshake response




commit 2ae6365a6aca7f561cec8ec3e88afa35bf37acd2
Author: Carlos Garcia Campos <cgarcia igalia com>
Date:   Thu Aug 29 12:27:23 2019 +0200

    WebSockets: handle Set-Cookie header in handshake response
    
    We are currently ignoring the Set-Cookie in handshake response because
    the SoupCookieJar feature handles the header in the got-headers signal
    that is never emitted for informational messages. SoupCookieJar should
    also handle Set-Cookie for switching protocols informational messages.

 libsoup/soup-cookie-jar.c |  4 +++
 tests/websocket-test.c    | 76 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 80 insertions(+)
---
diff --git a/libsoup/soup-cookie-jar.c b/libsoup/soup-cookie-jar.c
index b2b78909..f5f7716d 100644
--- a/libsoup/soup-cookie-jar.c
+++ b/libsoup/soup-cookie-jar.c
@@ -714,6 +714,10 @@ soup_cookie_jar_request_queued (SoupSessionFeature *feature,
                                         "Set-Cookie",
                                         G_CALLBACK (process_set_cookie_header),
                                         feature);
+        soup_message_add_status_code_handler (msg, "got-informational",
+                                              SOUP_STATUS_SWITCHING_PROTOCOLS,
+                                              G_CALLBACK (process_set_cookie_header),
+                                              feature);
 }
 
 static void
diff --git a/tests/websocket-test.c b/tests/websocket-test.c
index d9afd28c..320972ea 100644
--- a/tests/websocket-test.c
+++ b/tests/websocket-test.c
@@ -35,6 +35,8 @@ typedef struct {
        gboolean no_server;
        GIOStream *raw_server;
 
+       GList *initial_cookies;
+
        GMutex mutex;
 } Test;
 
@@ -216,10 +218,19 @@ client_connect (Test *test,
                gpointer user_data)
 {
        char *url;
+       SoupCookieJar *jar;
+       GList *l;
 
        if (!test->session)
                test->session = soup_test_session_new (SOUP_TYPE_SESSION, NULL);
 
+       jar = soup_cookie_jar_new ();
+       soup_session_add_feature (test->session, SOUP_SESSION_FEATURE (jar));
+       for (l = test->initial_cookies; l; l = g_list_next (l))
+               soup_cookie_jar_add_cookie (jar, (SoupCookie *)l->data);
+       g_clear_pointer (&test->initial_cookies, g_list_free);
+       g_object_unref (jar);
+
        url = g_strdup_printf ("ws://127.0.0.1:%u/unix", test->port);
        test->msg = soup_message_new ("GET", url);
        g_free (url);
@@ -1265,6 +1276,64 @@ test_client_context (Test *test,
        g_assert_no_error (test->client_error);
 }
 
+static void
+test_cookies_in_request (Test *test,
+                         gconstpointer data)
+{
+        SoupCookie *cookie;
+        const char *cookie_header;
+        SoupCookie *requested_cookie;
+
+        cookie = soup_cookie_new ("foo", "bar", "127.0.0.1", "/", -1);
+        test->initial_cookies = g_list_prepend (test->initial_cookies, soup_cookie_copy (cookie));
+
+        setup_soup_server (test, NULL, NULL, got_server_connection, test);
+        client_connect (test, NULL, NULL, got_client_connection, test);
+        WAIT_UNTIL (test->server != NULL);
+        WAIT_UNTIL (test->client != NULL || test->client_error != NULL);
+        g_assert_no_error (test->client_error);
+
+        cookie_header = soup_message_headers_get_one (test->msg->request_headers, "Cookie");
+        requested_cookie = soup_cookie_parse (cookie_header, NULL);
+        g_assert_true (soup_cookie_equal (cookie, requested_cookie));
+        soup_cookie_free (cookie);
+        soup_cookie_free (requested_cookie);
+}
+
+static void
+cookies_test_websocket_server_request_started (SoupServer *server, SoupMessage *msg,
+                                               SoupClientContext *client, gpointer user_data)
+{
+        soup_message_headers_append (msg->response_headers, "Set-Cookie", "foo=bar; Path=/");
+}
+
+static void
+test_cookies_in_response (Test *test,
+                          gconstpointer data)
+{
+        SoupCookieJar *jar;
+        GSList *cookies;
+        SoupCookie *cookie;
+
+        setup_soup_server (test, NULL, NULL, got_server_connection, test);
+        g_signal_connect (test->soup_server, "request-started",
+                          G_CALLBACK (cookies_test_websocket_server_request_started),
+                          NULL);
+        client_connect (test, NULL, NULL, got_client_connection, test);
+        WAIT_UNTIL (test->server != NULL);
+        WAIT_UNTIL (test->client != NULL || test->client_error != NULL);
+        g_assert_no_error (test->client_error);
+
+        jar = SOUP_COOKIE_JAR (soup_session_get_feature (test->session, SOUP_TYPE_COOKIE_JAR));
+        cookies = soup_cookie_jar_all_cookies (jar);
+        g_assert_nonnull (cookies);
+        g_assert_cmpuint (g_slist_length (cookies), ==, 1);
+        cookie = soup_cookie_new ("foo", "bar", "127.0.0.1", "/", -1);
+        g_assert_true (soup_cookie_equal (cookie, (SoupCookie *)cookies->data));
+        g_slist_free_full (cookies, (GDestroyNotify)soup_cookie_free);
+        soup_cookie_free (cookie);
+}
+
 int
 main (int argc,
       char *argv[])
@@ -1425,6 +1494,13 @@ main (int argc,
                    test_client_context,
                    teardown_soup_connection);
 
+        g_test_add ("/websocket/soup/cookies-in-request", Test, NULL, NULL,
+                    test_cookies_in_request,
+                    teardown_soup_connection);
+        g_test_add ("/websocket/soup/cookies-in-response", Test, NULL, NULL,
+                    test_cookies_in_response,
+                    teardown_soup_connection);
+
        ret = g_test_run ();
 
        test_cleanup ();


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]