diff options
-rw-r--r-- | libsoup/soup-auth-digest.c | 14 | ||||
-rw-r--r-- | libsoup/soup-auth-domain-digest.c | 2 | ||||
-rw-r--r-- | libsoup/soup-headers.c | 59 | ||||
-rw-r--r-- | libsoup/soup-headers.h | 3 | ||||
-rw-r--r-- | tests/header-parsing.c | 4 | ||||
-rw-r--r-- | tests/sniffing-test.c | 2 |
6 files changed, 60 insertions, 24 deletions
diff --git a/libsoup/soup-auth-digest.c b/libsoup/soup-auth-digest.c index f9c88bc5..90718c6c 100644 --- a/libsoup/soup-auth-digest.c +++ b/libsoup/soup-auth-digest.c @@ -436,30 +436,30 @@ get_authorization (SoupAuth *auth, SoupMessage *msg) out = g_string_new ("Digest "); - soup_header_g_string_append_param (out, "username", priv->user); + soup_header_g_string_append_param_quoted (out, "username", priv->user); g_string_append (out, ", "); - soup_header_g_string_append_param (out, "realm", auth->realm); + soup_header_g_string_append_param_quoted (out, "realm", auth->realm); g_string_append (out, ", "); - soup_header_g_string_append_param (out, "nonce", priv->nonce); + soup_header_g_string_append_param_quoted (out, "nonce", priv->nonce); g_string_append (out, ", "); - soup_header_g_string_append_param (out, "uri", url); + soup_header_g_string_append_param_quoted (out, "uri", url); g_string_append (out, ", "); algorithm = soup_auth_digest_get_algorithm (priv->algorithm); g_string_append_printf (out, "algorithm=%s", algorithm); g_free (algorithm); g_string_append (out, ", "); - soup_header_g_string_append_param (out, "response", response); + soup_header_g_string_append_param_quoted (out, "response", response); if (priv->opaque) { g_string_append (out, ", "); - soup_header_g_string_append_param (out, "opaque", priv->opaque); + soup_header_g_string_append_param_quoted (out, "opaque", priv->opaque); } if (priv->qop) { char *qop = soup_auth_digest_get_qop (priv->qop); g_string_append (out, ", "); - soup_header_g_string_append_param (out, "cnonce", priv->cnonce); + soup_header_g_string_append_param_quoted (out, "cnonce", priv->cnonce); g_string_append_printf (out, ", nc=%.8x, qop=%s", priv->nc, qop); g_free (qop); diff --git a/libsoup/soup-auth-domain-digest.c b/libsoup/soup-auth-domain-digest.c index f4a7f412..cee77451 100644 --- a/libsoup/soup-auth-domain-digest.c +++ b/libsoup/soup-auth-domain-digest.c @@ -374,7 +374,7 @@ challenge (SoupAuthDomain *domain, SoupMessage *msg) GString *str; str = g_string_new ("Digest "); - soup_header_g_string_append_param (str, "realm", soup_auth_domain_get_realm (domain)); + soup_header_g_string_append_param_quoted (str, "realm", soup_auth_domain_get_realm (domain)); g_string_append_printf (str, ", nonce=\"%lu%lu\"", (unsigned long) msg, (unsigned long) time (0)); diff --git a/libsoup/soup-headers.c b/libsoup/soup-headers.c index 98353927..5e73a3ca 100644 --- a/libsoup/soup-headers.c +++ b/libsoup/soup-headers.c @@ -795,21 +795,42 @@ soup_header_free_param_list (GHashTable *param_list) } static void -append_param_rfc2231 (GString *string, const char *value) +append_param_rfc2231 (GString *string, + const char *name, + const char *value) { char *encoded; + g_string_append (string, name); g_string_append (string, "*=UTF-8''"); encoded = soup_uri_encode (value, " *'%()<>@,;:\\\"/[]?="); g_string_append (string, encoded); g_free (encoded); } -static void -append_param_quoted (GString *string, const char *value) +/** + * soup_header_g_string_append_param_quoted: + * @string: a #GString being used to construct an HTTP header value + * @name: a parameter name + * @value: a parameter value + * + * Appends something like <literal>@name="@value"</literal> to + * @string, taking care to escape any quotes or backslashes in @value. + * + * Since: 2.32 + **/ +void +soup_header_g_string_append_param_quoted (GString *string, + const char *name, + const char *value) { int len; + g_return_if_fail (string != NULL); + g_return_if_fail (name != NULL); + g_return_if_fail (value != NULL); + + g_string_append (string, name); g_string_append (string, "=\""); while (*value) { while (*value == '\\' || *value == '"') { @@ -829,9 +850,9 @@ append_param_quoted (GString *string, const char *value) * @name: a parameter name * @value: a parameter value, or %NULL * - * Appends something like <literal>@name="@value"</literal> to - * @string, taking care to appropriately escape any quotes or - * backslashes in @value. + * Appends something like <literal>@name=@value</literal> to @string, + * taking care to quote @value if needed, and if so, to escape any + * quotes or backslashes in @value. * * Alternatively, if @value is a non-ASCII UTF-8 string, it will be * appended using RFC2231 syntax. Although in theory this is supposed @@ -844,26 +865,38 @@ append_param_quoted (GString *string, const char *value) * Since: 2.26 **/ void -soup_header_g_string_append_param (GString *string, const char *name, +soup_header_g_string_append_param (GString *string, + const char *name, const char *value) { const char *v; + gboolean token = TRUE; g_return_if_fail (string != NULL); g_return_if_fail (name != NULL); - g_string_append (string, name); - if (!value) + if (!value) { + g_string_append (string, name); return; + } for (v = value; *v; v++) { if (*v & 0x80) { if (g_utf8_validate (value, -1, NULL)) { - append_param_rfc2231 (string, value); + append_param_rfc2231 (string, name, value); return; - } else + } else { + token = FALSE; break; - } + } + } else if (!soup_char_is_token (*v)) + token = FALSE; } - append_param_quoted (string, value); + + if (token) { + g_string_append (string, name); + g_string_append_c (string, '='); + g_string_append (string, value); + } else + soup_header_g_string_append_param_quoted (string, name, value); } diff --git a/libsoup/soup-headers.h b/libsoup/soup-headers.h index 59f0e781..cc542c34 100644 --- a/libsoup/soup-headers.h +++ b/libsoup/soup-headers.h @@ -53,6 +53,9 @@ void soup_header_free_param_list (GHashTable *param_list); void soup_header_g_string_append_param (GString *string, const char *name, const char *value); +void soup_header_g_string_append_param_quoted (GString *string, + const char *name, + const char *value); G_END_DECLS diff --git a/tests/header-parsing.c b/tests/header-parsing.c index e8799b3f..bc1b8cfc 100644 --- a/tests/header-parsing.c +++ b/tests/header-parsing.c @@ -882,7 +882,7 @@ do_rfc2231_tests (void) #define CONTENT_TYPE_TEST_MIME_TYPE "text/plain" #define CONTENT_TYPE_TEST_ATTRIBUTE "charset" #define CONTENT_TYPE_TEST_VALUE "US-ASCII" -#define CONTENT_TYPE_TEST_HEADER "text/plain; charset=\"US-ASCII\"" +#define CONTENT_TYPE_TEST_HEADER "text/plain; charset=US-ASCII" #define CONTENT_TYPE_BAD_HEADER "plain text, not text/html" @@ -963,7 +963,7 @@ struct { { "five", "test with \xC3\xA1\xC3\xA7\xC4\x89\xC3\xA8\xC3\xB1\xC5\xA3\xC5\xA1" } }; -#define TEST_PARAMS_RESULT "one=\"foo\", two=\"test with spaces\", three=\"test with \\\"quotes\\\" and \\\\s\", four, five*=UTF-8''test%20with%20%C3%A1%C3%A7%C4%89%C3%A8%C3%B1%C5%A3%C5%A1" +#define TEST_PARAMS_RESULT "one=foo, two=\"test with spaces\", three=\"test with \\\"quotes\\\" and \\\\s\", four, five*=UTF-8''test%20with%20%C3%A1%C3%A7%C4%89%C3%A8%C3%B1%C5%A3%C5%A1" static void do_append_param_tests (void) diff --git a/tests/sniffing-test.c b/tests/sniffing-test.c index 9aca27bf..b2296bec 100644 --- a/tests/sniffing-test.c +++ b/tests/sniffing-test.c @@ -540,7 +540,7 @@ main (int argc, char **argv) test_sniffing ("/multiple_headers/home.gif", "image/gif"); /* Test that we keep the parameters when sniffing */ - test_sniffing ("/type/text_html; charset=\"UTF-8\"/test.html", "text/html; charset=\"UTF-8\""); + test_sniffing ("/type/text_html; charset=UTF-8/test.html", "text/html; charset=UTF-8"); /* Test that disabling the sniffer works correctly */ |