0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?