次のコードを検討してください。
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();
以前に署名された URL を使用して、クライアントから GCS にアクセスしています。
問題: [B] では宣言されていませんが、okhttp は本文 [A] で宣言された文字セットを URL にも (少なくとも text/plain では) 追加しているようです。これは私の署名付き URL を台無しにし、GCS は 403 Forbidden を返します。
- [A] から文字セットを削除しても、まだ追加されています。
- 署名する前に署名付き URL に文字セットを追加すると、それは機能し、GCS は 200 OK を返します。
しかし、これはあるべき姿ではありません。少なくとも署名付き URL を使用する場合は、宣言どおりに正確にサーバーに送信する必要があります。
Apache http クライアントを使用してみました (okhttpclient は既にインストールの一部であるため、本番環境では使用したくありません)。そのクライアントはこの動作を公開しません。
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();
Content-Type に追加するか、本文内で Content-Type を冗長に転送するという、okhttp の動作を抑制する方法はありますか?