ngx_http_request.c
来自「Nginx是一个高性能的HTTP和反向代理服务器」· C语言 代码 · 共 2,528 行 · 第 1/5 页
C
2,528 行
/* * Copyright (C) Igor Sysoev */#include <ngx_config.h>#include <ngx_core.h>#include <ngx_event.h>#include <ngx_http.h>static void ngx_http_init_request(ngx_event_t *ev);static void ngx_http_process_request_line(ngx_event_t *rev);static void ngx_http_process_request_headers(ngx_event_t *rev);static ssize_t ngx_http_read_request_header(ngx_http_request_t *r);static ngx_int_t ngx_http_alloc_large_header_buffer(ngx_http_request_t *r, ngx_uint_t request_line);static ngx_int_t ngx_http_process_header_line(ngx_http_request_t *r, ngx_table_elt_t *h, ngx_uint_t offset);static ngx_int_t ngx_http_process_unique_header_line(ngx_http_request_t *r, ngx_table_elt_t *h, ngx_uint_t offset);static ngx_int_t ngx_http_process_connection(ngx_http_request_t *r, ngx_table_elt_t *h, ngx_uint_t offset);static ngx_int_t ngx_http_process_cookie(ngx_http_request_t *r, ngx_table_elt_t *h, ngx_uint_t offset);static ngx_int_t ngx_http_process_request_header(ngx_http_request_t *r);static void ngx_http_process_request(ngx_http_request_t *r);static void ngx_http_find_virtual_server(ngx_http_request_t *r, u_char *host, size_t len, ngx_uint_t hash);static void ngx_http_request_handler(ngx_event_t *ev);static ngx_int_t ngx_http_set_write_handler(ngx_http_request_t *r);static void ngx_http_writer(ngx_http_request_t *r);static void ngx_http_test_reading(ngx_http_request_t *r);static void ngx_http_set_keepalive(ngx_http_request_t *r);static void ngx_http_keepalive_handler(ngx_event_t *ev);static void ngx_http_set_lingering_close(ngx_http_request_t *r);static void ngx_http_lingering_close_handler(ngx_event_t *ev);static ngx_int_t ngx_http_post_action(ngx_http_request_t *r);static void ngx_http_close_request(ngx_http_request_t *r, ngx_int_t error);static void ngx_http_request_done(ngx_http_request_t *r, ngx_int_t error);static void ngx_http_close_connection(ngx_connection_t *c);static u_char *ngx_http_log_error(ngx_log_t *log, u_char *buf, size_t len);static u_char *ngx_http_log_error_handler(ngx_http_request_t *r, ngx_http_request_t *sr, u_char *buf, size_t len);#if (NGX_HTTP_SSL)static void ngx_http_ssl_handshake(ngx_event_t *rev);static void ngx_http_ssl_handshake_handler(ngx_connection_t *c);#endifstatic char *ngx_http_client_errors[] = { /* NGX_HTTP_PARSE_INVALID_METHOD */ "client sent invalid method", /* NGX_HTTP_PARSE_INVALID_REQUEST */ "client sent invalid request", /* NGX_HTTP_PARSE_INVALID_09_METHOD */ "client sent invalid method in HTTP/0.9 request"};ngx_http_header_t ngx_http_headers_in[] = { { ngx_string("Host"), offsetof(ngx_http_headers_in_t, host), ngx_http_process_unique_header_line }, { ngx_string("Connection"), offsetof(ngx_http_headers_in_t, connection), ngx_http_process_connection }, { ngx_string("If-Modified-Since"), offsetof(ngx_http_headers_in_t, if_modified_since), ngx_http_process_unique_header_line }, { ngx_string("User-Agent"), offsetof(ngx_http_headers_in_t, user_agent), ngx_http_process_header_line }, { ngx_string("Referer"), offsetof(ngx_http_headers_in_t, referer), ngx_http_process_header_line }, { ngx_string("Content-Length"), offsetof(ngx_http_headers_in_t, content_length), ngx_http_process_unique_header_line }, { ngx_string("Content-Type"), offsetof(ngx_http_headers_in_t, content_type), ngx_http_process_header_line }, { ngx_string("Range"), offsetof(ngx_http_headers_in_t, range), ngx_http_process_header_line }, { ngx_string("If-Range"), offsetof(ngx_http_headers_in_t, if_range), ngx_http_process_unique_header_line }, { ngx_string("Transfer-Encoding"), offsetof(ngx_http_headers_in_t, transfer_encoding), ngx_http_process_header_line },#if (NGX_HTTP_GZIP) { ngx_string("Accept-Encoding"), offsetof(ngx_http_headers_in_t, accept_encoding), ngx_http_process_header_line }, { ngx_string("Via"), offsetof(ngx_http_headers_in_t, via), ngx_http_process_header_line },#endif { ngx_string("Authorization"), offsetof(ngx_http_headers_in_t, authorization), ngx_http_process_unique_header_line }, { ngx_string("Keep-Alive"), offsetof(ngx_http_headers_in_t, keep_alive), ngx_http_process_header_line },#if (NGX_HTTP_PROXY || NGX_HTTP_REALIP) { ngx_string("X-Forwarded-For"), offsetof(ngx_http_headers_in_t, x_forwarded_for), ngx_http_process_header_line },#endif#if (NGX_HTTP_REALIP) { ngx_string("X-Real-IP"), offsetof(ngx_http_headers_in_t, x_real_ip), ngx_http_process_header_line },#endif#if (NGX_HTTP_HEADERS) { ngx_string("Accept"), offsetof(ngx_http_headers_in_t, accept), ngx_http_process_header_line }, { ngx_string("Accept-Language"), offsetof(ngx_http_headers_in_t, accept_language), ngx_http_process_header_line },#endif#if (NGX_HTTP_DAV) { ngx_string("Depth"), offsetof(ngx_http_headers_in_t, depth), ngx_http_process_header_line }, { ngx_string("Destination"), offsetof(ngx_http_headers_in_t, destination), ngx_http_process_header_line }, { ngx_string("Overwrite"), offsetof(ngx_http_headers_in_t, overwrite), ngx_http_process_header_line }, { ngx_string("Date"), offsetof(ngx_http_headers_in_t, date), ngx_http_process_header_line },#endif { ngx_string("Cookie"), 0, ngx_http_process_cookie }, { ngx_null_string, 0, NULL }};voidngx_http_init_connection(ngx_connection_t *c){ ngx_event_t *rev; ngx_http_log_ctx_t *ctx; ctx = ngx_palloc(c->pool, sizeof(ngx_http_log_ctx_t)); if (ctx == NULL) { ngx_http_close_connection(c); return; } ctx->connection = c; ctx->request = NULL; ctx->current_request = NULL; c->log->connection = c->number; c->log->handler = ngx_http_log_error; c->log->data = ctx; c->log->action = "reading client request line"; c->log_error = NGX_ERROR_INFO; rev = c->read; rev->handler = ngx_http_init_request; c->write->handler = ngx_http_empty_handler;#if (NGX_STAT_STUB) ngx_atomic_fetch_add(ngx_stat_reading, 1);#endif if (rev->ready) { /* the deferred accept(), rtsig, aio, iocp */ if (ngx_use_accept_mutex) { ngx_post_event(rev, &ngx_posted_events); return; } ngx_http_init_request(rev); return; } ngx_add_timer(rev, c->listening->post_accept_timeout); if (ngx_handle_read_event(rev, 0) == NGX_ERROR) {#if (NGX_STAT_STUB) ngx_atomic_fetch_add(ngx_stat_reading, -1);#endif ngx_http_close_connection(c); return; }}static voidngx_http_init_request(ngx_event_t *rev){ ngx_time_t *tp; ngx_uint_t i; ngx_connection_t *c; ngx_http_request_t *r; ngx_http_in_port_t *hip; ngx_http_in_addr_t *hia; ngx_http_log_ctx_t *ctx; ngx_http_connection_t *hc; ngx_http_core_srv_conf_t *cscf; ngx_http_core_loc_conf_t *clcf; ngx_http_core_main_conf_t *cmcf;#if (NGX_STAT_STUB) ngx_atomic_fetch_add(ngx_stat_reading, -1);#endif c = rev->data; if (rev->timedout) { ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out"); ngx_http_close_connection(c); return; } hc = c->data; if (hc == NULL) { hc = ngx_pcalloc(c->pool, sizeof(ngx_http_connection_t)); if (hc == NULL) { ngx_http_close_connection(c); return; } } r = hc->request; if (r) { ngx_memzero(r, sizeof(ngx_http_request_t)); r->pipeline = hc->pipeline; if (hc->nbusy) { r->header_in = hc->busy[0]; } } else { r = ngx_pcalloc(c->pool, sizeof(ngx_http_request_t)); if (r == NULL) { ngx_http_close_connection(c); return; } hc->request = r; } c->data = r; r->http_connection = hc; c->sent = 0; r->signature = NGX_HTTP_MODULE; /* find the server configuration for the address:port */ /* AF_INET only */ hip = c->listening->servers; hia = hip->addrs; r->port = hip->port; r->port_text = &hip->port_text; i = 0; r->connection = c; if (hip->naddrs > 1) { /* * There are several addresses on this port and one of them * is the "*:port" wildcard so getsockname() is needed to determine * the server address. * * AcceptEx() already has given this address. */#if (NGX_WIN32) if (c->local_sockaddr) { r->in_addr = ((struct sockaddr_in *) c->local_sockaddr)->sin_addr.s_addr; } else#endif { if (ngx_http_server_addr(r, NULL) != NGX_OK) { ngx_http_close_connection(c); return; } } /* the last address is "*" */ for ( /* void */ ; i < hip->naddrs - 1; i++) { if (hia[i].addr == r->in_addr) { break; } } } else { r->in_addr = hia[0].addr; } r->virtual_names = hia[i].virtual_names; /* the default server configuration for the address:port */ cscf = hia[i].core_srv_conf; r->main_conf = cscf->ctx->main_conf; r->srv_conf = cscf->ctx->srv_conf; r->loc_conf = cscf->ctx->loc_conf; rev->handler = ngx_http_process_request_line;#if (NGX_HTTP_SSL) { ngx_http_ssl_srv_conf_t *sscf; sscf = ngx_http_get_module_srv_conf(r, ngx_http_ssl_module); if (sscf->enable) { if (c->ssl == NULL) { if (ngx_ssl_create_connection(&sscf->ssl, c, NGX_SSL_BUFFER) == NGX_ERROR) { ngx_http_close_connection(c); return; } rev->handler = ngx_http_ssl_handshake; } r->main_filter_need_in_memory = 1; } }#endif clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); c->log->file = clcf->err_log->file; if (!(c->log->log_level & NGX_LOG_DEBUG_CONNECTION)) { c->log->log_level = clcf->err_log->log_level; } if (c->buffer == NULL) { c->buffer = ngx_create_temp_buf(c->pool, cscf->client_header_buffer_size); if (c->buffer == NULL) { ngx_http_close_connection(c); return; } } if (r->header_in == NULL) { r->header_in = c->buffer; } r->pool = ngx_create_pool(cscf->request_pool_size, c->log); if (r->pool == NULL) { ngx_http_close_connection(c); return; } if (ngx_list_init(&r->headers_out.headers, r->pool, 20, sizeof(ngx_table_elt_t)) == NGX_ERROR) { ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); return; } r->ctx = ngx_pcalloc(r->pool, sizeof(void *) * ngx_http_max_module); if (r->ctx == NULL) { ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); return; } cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module); r->variables = ngx_pcalloc(r->pool, cmcf->variables.nelts * sizeof(ngx_http_variable_value_t)); if (r->variables == NULL) { ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); return; } c->single_connection = 1; c->destroyed = 0; r->main = r; tp = ngx_timeofday(); r->start_sec = tp->sec; r->start_msec = tp->msec; r->method = NGX_HTTP_UNKNOWN; r->headers_in.content_length_n = -1; r->headers_in.keep_alive_n = -1; r->headers_out.content_length_n = -1; r->headers_out.last_modified_time = -1; r->uri_changes = NGX_HTTP_MAX_URI_CHANGES + 1; r->subrequests = NGX_HTTP_MAX_SUBREQUESTS + 1; r->http_state = NGX_HTTP_READING_REQUEST_STATE; ctx = c->log->data; ctx->request = r; ctx->current_request = r; r->log_handler = ngx_http_log_error_handler;#if (NGX_STAT_STUB) ngx_atomic_fetch_add(ngx_stat_reading, 1); r->stat_reading = 1; ngx_atomic_fetch_add(ngx_stat_requests, 1);#endif rev->handler(rev);}#if (NGX_HTTP_SSL)static voidngx_http_ssl_handshake(ngx_event_t *rev){ u_char buf[1]; ssize_t n; ngx_int_t rc; ngx_connection_t *c; ngx_http_request_t *r; c = rev->data; r = c->data; ngx_log_debug0(NGX_LOG_DEBUG_HTTP, rev->log, 0, "http check ssl handshake"); if (rev->timedout) { ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out"); c->timedout = 1; ngx_http_close_request(r, NGX_HTTP_REQUEST_TIME_OUT); return; } n = recv(c->fd, (char *) buf, 1, MSG_PEEK); if (n == -1 && ngx_socket_errno == NGX_EAGAIN) { if (!rev->timer_set) { ngx_add_timer(rev, c->listening->post_accept_timeout); } if (ngx_handle_read_event(rev, 0) == NGX_ERROR) { ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); } return; } if (n == 1) { if (buf[0] == 0x80 /* SSLv2 */ || buf[0] == 0x16 /* SSLv3/TLSv1 */) { ngx_log_debug1(NGX_LOG_DEBUG_HTTP, rev->log, 0, "https ssl handshake: 0x%02Xd", buf[0]); rc = ngx_ssl_handshake(c); if (rc == NGX_AGAIN) { if (!rev->timer_set) { ngx_add_timer(rev, c->listening->post_accept_timeout); }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?