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.
- If I remove the charset from [A], it is still added.
- If I add the charset to the signed URL before I sign it, it works and GCS returns 200 OK.
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?