2012-09-21 41 views
5

Tôi đang phát triển dịch vụ web bảo mật giữa proxy web tự thực hiện của mình (chuyển tiếp các yêu cầu đến dịch vụ web thực) và ứng dụng android.Tái sử dụng kết nối SSL với Android HttpClient

Làm như vậy với các kết nối http chuẩn (không an toàn) hoạt động hoàn toàn tốt. Bây giờ tôi muốn sử dụng kết nối an toàn (SSL) giữa proxy và ứng dụng khách Android.

Điều này hoạt động miễn là tôi khởi tạo một HttpClient mới cho mỗi yêu cầu, đó là bên cạnh lãng phí tài nguyên cực kỳ chậm như tôi đang làm một cái bắt tay hai chiều cho mỗi yêu cầu.

Vì vậy, tôi đang cố gắng để tái sử dụng HttpClient cho mỗi yêu cầu mà kết quả cho các kết nối an toàn trong ngoại lệ sau đây

java.lang.IllegalStateException: Kết nối đã được mở. tại org.apache.http.impl.conn.AbstractPoolEntry.open (AbstractPoolEntry.java:150) tại org.apache.http.impl.conn.AbstractPooledConnAdapter.open (AbstractPooledConnAdapter.java:119) tại org.apache. http.impl.client.DefaultRequestDirector.execute (DefaultRequestDirector.java:360) tại org.apache.http.impl.client.AbstractHttpClient.execute (AbstractHttpClient.java:555) tại org.apache.http.impl.client. AbstractHttpClient.execute (AbstractHttpClient.java:487) tại org.apache.http.impl.client.AbstractHttpClient.execute (AbstractHttpClient.java:465)

Khi tôi thay đổi proxy của tôi và khách hàng để không-ssl thông tin liên lạc nó hoạt động mà không có bất kỳ vấn đề. Có ai biết tôi đang làm gì sai không? Cảm ơn sự giúp đỡ của bạn!

Bằng cách mã máy chủ hoàn toàn tương tự ngoại trừ việc sử dụng SSLServerSocket với chứng chỉ đã tải thay vì sử dụng ServerSocket.

tham số khách hàng thiết lập

// 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 tạo client

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

yêu cầu khách hàng thực hiện

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

Trả lời

0

Bạn đang sử dụng một trình quản lý kết nối thread-an toàn không? Nếu không, đó có thể là vấn đề nếu bạn đang sử dụng cùng một HttpClient trong nhiều chủ đề.

Bài viết này có chi tiết: http://candrews.integralblue.com/2011/09/best-way-to-use-httpclient-in-android/

+0

Cảm ơn câu trả lời của bạn. Có, tôi làm như bạn có thể thấy trong mã tôi đã cung cấp. Các mã hoạt động hoàn toàn tốt nếu tôi sử dụng nó mà không có SSL, ngay cả khi được sử dụng từ các chủ đề khác nhau. Nhưng khi tôi thay đổi sang SSL, nó sẽ phá vỡ với ngoại lệ trên đầu trang. Bất cứ một đề nghị nào khác? – user1033552

3

Tôi có cùng một vấn đề chính xác này với Android và HttpClient - nó chỉ dường như đơm hoa kết trái khi sử dụng giấy chứng nhận client-side, giống như bạn có. Hủy bỏ auth client và nó hoạt động tốt, chưa tìm được cách giải quyết nào.

Chỉnh sửa:

Bật kiểm tra kết nối cũ.

HttpConnectionParams.setStaleCheckingEnabled (params, true);

Sửa lỗi cho tôi.

+0

Thx. Có thể xác nhận điều này chỉ xảy ra với các chứng chỉ khách hàng được bật và điều này cũng đã khắc phục nó cho tôi. – icyerasor

Các vấn đề liên quan