リクエストデータの処理—Werkzeugドキュメント

提供:Dev Guides
Werkzeug/docs/1.0.x/request data
移動先:案内検索

リクエストデータの処理

Web開発に関する最も重要なルールは、「ユーザーを信頼しない」です。 これは、入力ストリームの着信要求データに特に当てはまります。 WSGIを使用すると、これは実際には予想よりも少し難しくなります。 そのため、Werkzeugはリクエストストリームをラップして、最も顕著な問題からあなたを救います。

入力ストリームにEOFマーカーがありません

入力ストリームにはファイルの終わりマーカーがありません。 wsgi.input ストリームでread()メソッドを呼び出すと、準拠しているサーバーでアプリケーションがハングします。 これは実際には意図的ですが、苦痛です。 Werkzeugは、入力ストリームを特別なLimitedStreamでラップすることにより、この問題を解決します。 入力ストリームは、streamとしてリクエストオブジェクトに公開されます。 これは、空のストリーム(フォームデータが解析された場合)または入力ストリームの内容を含む制限されたストリームのいずれかです。


Werkzeug Parseはいつですか?

Werkzeugは、次の状況で受信データを解析します。

  • formfiles、またはstreamのいずれかにアクセスし、要求方法は POST または PUT でした。
  • parse_form_data()を呼び出す場合。

これらの呼び出しは互換性がありません。 parse_form_data()を呼び出す場合は、リクエストオブジェクトを使用しないでください。少なくとも、解析プロセスをトリガーする属性を使用しないでください。

これは、解析の前に wsgi.input ストリームから読み取る場合にも当てはまります。

一般的なルール: WSGI入力ストリームはそのままにしておきます。 特にWSGIミドルウェアで。 解析関数またはリクエストオブジェクトのいずれかを使用します。 フォームデータの解析や入力ストリームで機能するその他のもののために、複数のWSGIユーティリティライブラリを混在させないでください。


どのように解析しますか?

標準のWerkzeug解析動作は、次の3つのケースを処理します。

  • 入力コンテンツタイプは multipart / form-data でした。 この状況では、streamは空になり、formには通常の POST / PUT データが含まれ、filesにはFileStorageオブジェクトとしてアップロードされたファイル。
  • 入力コンテンツタイプは application / x-www-form-urlencoded でした。 次に、streamは空になり、formには通常の POST / PUT データが含まれ、filesは空になります。
  • 入力コンテンツタイプはどちらでもありませんでした。streamは、さらに処理するための入力データを含むLimitedStreamを指します。

get_dataメソッドに関する特記事項:これを呼び出すと、完全な要求データがメモリにロードされます。 これは、max_content_lengthが設定されている場合にのみ安全です。 また、ストリームを読み取るまたはget_data()を呼び出すこともできます。


リクエストデータの制限

DDOS攻撃の被害を回避するために、受け入れられるコンテンツの最大長とリクエストフィールドサイズを設定できます。 BaseRequestクラスには、max_content_lengthmax_form_memory_sizeの2つの属性があります。

最初のものは、コンテンツの合計の長さを制限するために使用できます。 たとえば、1024 * 1024 * 16に設定すると、リクエストは16MBを超える送信データを受け入れません。

特定のデータ(通常の投稿データ)はハードディスクに移動できませんが、一時ファイルは移動できるため、設定できる2番目の制限があります。 max_form_memory_sizeは、 POST で送信されるフォームデータのサイズを制限します。 1024 * 1024 * 2に設定することで、メモリに保存されているすべてのフィールドのサイズが2MB以下であることを確認できます。

ただし、使用される stream_factory がメモリ内ファイルを返す場合、これはメモリ内に保存されたファイルに影響を与えません


解析を拡張する方法は?

最新のWebアプリケーションは、マルチパートフォームデータやURLエンコードされたデータよりもはるかに多くのものを送信します。 機能を拡張するには、BaseRequestまたはRequestをサブクラス化し、メソッドを追加または拡張します。

JSON解析を提供するミックスインはすでに存在します。

from werkzeug.wrappers import Request
from werkzeug.wrappers.json import JSONMixin

class JSONRequest(JSONMixin, Request):
    pass

その基本的な実装は次のようになります。

from werkzeug.utils import cached_property
from werkzeug.wrappers import Request
import simplejson as json

class JSONRequest(Request):
    @cached_property
    def json(self):
        if self.mimetype == "application/json":
            return json.loads(self.data)