V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
wcsjtu
V2EX  ›  程序员

浏览器什么时候会在 http 请求头中添加 proxy-connection: keepalive

  •  
  •   wcsjtu · 2017-12-01 13:23:47 +08:00 · 6366 次点击
    这是一个创建于 2568 天前的主题,其中的信息可能已经有所发展或是发生改变。

    对于 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
    
    
    20 条回复    2020-01-05 14:40:46 +08:00
    choury
        1
    choury  
       2017-12-01 13:37:28 +08:00   ❤️ 2
    代理会把这个头改成 connection: keepalive 然后发给 S,自己啥也不干,因为这个头不是给它看的
    xiaxiaocao
        2
    xiaxiaocao  
       2017-12-01 13:46:24 +08:00
    http1.0 时代的产物。老旧的代理,如果设置 connection: keepalive,代理原样转发给服务器,服务器会以为要建立长久连接,但是代理并不支持,这样就出问题了。
    所以改为设置 proxy-connection: keepalive,如果是新的代理,支持 keepalive,它会认得这个头,并改成 connection: keepalive 转发给服务器,顺利建立持久连接;如果是老的代理,它不认识,会原样转发,这时候服务器也不会建立持久连接。完美。
    wcsjtu
        3
    wcsjtu  
    OP
       2017-12-01 13:46:34 +08:00
    @choury 就等于是说, 如果 S 回复 keepalive, 对于 P 来说,要同时维持两条连接?
    xiaxiaocao
        4
    xiaxiaocao  
       2017-12-01 13:49:11 +08:00
    代理请求的 URL 必须是完整路径,这个也是 Http1.0 规范
    wcsjtu
        5
    wcsjtu  
    OP
       2017-12-01 13:50:24 +08:00
    @xiaxiaocao 嗯。这个头部就是为了解决哑代理的问题。 有一点我不太理解的是, 如果要复用之前的连接
    C <--------> P <---------->S1
    那么浏览器在 CP 上发来一个要转发给 S2 的请求怎么办?
    wcsjtu
        6
    wcsjtu  
    OP
       2017-12-01 13:53:26 +08:00
    @xiaxiaocao 我最近在写 http 代理, 发现浏览器经常发起始行没有 host 的请求。 这样我就不知道这个包到底要发到哪去。。。。。。
    xiaxiaocao
        7
    xiaxiaocao  
       2017-12-01 14:12:07 +08:00   ❤️ 1
    @wcsjtu 并没有说 CP 和 PS1 之间的连接是一一对应的,实际实现的时候也不会这样做。
    至于你说的不是绝对路径 URL 的情况, 我现在也在用我写的代理,倒没有发现这种情况;应该可以用 Host 那个头来区别吧。
    zhangysh1995
        8
    zhangysh1995  
       2017-12-01 14:14:07 +08:00
    因为 HTTP 分为持久性和非持久性的链接,持久性的会保留下来链接。有兴趣的话下个 Wireshark 抓包,或者 burpsuite 都可以。可以看到网络模型五层的内容。
    wcsjtu
        9
    wcsjtu  
    OP
       2017-12-01 14:39:07 +08:00
    @xiaxiaocao 那么可不可以这么认为,proxy-connection: keepalive, 只是为了复用 C 到 P 的连接?

    而且对于 P 来说,一个 CP 对应多个 PS 的情况下, 数据在内部还要做一次中转?
    wcsjtu
        10
    wcsjtu  
    OP
       2017-12-01 14:41:03 +08:00
    @zhangysh1995 蛤~ 我这个是代理的情况,两条连接, 不知道应该保持哪一条
    wcsjtu
        11
    wcsjtu  
    OP
       2017-12-01 14:54:31 +08:00
    @xiaxiaocao 额~ 我傻 b 了,中转肯定是要的。。。。。。 只不过要在 P 内部记录 CP 到 PSi 的映射
    xiaxiaocao
        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 传过来的。
    xiaxiaocao
        13
    xiaxiaocao  
       2017-12-01 14:57:49 +08:00
    @wcsjtu 看实现吧,通常并不一定需要记录映射。你把 P 当作对 client 是一个 server,对 S 是一个 client,然后你如果连接 S 的时候用了一个本身支持连接池的 http client lib,那你用这个 lib 发请求的时候就会从连接池里拿一个对应的连接出来。
    wcsjtu
        14
    wcsjtu  
    OP
       2017-12-01 15:01:32 +08:00
    @xiaxiaocao 我这样想的。如果 CP、PS 都是持久连接,而且是 1 对 1 的情况下,后续 C 的请求起始行就可以不带 host 信息了。 类似于 http CONNECT 和 socks5 那样,第一个包用来打通连接的,需要带上 C 的地址,后续的包就不用了。
    wcsjtu
        15
    wcsjtu  
    OP
       2017-12-01 15:02:53 +08:00
    @wcsjtu 额, 上一条写错, 应该是需要带上 S 的地址
    xiaxiaocao
        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 的情况,是不应该出现的。
    wcsjtu
        17
    wcsjtu  
    OP
       2017-12-01 15:21:21 +08:00
    @xiaxiaocao 这个我也看到了。。。。。。那为什么我经常从 Request-URI 中解析 host 失败。。。。。还是滚回去检查代码吧。。。。。
    wcsjtu
        18
    wcsjtu  
    OP
       2017-12-01 15:33:09 +08:00
    @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 的?
    xiaxiaocao
        19
    xiaxiaocao  
       2017-12-01 15:42:04 +08:00
    @wcsjtu 看着是这个意思,那是我理解错了
    tanxiong
        20
    tanxiong  
       2020-01-05 14:40:46 +08:00
    @wcsjtu 按照这种说法, 如果 PC 之间的连接关闭了会怎么处理? S 感知不到, 并且 S 以为还继续和 C 维持长连接,这时候 S 往 P 发送数据呢?
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   986 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 18:52 · PVG 02:52 · LAX 10:52 · JFK 13:52
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.