2012-09-21 22 views
5

Sto sviluppando un servizio Web protetto tra il mio proxy web java auto-implementato (che inoltra richieste al servizio web effettivo) e un'applicazione Android.Riutilizzo della connessione SSL con Android HttpClient

Fare questo con connessioni HTTP standard (insicure) funziona perfettamente. Ora voglio usare una connessione sicura (SSL) tra il proxy e il client Android.

Questo funziona fintanto che istanzio un nuovo HttpClient per ogni richiesta, che è oltre a sprecare risorse estremamente lento poiché sto facendo un handshake bidirezionale per ogni richiesta.

Così sto cercando di riutilizzare il HttpClient per ogni richiesta che si traduce per le connessioni protette nel seguente eccezione

java.lang.IllegalStateException: connessione già aperta. in org.apache.http.impl.conn.AbstractPoolEntry.open (AbstractPoolEntry.java:150) in org.apache.http.impl.conn.AbstractPooledConnAdapter.open (AbstractPooledConnAdapter.java:119) in org.apache. http.impl.client.DefaultRequestDirector.execute (DefaultRequestDirector.java:360) in org.apache.http.impl.client.AbstractHttpClient.execute (AbstractHttpClient.java:555) all'indirizzo org.apache.http.impl.client. AbstractHttpClient.execute (AbstractHttpClient.java:487) a org.apache.http.impl.client.AbstractHttpClient.execute (AbstractHttpClient.java:465)

Quando cambio il mio proxy e il client per no-ssl comunicazione funziona senza problemi. Qualcuno sa cosa sto facendo male? Grazie mille per il vostro aiuto!

Il codice del server è del tutto simile tranne che per l'utilizzo di SSLServerSocket con certificati caricati invece di utilizzare ServerSocket.

parametro client di installazione

// Set basic data 
    HttpParams params = new BasicHttpParams(); 
    HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1); 
    HttpProtocolParams.setContentCharset(params, "UTF-8"); 
    HttpProtocolParams.setUseExpectContinue(params, true); 
    HttpProtocolParams.setUserAgent(params, "Android app/1.0.0"); 

    // Make pool 
    ConnPerRoute connPerRoute = new ConnPerRouteBean(12); 
    ConnManagerParams.setMaxConnectionsPerRoute(params, connPerRoute); 
    ConnManagerParams.setMaxTotalConnections(params, 20); 

    // Set timeout 
    HttpConnectionParams.setStaleCheckingEnabled(params, false); 
    HttpConnectionParams.setConnectionTimeout(params, connectionTimeoutMillis); 
    HttpConnectionParams.setSoTimeout(params, socketTimeoutMillis); 
    HttpConnectionParams.setSocketBufferSize(params, 8192); 

    // Some client params 
    HttpClientParams.setRedirecting(params, false); 

Http creazione cliente

// load truststore certificate 
      InputStream clientTruststoreIs = context.getResources().openRawResource(R.raw.server); 
      KeyStore trustStore = KeyStore.getInstance("BKS"); 
      trustStore.load(clientTruststoreIs, "server".toCharArray()); 

      // initialize trust manager factory with the read truststore 
      TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); 
      trustManagerFactory.init(trustStore); 

      // setup client certificate 

      // load client certificate 
      InputStream keyStoreStream = context.getResources().openRawResource(R.raw.client); 
      KeyStore keyStore = KeyStore.getInstance("BKS"); 
      keyStore.load(keyStoreStream, "client".toCharArray()); 

      // initialize key manager factory with the read client 
      // certificate 
      KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); 
      keyManagerFactory.init(keyStore, "client".toCharArray()); 

      // initialize SSLSocketFactory to use the certificates 
      SSLSocketFactory socketFactory = new SSLSocketFactory(SSLSocketFactory.TLS, keyStore, "client", trustStore, null, null); 

      // Register http/s shemas! 
      SchemeRegistry schReg = new SchemeRegistry(); 
      schReg.register(new Scheme("https", socketFactory, port)); 
      ClientConnectionManager conMgr = new ThreadSafeClientConnManager(params, schReg); 

      httpClient = new DefaultHttpClient(conMgr, params); 

richiesta client esecuzione

HttpResponse response = httpClient.execute(request); 
     HttpEntity entity = response.getEntity(); 
     in = entity.getContent(); 
     String result = convertStreamToString(in); 
     in.close(); 

risposta

0

Si sta utilizzando una gestione connessione thread-safe? In caso contrario, potrebbe essere il problema se si sta utilizzando lo stesso HttpClient in più thread.

Questo articolo ha particolari: http://candrews.integralblue.com/2011/09/best-way-to-use-httpclient-in-android/

+0

Grazie per la risposta. Sì, come puoi vedere nel codice che ho fornito. Il codice funziona perfettamente se lo uso senza SSL, anche se usato da thread diversi. Ma quando cambio su SSL si rompe con l'eccezione in alto. Qualche altro suggerimento? – user1033552

3

Ho questo problema esattamente lo stesso con Android e HttpClient - sembra solo a manifestarsi quando si utilizza un certificato client-side, proprio come avete. Rimuove l'autenticazione del client e funziona bene, non ha ancora trovato una soluzione.

Modifica:

Abilita il controllo del collegamento non aggiornato.

HttpConnectionParams.setStaleCheckingEnabled (params, true);

risolto per me.

+0

Thx. Posso confermare che ciò accade solo con i certificati client abilitati e questo lo ha risolto anche per me. – icyerasor

Problemi correlati