グローバルナビゲーションへ

本文へ

フッターへ

お役立ち情報Blog



goでHTTPリクエストボディのサイズを制限する「MaxBytesReader」

webアプリケーションを作成していると、ユーザが誤って、もしくは悪意を持って巨大なリクエストを送ってくる場合があります。 何も対応しないとリクエストを受け付けてしまい、アプリケーションが不安定になったり無駄にメモリを確保してしまいます。

そこで今回はgoでHTTPのリクエストボディを制限するMaxBytesReaderを紹介します。

MaxBytesReaderとは?

MaxBytesReader is similar to io.LimitReader but is intended for limiting the size of incoming request bodies. In contrast to io.LimitReader, MaxBytesReader’s result is a ReadCloser, returns a non-EOF error for a Read beyond the limit, and closes the underlying reader when its Close method is called.

MaxBytesReader prevents clients from accidentally or maliciously sending a large request and wasting server resources.

MaxBytesReader は io.LimitReader に似ていますが、受信するリクエスト ボディのサイズを制限することを目的としています。 io.LimitReader とは対照的に、MaxBytesReader の結果は ReadCloser であり、制限を超えた読み取りに対しては非 EOF エラーを返し、 Close メソッドが呼び出されると基礎となるリーダーを閉じます。

MaxBytesReaderは、クライアントが誤ってまたは悪意を持って大きなリクエストを送信し、サーバーのリソースを浪費することを防ぎます。MaxBytesReader

関数の定義は以下のようになっています。

使い方

以下の例ではmyHandler関数内でリクエストのBodyをバイト数10で指定してMaxBytesReaderでWrapしています。

上記を実行すると以下の出力が得られます。

io.Copyで書き出した数が10となっており、指定したバイト数と一致しています。
また、errには  http: request body too large  というメッセージが入っています。これはMaxBytesReaderの定型エラーメッセージです。
最後にmain関数側で読み込んだ10バイト分が出力されています。

ginで利用する場合

先ほどの例ではハンドラー毎に制限をかける必要があるのでginで一括でリクエストに対して制限をかける例を紹介します。

以下のサンプルはPOSTで受けたJSONリクエストをmap[string]string{}にバインドしてその値をまたJSON形式に変換して返します。 リクエストのサイズ制限は10バイトとして定義しています。

ginのミドルウェアの機構を利用してリクエストがあった場合に事前にRequest.Bodyを MaxBytesReader でWrapしておいて、 実際の読みだし(このケースの場合は ctx.BindJSON )でエラーを取得しています。

このサンプルを実行して10バイト以上のデータを送ると以下のエラーが返されます。

さいごに

いかがだったでしょうか。 関数が用意されているので意外と簡単にリクエストのサイズを制限する事ができました。 実際に運用する場合はwebサーバ側やContent-Lengthなど他の制限手段と併せてリクエストに制限を加えるのがいいと思います。

The following two tabs change content below.

竹内 和也

事業開発部 web application engineer
大学卒業後、Web系ベンチャー企業でシステムエンジニアを経て、2009年にアーティスへ入社。 システムエンジニアとして多くの大学・病院・企業・自社のwebシステム開発に携わる。 2020年より事業開発部として新規サービスの開発に従事している。 資格:LPIC3
この記事のカテゴリ

FOLLOW US

最新の情報をお届けします