2015-10-27 18 views
6

Sto usando HttpURLConnection sulla falsariga di quanto segue:Prevenire metodo CONNECT non richiesti chiamate da HttpURLConnection

String strURL = "https://example.herokuapp.com"; 
Bitmap bmImage = null; 
HttpURLConnection connection = null; 
InputStream in = null; 
showMessage(context.getString(R.string.message_preparing)); 
try { 
    int timeoutMS = 15000; 
    URL url = new URL(strURL); 
    connection = (HttpURLConnection) url.openConnection(); 
    connection.setDoInput(true); 
    connection.setConnectTimeout(timeoutMS); 
    connection.setReadTimeout(timeoutMS); 
    connection.connect(); 
    in = connection.getInputStream(); 
    BitmapFactory.Options options = new BitmapFactory.Options(); 
    bmImage = BitmapFactory.decodeStream(in, null, options); 
} catch (Exception e) { 
    e.printStackTrace(); 
} finally { 
    if (connection != null) 
     connection.disconnect(); 
    if (in != null) { 
     try { 
      in.close(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 
} 

return bmImage; 

Questo funziona bene, con l'URL definito da strURL restituendo un'immagine BMP, e questo viene decodificato pronto per utilizzare con il codice precedente.

Ma per un utente in particolare, sebbene il codice funzioni correttamente per recuperare l'immagine bmp, sul server (un server node.js su heroku) è evidente che una richiesta CONNECT viene inviata anche dal proprio dispositivo. Tale richiesta viene respinta automaticamente con una risposta 503, quindi non è un problema in quanto tale e il bmp viene comunque inviato al dispositivo, ma mi piacerebbe sapere perché vengono inviate quelle richieste CONNECT e come fermarle . Sicuramente non ci dovrebbero essere nient'altro che le richieste GET?

Ho provato this solution a quello che sembra essere un problema simile, ma per me non fa alcuna differenza.

Si noti che strURL è a un server https e sto usando HttpURLConnection (non Https) - non sono sicuro se c'è un significato in questo.

Non sono sicuro al 100% che le richieste di CONNECT derivino dalle chiamate precedenti, ma si verificano certamente nello stesso periodo di una richiesta GET che consegna il bmp. Forse potrebbe essere generato dal sistema operativo in qualche modo, al di fuori del mio codice? Non sono sicuro.

In caso aiuta, un messaggio di esempio log dal Heroku, in risposta a una delle CONNECT richieste, è la seguente:

Oct 27 14:14:25 example heroku/router: at=error code=H13 desc="Connection closed without response" method=CONNECT path="example.herokuapp.com:443" host=example.herokuapp.com request_id=353e623x-dec4-42x5-bcfb-452add02ecef fwd="111.22.333.4" dyno=web.1 connect=0ms service=1ms status=503 bytes=0 

EDIT: può anche essere di rilevanza che il dispositivo in questione in realtà fa due richieste GET indipendenti in breve tempo l'una dall'altra (richieste completamente separate e legittime), ma c'è sempre una sola richiesta CONNECT apparente (all'incirca alla stessa ora della coppia di richieste GET). Quindi non è come se ci fosse un CONNECT per ogni GET.

+0

Questo è l'uso intenzionale di un proxy: http://stackoverflow.com/questions/15927079/how-to-use-httpsurlconnection-through-proxy-by-setproperty –

+0

C'è un modo in cui un si può tentare l'uso di un proxy quando il mio codice non contiene elementi proxy in esso? – drmrbrewer

+0

Non che io abbia mai sentito nominare. Sono d'accordo, non ha senso. E dal momento che è limitato a un piccolo sottoinsieme di client, e solo osservato in natura, è dannatamente misterioso. Sospetto un comportamento o un bug specifico della versione. Le richieste in avvicinamento ti dicono qualcosa sullo user agent? Oppure potresti aggiungere del codice per raccogliere informazioni sul sistema operativo e sull'hardware e trasmetterlo in un'intestazione personalizzata sulla richiesta GET? –

risposta

2

Il metodo CONNECT può precedere una richiesta a un server HTTP (o un server proxy o un server di origine), e significa fondamentalmente:

"A proposito, vecchio mio, si dovrebbe non mente riferendo questa roba dico "verbatim" all'host/port che mi capita di pronunciare, Non c'è bisogno di prestare attenzione a quello che sto dicendo, davvero. "

Di solito questa sarebbe un'istruzione per un proxy, per "togliersi di mezzo" e consentire al richiedente (che potrebbe essere l'agente utente O un altro proxy) di parlare direttamente al server upstream.

È una funzione utile se esiste un proxy altrimenti non cooperativo (forse obsoleto) tra voi e un server di origine. È anche utile se sei un hacker e vorresti che un server di origine configurato in modo non corretto faciliti allegramente il tuo ingresso nella rete interna.

Tuttavia, a meno che tu non abbia una conoscenza perfetta della rete e "sappia" che il tuo percorso sia UN solo proxy, dovrai "impilare" l'intestazione CONNECT fino a quando non ottieni un rifiuto.

Ad esempio:

CONNECT site.example.com 80 HTTP/1.1 
CONNECT site.example.com 80 HTTP/1.1 
GET /foo HTTP/1.1 
Host: site.example.com 

.... sarà o si ottenere attraverso 2 interferire, buono a nulla, proxy a monte; OPPURE riesci a superare solo l'1 che è effettivamente lì e guadagnarti un 503 dal server di origine ... dopo di che dovrai ripetere la tua richiesta con i metodi di prefazione di ONE FEWER CONNECT.

Quindi questo spiegherebbe il comportamento visto finora.

Tuttavia, ciò che non è chiaro è WHO sta AGGIUNGENDO LA PREFAZIONE CONNECT ?! E perché non gli piacciono i proxy?

Potrebbe essere:

  1. codice a User-Agent (la vostra applicazione Android su smartphone del cliente utilizzando HttpUrlConnection o HttpsUrlConnection (utilizzato automaticamente dal openConnection() se l'URL è uno schema https://);
  2. qualsiasi Proxy tra l'User-Agent e il server di origine, che per qualche motivo è diffidente nei confronti dei suoi proxy upstream o deve eseguire il tunneling HTTPS tramite un proxy che supporta solo HTTP (che è ciò che CONNECT è per)
  3. un Proxy che è stato violato e che sta cercando dumb origin-server da sfruttare ... ma perché aspettare fino a quando qualcuno non ha realmente bisogno di roba, per importare il server di origine?

L'intero contenuto del metodo CONNECT e l'IP di origine per il pacchetto sarebbero interessanti. Sto scommettendo sul # 2 e prevedo che non vedrai lo CONNECT se hai effettuato l'accesso al sito tramite un URL http://.

Non c'è nulla che lo di possa fare al riguardo.

+0

Risposta sorprendente, e tutto molto molto plausibile. Fino ad ora l'avevo appena lasciato all'app del nodo per rifiutare le richieste di "CONNECT", che sembra funzionare automaticamente con una risposta "503". Promosso dalla tua risposta, e così posso esaminare le intestazioni della richiesta 'CONNECT', ora ho aggiunto un metodo al server node.js (le richieste sono gestite dal modulo express) per gestire' CONNECT's, sebbene solo per scaricare le intestazioni sulla console e inviare una risposta '503'. E sto ancora aspettando un 'CONNECT' ... Mi chiedo se è un caso che un piatto visto non bolle mai ... o il gatto di Schroedinger ... – drmrbrewer

+0

Sembra che io non possa effettivamente esaminare queste richieste CONNECT perché sono catturato al di fuori della mia app dai server di heroku. Quindi non sarò probabilmente in grado di imparare molto di più su di loro, ma è davvero molto utile capire quale sia la causa probabile. Quindi grazie. – drmrbrewer

Problemi correlati