重用在Android的SSL会话使用的HttpClient用在、Android、HttpClient、SSL

2023-09-12 07:17:15 作者:你的梨涡我的梦

我有很多困难的HttpClient使用Android上恢复SSL会话。

我是轮询服务器每90秒(这是为工业设备与一个函数只),所以我需要从几KB高达每小时150-200kB,这是不可持续的恢复会话或者数据使用一飞冲天。服务器嵌入码头在的Restlet,并支持恢复SSL会话,当我测试它使用OpenSSL据我可以告诉。

我再利用我的HttpClient对象,所以它不是。 Android有一个特定的SSLCertificateSocketFactory,我也试着和它似乎也没有工作。

时有什么我完全缺少在这里?我有presumed的HttpClient会自动做到这一点,我不知道我在做什么错了,并在互联网上没有人似乎来面对类似的问题。

我已经成立了HttpClient的经过:

 公共HttpClient的getNewHttpClient(上下文的背景下){
    尝试 {

        的HttpParams PARAMS =新BasicHttpParams();
        HttpProtocolParams.setVersion(参数,可以HttpVersion.HTTP_1_1);
        HttpProtocolParams.setContentCharset(参数,可以HTTP.UTF_8);
        HttpConnectionParams.setStaleCheckingEnabled(参数,可以假);

        HttpConnectionParams.setConnectionTimeout(参数,可以4 * 1000);
        HttpConnectionParams.setSoTimeout(PARAMS,5 * 1000);
        HttpConnectionParams.setSocketBufferSize(PARAMS,8192);

        HttpClientParams.setRedirecting(参数,可以假);

        SSLSessionCache的SSLSession =新SSLSessionCache(上下文);
        SchemeRegistry注册表=新SchemeRegistry();

        registry.register(新计划(HTTP,PlainSocketFactory.getSocketFactory(),80));
        registry.register(新计划(https开头,SSLCertificateSocketFactory.getHttpSocketFactory(10 * 60 * 1000,的SSLSession),444));
        //registry.register(new计划(https开头,SSLSocketFactory.getSocketFactory(),444));

        ClientConnectionManager CCM =新ThreadSafeClientConnManager(参数,可以登记);

        返回新DelegateHttpClient(CCM,则params);

    }赶上(例外五){
        返回新DefaultHttpClient();
    }
}

私有静态类DelegateHttpClient扩展DefaultHttpClient {

    私人DelegateHttpClient(ClientConnectionManager CCM,的HttpParams PARAMS){
      超(CCM,则params);
    }

    @覆盖
    保护的HttpContext createHttpContext(){

      HttpContext的背景下=新BasicHttpContext();
      context.setAttribute(ClientContext.AUTHSCHEME_REGISTRY,getAuthSchemes());
      context.setAttribute(ClientContext.COOKIESPEC_REGISTRY,getCookieSpecs());
      context.setAttribute(ClientContext.CREDS_PROVIDER,getCredentialsProvider());

      CookieStore的CookieStore的=新BasicCookieStore(); //创建cookie存储的本地实例
      context.setAttribute(ClientContext.COOKIE_STORE,CookieStore的);

      返回范围内;
    }
  }
 

(我使用的目的端口444)

然后就重用我用一个简单的HTTPGET和基本授权HttpClient的对象。

我在做什么错在这里!?任何人,请大家帮忙!

解决方案

它的固定。它现在使用会话和消费数据的微量。

  registry.register(新计划(HTTP,PlainSocketFactory.getSocketFactory(),80));
 

删除该行修复它,尽管HttpClient的甚至从来没有使用HTTP /端口80,为什么这个作品我也不知道。

快速android app开发,快速学会开发 Android App

I'm having a lot of difficulty resuming an SSL session on Android using HttpClient.

I'm polling a server every 90 seconds (it's for industrial devices with one function only), so I need to resume the session or else data use skyrockets from a few kB an hour up to 150-200kB, which is unsustainable. The server is embedded Jetty in Restlet, and supports resumption of SSL sessions when I test it using OpenSSL as far as I can tell.

I'm reusing my HttpClient object, so it's not that. Android has a specific SSLCertificateSocketFactory which I've also tried and it also doesn't seem to work.

Is there something I'm completely missing here? I had presumed HttpClient would do this automatically, I'm not sure what I'm doing wrong, and no-one on the internet seems to be coming up against a similar problem.

I've set up the httpClient via:

    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;
    }
  }

(I'm using port 444 on purpose)

Then just I reuse the HttpClient object using a simple HttpGet and Basic authorization.

What am I doing wrong here !? Anyone, please help !

解决方案

It's fixed. It is now using sessions and consuming minute amounts of data.

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

Removing that line fixes it, despite HttpClient never even using http/port 80. Why this works I have no idea.