golang http 1.1 max body实现

博客讨论了HTTP1.1与RPC在处理消息大小上的差异。HTTP1.1没有内置的最大消息体限制,而RPC如gRPC通过5字节的头部来指定消息长度,确保不超过设定的最大限制,防止服务崩溃。文章还提供了示例代码展示如何在RPC中检查并防止超大消息的接收,并给出了一个额外的函数来验证最大尺寸的读取。
摘要由CSDN通过智能技术生成
  1. http1.1没有实现max body的设置,不像rpc可以直接设置接受和发送的body最大大小,具体可以参考grpc 客户端、服务端 发送、接收消息大小,是按照有多大就发送多大的内容,容易导致服务撑死

  2. rpc比较机智,使用5个字节的header来存储请求数据的大小,第一个字段表示是否有数据,0表示没有,1表示有,后面4个节点表示数据的长度,所有服务端直接从header里面读取大小,就可以判断是不是超了最大限制

    func (p *parser) recvMsg(maxReceiveMessageSize int) (pf payloadFormat, msg []byte, err error)    {
        if _, err := p.r.Read(p.header[:]); err != nil {
    	    return 0, nil, err
        }
    
        pf = payloadFormat(p.header[0])
        length := binary.BigEndian.Uint32(p.header[1:])
    
        if length == 0 {
    	    return pf, nil, nil
        }
        if int64(length) > int64(maxInt) {
    	    return 0, nil, status.Errorf(codes.ResourceExhausted, "grpc: received message larger than max length allowed on current machine (%d vs. %d)", length, maxInt)
        }
        if int(length) > maxReceiveMessageSize {
    	    return 0, nil, status.Errorf(codes.ResourceExhausted, "grpc: received message larger than max (%d vs. %d)", length, maxReceiveMessageSize)
        }
        ...
    }
    
  3. 可以通过先读取maxSize进行读取,然后再次读取,看是不是返回EOF错误

    func maxLimitBody(r io.Reader, size int) ([]byte, error) {
        if r == nil {
    	    return nil, nil
        }
    
        result := make([]byte, size)
        count, err := r.Read(result)
        if err != nil {
    	    return nil, err
        }
    
        if count != size {
    	    return result, nil
        }
    
        oneMore := make([]byte, 1)
        _, err = r.Read(oneMore)
        if err == io.EOF {
    	    return result, nil
        }
    
        if err != nil {
    	    return nil, err
        }
        return nil, fmt.Errorf("data more than %d", size)
    }
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值