diff options
author | Dan Winship <danw@gnome.org> | 2011-04-04 13:21:16 -0400 |
---|---|---|
committer | Dan Winship <danw@gnome.org> | 2011-04-07 08:36:07 -0400 |
commit | 429ae942574c9f62938ad77eebe70aed0500b665 (patch) | |
tree | 100c158add13abe8fdb99ff45f560d5fc62de654 /libsoup/soup-headers.c | |
parent | d94e3e1abfecad4c2f64b44db854352d946d7551 (diff) | |
download | libsoup-429ae942574c9f62938ad77eebe70aed0500b665.tar.gz |
soup-multipart: Fix generation of Content-Disposition for broken servers
Some servers require that Content-Disposition headers use
quoted-string values, even if the provided filename can be represented
as a token. So use soup_header_g_string_append_param_quoted(), but also
change that to fall back to using RFC 5987 encoding if necessary, so
that we can still specify UTF-8-encoded filenames.
Diffstat (limited to 'libsoup/soup-headers.c')
-rw-r--r-- | libsoup/soup-headers.c | 92 |
1 files changed, 56 insertions, 36 deletions
diff --git a/libsoup/soup-headers.c b/libsoup/soup-headers.c index 33f6f6f4..2b9c29df 100644 --- a/libsoup/soup-headers.c +++ b/libsoup/soup-headers.c @@ -844,6 +844,57 @@ append_param_rfc5987 (GString *string, g_free (encoded); } +static void +append_param_quoted (GString *string, + const char *name, + const char *value) +{ + int len; + + g_string_append (string, name); + g_string_append (string, "=\""); + while (*value) { + while (*value == '\\' || *value == '"') { + g_string_append_c (string, '\\'); + g_string_append_c (string, *value++); + } + len = strcspn (value, "\\\""); + g_string_append_len (string, value, len); + value += len; + } + g_string_append_c (string, '"'); +} + +static void +append_param_internal (GString *string, + const char *name, + const char *value, + gboolean allow_token) +{ + const char *v; + gboolean use_token = allow_token; + + for (v = value; *v; v++) { + if (*v & 0x80) { + if (g_utf8_validate (value, -1, NULL)) { + append_param_rfc5987 (string, name, value); + return; + } else { + use_token = FALSE; + break; + } + } else if (!soup_char_is_token (*v)) + use_token = FALSE; + } + + if (use_token) { + g_string_append (string, name); + g_string_append_c (string, '='); + g_string_append (string, value); + } else + append_param_quoted (string, name, value); +} + /** * soup_header_g_string_append_param_quoted: * @string: a #GString being used to construct an HTTP header value @@ -853,6 +904,9 @@ append_param_rfc5987 (GString *string, * Appends something like <literal>@name="@value"</literal> to * @string, taking care to escape any quotes or backslashes in @value. * + * If @value is (non-ASCII) UTF-8, this will instead use RFC 5987 + * encoding, just like soup_header_g_string_append_param(). + * * Since: 2.32 **/ void @@ -860,24 +914,11 @@ 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 == '"') { - g_string_append_c (string, '\\'); - g_string_append_c (string, *value++); - } - len = strcspn (value, "\\\""); - g_string_append_len (string, value, len); - value += len; - } - g_string_append_c (string, '"'); + append_param_internal (string, name, value, FALSE); } /** @@ -905,9 +946,6 @@ 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); @@ -916,23 +954,5 @@ soup_header_g_string_append_param (GString *string, return; } - for (v = value; *v; v++) { - if (*v & 0x80) { - if (g_utf8_validate (value, -1, NULL)) { - append_param_rfc2231 (string, name, value); - return; - } else { - token = FALSE; - break; - } - } else if (!soup_char_is_token (*v)) - token = FALSE; - } - - 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); + append_param_internal (string, name, value, TRUE); } |