为了账号安全,请及时绑定邮箱和手机立即绑定

Golang 中的内容长度

Golang 中的内容长度

Go
慕妹3146593 2023-05-08 18:07:27
我在网上找不到任何有用的东西。我正在编写一个 REST API,我想以字节为单位记录请求正文的大小以获取指标。Go net/http API 不直接提供。http.Request 确实有 Content-Length 字段,但该字段可以为空,否则客户端可能会发送虚假数据。有没有办法在中间件级别获得它?蛮力方法是阅读全身并检查大小。但是如果我在中间件中这样做,处理程序将无法访问主体,因为它已经被读取和关闭。
查看完整描述

3 回答

?
Qyouu

TA贡献1786条经验 获得超11个赞

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

查看完整回答
反对 回复 2023-05-08
?
绝地无双

TA贡献1946条经验 获得超4个赞

您可以编写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

}

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


查看完整回答
反对 回复 2023-05-08
?
扬帆大鱼

TA贡献1799条经验 获得超9个赞

选项1

使用TeeReader,这是可扩展的。它将阅读器分成两部分,其中之一使用分配的内存计算大小。另外,在第一种情况下

 maxmem := 4096

  var buf bytes.Buffer

  // comment this line out if you want to disable gathering metrics

  resp.Body = io.TeeReader(resp.Body, &buf) 


  readsize := func(r io.Reader) int {

    bytes := make([]byte, maxmem)

    var size int

      for {

        read, err := r.Read(bytes)

        if err == io.EOF {

        break

      }

      size += read

    }

    return size

  }


  log.Printf("Size is %d", readsize(&buf))

选项2不可扩展的方式(原始答案)

您可以只读取正文,计算大小,然后解组为结构,这样它就变成了:


    b, _ := ioutil.ReadAll(r.Body)


    size := len(b) // can be nil so check err in your app

    

    if err := json.Unmarshal(b, &input); err != nil {

        s.BadReq(w, errors.New("error reading body"))

        return

    }


查看完整回答
反对 回复 2023-05-08
  • 3 回答
  • 0 关注
  • 142 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信