Closed Andrapyre closed 8 months ago
@lihaoyi , could you take a look at this?
@Andrapyre could you explain why the current code does not already do this? I see MultiPartFormRequestBlob
already has the following:
override def headers = Seq(
"Content-Type" -> s"multipart/form-data; boundary=$boundary"
)
Is there some reason that isn't working?
@lihaoyi , yes, the file upload request should look something like the following:
POST /upload HTTP/1.1
Content-Type: multipart/form-data; boundary=3b412ae8-c491-4988-8299-0aa83a06d342
Accept: */*
Authorization: auth_token
Accept-Encoding: gzip, deflate
User-Agent: requests-scala
Cache-Control: no-cache
Pragma: no-cache
Host: host
Connection: keep-alive
Content-Length: 1082
--3b412ae8-c491-4988-8299-0aa83a06d342
Content-Type: application/octet-stream
Content-Length: 865
Content-Disposition: form-data; name=“fileKey”; filename=“license.zip"
…long set of bytes…
--3b412ae8-c491-4988-8299-0aa83a06d342--
So with two different header groups and content types - one for the overall request (multipart upload) and one for the file itself (application/octet-stream). The second header is being omitted. While some servers automatically parse it anyway and retrieve the correct content type, others don't, with weird, unpredictable errors as the result.
This PR fixes that. I realized I could get a much simpler implementation of this, but didn't have time until today. I've also created a simple unit test to check for this going forward.
Got it, thanks!
Background
Content-Type
headers are not present in multipart item file uploads. This can be difficult to see quickly, as some servers (likehttpbin.org
) automatically parse files to the correct content type, so that there is no noticeable effect. Some servers, however, require the content type to be present, which can lead to unexpected and often cryptic errors.Reproduce
"com.lihaoyi" %% "requests" % "0.8.0"
dependency and with a file containing the code below:readme.zip
file and add this file to your project resources.localhost:3000
. Make sure that this webserver is set up to receive multipart upload post requests at the/file
path.MultipartTrial.upload()
and inspect the http packets. You should find a packet containing something like the following, without any content type header:Description
This PR adds the correct
Content-Type
headers to all multipart item file uploads. The result is that the previous request, illustrated above, will produce something similar to the following, this time with the correct content type header:Important Note
After writing tests for this bugfix, I discovered that
httpbin.org
automatically adds the correct content type header to the request, if no header is present. This generates false positives for all tests that are checking for theapplication/octet-stream
content type header on the multipart item. I have left these tests with aTODO
comment for a future fix. Testing these properly will require a different testing strategy and I didn't want to introduce that with this PR.