《HttpClient官方文档》2.7 连接套接字工厂

2.7. Socket连接工厂

HTTP连接在内部使用java.net.Socket类的对象来处理数据在线路上的传输。 然而,他们依靠 ConnectionSocketFactory接口来创建,初始化和连接Socket。HttpClient的使用者能够在运行时,提供应用程序特定的Socket初始化代码。PlainConnectionSocketFactory类是创建和初始化普通(未加密)套接字的默认工厂类。

创建一个套接字和连接到主机的过程是解耦的,以便连接操作被阻塞的时候套接字能够被关闭

HttpClientContext clientContext = HttpClientContext.create();
PlainConnectionSocketFactory sf = PlainConnectionSocketFactory.getSocketFactory();
Socket socket = sf.createSocket(clientContext);
int timeout = 1000; //ms
HttpHost target = new HttpHost("localhost");
InetSocketAddress remoteAddress = new InetSocketAddress(
        InetAddress.getByAddress(new byte[] {127,0,0,1}), 80);
sf.connectSocket(timeout, socket, target, remoteAddress, null, clientContext);

2.7.1. 安全套接字层

LayeredConnectionSocketFactory接口是 ConnectionSocketFactory接口的扩展。阶层式套接字工厂能够在现有普通套接字上创建层次化的套接字。层次化套接字主要用于通过代理创建安全套接字。
HttpClient附带了实现SSL / TLS分层的SSLSocketFactory类。请注意 HttpClient 不使用任何自定义的加密功能,它完全依赖于 Java 加密 (JCE) 和安全套接字 (JSEE) 扩展标准。

2.7.2. 连接管理器集成

自定义连接套接字工厂可以与特定的协议方案相关联,如HTTP或HTTPS,然后用来创建自定义连接管理器。

ConnectionSocketFactory plainsf = <...>
LayeredConnectionSocketFactory sslsf = <...>
Registry<ConnectionSocketFactory> r = RegistryBuilder.<ConnectionSocketFactory>create()
        .register("http", plainsf)
        .register("https", sslsf)
        .build();

HttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(r);
HttpClients.custom()
        .setConnectionManager(cm)
        .build();

2.7.3. 自定义SSL/TLS

HttpClient 利用 SSLConnectionSocketFactory类创建 SSL 连接。SSLConnectionSocketFactory类允许高度自定义,可以把javax.net.ssl.SSLContext接口的实例作为参数传入,并使用它来创建自定义配置的SSL连接。

KeyStore myTrustStore = <...>
SSLContext sslContext = SSLContexts.custom()
        .loadTrustMaterial(myTrustStore)
        .build();
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext);

对SSLConnectionSocketFactory类自定义意味着对SSL / TLS协议的概念有一定程度的了解,其详细说明不在本文档范围内。请点击

Java™ Secure Socket Extension (JSSE) Reference Guide
来获取javax.net.ssl.SSLContext接口和相关工具的详细说明。

2.7.4. 主机名验证

除了在SSL / TLS协议级别上进行信任验证和客户端身份验证之外,一旦建立了连接,HttpClient可以选择性地验证目标主机名是否与存储在服务器的X.509证书中的名称匹配。该验证可以提供对服务器信任材料的真实性的额外保证。javax.net.ssl.HostnameVerifier接口代表主机名验证策略。 HttpClient附带了javax.net.ssl.HostnameVerifier接口的两个实现类。重要:主机名验证和SSL信任验证这两者不应混淆。

  • DefaultHostnameVerifier: HttpClient使用的默认实现类,它应兼容RFC 2818。主机名必须匹配证书指定的任何别名,或在证书持有者没有为别名给出最明确的证书通用名(CN)的情况下。 在证书通用名(CN),以及任何subject-alts中都可以出现通配符。

  • NoopHostnameVerifier类:  作为主机名验证工具,实质上关闭了主机名验证,它接受任何有效的SSL会话并匹配到目标主机。

HttpClient默认使用DefaultHostnameVerifier类来实现。 如果需要,可以指定其他的主机名验证器来实现。

SSLContext sslContext = SSLContexts.createSystemDefault();
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
        sslContext,
        NoopHostnameVerifier.INSTANCE);

自版本4.4后HttpClient使用由Mozilla基金维护的公共后缀名列表,以确保SSL证书中的通配符不会被滥用于申请拥有公共顶级域名的多个域。 HttpClient 附带了在释放时回收的列表的副本。 https://publicsuffix.org/list/这个URL能够获取最近的版本号列表,强烈建议制作这个列表的本地副本,并每天从其原始位置下载不超过一次。

PublicSuffixMatcher publicSuffixMatcher = PublicSuffixMatcherLoader.load(
    PublicSuffixMatcher.class.getResource("my-copy-effective_tld_names.dat"));
DefaultHostnameVerifier hostnameVerifier = new DefaultHostnameVerifier(publicSuffixMatcher);

可以使用“null”这个参数来禁用对公共后缀名列表的验证。

DefaultHostnameVerifier hostnameVerifier = new DefaultHostnameVerifier(null);

 

原创文章,转载请注明: 转载自并发编程网 – ifeve.com本文链接地址: 《HttpClient官方文档》2.7 连接套接字工厂

  • Trackback 关闭
  • 评论 (1)
  1. 请补充下原文链接

return top