summaryrefslogtreecommitdiff
path: root/libsoup/soup-headers.c
diff options
context:
space:
mode:
authorDan Winship <danw@gnome.org>2011-04-04 13:21:16 -0400
committerDan Winship <danw@gnome.org>2011-04-07 08:36:07 -0400
commit429ae942574c9f62938ad77eebe70aed0500b665 (patch)
tree100c158add13abe8fdb99ff45f560d5fc62de654 /libsoup/soup-headers.c
parentd94e3e1abfecad4c2f64b44db854352d946d7551 (diff)
downloadlibsoup-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.c92
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);
}