しかし、残念ながらPOSTデータの使用方法については、情報が叫びました。
まず、Igor Sysoev( nginxの作成者 )は、モジュールでのPOSTデータの使用を非常に注意深く調べます。 そして、これは原則として正当化されます:原則として、POSTでは、ヘッダーサイズに比べてデータが大量に使用されるため、処理メカニズムが異なります。 また、余分なデータを処理すると、常に間接的にパフォーマンスに影響する可能性があります。 nginxでのプロセスはできる限り簡単にして、女性が接続をできるだけ早く処理し、次の接続の処理を開始できるようにする必要があります。
処理サイクルを考慮してください。
- 読み取りフェーズを要求します。
- サーバーレベルでのURIのフェーズ変換。
- 要求が処理される構成を検索します。
- ロケーションレベルでのフェーズURIマッピング。
- 結果を処理するフェーズ、リクエストURIの変換、
- アクセス検証の準備段階。
- アクセス検証フェーズ。
- アクセス制御結果を処理するフェーズ。
- 処理フェーズtry_files;
- 応答生成フェーズ。
- ロギングフェーズ。
通常、すべてのhttpモジュールは、応答生成フェーズ中にハングアップします。 もちろん、例外はアップストリームモジュールとフィルターです。 Emillerの詳細
POSTの場合、すべてが異なり、まったく処理されない場合があります。 リクエストngx_http_request_t * rの構造を見ると、これはすべてのhttpモジュールを赤いスレッドとして渡し、コンテンツハンドラーでフィールドの値を次のように渡します。
r-> request_body-> bufは現在のバッファーであり、
r-> request_body-> bufs-POST要求のデータバッファーのチェーンは空(NULL)になります。 これは、処理が開始されなかったためです。
POSTリクエスト処理は、ボディハンドラコールバックをngx_http_read_client_request_bodyに設定することで実行されます(関数はhttp_request_body.cで定義されています)。
次のようなものがあるはずです。
rc = ngx_http_read_client_request_body ( r, ngx_http_mymodule_body_handler ) ; // " " <br/>
// , , NGX_AGAIN, <br/>
<br/>
if ( rc >= NGX_HTTP_SPECIAL_RESPONSE ) { <br/>
return rc ; <br/>
} <br/>
<br/>
return NGX_DONE ;
rc = ngx_http_read_client_request_body ( r, ngx_http_mymodule_body_handler ) ; // " " <br/>
// , , NGX_AGAIN, <br/>
<br/>
if ( rc >= NGX_HTTP_SPECIAL_RESPONSE ) { <br/>
return rc ; <br/>
} <br/>
<br/>
return NGX_DONE ;
ngx_http_mymodule_body_handlerは、POST要求の本文を処理するためのハンドラーです。 ハンドラーの本体では、ハンドラーフェーズが呼び出されます。 ボディハンドラコードは次のようになります。
static void ngx_http_mymodule_body_handler ( request_body * r ) { <br/>
ngx_int_t rc = NGX_OK ; <br/>
<br/>
rc = ngx_http_mymodule_phase_handler ( r ) ; // <br/>
if ( rc >= NGX_HTTP_SPECIAL_RESPONSE ) { <br/>
ngx_http_finalize_request ( f, 0 ) ; // , , . <br/>
} <br/>
return ; <br/>
} <br/>
static void ngx_http_mymodule_body_handler ( request_body * r ) { <br/>
ngx_int_t rc = NGX_OK ; <br/>
<br/>
rc = ngx_http_mymodule_phase_handler ( r ) ; // <br/>
if ( rc >= NGX_HTTP_SPECIAL_RESPONSE ) { <br/>
ngx_http_finalize_request ( f, 0 ) ; // , , . <br/>
} <br/>
return ; <br/>
} <br/>
ハンドラーフェーズでは、POSTデータを含むチャンクが処理されます。 フェーズハンドラーはデータを処理し、コールバックをボディ処理に再度設定します。 ハンドラーフェーズコードは次のようになります。
<br/>
ngx_int_t ngx_http_mymodule_phase_handler ( request_body * r ) { <br/>
<br/>
ngx_int_t rc = NGX_OK ; <br/>
if ( r - > request_body == NULL ) { <br/>
// POST , <br/>
rc = ngx_http_read_client_request_body ( r, ngx_http_mymodule_body_handler ) ; <br/>
<br/>
if ( rc >= NGX_HTTP_SPECIAL_RESPONSE ) { <br/>
return rc ; <br/>
} <br/>
<br/>
return NGX_DONE ; <br/>
} <br/>
<br/>
// ? <br/>
if ( r - > request_body - > rest ) { <br/>
return NGX_DONE ; <br/>
} <br/>
return rc ; <br/>
} <br/>
<br/>
ngx_int_t ngx_http_mymodule_phase_handler ( request_body * r ) { <br/>
<br/>
ngx_int_t rc = NGX_OK ; <br/>
if ( r - > request_body == NULL ) { <br/>
// POST , <br/>
rc = ngx_http_read_client_request_body ( r, ngx_http_mymodule_body_handler ) ; <br/>
<br/>
if ( rc >= NGX_HTTP_SPECIAL_RESPONSE ) { <br/>
return rc ; <br/>
} <br/>
<br/>
return NGX_DONE ; <br/>
} <br/>
<br/>
// ? <br/>
if ( r - > request_body - > rest ) { <br/>
return NGX_DONE ; <br/>
} <br/>
return rc ; <br/>
} <br/>
リクエストPOStデータは、ngx_http_request.hで定義されたngx_http_request_body_t構造体にあります
typedef struct { <br/>
ngx_temp_file_t * temp_file ; // ( ) <br/>
ngx_chain_t * bufs ; // . <br/>
ngx_buf_t * buf ; // <br/>
off_t rest ; <br/>
ngx_chain_t * to_write ; <br/>
ngx_http_client_body_handler_pt post_handler ; <br/>
} ngx_http_request_body_t ; <br/>
typedef struct { <br/>
ngx_temp_file_t * temp_file ; // ( ) <br/>
ngx_chain_t * bufs ; // . <br/>
ngx_buf_t * buf ; // <br/>
off_t rest ; <br/>
ngx_chain_t * to_write ; <br/>
ngx_http_client_body_handler_pt post_handler ; <br/>
} ngx_http_request_body_t ; <br/>
この構造体へのポインタは、ngx_http_request_sリクエスト構造体で定義されています:
r-> request_body;
現在のウィンドウのデータは、バッファフレームによって決定されます。
r-> request_body-> buf-> start
r-> request_body-> buf-> end
または、POST要求サイズが大きい場合、データはバッファーチェーンr-> request_body-> bufs-> buf-> start ... endから抽出され、次のバッファーが取得されます。そのアドレスは次のフィールドにあります。 ngx_chain_s構造を参照してください:
// core/ngx_buf.h
struct ngx_chain_s {
ngx_buf_t * buf ;
ngx_chain_t * next ;
} ;
size -- ( start end) Content-Length r->headers_in->off_t ;
- .
.
// core/ngx_buf.h
struct ngx_chain_s {
ngx_buf_t * buf ;
ngx_chain_t * next ;
} ;
size -- ( start end) Content-Length r->headers_in->off_t ;
- .
.