Consider the following code:
OkHttpClient client = new OkHttpClient();
MediaType mediaType = MediaType.parse("text/plain; charset=utf-8"); // [A]
RequestBody body = RequestBody.create(mediaType, media);
String[] aclHeader = "x-goog-acl:public-read".split(":");
Request request = new Request.Builder()
.addHeader("Content-Type", "text/plain") // [B]
.addHeader(aclHeader[0], aclHeader[1])
.url(url)
.put(body)
.build();
Response response = client.newCall(request).execute();
I am accessing GCS from a client, with a previously signed URL.
Problem: It seems okhttp adds the charset declared for the body [A] to the URL as well (at least for text/plain), even though it is not declared in [B]. This messes up my signed URL and GCS returns 403 Forbidden.
But this is not as it should be. At least when working with signed URLs, these must be sent to the server exactly as declared.
I tried using the Apache http client (which I don't want to use in production as okhttpclient is already part of my installation) and that client does not expose this behavior:
String[] aclHeader = "x-goog-acl:public-read".split(":");
StatusLine statusLine = Request
.Put(url)
.addHeader("Content-Type", "text/plain")
.addHeader(aclHeader[0], aclHeader[1])
.bodyByteArray(media)
.execute().returnResponse().getStatusLine();
Is there a way to suppress the behavior in okhttp, that it adds to the Content-Type or transfers the Content-Type within the body redundantly?
Removing the Charset From a Content-Type Header Solution is simple - we can create StringContent with whatever encoding and then set charset to empty string. This removes the charset definiton from the request content-type header. My code started to work after this change.
static MediaType. parse(String string) Returns a media type for string , or null if string is not a well-formed media type. String.
I found the solution:
The following line is the culprit:
RequestBody body = RequestBody.create(mediaType, media);
create has 3 signatures for media:
When I pass a String, it disregards the supplied mediaType and adds the charset to it. Even for image/jpeg it would send
image/jpeg; charset=utf-8
to the server.
Using byte[] or File suppresses that behavior.
I hope this helps you!
[Stupid me - for simplicity I gave it a String during testing, as I didn't care about the body ;-( ]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With