square / okhttp

Square’s meticulous HTTP client for the JVM, Android, and GraalVM.
https://square.github.io/okhttp/
Apache License 2.0
45.87k stars 9.16k forks source link

Failed to build MultipartReader #8068

Open SaitoLi opened 1 year ago

SaitoLi commented 1 year ago

I found that when using CloudFront CDN and OkHttp for Multipart requests, CloudFront CDN added the 'CloudFront:' field in the boundary, which caused the value of boundary to be null when building MultipartReader. It seems that the cause of the issue is due to the toMediaType method in MediaType not including ':' in its regular expression, causing it to fail. Could you kindly advise on how to solve this problem? okhttp 4.9.x

the response be like:

--CloudFront:ED461CAD63CDFC53A7F46FB099C72CEE
Content-Type: application/octet-stream
Content-Range: bytes xxxxx

and MediaType not including ':'

private const val TOKEN = "([a-zA-Z0-9-!#$%&'*+.^_`{|}~]+)"
yschimke commented 1 year ago

Do you have a way to repro? A public server we can hit?

SaitoLi commented 1 year ago

Do you have a way to repro? A public server we can hit?

Sorry for the late reply. Due to our internal policy, we are not able to share the test links. I think you can try using a boundary containing ':' symbol, and create a ResponseBody object as a test case to verify if the following code can obtain the correct result

boundary = response.contentType()?.parameter("boundary")
          ?: throw ProtocolException("expected the Content-Type to have a boundary parameter")
swankjesse commented 11 months ago

Looks like : is permitted when the boundary is in a quoted-string.

We need to fix OkHttp’s MultipartBody, to quote boundary when necessary. See RFC 2045 section 5.1.

Cloudfront needs to either quote the boundary parameter or use a character other than :.

You can work-around by re-writing the Content-Type header to add quotes around the boundary parameter. Should be straightforward if you’re good with regex.