Golang 中的内容长度

Hus*_*ain 5 http go

我在网上找不到任何对此有帮助的信息。

我正在编写一个 REST API,我想记录请求正文的大小(以字节为单位)以获取指标。Go net/http API 不直接提供这一点。http.Request 确实有 Content-Length 字段,但该字段可以为空,否则客户端可能会发送错误数据。

有没有办法在中间件级别实现这一点?暴力方法是读取全文并检查大小。但如果我在中间件中这样做,处理程序将无法访问主体,因为它会被读取并关闭。

Kib*_*Gzr 7

为什么你要在这里中间?
简单的方法是 根据需要使用请求正文b, err = io.Copy(anyWriterOrMultiwriter, r.Body)
b时请求的总内容长度。err == nil
b, err = io.Copy(ioutil.Discard, r.Body)


Dar*_*nec 5

您可以编写一个自定义程序ReadCloser来代理现有的程序并计算字节数。就像是:

type LengthReader struct {
    Source io.ReadCloser
    Length int
}

func (r *LengthReader) Read(b []byte) (int, error) {
    n, err := r.Source.Read(b)
    r.Length += n
    return n, err
}

func (r *LengthReader) Close() error {
    var buf [32]byte
    var n int
    var err error
    for err == nil {
        n, err = r.Source.Read(buf[:])
        r.Length += n
    }
    closeerr := r.Source.Close()
    if err != nil && err != io.EOF {
        return err
    }
    return closeerr
}
Run Code Online (Sandbox Code Playgroud)

这将在您从流中读取字节时对字节进行计数,关闭时它将首先消耗并计算所有剩余的未读字节。完成流后,您可以访问长度。