summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlos Garcia Campos <cgarcia@igalia.com>2021-01-27 10:48:04 +0100
committerCarlos Garcia Campos <cgarcia@igalia.com>2021-01-27 10:48:04 +0100
commitc44a4eb070a7559d453fdd300670a2eddacce70b (patch)
treead277f20466dccfc184184e58571b3ee5b842d58
parent223a22d4e2a6e90d5a5f01382d4828e5efbad958 (diff)
downloadlibsoup-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.c48
-rw-r--r--tests/request-body-test.c31
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 ();