diff options
author | Carlos Garcia Campos <cgarcia@igalia.com> | 2021-01-27 10:48:04 +0100 |
---|---|---|
committer | Carlos Garcia Campos <cgarcia@igalia.com> | 2021-01-27 10:48:04 +0100 |
commit | c44a4eb070a7559d453fdd300670a2eddacce70b (patch) | |
tree | ad277f20466dccfc184184e58571b3ee5b842d58 | |
parent | 223a22d4e2a6e90d5a5f01382d4828e5efbad958 (diff) | |
download | libsoup-carlosgc/request-body-no-content-type.tar.gz |
soup-message: Allow to pass a NULL content type to soup_message_set_request_bodycarlosgc/request-body-no-content-type
If it's unknown or has already been set in headers. It was already
possible in libsoup 2 API just by setting the request body directly
instead of using the convenient API.
-rw-r--r-- | libsoup/soup-message.c | 48 | ||||
-rw-r--r-- | tests/request-body-test.c | 31 |
2 files changed, 49 insertions, 30 deletions
diff --git a/libsoup/soup-message.c b/libsoup/soup-message.c index afac1a1e..9b2bda0a 100644 --- a/libsoup/soup-message.c +++ b/libsoup/soup-message.c @@ -911,12 +911,13 @@ soup_message_new_from_multipart (const char *uri_string, /** * soup_message_set_request_body: * @msg: the message - * @content_type: (allow-none): MIME Content-Type of the body + * @content_type: (allow-none): MIME Content-Type of the body, or %NULL if unknown * @stream: (allow-none): a #GInputStream to read the request body from - * @content_length: the byte length of @tream or -1 if unknown + * @content_length: the byte length of @stream or -1 if unknown * - * Set the request body of a #SoupMessage. If - * @content_type is %NULL, the request body must be empty (or @stream %NULL) as well. + * Set the request body of a #SoupMessage. + * If @content_type is %NULL and @stream is not %NULL the Content-Type header will + * not be changed if present. * The request body needs to be set again in case @msg is restarted * (in case of redirection or authentication). */ @@ -927,22 +928,26 @@ soup_message_set_request_body (SoupMessage *msg, gssize content_length) { g_return_if_fail (SOUP_IS_MESSAGE (msg)); - g_return_if_fail (content_type != NULL || content_length == 0); - g_return_if_fail (content_type == NULL || G_IS_INPUT_STREAM (stream)); + g_return_if_fail (stream == NULL || G_IS_INPUT_STREAM (stream)); + g_return_if_fail (content_length == -1 || content_length >= 0); SoupMessagePrivate *priv = soup_message_get_instance_private (msg); g_clear_object (&priv->request_body_stream); - if (content_type) { - g_warn_if_fail (strchr (content_type, '/') != NULL); + if (stream) { + if (content_type) { + g_warn_if_fail (strchr (content_type, '/') != NULL); + + if (soup_message_headers_get_content_type (priv->request_headers, NULL) != content_type) + soup_message_headers_replace (priv->request_headers, "Content-Type", content_type); + } - if (soup_message_headers_get_content_type (priv->request_headers, NULL) != content_type) - soup_message_headers_replace (priv->request_headers, "Content-Type", content_type); if (content_length == -1) soup_message_headers_set_encoding (priv->request_headers, SOUP_ENCODING_CHUNKED); else soup_message_headers_set_content_length (priv->request_headers, content_length); + priv->request_body_stream = g_object_ref (stream); } else { soup_message_headers_remove (priv->request_headers, "Content-Type"); @@ -953,11 +958,12 @@ soup_message_set_request_body (SoupMessage *msg, /** * soup_message_set_request_body_from_bytes: * @msg: the message - * @content_type: (allow-none): MIME Content-Type of the body + * @content_type: (allow-none): MIME Content-Type of the body, or %NULL if unknown * @bytes: (allow-none): a #GBytes with the request body data * - * Set the request body of a #SoupMessage from #GBytes. If - * @content_type is %NULL, the request body must be empty (or @bytes %NULL) as well. + * Set the request body of a #SoupMessage from #GBytes. + * If @content_type is %NULL and @bytes is not %NULL the Content-Type header will + * not be changed if present. * The request body needs to be set again in case @msg is restarted * (in case of redirection or authentication). */ @@ -967,17 +973,15 @@ soup_message_set_request_body_from_bytes (SoupMessage *msg, GBytes *bytes) { g_return_if_fail (SOUP_IS_MESSAGE (msg)); - g_return_if_fail (content_type == NULL || bytes != NULL); - g_return_if_fail (content_type != NULL || g_bytes_get_size (bytes) == 0); - if (bytes) { - GInputStream *stream; + if (bytes) { + GInputStream *stream; - stream = g_memory_input_stream_new_from_bytes (bytes); - soup_message_set_request_body (msg, content_type, stream, g_bytes_get_size (bytes)); - g_object_unref (stream); - } else - soup_message_set_request_body (msg, NULL, NULL, 0); + stream = g_memory_input_stream_new_from_bytes (bytes); + soup_message_set_request_body (msg, content_type, stream, g_bytes_get_size (bytes)); + g_object_unref (stream); + } else + soup_message_set_request_body (msg, NULL, NULL, 0); } void diff --git a/tests/request-body-test.c b/tests/request-body-test.c index aa49f9a9..091633a9 100644 --- a/tests/request-body-test.c +++ b/tests/request-body-test.c @@ -14,6 +14,7 @@ typedef struct { SoupSession *session; GInputStream *stream; GBytes *bytes; + const char *content_type; int nwrote; } PutTestData; @@ -22,12 +23,13 @@ typedef enum { RESTART = 1 << 1, ASYNC = 1 << 2, LARGE = 1 << 3, - EMPTY = 1 << 4 + EMPTY = 1 << 4, + NO_CONTENT_TYPE = 1 << 5, } RequestTestFlags; static void wrote_body_data (SoupMessage *msg, - guint count, + guint count, PutTestData *ptd) { debug_printf (2, " wrote_body_data, %u bytes\n", count); @@ -61,6 +63,7 @@ setup_request_body (PutTestData *ptd, g_checksum_update (check, (guchar *)data, strlen (data)); } ptd->stream = flags & BYTES ? NULL : g_memory_input_stream_new_from_bytes (ptd->bytes); + ptd->content_type = flags & NO_CONTENT_TYPE ? NULL : "text/plain"; return check; } @@ -79,9 +82,9 @@ restarted (SoupMessage *msg, if (ptd->stream) { g_object_unref (ptd->stream); ptd->stream = g_memory_input_stream_new_from_bytes (ptd->bytes); - soup_message_set_request_body (msg, "text/plain", ptd->stream, -1); + soup_message_set_request_body (msg, ptd->content_type, ptd->stream, -1); } else { - soup_message_set_request_body_from_bytes (msg, "text/plain", ptd->bytes); + soup_message_set_request_body_from_bytes (msg, ptd->content_type, ptd->bytes); } } @@ -92,6 +95,7 @@ do_request_test (gconstpointer data) GUri *uri; PutTestData ptd; SoupMessage *msg; + SoupMessageHeaders *request_headers; const char *client_md5, *server_md5; GChecksum *check; @@ -105,10 +109,17 @@ do_request_test (gconstpointer data) client_md5 = g_checksum_get_string (check); msg = soup_message_new_from_uri ("PUT", uri); - if (flags & BYTES) - soup_message_set_request_body_from_bytes (msg, flags & EMPTY ? NULL : "text/plain", ptd.bytes); - else - soup_message_set_request_body (msg, "text/plain", ptd.stream, -1); + request_headers = soup_message_get_request_headers (msg); + if (flags & BYTES) { + 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 { + 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); + } + g_assert_cmpstr (soup_message_headers_get_one (request_headers, "Content-Type"), ==, ptd.content_type); if (flags & RESTART) { g_signal_connect (msg, "restarted", @@ -191,12 +202,16 @@ main (int argc, char **argv) g_test_add_data_func ("/request-body/sync/restart-bytes", GINT_TO_POINTER (RESTART | BYTES), do_request_test); g_test_add_data_func ("/request-body/sync/large", GINT_TO_POINTER (BYTES | LARGE), do_request_test); 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/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); g_test_add_data_func ("/request-body/async/restart-bytes", GINT_TO_POINTER (RESTART | ASYNC | BYTES), do_request_test); g_test_add_data_func ("/request-body/async/large", GINT_TO_POINTER (BYTES | LARGE | ASYNC), do_request_test); 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); ret = g_test_run (); |