[libsoup/nacho/fixes] Improve support for rfc 7230




commit d71e0fe32a4f02a93b0711c657060085ff77e81a
Author: Ignacio Casal Quinteiro <qignacio amazon com>
Date:   Wed Jul 21 13:34:57 2021 +0200

    Improve support for rfc 7230
    
    A server MUST NOT send a Content-Length header field in any response
    with a status code of 1xx (Informational) or 204 (No Content)

 libsoup/server/soup-server-io.c | 10 +++++-
 tests/misc-test.c               | 77 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 86 insertions(+), 1 deletion(-)
---
diff --git a/libsoup/server/soup-server-io.c b/libsoup/server/soup-server-io.c
index 5449c0f1..d1af115b 100644
--- a/libsoup/server/soup-server-io.c
+++ b/libsoup/server/soup-server-io.c
@@ -314,7 +314,15 @@ write_headers (SoupServerMessage  *msg,
         else
                 *encoding = claimed_encoding;
 
-        if (claimed_encoding == SOUP_ENCODING_CONTENT_LENGTH &&
+        /* Per rfc 7230:
+         * A server MUST NOT send a Content-Length header field in any response
+         * with a status code of 1xx (Informational) or 204 (No Content).
+         */
+
+        if (status_code  == SOUP_STATUS_NO_CONTENT ||
+            SOUP_STATUS_IS_INFORMATIONAL (status_code)) {
+                soup_message_headers_remove (response_headers, "Content-Length");
+        } else if (claimed_encoding == SOUP_ENCODING_CONTENT_LENGTH &&
             !soup_message_headers_get_content_length (response_headers)) {
                 SoupMessageBody *response_body;
 
diff --git a/tests/misc-test.c b/tests/misc-test.c
index efbe2798..0318aff7 100644
--- a/tests/misc-test.c
+++ b/tests/misc-test.c
@@ -861,6 +861,82 @@ do_new_request_on_redirect_test (void)
         soup_test_session_abort_unref (session);
 }
 
+static void
+wrote_informational_check_content_length (SoupServerMessage *msg,
+                                          gpointer           user_data)
+{
+        SoupMessageHeaders *response_headers;
+
+        response_headers = soup_server_message_get_response_headers (msg);
+        g_assert_null (soup_message_headers_get_one (response_headers, "Content-Length"));
+}
+
+static void
+upgrade_server_check_content_length_callback (SoupServer        *server,
+                                              SoupServerMessage *msg,
+                                              const char        *path,
+                                              GHashTable        *query,
+                                              gpointer           data)
+{
+        SoupMessageHeaders *request_headers;
+
+        if (soup_server_message_get_method (msg) != SOUP_METHOD_GET) {
+                soup_server_message_set_status (msg, SOUP_STATUS_NOT_IMPLEMENTED, NULL);
+                return;
+        }
+
+        soup_server_message_set_status (msg, SOUP_STATUS_SWITCHING_PROTOCOLS, NULL);
+
+        request_headers = soup_server_message_get_request_headers (msg);
+        soup_message_headers_append (request_headers, "Upgrade", "ECHO");
+        soup_message_headers_append (request_headers, "Connection", "upgrade");
+
+        g_signal_connect (msg, "wrote-informational",
+                          G_CALLBACK (wrote_informational_check_content_length), NULL);
+}
+
+static void
+switching_protocols_check_length (SoupMessage *msg,
+                                  gpointer     user_data)
+{
+        SoupMessageHeaders *response_headers;
+
+        response_headers = soup_message_get_response_headers (msg);
+        g_assert_null (soup_message_headers_get_one (response_headers, "Content-Length"));
+}
+
+static void
+do_response_informational_content_length_test (void)
+{
+        SoupServer *server;
+        SoupSession *session;
+        SoupMessage *msg;
+        SoupMessageHeaders *request_headers;
+        GInputStream *stream;
+        GError *error = NULL;
+
+        server = soup_test_server_new (SOUP_TEST_SERVER_IN_THREAD);
+        soup_server_add_handler (server, NULL, upgrade_server_check_content_length_callback, NULL, NULL);
+
+        session = soup_test_session_new (NULL);
+        msg = soup_message_new_from_uri ("GET", base_uri);
+        request_headers = soup_message_get_request_headers (msg);
+        soup_message_headers_append (request_headers, "Upgrade", "echo");
+        soup_message_headers_append (request_headers, "Connection", "upgrade");
+
+        soup_message_add_status_code_handler (msg, "got-informational",
+                                              SOUP_STATUS_SWITCHING_PROTOCOLS,
+                                              G_CALLBACK (switching_protocols_check_length), NULL);
+
+        stream = soup_session_send (session, msg, NULL, &error);
+        g_assert_null (stream);
+        g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CONNECTION_CLOSED);
+        g_object_unref (msg);
+
+        soup_test_session_abort_unref (session);
+        soup_test_server_quit_unref (server);
+}
+
 int
 main (int argc, char **argv)
 {
@@ -896,6 +972,7 @@ main (int argc, char **argv)
         g_test_add_func ("/misc/connection-id", do_connection_id_test);
         g_test_add_func ("/misc/remote-address", do_remote_address_test);
         g_test_add_func ("/misc/new-request-on-redirect", do_new_request_on_redirect_test);
+        g_test_add_func ("/misc/response/informational/content-length", 
do_response_informational_content_length_test);
 
        ret = g_test_run ();
 


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