名前からして明らかですが、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ヘッダ部の受信する関数でしょう。