2014-08-29 5 views
9

den folgenden Code vor:Wie zu unterdrücken Charset wird automatisch hinzugefügt, um Content-Type in okhttp

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(); 

ich GCS bin Zugriff von einem Client, mit einer zuvor unterzeichnet URL.

Problem: Es scheint, okhttp fügt den Zeichensatz, der für den Körper [A] deklariert wurde, ebenfalls zur URL hinzu (zumindest für text/plain), obwohl er in [B] nicht deklariert ist. Dies bringt meine signierte URL durcheinander und GCS gibt 403 Forbidden zurück.

  • Wenn ich den Zeichensatz von [A] entferne, wird er noch hinzugefügt.
  • Wenn ich den Zeichensatz der signierten URL hinzufüge, bevor ich ihn unterzeichne, funktioniert es und GCS gibt 200 OK zurück.

Aber das ist nicht so, wie es sein sollte. Zumindest wenn Sie mit signierten URLs arbeiten, müssen diese genau wie angegeben an den Server gesendet werden.

ich das Apache HTTP-Client versucht, mit (was ich will nicht in der Produktion verwenden, wie okhttpclient bereits Teil meiner Installation ist) und dass Client aussetzen dieses Verhalten nicht:

 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(); 

Gibt es ein Möglichkeit, das Verhalten in okhttp zu unterdrücken, dass es dem Content-Type hinzugefügt wird oder den Content-Type innerhalb des Körpers redundant überträgt?

Antwort

16

fand ich die Lösung:

Die folgende Zeile ist der Täter:

RequestBody body = RequestBody.create(mediaType, media); 

erstellen 3 Unterschriften für Medien hat:

  • String
  • byte []
  • Datei

Wenn ich einen String übergebe, ignoriert er den angegebenen mediaType und fügt den Zeichensatz hinzu. Sogar für Bild/JPEG würde es senden

image/jpeg; charset = utf-8

an den Server.

Mit Byte [] oder Datei unterdrückt dieses Verhalten.

Ich hoffe, das hilft Ihnen!

[Dumme mir - der Einfachheit halber ich es gab einen String während des Tests, da ich nicht über den Körper scherte ;-(].

+1

Yup OkHttp muss entscheiden, wie Sie Ihre String-Bytes zu konvertieren, und wenn es tut so, dass es diese Entscheidung im Zeichensatz feststellt. Übrigens, warum geben Sie keinen Zeichensatz an? Der Server kann Heuristiken verwenden, um zu raten, und er kann falsch raten! –

+0

Ich verstehe, ja. Ich hatte den Zeichensatz nicht angegeben weil ich dachte, dass ein Bild binär ist und ich nur die Zeichenfolge verwendet habe, um etwas einzufügen, war mir der Inhalt egal, also kümmerte ich mich auch nicht um den Zeichensatz, aber ich gebe zu, dass es Sinn macht. –