› httpbin - 协议调试工具
› httpstatuses - 协议状态码查询
› httpie - cURL-like tool for humans
Fiddler
leaflxh
V2EX  ›  HTTP

在写一个 HTTP 服务器,想问一下请求报文中的 Content-Length 该如何验证

  •  
  •   leaflxh · Aug 7, 2019 · 5330 views
    This topic created in 2649 days ago, the information mentioned may be changed or developed.

    平台是 linux,使用 select 函数来进行 IO 复用

    对于每一个已连接的描述符,会有一个缓冲区来存储其发送过来的数据。(存储数据的逻辑在文尾)

    由于是来多少数据就往缓冲区里存多少数据,这样如果有两个及以上的报文同时进了缓冲区,需要对他们进行分割。

    我打算是先以两个\r\n 来进行分割,取出缓冲区里的第一个报文头,如果报文头里有 Content-Length 字段,就继续从缓冲区里读相应长度的数据。

    然后就遇到了问题,假如 Content-Length 是伪造的,数值大于实际发送过来的数据的长度,那么会读到下一个报文的报文。

    所以想问一下各位有什么解决办法吗

    13 replies  •  2019-08-30 15:09:28 +08:00
    leaflxh
    leaflxh
    OP
    Aug 7, 2019
    1
    zzzbkl
    zzzbkl
    Aug 7, 2019 via Android
    2
    rfc 里面描述 content-length 时用的是 should 而不是 must,通过它来验证长度确实不靠谱。同好奇
    009694
    009694
    Aug 7, 2019 via iPhone
    3
    content-length 是用来验证报文完整性而不是用来听之任之长度读取的吧。。
    abcbuzhiming
    abcbuzhiming
    Aug 7, 2019❤️1
    4
    楼主,我觉得你的思路不对,首先 Http 是基于 TCP 的,每个连接的缓冲区都是独立的,现在假设有一个有恶意的人,伪造了 Content-Length,把它变的更长,那么就算你读下去,你读到的仍然是这个人后续发来的包,你就把后续得到的包数据也当成是 request body 的内容好了。这有什么问题呢,你是告诉我有这么长的,我就读这么长,我看过 Nginx 的实现,只有在读到不够长度的数据时才会报错断开连接,但是只要后续能继续读到数据,就会继续读下去,http 的 content-length 就是 body 长度指示器,只要它不超过 http 协议定义的最大长度,你就照着读,没错的
    ipwx
    ipwx
    Aug 7, 2019 via Android
    5
    @abcbuzhiming 我觉得楼主可能担心客户端伪造了超长 content length
    xenme
    xenme
    Aug 7, 2019 via iPhone
    6
    @ipwx 一段时间没数据或者 idle 很久就可以断开连接了
    des
    des
    Aug 7, 2019 via Android
    7
    补充一点,仅仅两个\r\n 来进行分割,也是考虑不完全的,因为有可能对方不发这个,然后就挂了
    abcbuzhiming
    abcbuzhiming
    Aug 7, 2019
    8
    @ipwx 超长的 content length 可以被 http 服务器的最大包长参数限制,主流的 http 服务器实现都带有这个参数,一旦超了直接 close socket
    walkman660
    walkman660
    Aug 7, 2019
    9
    觉得楼主可以试下在已有开源的 HTTP SERVER 做修改满足需求
    自己写一边太麻烦了
    leaflxh
    leaflxh
    OP
    Aug 7, 2019
    10
    🌚决定直接关闭连接,因为请求者发送的数据长度扰乱了本次连接的缓冲区管理
    julyclyde
    julyclyde
    Aug 7, 2019
    11
    首先 HTTP 是基于 TCP 的
    TCP 不是报文,而是流
    只有坚信流式思维才能想明白这个问题
    tabris17
    tabris17
    Aug 7, 2019
    12
    根据 content-length 来截断数据包这个思路本身就有问题吧
    momocraft
    momocraft
    Aug 30, 2019
    13
    content-length 是用户传的(而且和其他请求一样是可以随便造的)。服务器能处理正确情况,并在出错时继续稳定运行就可。
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   880 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 38ms · UTC 23:49 · PVG 07:49 · LAX 15:49 · JFK 18:49
    ♥ Do have faith in what you're doing.