在写一个 HTTP 服务器,想问一下请求报文中的 Content-Length 该如何验证 - V2EX
httpbin - 协议调试工具
httpstatuses - 协议状态码查询
httpie - cURL-like tool for humans
Fiddler
leaflxh
V2EX    HTTP

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

  •  
  •   leaflxh Aug 7, 2019 4879 views
    This topic created in 2480 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
        1
    leaflxh  
    OP
       Aug 7, 2019
    zzzbkl
        2
    zzzbkl  
       Aug 7, 2019 via Android
    rfc 里面描述 content-length 时用的是 should 而不是 must,通过它来验证长度确实不靠谱。同好奇
    009694
        3
    009694  
       Aug 7, 2019 via iPhone
    content-length 是用来验证报文完整性而不是用来听之任之长度读取的吧。。
    abcbuzhiming
        4
    abcbuzhiming  
       Aug 7, 2019   1
    楼主,我觉得你的思路不对,首先 Http 是基于 TCP 的,每个连接的缓冲区都是独立的,现在假设有一个有恶意的人,伪造了 Content-Length,把它变的更长,那么就算你读下去,你读到的仍然是这个人后续发来的包,你就把后续得到的包数据也当成是 request body 的内容好了。这有什么问题呢,你是告诉我有这么长的,我就读这么长,我看过 Nginx 的实现,只有在读到不够长度的数据时才会报错断开连接,但是只要后续能继续读到数据,就会继续读下去,http 的 content-length 就是 body 长度指示器,只要它不超过 http 协议定义的最大长度,你就照着读,没错的
    ipwx
        5
    ipwx  
       Aug 7, 2019 via Android
    @abcbuzhiming 我觉得楼主可能担心客户端伪造了超长 content length
    xenme
        6
    xenme  
       Aug 7, 2019 via iPhone
    @ipwx 一段时间没数据或者 idle 很久就可以断开连接了
    des
        7
    des  
       Aug 7, 2019 via Android
    补充一点,仅仅两个\r\n 来进行分割,也是考虑不完全的,因为有可能对方不发这个,然后就挂了
    abcbuzhiming
        8
    abcbuzhiming  
       Aug 7, 2019
    @ipwx 超长的 content length 可以被 http 服务器的最大包长参数限制,主流的 http 服务器实现都带有这个参数,一旦超了直接 close socket
    walkman660
        9
    walkman660  
       Aug 7, 2019
    觉得楼主可以试下在已有开源的 HTTP SERVER 做修改满足需求
    自己写一边太麻烦了
    leaflxh
        10
    leaflxh  
    OP
       Aug 7, 2019
    决定直接关闭连接,因为请求者发送的数据长度扰乱了本次连接的缓冲区管理
    julyclyde
        11
    julyclyde  
       Aug 7, 2019
    首先 HTTP 是基于 TCP 的
    TCP 不是报文,而是流
    只有坚信流式思维才能想明白这个问题
    tabris17
        12
    tabris17  
       Aug 7, 2019
    根据 content-length 来截断数据包这个思路本身就有问题吧
    momocraft
        13
    momocraft  
       Aug 30, 2019
    content-length 是用户传的(而且和其他请求一样是可以随便造的)。服务器能处理正确情况,并在出错时继续稳定运行就可。
    About     Help     Advertise     Blog     API     FAQ     Solana     2750 Online   Highest 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 61ms UTC 01:18 PVG 09:18 LAX 18:18 JFK 21:18
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86