我正在构建一个 WebClient 库。现在我正在实现一个代理功能,所以我正在做一些研究,我看到了一些使用该CONNECT
方法请求 URL 的代码。
但是在我的网络浏览器中检查它,它不使用该CONNECT
方法,而是调用 GET 方法。
所以我很困惑。我什么时候应该使用这两种方法?
我正在构建一个 WebClient 库。现在我正在实现一个代理功能,所以我正在做一些研究,我看到了一些使用该CONNECT
方法请求 URL 的代码。
但是在我的网络浏览器中检查它,它不使用该CONNECT
方法,而是调用 GET 方法。
所以我很困惑。我什么时候应该使用这两种方法?
TL;DR仅当Web 客户端CONNECT
知道它与代理通信并且最终 URI 以https://
.
当浏览器说:
CONNECT www.google.com:443 HTTP/1.1
它的意思是:
嗨代理,请打开到谷歌的原始 TCP 连接;我写的任何后续字节,您只需重复该连接而无需任何解释。哦,还有一件事。仅当您直接与 Google 交谈时才这样做,但如果您自己使用另一个代理,则只需告诉他们相同的
CONNECT
.
请注意,这对 TLS (https) 没有任何说明。实际上CONNECT
与 TLS 是正交的;你可以只有一个,你可以有另一个,或者你可以同时拥有它们。
话虽如此,其目的CONNECT
是允许端到端加密的 TLS 会话,因此代理(或整个代理链)无法读取数据。即使代理根本不理解 TLS,它也可以工作,因为CONNECT
可以在纯 HTTP 中发出,并且只需要从代理复制原始字节。
但是与第一个代理的连接可以是 TLS (https),尽管这意味着您和第一个代理之间的流量双重加密。
显然,CONNECT
直接与最终服务器对话是没有意义的。您只需开始谈论 TLS,然后发出 HTTP GET
。终端服务器通常CONNECT
完全禁用。
对于代理,CONNECT
支持增加了安全风险。任何数据都可以通过CONNECT
,甚至 ssh 黑客攻击 192.168.1.* 上的服务器,甚至 SMTP 发送垃圾邮件。外界将这些攻击视为由代理发起的常规 TCP 连接。他们不在乎是什么原因,他们无法检查是否CONNECT
应该归咎于 HTTP。因此,由代理来保护自己免受滥用。
CONNECT 请求促使您的代理建立到远程端点的 HTTP 隧道。 通常它用于 SSL 连接,尽管它也可以与 HTTP 一起使用(用于代理链和隧道的目的)
CONNECT www.google.com:443
上面的行在端口 443 上打开了从您的代理到 www.google.com 的连接。此后,客户端发送的内容由代理转发到www.google.com:443
.
如果用户尝试检索页面http://www.google.com,代理可以代表他发送完全相同的请求并检索响应。
使用 SSL(HTTPS),只有两个远程端点理解请求,代理无法解密它们。因此,它所做的只是使用 CONNECT 打开该隧道,并让两个端点(Web 服务器和客户端)直接相互通信。
代理链:
如果您要链接 2 个代理服务器,则这是要发出的请求序列。
GET1 is the original GET request (HTTP URL)
CONNECT1 is the original CONNECT request (SSL/HTTPS URL or Another Proxy)
User Request ==CONNECT1==> (Your_Primary_Proxy ==CONNECT==> AnotherProxy-1 ... ==CONNECT==> AnotherProxy-n) ==GET1(IF is http)/CONNECT1(IF is https)==> Destination_URL
根据经验,GET 用于纯 HTTP,CONNECT 用于 HTTPS
不过还有更多细节,所以您可能想阅读相关的 RFC-s
http://www.ietf.org/rfc/rfc2068.txt http://www.ietf.org/rfc/rfc2817.txt
CONNECT 方法将请求连接转换为透明的 TCP/IP 隧道,通常是为了通过未加密的 HTTP 代理促进 SSL 加密通信 (HTTPS)。