diff options
author | Carlos Garcia Campos <cgarcia@igalia.com> | 2021-02-03 15:54:38 +0100 |
---|---|---|
committer | Carlos Garcia Campos <cgarcia@igalia.com> | 2021-02-03 15:54:38 +0100 |
commit | dde1a85cf5f8bfb042e6c47530c82b5c6c40353e (patch) | |
tree | d3d573662edaa43952197a806999b125db017783 | |
parent | ac985daae31def82869ac60ef1e9f2ebf3fd259f (diff) | |
download | libsoup-carlosgc/null-post-content-length.tar.gz |
session: Include Content-Length header for put and post requests with no bodycarlosgc/null-post-content-length
As suggested in the HTTP spec.
-rw-r--r-- | libsoup/soup-session.c | 13 | ||||
-rw-r--r-- | tests/request-body-test.c | 24 |
2 files changed, 33 insertions, 4 deletions
diff --git a/libsoup/soup-session.c b/libsoup/soup-session.c index d867684a..4509993a 100644 --- a/libsoup/soup-session.c +++ b/libsoup/soup-session.c @@ -1006,6 +1006,7 @@ soup_session_send_queue_item (SoupSession *session, { SoupSessionPrivate *priv = soup_session_get_instance_private (session); SoupMessageHeaders *request_headers; + const char *method; request_headers = soup_message_get_request_headers (item->msg); if (priv->user_agent) @@ -1042,6 +1043,18 @@ soup_session_send_queue_item (SoupSession *session, g_free (host); } + /* A user agent SHOULD send a Content-Length in a request message when + * no Transfer-Encoding is sent and the request method defines a meaning + * for an enclosed payload body. For example, a Content-Length header + * field is normally sent in a POST request even when the value is 0 + * (indicating an empty payload body). + */ + method = soup_message_get_method (item->msg); + if ((method == SOUP_METHOD_POST || method == SOUP_METHOD_PUT) && + soup_message_get_request_body_stream (item->msg) == NULL) { + soup_message_headers_set_content_length (request_headers, 0); + } + soup_message_starting (item->msg); if (item->state == SOUP_MESSAGE_RUNNING) soup_connection_send_request (item->conn, item, completion_cb, item); diff --git a/tests/request-body-test.c b/tests/request-body-test.c index 091633a9..e5d9ffa1 100644 --- a/tests/request-body-test.c +++ b/tests/request-body-test.c @@ -25,6 +25,7 @@ typedef enum { LARGE = 1 << 3, EMPTY = 1 << 4, NO_CONTENT_TYPE = 1 << 5, + NULL_STREAM = 1 << 6, } RequestTestFlags; static void @@ -44,6 +45,14 @@ setup_request_body (PutTestData *ptd, ptd->nwrote = 0; check = g_checksum_new (G_CHECKSUM_MD5); + if (flags & NULL_STREAM) { + ptd->bytes = NULL; + ptd->stream = NULL; + ptd->content_type = NULL; + + return check; + } + if (flags & LARGE) { static const unsigned int large_size = 1000000; char *large_data; @@ -83,7 +92,7 @@ restarted (SoupMessage *msg, g_object_unref (ptd->stream); ptd->stream = g_memory_input_stream_new_from_bytes (ptd->bytes); soup_message_set_request_body (msg, ptd->content_type, ptd->stream, -1); - } else { + } else if (ptd->bytes) { soup_message_set_request_body_from_bytes (msg, ptd->content_type, ptd->bytes); } } @@ -114,7 +123,7 @@ do_request_test (gconstpointer data) soup_message_set_request_body_from_bytes (msg, ptd.content_type, ptd.bytes); g_assert_cmpuint (soup_message_headers_get_content_length (request_headers), ==, g_bytes_get_size (ptd.bytes)); g_assert_true (soup_message_headers_get_encoding (request_headers) == SOUP_ENCODING_CONTENT_LENGTH); - } else { + } else if (!(flags & NULL_STREAM)) { soup_message_set_request_body (msg, ptd.content_type, ptd.stream, -1); g_assert_cmpuint (soup_message_headers_get_content_length (request_headers), ==, 0); g_assert_true (soup_message_headers_get_encoding (request_headers) == SOUP_ENCODING_CHUNKED); @@ -134,13 +143,18 @@ do_request_test (gconstpointer data) else soup_test_session_send_message (session, msg); soup_test_assert_message_status (msg, SOUP_STATUS_CREATED); - g_assert_cmpint (g_bytes_get_size (ptd.bytes), ==, ptd.nwrote); + if (flags & NULL_STREAM) { + g_assert_cmpint (ptd.nwrote, ==, 0); + g_assert_cmpstr (soup_message_headers_get_one (request_headers, "Content-Length"), ==, "0"); + } else { + g_assert_cmpint (g_bytes_get_size (ptd.bytes), ==, ptd.nwrote); + } server_md5 = soup_message_headers_get_one (soup_message_get_response_headers (msg), "Content-MD5"); g_assert_cmpstr (client_md5, ==, server_md5); - g_bytes_unref (ptd.bytes); + g_clear_pointer (&ptd.bytes, g_bytes_unref); g_clear_object (&ptd.stream); g_object_unref (msg); g_checksum_free (check); @@ -204,6 +218,7 @@ main (int argc, char **argv) g_test_add_data_func ("/request-body/sync/empty", GINT_TO_POINTER (BYTES | EMPTY), do_request_test); g_test_add_data_func ("/request-body/sync/no-content-type-stream", GINT_TO_POINTER (NO_CONTENT_TYPE), do_request_test); g_test_add_data_func ("/request-body/sync/no-content-type-bytes", GINT_TO_POINTER (BYTES | NO_CONTENT_TYPE), do_request_test); + g_test_add_data_func ("/request-body/sync/null", GINT_TO_POINTER (NULL_STREAM), do_request_test); g_test_add_data_func ("/request-body/async/stream", GINT_TO_POINTER (ASYNC), do_request_test); g_test_add_data_func ("/request-body/async/bytes", GINT_TO_POINTER (BYTES | ASYNC), do_request_test); g_test_add_data_func ("/request-body/async/restart-stream", GINT_TO_POINTER (RESTART | ASYNC), do_request_test); @@ -212,6 +227,7 @@ main (int argc, char **argv) g_test_add_data_func ("/request-body/async/empty", GINT_TO_POINTER (BYTES | EMPTY | ASYNC), do_request_test); g_test_add_data_func ("/request-body/async/no-content-type-stream", GINT_TO_POINTER (NO_CONTENT_TYPE | ASYNC), do_request_test); g_test_add_data_func ("/request-body/async/no-content-type-bytes", GINT_TO_POINTER (BYTES | NO_CONTENT_TYPE | ASYNC), do_request_test); + g_test_add_data_func ("/request-body/async/null", GINT_TO_POINTER (NULL_STREAM | ASYNC), do_request_test); ret = g_test_run (); |