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


ngx_http_init_connection関数

accept()後に(たぶん・・・名前から推測)一回だけ通る関数。
ログに関する構造体の初期値設定を行う。
revのhandlerには、ngx_http_init_request
writeのhandlerにngx_http_empty_handlerをセット



    174 void
    175 ngx_http_init_connection(ngx_connection_t *c)
    176 {
    177     ngx_event_t         *rev;
    178     ngx_http_log_ctx_t  *ctx;
    179
    180     ctx = ngx_palloc(c->pool, sizeof(ngx_http_log_ctx_t));
    181     if (ctx == NULL) {
    182         ngx_http_close_connection(c);
    183         return;
    184     }
    185
    186     ctx->connection = c;
    187     ctx->request = NULL;
    188     ctx->current_request = NULL;
    189
    190     c->log->connection = c->number;
    191     c->log->handler = ngx_http_log_error;
    192     c->log->data = ctx;
    193     c->log->action = "reading client request line";
    194
    195     c->log_error = NGX_ERROR_INFO;
    196
    197     rev = c->read;
    198     rev->handler = ngx_http_init_request;
    199     c->write->handler = ngx_http_empty_handler;
    200
    201 #if (NGX_STAT_STUB)
    202     (void) ngx_atomic_fetch_add(ngx_stat_reading, 1);
    203 #endif
    204
    205     if (rev->ready) {
    206         /* the deferred accept(), rtsig, aio, iocp */
    207
    208         if (ngx_use_accept_mutex) {
    209             ngx_post_event(rev, &ngx_posted_events);
    210             return;
    211         }
    212
    213         ngx_http_init_request(rev);
    214         return;
    215     }
    216
    217     ngx_add_timer(rev, c->listening->post_accept_timeout);
    218
    219     if (ngx_handle_read_event(rev, 0) != NGX_OK) {
    220 #if (NGX_STAT_STUB)
    221         (void) ngx_atomic_fetch_add(ngx_stat_reading, -1);
    222 #endif
    223         ngx_http_close_connection(c);
    224         return;
    225     }
    226 }

205行目のif文(rev->ready) が真であればngx_http_init_request()と処理が続いていきます。
しかし、accept()した場合の段階ではrev->ready=0であり、このif文が真となりません。

rev->ready=1となる場所はこちら。
ngx_epoll_process_events()関数より。
    502         if ((revents & EPOLLIN) && rev->active) {
    503
    504             if ((flags & NGX_POST_THREAD_EVENTS) && !rev->accept) {
    505                 rev->posted_ready = 1;
    506
    507             } else {
    508                 rev->ready = 1;
    509             }

ということで、いったんngx_http_init_connection()終了→ngx_event_accept()終了→ngx_epoll_process_events()と戻っていきます。
そしてぐるっと回って再びepoll_wait()
今度はaccept終わっているのでレベルトリガセットだったはず(未確認)
データが来ていればepoll_wait()を抜けて、rev->ready = 1が入るのです。

そして、ngx_epoll_process_events()のrev->handler(rev)→ngx_http_init_requestに飛ぶのでした。


では、ngx_http_init_requestでは何をするのでしょうか。

    229 static void
    230 ngx_http_init_request(ngx_event_t *rev)
    231 {
    232     ngx_time_t                 *tp;
    233     ngx_uint_t                  i;
    234     ngx_connection_t           *c;
    235     ngx_http_request_t         *r;
    236     struct sockaddr_in         *sin;
    237     ngx_http_port_t            *port;
    238     ngx_http_in_addr_t         *addr;
    239     ngx_http_log_ctx_t         *ctx;
    240     ngx_http_addr_conf_t       *addr_conf;
    241     ngx_http_connection_t      *hc;
    242     ngx_http_core_srv_conf_t   *cscf;
    243     ngx_http_core_loc_conf_t   *clcf;
    244     ngx_http_core_main_conf_t  *cmcf;
    245 #if (NGX_HAVE_INET6)
    246     struct sockaddr_in6        *sin6;
    247     ngx_http_in6_addr_t        *addr6;
    248 #endif
    249
    250 #if (NGX_STAT_STUB)
    251     (void) ngx_atomic_fetch_add(ngx_stat_reading, -1);
    252 #endif
    253
    254     c = rev->data;
    255
    256     if (rev->timedout) {
    257         ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out");
    258
    259         ngx_http_close_connection(c);
    260         return;
    261     }
    262
    263     c->requests++;
    264
    265     hc = c->data;
    266
    267     if (hc == NULL) {
    268         hc = ngx_pcalloc(c->pool, sizeof(ngx_http_connection_t));
    269         if (hc == NULL) {
    270             ngx_http_close_connection(c);
    271             return;
    272         }
    273     }
    274
    275     r = hc->request;
    276
    277     if (r) {
    278         ngx_memzero(r, sizeof(ngx_http_request_t));
    279
    280         r->pipeline = hc->pipeline;
    281
    282         if (hc->nbusy) {
    283             r->header_in = hc->busy[0];
    284         }
    285
    286     } else {
    287         r = ngx_pcalloc(c->pool, sizeof(ngx_http_request_t));
    288         if (r == NULL) {
    289             ngx_http_close_connection(c);
    290             return;
    291         }
    292
    293         hc->request = r;
    294     }
    295
    296     c->data = r;
    297     r->http_connection = hc;
    298
    299     c->sent = 0;
    300     r->signature = NGX_HTTP_MODULE;
    301
    302     /* find the server configuration for the address:port */
    303
    304     port = c->listening->servers;
    305
    306     r->connection = c;
    307
    308     if (port->naddrs > 1) {
    309
    310         /*
    311          * there are several addresses on this port and one of them
    312          * is an "*:port" wildcard so getsockname() in ngx_http_server_addr()
    313          * is required to determine a server address
    314          */
    315
    316         if (ngx_connection_local_sockaddr(c, NULL, 0) != NGX_OK) {
    317             ngx_http_close_connection(c);
    318             return;
    319         }
    320
    321         switch (c->local_sockaddr->sa_family) {
    322
    323 #if (NGX_HAVE_INET6)
    324         case AF_INET6:
    325             sin6 = (struct sockaddr_in6 *) c->local_sockaddr;
    326
    327             addr6 = port->addrs;
    328
    329             /* the last address is "*" */
    330
    331             for (i = 0; i < port->naddrs - 1; i++) {
    332                 if (ngx_memcmp(&addr6[i].addr6, &sin6->sin6_addr, 16) == 0) {
    333                     break;
    334                 }
    335             }
    336
    337             addr_conf = &addr6[i].conf;
    338
    339             break;
    340 #endif
    341
    342         default: /* AF_INET */
    343             sin = (struct sockaddr_in *) c->local_sockaddr;
    344
    345             addr = port->addrs;
    346
    347             /* the last address is "*" */
    348
    349             for (i = 0; i < port->naddrs - 1; i++) {
    350                 if (addr[i].addr == sin->sin_addr.s_addr) {
    351                     break;
    352                 }
    353             }
    354
    355             addr_conf = &addr[i].conf;
    356
    357             break;
    358         }
    359
    360     } else {
    361
    362         switch (c->local_sockaddr->sa_family) {
    363
    364 #if (NGX_HAVE_INET6)
    365         case AF_INET6:
    366             addr6 = port->addrs;
    367             addr_conf = &addr6[0].conf;
    368             break;
    369 #endif
    370
    371         default: /* AF_INET */
    372             addr = port->addrs;
    373             addr_conf = &addr[0].conf;
    374             break;
    375         }
    376     }
    377
    378     r->virtual_names = addr_conf->virtual_names;
    379
    380     /* the default server configuration for the address:port */
    381     cscf = addr_conf->core_srv_conf;
    382
    383     r->main_conf = cscf->ctx->main_conf;
    384     r->srv_conf = cscf->ctx->srv_conf;
    385     r->loc_conf = cscf->ctx->loc_conf;
    386
    387     rev->handler = ngx_http_process_request_line;
    388     r->read_event_handler = ngx_http_block_reading;
    389
    390 #if (NGX_HTTP_SSL)
    391
    392     {
    393     ngx_http_ssl_srv_conf_t  *sscf;
    394
    395     sscf = ngx_http_get_module_srv_conf(r, ngx_http_ssl_module);
    396     if (sscf->enable || addr_conf->ssl) {
    397
    398         if (c->ssl == NULL) {
    399
    400             c->log->action = "SSL handshaking";
    401
    402             if (addr_conf->ssl && sscf->ssl.ctx == NULL) {
    403                 ngx_log_error(NGX_LOG_ERR, c->log, 0,
    404                               "no \"ssl_certificate\" is defined "
    405                               "in server listening on SSL port");
    406                 ngx_http_close_connection(c);
    407                 return;
    408             }
    409
    410             if (ngx_ssl_create_connection(&sscf->ssl, c, NGX_SSL_BUFFER)
    411                 != NGX_OK)
    412             {
    413                 ngx_http_close_connection(c);
    414                 return;
    415             }
    416
    417             rev->handler = ngx_http_ssl_handshake;
    418         }
    419
    420         r->main_filter_need_in_memory = 1;
    421     }
    422     }
    423
    424 #endif
    425
    426     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
    427     c->log->file = clcf->error_log->file;
    428     if (!(c->log->log_level & NGX_LOG_DEBUG_CONNECTION)) {
    429         c->log->log_level = clcf->error_log->log_level;
    430     }
    431
    432     if (c->buffer == NULL) {
    433         c->buffer = ngx_create_temp_buf(c->pool,
    434                                         cscf->client_header_buffer_size);
    435         if (c->buffer == NULL) {
    436             ngx_http_close_connection(c);
    437             return;
    438         }
    439     }
    440
    441     if (r->header_in == NULL) {
    442         r->header_in = c->buffer;
    443     }
    444
    445     r->pool = ngx_create_pool(cscf->request_pool_size, c->log);
    446     if (r->pool == NULL) {
    447         ngx_http_close_connection(c);
    448         return;
    449     }
    450
    451
    452     if (ngx_list_init(&r->headers_out.headers, r->pool, 20,
    453                       sizeof(ngx_table_elt_t))
    454         != NGX_OK)
    455     {
    456         ngx_destroy_pool(r->pool);
    457         ngx_http_close_connection(c);
    458         return;
    459     }
    460
    461     r->ctx = ngx_pcalloc(r->pool, sizeof(void *) * ngx_http_max_module);
    462     if (r->ctx == NULL) {
    463         ngx_destroy_pool(r->pool);
    464         ngx_http_close_connection(c);
    465         return;
    466     }
    467
    468     cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
    469
    470     r->variables = ngx_pcalloc(r->pool, cmcf->variables.nelts
    471                                         * sizeof(ngx_http_variable_value_t));
    472     if (r->variables == NULL) {
    473         ngx_destroy_pool(r->pool);
    474         ngx_http_close_connection(c);
    475         return;
    476     }
    477
    478     c->single_connection = 1;
    479     c->destroyed = 0;
    480
    481     r->main = r;
    482
    483     tp = ngx_timeofday();
    484     r->start_sec = tp->sec;
    485     r->start_msec = tp->msec;
    486
    487     r->method = NGX_HTTP_UNKNOWN;
    488
    489     r->headers_in.content_length_n = -1;
    490     r->headers_in.keep_alive_n = -1;
    491     r->headers_out.content_length_n = -1;
    492     r->headers_out.last_modified_time = -1;
    493
    494     r->uri_changes = NGX_HTTP_MAX_URI_CHANGES + 1;
    495     r->subrequests = NGX_HTTP_MAX_SUBREQUESTS + 1;
    496
    497     r->http_state = NGX_HTTP_READING_REQUEST_STATE;
    498
    499     ctx = c->log->data;
    500     ctx->request = r;
    501     ctx->current_request = r;
    502     r->log_handler = ngx_http_log_error_handler;
    503
    504 #if (NGX_STAT_STUB)
    505     (void) ngx_atomic_fetch_add(ngx_stat_reading, 1);
    506     r->stat_reading = 1;
    507     (void) ngx_atomic_fetch_add(ngx_stat_requests, 1);
    508 #endif
    509
    510     rev->handler(rev);
    511 }

ngx_http_request_t構造体を作成、値をセットといったところですね。
Apacheにおけるrequest_r構造体と思われます。
484 r->start_sec = tp->sec; 485 r->start_msec = tp->msec;
を見ると、ログで処理時間を出すとした場合にここで取得した時刻との計算をするんだろうなと予想

さてrev->handler(rev);で飛ぶ先はどこかというと・・・ngx_http_process_request_line()のようですね。
SSLを使用している場合はngx_http_ssl_handshakeみたいですが、今はHTTPの処理を追いましょう。
ってことでngx_http_process_request_lineに行きます。

このページへのコメント

klAo0T <a href="http://dhfnuanrnlpm.com/">dhfnuanrnlpm</a>, [url=http://apchysdezpad.com/]apchysdezpad[/url], [link=http://arwgqpbmxmqi.com/]arwgqpbmxmqi[/link], http://tznyyylyssih.com/

0
Posted by sbnwmebne 2013年11月21日(木) 02:23:06 返信

lRVYqj <a href="http://ykfdcjkbgngh.com/">ykfdcjkbgngh</a>, [url=http://ajlougwsuplf.com/]ajlougwsuplf[/url], [link=http://mrfohjluvoze.com/]mrfohjluvoze[/link], http://trswhaaqowww.com/

0
Posted by abjaiiiqv 2013年11月14日(木) 09:29:35 返信

lfOcqL <a href="http://mhimxbshcbvr.com/">mhimxbshcbvr</a>, [url=http://gcptyaaqnfvx.com/]gcptyaaqnfvx[/url], [link=http://gfgarjhcnyof.com/]gfgarjhcnyof[/link], http://sdjahycpglrq.com/

0
Posted by zmeshc 2013年07月07日(日) 11:00:00 返信

コメントをかく


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

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

Menu

メニューサンプル1

メニューサンプル2

開くメニュー

閉じるメニュー

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

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