对于 http 代理服务器来说, 浏览器发过来的 proxy-connection: keepalive 意味着什么?
C <--------> P <---------> S
http 代理服务器接收到这样的头部后,是要同时保持 CP、PS 连接,还是只用保持 CP 连接就行了?
还有另外一个问题,浏览器发给 http 代理的请求, 都是下面这样的么?
GET http://www.163.com/ HTTP/1.1
User-Agent: blabla
Host: www.163.com
还是会出现起始行不包含 host, 只有 uri 的报文
GET / HTTP/1.1
Host: www.163.com
1
choury 2017-12-01 13:37:28 +08:00 2
代理会把这个头改成 connection: keepalive 然后发给 S,自己啥也不干,因为这个头不是给它看的
|
2
xiaxiaocao 2017-12-01 13:46:24 +08:00
http1.0 时代的产物。老旧的代理,如果设置 connection: keepalive,代理原样转发给服务器,服务器会以为要建立长久连接,但是代理并不支持,这样就出问题了。
所以改为设置 proxy-connection: keepalive,如果是新的代理,支持 keepalive,它会认得这个头,并改成 connection: keepalive 转发给服务器,顺利建立持久连接;如果是老的代理,它不认识,会原样转发,这时候服务器也不会建立持久连接。完美。 |
4
xiaxiaocao 2017-12-01 13:49:11 +08:00
代理请求的 URL 必须是完整路径,这个也是 Http1.0 规范
|
5
wcsjtu OP @xiaxiaocao 嗯。这个头部就是为了解决哑代理的问题。 有一点我不太理解的是, 如果要复用之前的连接
C <--------> P <---------->S1 那么浏览器在 CP 上发来一个要转发给 S2 的请求怎么办? |
6
wcsjtu OP @xiaxiaocao 我最近在写 http 代理, 发现浏览器经常发起始行没有 host 的请求。 这样我就不知道这个包到底要发到哪去。。。。。。
|
7
xiaxiaocao 2017-12-01 14:12:07 +08:00 1
@wcsjtu 并没有说 CP 和 PS1 之间的连接是一一对应的,实际实现的时候也不会这样做。
至于你说的不是绝对路径 URL 的情况, 我现在也在用我写的代理,倒没有发现这种情况;应该可以用 Host 那个头来区别吧。 |
8
zhangysh1995 2017-12-01 14:14:07 +08:00
因为 HTTP 分为持久性和非持久性的链接,持久性的会保留下来链接。有兴趣的话下个 Wireshark 抓包,或者 burpsuite 都可以。可以看到网络模型五层的内容。
|
9
wcsjtu OP @xiaxiaocao 那么可不可以这么认为,proxy-connection: keepalive, 只是为了复用 C 到 P 的连接?
而且对于 P 来说,一个 CP 对应多个 PS 的情况下, 数据在内部还要做一次中转? |
10
wcsjtu OP @zhangysh1995 蛤~ 我这个是代理的情况,两条连接, 不知道应该保持哪一条
|
11
wcsjtu OP @xiaxiaocao 额~ 我傻 b 了,中转肯定是要的。。。。。。 只不过要在 P 内部记录 CP 到 PSi 的映射
|
12
xiaxiaocao 2017-12-01 14:54:48 +08:00
@wcsjtu CP 和 PS 之间都可以建立持久连接。比如代理实现的时候可以收到 C 的请求,然后跟 S 建立持久连接,然后收到一个 response 就发一个 connect close 会去关闭和 C 的连接,这样的都没问题。
HTTP 代理是要对每个 request 都做处理的,像 Accept-Encoding,Upgrade 这样的头都要看代理本身支持情况来修改,而不是直接用 client 传过来的。 |
13
xiaxiaocao 2017-12-01 14:57:49 +08:00
@wcsjtu 看实现吧,通常并不一定需要记录映射。你把 P 当作对 client 是一个 server,对 S 是一个 client,然后你如果连接 S 的时候用了一个本身支持连接池的 http client lib,那你用这个 lib 发请求的时候就会从连接池里拿一个对应的连接出来。
|
14
wcsjtu OP @xiaxiaocao 我这样想的。如果 CP、PS 都是持久连接,而且是 1 对 1 的情况下,后续 C 的请求起始行就可以不带 host 信息了。 类似于 http CONNECT 和 socks5 那样,第一个包用来打通连接的,需要带上 C 的地址,后续的包就不用了。
|
16
xiaxiaocao 2017-12-01 15:05:15 +08:00 1
@wcsjtu 这个我真不知道……按照 RFC 的说法,The absoluteURI form is REQUIRED when the request is being made to a proxy,所以这种不带 host 的情况,是不应该出现的。
|
17
wcsjtu OP @xiaxiaocao 这个我也看到了。。。。。。那为什么我经常从 Request-URI 中解析 host 失败。。。。。还是滚回去检查代码吧。。。。。
|
18
wcsjtu OP @xiaxiaocao 额~ 我在 rfc2068 里 8.1.3 节看到这句话
The proxy server MUST signal persistent connections separately with its clients and the origin servers (or other proxy servers) that it connects to. Each persistent connection applies to only one transport link. 这意味着 CP PS 是 1 对 1 的? |
19
xiaxiaocao 2017-12-01 15:42:04 +08:00
@wcsjtu 看着是这个意思,那是我理解错了
|