Как использовать настраиваемую фабрику сокетов в Apache HttpComponents

Я пытался использовать собственный SocketFactory в библиотеке httpclient из проекта Apache HTTPComponents. Пока без везения. Я ожидал, что могу просто установить фабрику сокетов для экземпляра HttpClient, но это явно не так просто.

Документация для HttpComponents по адресу http://hc.apache.org/httpcomponents-client-ga/tutorial/html/connmgmt.html упоминает фабрики сокетов, но не говорит, как их использовать.

Кто-нибудь знает, как это делается?


person daniel kullmann    schedule 22.11.2011    source источник
comment
См. «Пользовательский контекст SSL» в примерах Apache HttpClient. http://hc.apache.org/httpcomponents-client-ga/examples.html   -  person ok2c    schedule 22.11.2011


Ответы (2)


Ответ Олега, конечно, правильный, я просто хотел разместить информацию прямо здесь, на случай, если ссылка испортится. В коде, который создает HttpClient, я использую этот код, чтобы позволить ему использовать мою фабрику сокетов:

    CustomSocketFactory socketFactory = new CustomSocketFactory();
    Scheme scheme = new Scheme("http", 80, socketFactory);
    httpclient.getConnectionManager().getSchemeRegistry().register(scheme);

CustomSocketFactory - это моя собственная фабрика сокетов, и я хочу использовать ее для обычного HTTP-трафика, поэтому я использую "http" и 80 в качестве параметров.

Моя CustomSchemeSocketFactory выглядит примерно так:

public class CustomSchemeSocketFactory implements SchemeSocketFactory {

  @Override
  public Socket connectSocket( Socket socket, InetSocketAddress remoteAddress, InetSocketAddress localAddress, HttpParams params ) throws IOException, UnknownHostException, ConnectTimeoutException {

    if (localAddress != null) {
      socket.setReuseAddress(HttpConnectionParams.getSoReuseaddr(params));
      socket.bind(localAddress);
    }
    int connTimeout = HttpConnectionParams.getConnectionTimeout(params);
    int soTimeout = HttpConnectionParams.getSoTimeout(params);

    try {
        socket.setSoTimeout(soTimeout);
        socket.connect(remoteAddress, connTimeout );
    } catch (SocketTimeoutException ex) {
        throw new ConnectTimeoutException("Connect to " + remoteAddress + " timed out");
    }

    return socket;
  }

  @Override
  public Socket createSocket( HttpParams params ) throws IOException {
    // create my own socket and return it
  }

  @Override
  public boolean isSecure( Socket socket ) throws IllegalArgumentException {
    return false;
  }

}
person daniel kullmann    schedule 22.11.2011

Мы используем настраиваемую фабрику сокетов, чтобы подключения HttpClient могли подключаться к URL-адресам HTTPS с ненадежными сертификатами.

Вот как мы это сделали:

  1. Мы адаптировали реализации классов EasySSLProtocolSocketFactory и EasyX509TrustManager из исходного каталога примеров, на который ссылается Олег.

  2. В коде запуска HttpClient мы делаем следующее, чтобы включить новую фабрику сокетов:

    HttpClient httpClient = new HttpClient();
    Protocol easyhttps = new Protocol("https", new EasySSLProtocolSocketFactory(), 443);
    Protocol.registerProtocol("https", easyhttps);
    

Таким образом, каждый раз, когда мы запрашиваем URL-адрес https: //, используется эта фабрика сокетов.

person Jason Buberel    schedule 22.11.2011
comment
Если я не ошибаюсь, EasySSLProtocolSocketFactory - это класс HttpClient 3. Он недоступен в новом клиенте HttpComponents v4. - person FabienB; 30.11.2012