2012-09-21 15 views
5

Estoy desarrollando un servicio web seguro entre mi proxy web java autoejecutado (que reenvía las solicitudes al servicio web real) y una aplicación de Android.Reutilización de la conexión SSL con Android HttpClient

Hacerlo con conexiones HTTP estándar (inseguras) funciona perfectamente bien. Ahora quiero usar una conexión segura (SSL) entre el proxy y el cliente de Android.

Esto funciona siempre que crea una instancia de un nuevo HttpClient para cada solicitud, que además de desperdiciar recursos es extremadamente lento ya que estoy haciendo un intercambio bidireccional para cada solicitud.

Así que estoy tratando de volver a utilizar el HttpClient para cada solicitud que se traduce para conexiones seguras en la siguiente excepción

java.lang.IllegalStateException: La conexión ya está abierta. en org.apache.http.impl.conn.AbstractPoolEntry.open (AbstractPoolEntry.java:150) en org.apache.http.impl.conn.AbstractPooledConnAdapter.open (AbstractPooledConnAdapter.java:119) en org.apache. http.impl.client.DefaultRequestDirector.execute (DefaultRequestDirector.java:360) en org.apache.http.impl.client.AbstractHttpClient.execute (AbstractHttpClient.java:555) en org.apache.http.impl.client. AbstractHttpClient.execute (AbstractHttpClient.java:487) en org.apache.http.impl.client.AbstractHttpClient.execute (AbstractHttpClient.java:465)

Cuando cambio mi proxy y el cliente no-SSL la comunicación funciona sin ningún problema. ¿Alguien sabe lo que estoy haciendo mal? ¡Muchas gracias por tu ayuda!

Por cierto, el código del servidor es totalmente similar excepto que usa SSLServerSocket con certificados cargados en lugar de ServerSocket.

parámetro de configuración de cliente

// 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 creación de clientes

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

ejecución de la petición del cliente

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

Respuesta

0

¿Está utilizando un administrador de conexión flujos seguros? Si no, ese puede ser el problema si está usando el mismo HttpClient en múltiples hilos.

Este artículo tiene detalles: http://candrews.integralblue.com/2011/09/best-way-to-use-httpclient-in-android/

+0

Gracias por su respuesta. Sí, lo hago, como puede ver en el código que proporcioné. El código funciona perfectamente bien si lo uso sin SSL, incluso cuando se usa desde diferentes subprocesos. Pero cuando cambio a SSL se rompe con la excepción en la parte superior. ¿Cualquier otra sugerencia? – user1033552

3

tengo este problema exactamente el mismo con Android y HttpClient - sólo parece manifestarse cuando se utiliza un certificado de cliente, al igual que lo tiene. Elimine la autenticación del cliente y funciona bien, todavía no se ha encontrado una solución.

Editar:

Habilitar la comprobación de conexión obsoleta.

HttpConnectionParams.setStaleCheckingEnabled (params, true);

Me lo arreglaron.

+0

Thx. Puedo confirmar que esto solo ocurre con certificaciones de clientes habilitadas y esto también lo solucionó yo. – icyerasor

Cuestiones relacionadas