[libsoup] soup-multipart: Fix generation of Content-Disposition for broken servers



commit 429ae942574c9f62938ad77eebe70aed0500b665
Author: Dan Winship <danw gnome org>
Date:   Mon Apr 4 13:21:16 2011 -0400

    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.

 libsoup/soup-headers.c   |   92 ++++++++++++++++++++++++++++------------------
 libsoup/soup-multipart.c |    4 +-
 2 files changed, 58 insertions(+), 38 deletions(-)
---
diff --git a/libsoup/soup-headers.c b/libsoup/soup-headers.c
index 33f6f6f..2b9c29d 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);
 }
diff --git a/libsoup/soup-multipart.c b/libsoup/soup-multipart.c
index 45deed6..31d4aba 100644
--- a/libsoup/soup-multipart.c
+++ b/libsoup/soup-multipart.c
@@ -371,10 +371,10 @@ soup_multipart_append_form_file (SoupMultipart *multipart,
 
 	headers = soup_message_headers_new (SOUP_MESSAGE_HEADERS_MULTIPART);
 	disposition = g_string_new ("form-data; ");
-	soup_header_g_string_append_param (disposition, "name", control_name);
+	soup_header_g_string_append_param_quoted (disposition, "name", control_name);
 	if (filename) {
 		g_string_append (disposition, "; ");
-		soup_header_g_string_append_param (disposition, "filename", filename);
+		soup_header_g_string_append_param_quoted (disposition, "filename", filename);
 	}
 	soup_message_headers_append (headers, "Content-Disposition",
 				     disposition->str);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]