LoginSignup
0
0

More than 3 years have passed since last update.

GinでBodyを取得する際の最大サイズについて

Posted at

概要

ginで不確定なjosnをinterfaceに変換する際、一定サイズを超えると変換できない状態になった。

コード

func SAmple(c *gin.Context) {
    ~~~
    //bodyを取得
    buf := make([]byte, 1028)
    n, _ := c.Request.Body.Read(buf)
    body := string(buf[0:n])
    //bodyをmapに変換
    var json_parse map[string]interface{}
    err := json.Unmarshal([]byte(b), &json_parse)
    ~~~
}

c.Request.Body.Readでバイトスライスにボディを格納してstring形に変換していますが、
jsonのサイズが一定値を超えるとパースできなくなりました。

私の環境ではnが2575で上限になりそれ以降のリクエストボディがbodyに格納されずjson.Unmarssamlでエラーになっていました。

修正前に

Webサーバがbodyを制限なく受け入れるとbodyサイズだけサーバのメモリが消費されるため、
大きなbodyを送信しサーバをダウンさせるセキュリティホールになります。
そのため、API側で受け取れるbodyに上限を設けることは、Webに公開するAPIの場合必須になります。

その点は注意したうえで実装してください。

修正後

func SAmple(c *gin.Context) {
    ~~~
    //bodyを取得
    var bodyBytes []byte
    if c.Request.Body != nil {
      bodyBytes, _ = ioutil.ReadAll(c.Request.Body)
    }
    c.Request.Body = ioutil.NopCloser(bytes.NewBuffer(bodyBytes))
    bodyString := string(bodyBytes)
    //変換
    var json_parse map[string]interface{}
    err := json.Unmarshal([]byte(b), &json_parse)
    ~~~
}

ioutil.ReadAllですべてのbodyを読み込めるので問題なくjsonをinterfaceへ変換できます。

まとめ

c.Request.Body.Read(buf)にはサイズに上限がある。
全部読み込みたい場合は、ioutil.ReadAll(c.Request.Body)で読み込みましょう

ありがとうございました。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0