[libsoup] soup_header_g_string_append_param: if @value is a token, don't quote it
- From: Dan Winship <danw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libsoup] soup_header_g_string_append_param: if @value is a token, don't quote it
- Date: Fri, 9 Apr 2010 23:52:58 +0000 (UTC)
commit 7dfc7855fc9e41fd542c0cef7a229fe2c2e959ca
Author: Dan Winship <danw gnome org>
Date: Tue Apr 6 12:05:26 2010 -0400
soup_header_g_string_append_param: if @value is a token, don't quote it
also add soup_header_g_string_append_param_quoted(), for places that
need to guarantee they're adding a quoted-string, not a token, even if
a token would be syntactically correct. (eg, digest auth, where lots of
implementations are very very picky)
libsoup/soup-auth-digest.c | 14 ++++----
libsoup/soup-auth-domain-digest.c | 2 +-
libsoup/soup-headers.c | 59 ++++++++++++++++++++++++++++--------
libsoup/soup-headers.h | 3 ++
tests/header-parsing.c | 4 +-
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 f9c88bc..90718c6 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 f4a7f41..cee7745 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 9835392..5e73a3c 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 59f0e78..cc542c3 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 e8799b3..bc1b8cf 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 9aca27b..b2296be 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 */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]