WebサーバとしてのNginxの調査結果を記録する。


ngx_http_process_request_line関数

名前からして明らかですが、HTTPのリクエストラインを処理する関数でしょう。
このあたりはわかりやすいつくりだと思います。

    676 static void
    677 ngx_http_process_request_line(ngx_event_t *rev)
    678 {
    679     u_char                    *host;
    680     ssize_t                    n;
    681     ngx_int_t                  rc, rv;
    682     ngx_connection_t          *c;
    683     ngx_http_request_t        *r;
    684     ngx_http_core_srv_conf_t  *cscf;
    685
    686     c = rev->data;
    687     r = c->data;
    688
    689     ngx_log_debug0(NGX_LOG_DEBUG_HTTP, rev->log, 0,
    690                    "http process request line");
    691
    692     if (rev->timedout) {
    693         ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out");
    694         c->timedout = 1;
    695         ngx_http_close_request(r, NGX_HTTP_REQUEST_TIME_OUT);
    696         return;
    697     }
rev->timedoutが真であれば、タイムアウトエラーで終了となってます。
まだリクエストラインを受信していないけど、この場合エラー画面はどうなるんだろう。
ngx_http_close_request()を見ればよいのですが、いったん飛ばします。
rev->timedout=1が入るのもどこか・・・おそらくepoll_waitあたりだと思うけどこれも後回し。

    698
    699     rc = NGX_AGAIN;
    700
    701     for ( ;; ) {
    702
    703         if (rc == NGX_AGAIN) {
    704             n = ngx_http_read_request_header(r);
    705
    706             if (n == NGX_AGAIN || n == NGX_ERROR) {
    707                 return;
    708             }
    709         }
    710
    711         rc = ngx_http_parse_request_line(r, r->header_in);
    712
    713         if (rc == NGX_OK) {
    714
    715             /* the request line has been parsed successfully */
    716
    717             r->request_line.len = r->request_end - r->request_start;
    718             r->request_line.data = r->request_start;
    719
    720
    721             if (r->args_start) {
    722                 r->uri.len = r->args_start - 1 - r->uri_start;
    723             } else {
    724                 r->uri.len = r->uri_end - r->uri_start;
    725             }
    726
    727
    728             if (r->complex_uri || r->quoted_uri) {
    729
    730                 r->uri.data = ngx_pnalloc(r->pool, r->uri.len + 1);
    731                 if (r->uri.data == NULL) {
    732                     ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
    733                     return;
    734                 }
    735
    736                 cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
    737
    738                 rc = ngx_http_parse_complex_uri(r, cscf->merge_slashes);
    739
    740                 if (rc == NGX_HTTP_PARSE_INVALID_REQUEST) {
    741                     ngx_log_error(NGX_LOG_INFO, c->log, 0,
    742                                   "client sent invalid request");
    743                     ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
    744                     return;
    745                 }
    746
    747             } else {
    748                 r->uri.data = r->uri_start;
    749             }
    750
    751
    752             r->unparsed_uri.len = r->uri_end - r->uri_start;
    753             r->unparsed_uri.data = r->uri_start;
    754
    755
    756             r->method_name.len = r->method_end - r->request_start + 1;
    757             r->method_name.data = r->request_line.data;
    758
    759
    760             if (r->http_protocol.data) {
    761                 r->http_protocol.len = r->request_end - r->http_protocol.data;
    762             }
    763
    764
    765             if (r->uri_ext) {
    766                 if (r->args_start) {
    767                     r->exten.len = r->args_start - 1 - r->uri_ext;
    768                 } else {
    769                     r->exten.len = r->uri_end - r->uri_ext;
    770                 }
    771
    772                 r->exten.data = r->uri_ext;
    773             }
    774
    775
    776             if (r->args_start && r->uri_end > r->args_start) {
    777                 r->args.len = r->uri_end - r->args_start;
    778                 r->args.data = r->args_start;
    779             }
    780
    781 #if (NGX_WIN32)
    782             {
    783             u_char  *p;
    784
    785             p = r->uri.data + r->uri.len - 1;
    786
    787             if (*p == '.' || *p == ' ') {
    788
    789                 while (--p > r->uri.data && (*p == '.' || *p == ' ')) {
    790                     /* void */
    791                 }
    792
    793                 r->uri.len = p + 1 - r->uri.data;
    794
    795                 ngx_http_set_exten(r);
    796             }
    797             }
    798 #endif
    799
    800             ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
    801                            "http request line: \"%V\"", &r->request_line);
    802
    803             ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
    804                            "http uri: \"%V\"", &r->uri);
    805
    806             ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
    807                            "http args: \"%V\"", &r->args);
    808
    809             ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
    810                            "http exten: \"%V\"", &r->exten);
    811
    812             if (r->host_start && r->host_end) {
    813
    814                 host = r->host_start;
    815                 n = ngx_http_validate_host(r, &host,
    816                                            r->host_end - r->host_start, 0);
    817
    818                 if (n == 0) {
    819                     ngx_log_error(NGX_LOG_INFO, c->log, 0,
    820                                   "client sent invalid host in request line");
    821                     ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
    822                     return;
    823                 }
    824
    825                 if (n < 0) {
    826                     ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
    827                     return;
    828                 }
    829
    830                 r->headers_in.server.len = n;
    831                 r->headers_in.server.data = host;
    832             }
    833
    834             if (r->http_version < NGX_HTTP_VERSION_10) {
    835
    836                 if (ngx_http_find_virtual_server(r, r->headers_in.server.data,
    837                                                  r->headers_in.server.len)
    838                     == NGX_ERROR)
    839                 {
    840                     ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
    841                     return;
    842                 }
    843
    844                 ngx_http_process_request(r);
    845                 return;
    846             }
    847
    848
    849             if (ngx_list_init(&r->headers_in.headers, r->pool, 20,
    850                               sizeof(ngx_table_elt_t))
    851                 != NGX_OK)
    852             {
    853                 ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
    854                 return;
    855             }
    856
    857
    858             if (ngx_array_init(&r->headers_in.cookies, r->pool, 2,
    859                                sizeof(ngx_table_elt_t *))
    860                 != NGX_OK)
    861             {
    862                 ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
    863                 return;
    864             }
    865
    866             c->log->action = "reading client request headers";
    867
    868             rev->handler = ngx_http_process_request_headers;
    869             ngx_http_process_request_headers(rev);
    870
    871             return;
    872         }
    873
    874         if (rc != NGX_AGAIN) {
    875
    876             /* there was error while a request line parsing */
    877
    878             ngx_log_error(NGX_LOG_INFO, c->log, 0,
    879                           ngx_http_client_errors[rc - NGX_HTTP_CLIENT_ERROR]);
    880             ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
    881             return;
    882         }
    883
    884         /* NGX_AGAIN: a request line parsing is still incomplete */
    885
    886         if (r->header_in->pos == r->header_in->end) {
    887
    888             rv = ngx_http_alloc_large_header_buffer(r, 1);
    889
    890             if (rv == NGX_ERROR) {
    891                 ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
    892                 return;
    893             }
    894
    895             if (rv == NGX_DECLINED) {
    896                 r->request_line.len = r->header_in->end - r->request_start;
    897                 r->request_line.data = r->request_start;
    898
    899                 ngx_log_error(NGX_LOG_INFO, c->log, 0,
    900                               "client sent too long URI");
    901                 ngx_http_finalize_request(r, NGX_HTTP_REQUEST_URI_TOO_LARGE);
    902                 return;
    903             }
    904         }
    905     }
    906 }

処理長っ。
for文のループですね。
for文を抜ける条件は・・・いっぱいある。
コードを細かく前にまず、予想。
リクエストラインを読む関数なので、for文のループを抜けるのはリクエストラインを抜けるまで。
1行目が改行の場合を考えてfor文ループか、この処理でHTTPヘッダ部をすべて観てしまうかのどちらか。

まずは必ず最初にngx_http_read_request_header()を通ります。
ここではrecv()をしており、クライアントからの受信データが入ります。
関数の概要は以下のとおり。

関数:ngx_http_read_request_header
戻り値:受信したサイズ
    受信したデータはr->header_in->posのアドレスからr->header_in->lastまでに入っています。

よって、r->header_inでは受信したデータが入りました。受信したデータサイズはnです。
そして次にngx_http_parse_request_line()が呼ばれます。


関数:ngx_http_parse_request_line
戻り値: NGX_HTTP_PARSE_INVALID_REQUEST ⇒ フォーマットエラー
     NGX_AGAIN ⇒ フォーマットは合っていてLFで終わらなかった場合
     NGX_OK ⇒ フォーマットがあってLFで終わった場合
処理内容:
  リクエストラインの解析。すなわち[HTTPメソッド] [URI] [HTTPバージョン]をパースする。
  HTTPメソッドはr->method、URIはr->uri_start,r->uri_end、HTTPバージョンはr->http_major,r->http_minorに入る。
  その他、http://形式で入っていた場合スキーマやポート番号をr->port_startなどに入る。


ということで、ngx_http_parse_request_lineはリクエストラインだけを処理します。
ここでNGX_OKだとngx_http_process_request_headers()を経て、returnですね。
for文のループは、LFがない場合ってことですね。
すごい長いURLを指定した場合なんかがNGX_AGAINのままですね。

長いURLの場合は、ngx_http_alloc_large_header_bufferのようです。
せっかくなので見てみました。

設定項目large_client_header_buffersで設定した値と比較している。
large_client_header_buffersでは「num」と「バッファーサイズ」を設定する。
バッファーサイズは受信したヘッダデータが超えていないかチェックし、超えていた場合はNGX_DECLINEDで返る。
一方の「num」がわからない。
こっちはhttp_connection構造体のnbusyという値と比較しているがこれは何の数値だろう??
それが何だかわからず。

さて、正常処理だとここでは最終的に以下のようになりますん。
    868             rev->handler = ngx_http_process_request_headers;
    869             ngx_http_process_request_headers(rev);
ってことで次はngx_http_process_request_headersを見ます。
HTTPヘッダ部の受信する関数でしょう。

このページへのコメント

HFVSZR <a href="http://fxejgtjspvdn.com/">fxejgtjspvdn</a>, [url=http://rbwymlfgwyhl.com/]rbwymlfgwyhl[/url], [link=http://yfhygbvmvutq.com/]yfhygbvmvutq[/link], http://jndqettmhbly.com/

0
Posted by iizgydoscs 2013年11月20日(水) 21:24:54 返信

YcRjNb <a href="http://fimvkdmltxin.com/">fimvkdmltxin</a>, [url=http://dlywldzpdsxa.com/]dlywldzpdsxa[/url], [link=http://nwfgqqixvnlf.com/]nwfgqqixvnlf[/link], http://iqsvgmeirfxw.com/

0
Posted by fzygnliuacc 2013年11月14日(木) 10:59:22 返信

Zc3y9D <a href="http://bhsytphxgtgs.com/">bhsytphxgtgs</a>, [url=http://cnugczfnmggy.com/]cnugczfnmggy[/url], [link=http://yqvagwyknjyd.com/]yqvagwyknjyd[/link], http://mjrirvbhvgff.com/

0
Posted by jtilugudk 2013年07月07日(日) 17:03:15 返信

コメントをかく


「http://」を含む投稿は禁止されています。

利用規約をご確認のうえご記入下さい

Menu

メニューサンプル1

メニューサンプル2

開くメニュー

閉じるメニュー

  • アイテム
  • アイテム
  • アイテム
【メニュー編集】

管理人/副管理人のみ編集できます