GNOME Bugzilla – Bug 614198
No Content-Transfer-Encoding should be used in multipart within HTTP
Last modified: 2010-04-09 23:53:49 UTC
When using the multipart/form-data, libsoup insert the header "Content-Transfer-Encoding". This causes problems with some servers I try to upload files to. According to RFC 2616 Section 3.6 Transfer Codings <cite> Transfer-codings are analogous to the Content-Transfer-Encoding values of MIME [7], which were designed to enable safe transport of binary data over a 7-bit transport service. However, safe transport has a different focus for an 8bit-clean transfer protocol. In HTTP, the only unsafe characteristic of message-bodies is the difficulty in determining the exact body length (section 7.2.2), or the desire to encrypt data over a shared transport. </cite> and Section 19.4.5 No Content-Transfer-Encoding <cite> HTTP does not use the Content-Transfer-Encoding (CTE) field of RFC 2045. Proxies and gateways from MIME-compliant protocols to HTTP MUST remove any non-identity CTE ("quoted-printable" or "base64") encoding prior to delivering the response message to an HTTP client. Proxies and gateways from HTTP to MIME-compliant protocols are responsible for ensuring that the message is in the correct format and encoding for safe transport on that protocol, where "safe transport" is defined by the limitations of the protocol being used. Such a proxy or gateway SHOULD label the data with an appropriate Content-Transfer-Encoding if doing so will improve the likelihood of safe transport over the destination protocol. </cite> I believe it is incorrect to use the header "Content-Transfer-Encoding" within HTTP. This can be supported by the fact that Mozilla Firefox do *not* insert "Content-Transfer-Encoding" in multipart when uploading files ascii-text, non-ascii-text nor binary data. This is easily fixed in soup-multipart.c in function soup_multipart_append_form_file () by removing the following lines: if (content_type && strncmp (content_type, "text/", 5) != 0) { soup_message_headers_append (headers, "Content-Transfer-Encoding", "binary"); } else { soup_message_headers_append (headers, "Content-Transfer-Encoding", "8bit"); }
So first, some explanation. HTTP doesn't use Content-Transfer-Encoding *itself*, but when you send a multipart body, that body is opaque to HTTP, and interpreted according to MIME rules (RFC 2616, 3.7.2) and so may use MIME headers that HTTP itself does not use. In this particular case, as the comment immediately above the quoted lines from soup-multipart.c says: /* The HTML spec says we need to set Content-Transfer-Encoding * if the data is not 7bit. The relevant spec quote is from section 17.13.4 of the HTML 4.01 spec: Each part may be encoded and the "Content-Transfer-Encoding" header supplied if the value of that part does not conform to the default (7BIT) encoding (see [RFC2045], section 6) The HTML5 spec removes that explicit rule though, and just refers to RFC 2388, which, admittedly, also seems to suggest that it's required, but doesn't go right out and say it... All that said, if the big browsers don't do it this way, then we shouldn't either.
fixed in master, will go into 2.30.1