2014-08-29 4 views
9

Si consideri il seguente codice:Come sopprimere Charset essere automaticamente aggiunto al 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(); 

sto accedendo GCS da un client, con un URL firmato in precedenza.

Problema: Sembra okhttp aggiunge il set di caratteri dichiarato per il corpo [A] all'URL (almeno per testo/plain), anche se non è dichiarato in [B]. Questo rovina il mio URL firmato e GCS restituisce 403 Proibito.

  • Se rimuovo il set di caratteri da [A], è ancora aggiunto.
  • Se aggiungo il set di caratteri all'URL firmato prima che firmi, funziona e GCS restituisce 200 OK.

Ma questo non è come dovrebbe essere. Almeno quando si lavora con URL firmati, questi devono essere inviati al server esattamente come dichiarato.

Ho provato ad utilizzare il client di Apache HTTP (che io non voglio usare in produzione come okhttpclient è già parte della mia installazione) e che il cliente non espone questo comportamento:

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

C'è un modo di sopprimere il comportamento in okhttp, che aggiunge al Content-Type o trasferisce il Content-Type all'interno del corpo in modo ridondante?

risposta

16

ho trovato la soluzione:

La riga seguente è il colpevole:

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

creare dispone di 3 firme per i media:

  • String
  • byte []
  • File

Quando passo una stringa, ignora il mediaType fornito e aggiunge il set di caratteri. Anche per immagine/jpeg invierebbe

image/jpeg; charset = utf-8

al server.

L'utilizzo di byte [] o File elimina tale comportamento.

Spero che questo ti aiuti!

[Stupido me - per semplicità ho dato una stringa durante i test, come non mi interessa il corpo ;-(].

+1

Yup OkHttp deve decidere come convertire la stringa di byte, e quando lo fa notare la decisione nel set. A proposito, perché non stai specificando un set di caratteri? Il server può usare l'euristica per indovinare, e può indovinare! –

+0

Capisco, sì. Non avevo specificato il set di caratteri perché pensavo che un'immagine fosse binaria e ho usato solo la stringa per nutrire qualcosa. Non mi interessava il contenuto, quindi non mi importava nemmeno del charset, ma ammetto che ha senso. –

Problemi correlati