閱讀252 返回首頁    go 技術社區[雲棲]


《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

最後更新:2017-05-19 12:04:57

  上一篇:go  如何用樹莓派搭建個人 web 服務器
  下一篇:go  CentOS 上最佳的第三方倉庫