Повторное использование сеансов SSL в Android с помощью HttpClient - PullRequest
11 голосов
/ 13 апреля 2011

У меня возникают большие трудности с возобновлением сеанса SSL на Android с использованием HttpClient.

Я опрашиваю сервер каждые 90 секунд (это для промышленных устройств только с одной функцией), поэтому мне нужновозобновить сеанс или использовать данные, увеличивающие скорость от нескольких килобайт в час до 150-200 килобайт, что является неустойчивым.Насколько мне известно, на сервере встроен Jetty в Restlet, и он поддерживает возобновление сеансов SSL, когда я тестирую его с использованием OpenSSL.

Я повторно использую свой объект HttpClient, так что это не так.В Android есть определенный SSLCertificateSocketFactory, который я тоже пробовал, и он тоже не работает.

Есть ли что-то, чего я здесь полностью упускаю?Я предполагал, что HttpClient сделает это автоматически, я не уверен, что делаю неправильно, и никто в Интернете, похоже, не сталкивается с подобной проблемой.

Я настроилhttpClient через:

    public HttpClient getNewHttpClient(Context context) {
    try {

        HttpParams params = new BasicHttpParams();
        HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
        HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);
        HttpConnectionParams.setStaleCheckingEnabled(params, false);

        HttpConnectionParams.setConnectionTimeout(params, 4 * 1000);
        HttpConnectionParams.setSoTimeout(params, 5 * 1000);
        HttpConnectionParams.setSocketBufferSize(params, 8192);

        HttpClientParams.setRedirecting(params, false);

        SSLSessionCache sslSession = new SSLSessionCache(context);
        SchemeRegistry registry = new SchemeRegistry();

        registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
        registry.register(new Scheme("https", SSLCertificateSocketFactory.getHttpSocketFactory(10*60*1000, sslSession), 444));
        //registry.register(new Scheme("https", SSLSocketFactory.getSocketFactory(), 444));

        ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry);

        return new DelegateHttpClient(ccm, params);

    } catch (Exception e) {
        return new DefaultHttpClient();
    }
}

private static class DelegateHttpClient extends DefaultHttpClient {

    private DelegateHttpClient(ClientConnectionManager ccm, HttpParams params) {
      super(ccm, params);
    }

    @Override
    protected HttpContext createHttpContext() {

      HttpContext context = new BasicHttpContext();
      context.setAttribute(ClientContext.AUTHSCHEME_REGISTRY, getAuthSchemes());
      context.setAttribute(ClientContext.COOKIESPEC_REGISTRY, getCookieSpecs());
      context.setAttribute(ClientContext.CREDS_PROVIDER, getCredentialsProvider());

      CookieStore cookieStore = new BasicCookieStore(); // Create a local instance of cookie store
      context.setAttribute(ClientContext.COOKIE_STORE, cookieStore);

      return context;
    }
  }

(я специально использую порт 444)

Затем я просто повторно использую объект HttpClient, используя простую авторизацию HttpGet и Basic.

Чтоя здесь не так делаю!Любой, пожалуйста, помогите!

1 Ответ

2 голосов
/ 15 апреля 2011

Это исправлено. Теперь он использует сеансы и потребляет незначительные объемы данных.

registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));

Удаление этой строки исправляет это, несмотря на то, что HttpClient никогда не использует http / порт 80. Почему это работает, я не знаю.

...