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