ngx_http_request.c
来自「Nginx是一个高性能的HTTP和反向代理服务器」· C语言 代码 · 共 2,528 行 · 第 1/5 页
C
2,528 行
c->ssl->handler = ngx_http_ssl_handshake_handler; return; } ngx_http_ssl_handshake_handler(c); return; } else { ngx_log_debug0(NGX_LOG_DEBUG_HTTP, rev->log, 0, "plain http"); r->plain_http = 1; } } rev->handler = ngx_http_process_request_line; ngx_http_process_request_line(rev);}static voidngx_http_ssl_handshake_handler(ngx_connection_t *c){ ngx_http_request_t *r; if (c->ssl->handshaked) { /* * The majority of browsers do not send the "close notify" alert. * Among them are MSIE, old Mozilla, Netscape 4, Konqueror, * and Links. And what is more, MSIE ignores the server's alert. * * Opera and recent Mozilla send the alert. */ c->ssl->no_wait_shutdown = 1; c->read->handler = ngx_http_process_request_line; /* STUB: epoll edge */ c->write->handler = ngx_http_empty_handler; ngx_http_process_request_line(c->read); return; } r = c->data; ngx_http_close_request(r, NGX_HTTP_BAD_REQUEST); return;}#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAMEintngx_http_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg){ u_char *p; ngx_uint_t hash; const char *servername; ngx_connection_t *c; ngx_http_request_t *r; ngx_http_ssl_srv_conf_t *sscf; servername = SSL_get_servername(ssl_conn, TLSEXT_NAMETYPE_host_name); if (servername == NULL) { return SSL_TLSEXT_ERR_NOACK; } c = ngx_ssl_get_connection(ssl_conn); ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, "SSL server name: \"%s\"", servername); r = c->data; if (r->virtual_names == NULL) { return SSL_TLSEXT_ERR_NOACK; } /* it seems browsers send low case server name */ hash = 0; for (p = (u_char *) servername; *p; p++) { hash = ngx_hash(hash, *p); } ngx_http_find_virtual_server(r, (u_char *) servername, p - (u_char *) servername, hash); sscf = ngx_http_get_module_srv_conf(r, ngx_http_ssl_module); SSL_set_SSL_CTX(ssl_conn, sscf->ssl.ctx); return SSL_TLSEXT_ERR_OK;}#endif#endifstatic voidngx_http_process_request_line(ngx_event_t *rev){ ssize_t n; ngx_int_t rc, rv; ngx_connection_t *c; ngx_http_request_t *r; ngx_http_core_srv_conf_t *cscf; c = rev->data; r = c->data; ngx_log_debug0(NGX_LOG_DEBUG_HTTP, rev->log, 0, "http process request line"); 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; } rc = NGX_AGAIN; for ( ;; ) { if (rc == NGX_AGAIN) { n = ngx_http_read_request_header(r); if (n == NGX_AGAIN || n == NGX_ERROR) { return; } } rc = ngx_http_parse_request_line(r, r->header_in); if (rc == NGX_OK) { /* the request line has been parsed successfully */ r->request_line.len = r->request_end - r->request_start; r->request_line.data = r->request_start; if (r->args_start) { r->uri.len = r->args_start - 1 - r->uri_start; } else { r->uri.len = r->uri_end - r->uri_start; } if (r->complex_uri || r->quoted_uri) { r->uri.data = ngx_palloc(r->pool, r->uri.len + 1); if (r->uri.data == NULL) { ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); return; } cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module); rc = ngx_http_parse_complex_uri(r, cscf->merge_slashes); if (rc == NGX_HTTP_PARSE_INVALID_REQUEST) { ngx_log_error(NGX_LOG_INFO, c->log, 0, "client sent invalid request"); ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST); return; } } else { r->uri.data = r->uri_start; } r->unparsed_uri.len = r->uri_end - r->uri_start; r->unparsed_uri.data = r->uri_start; r->method_name.len = r->method_end - r->request_start + 1; r->method_name.data = r->request_line.data; if (r->http_protocol.data) { r->http_protocol.len = r->request_end - r->http_protocol.data; } if (r->uri_ext) { if (r->args_start) { r->exten.len = r->args_start - 1 - r->uri_ext; } else { r->exten.len = r->uri_end - r->uri_ext; } r->exten.data = r->uri_ext; } if (r->args_start && r->uri_end > r->args_start) { r->args.len = r->uri_end - r->args_start; r->args.data = r->args_start; } ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, "http request line: \"%V\"", &r->request_line); ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, "http uri: \"%V\"", &r->uri); ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, "http args: \"%V\"", &r->args); ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, "http exten: \"%V\"", &r->exten); if (r->http_version < NGX_HTTP_VERSION_10) { ngx_http_process_request(r); return; } if (ngx_list_init(&r->headers_in.headers, r->pool, 20, sizeof(ngx_table_elt_t)) == NGX_ERROR) { ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); return; } if (ngx_array_init(&r->headers_in.cookies, r->pool, 2, sizeof(ngx_table_elt_t *)) == NGX_ERROR) { ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); return; } c->log->action = "reading client request headers"; rev->handler = ngx_http_process_request_headers; ngx_http_process_request_headers(rev); return; } if (rc != NGX_AGAIN) { /* there was error while a request line parsing */ ngx_log_error(NGX_LOG_INFO, c->log, 0, ngx_http_client_errors[rc - NGX_HTTP_CLIENT_ERROR]); ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST); return; } /* NGX_AGAIN: a request line parsing is still incomplete */ if (r->header_in->pos == r->header_in->end) { rv = ngx_http_alloc_large_header_buffer(r, 1); if (rv == NGX_ERROR) { ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); return; } if (rv == NGX_DECLINED) { r->request_line.len = r->header_in->end - r->request_start; r->request_line.data = r->request_start; ngx_log_error(NGX_LOG_INFO, c->log, 0, "client sent too long URI"); ngx_http_finalize_request(r, NGX_HTTP_REQUEST_URI_TOO_LARGE); return; } } }}static voidngx_http_process_request_headers(ngx_event_t *rev){ ssize_t n; ngx_int_t rc, rv; ngx_str_t header; ngx_uint_t i; ngx_table_elt_t *h; ngx_connection_t *c; ngx_http_header_t *hh; ngx_http_request_t *r; ngx_http_core_srv_conf_t *cscf; ngx_http_core_main_conf_t *cmcf; c = rev->data; r = c->data; ngx_log_debug0(NGX_LOG_DEBUG_HTTP, rev->log, 0, "http process request header line"); 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; } cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module); cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module); rc = NGX_AGAIN; for ( ;; ) { if (rc == NGX_AGAIN) { if (r->header_in->pos == r->header_in->end) { rv = ngx_http_alloc_large_header_buffer(r, 0); if (rv == NGX_ERROR) { ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); return; } if (rv == NGX_DECLINED) { header.len = r->header_in->end - r->header_name_start; header.data = r->header_name_start; if (header.len > NGX_MAX_ERROR_STR - 300) { header.len = NGX_MAX_ERROR_STR - 300; header.data[header.len++] = '.'; header.data[header.len++] = '.'; header.data[header.len++] = '.'; } ngx_log_error(NGX_LOG_INFO, c->log, 0, "client sent too long header line: \"%V\"", &header); ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST); return; } } n = ngx_http_read_request_header(r); if (n == NGX_AGAIN || n == NGX_ERROR) { return; } } rc = ngx_http_parse_header_line(r, r->header_in); if (rc == NGX_OK) { if (r->invalid_header && cscf->ignore_invalid_headers) { /* there was error while a header line parsing */ header.len = r->header_end - r->header_name_start; header.data = r->header_name_start; ngx_log_error(NGX_LOG_INFO, c->log, 0, "client sent invalid header line: \"%V\"", &header); continue; } /* a header line has been parsed successfully */ h = ngx_list_push(&r->headers_in.headers); if (h == NULL) { ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); return; } h->hash = r->header_hash; h->key.len = r->header_name_end - r->header_name_start; h->key.data = r->header_name_start; h->key.data[h->key.len] = '\0'; h->value.len = r->header_end - r->header_start; h->value.data = r->header_start; h->value.data[h->value.len] = '\0'; h->lowcase_key = ngx_palloc(r->pool, h->key.len); if (h->lowcase_key == NULL) { ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); return; } if (h->key.len == r->lowcase_index) { ngx_memcpy(h->lowcase_key, r->lowcase_header, h->key.len); } else { for (i = 0; i < h->key.len; i++) { h->lowcase_key[i] = ngx_tolower(h->key.data[i]); } } hh = ngx_hash_find(&cmcf->headers_in_hash, h->hash, h->lowcase_key, h->key.len); if (hh && hh->handler(r, h, hh->offset) != NGX_OK) { return; } ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "http header: \"%V: %V\"", &h->key, &h->value); continue; } if (rc == NGX_HTTP_PARSE_HEADER_DONE) { /* a whole header has been parsed successfully */ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "http header done"); r->request_length += r->header_in->pos - r->header_in->start; r->http_state = NGX_HTTP_PROCESS_REQUEST_STATE; rc = ngx_http_process_request_header(r); if (rc != NGX_OK) { return; } ngx_http_process_request(r); return; } if (rc == NGX_AGAIN) { /* a header line parsing is still not complete */ continue; } /* rc == NGX_HTTP_PARSE_INVALID_HEADER: "\r" is not followed by "\n" */ header.len = r->header_end - r->header_name_start; header.data = r->header_name_start; ngx_log_error(NGX_LOG_INFO, c->log, 0, "client sent invalid header line: \"%V\\r...\"", &header); ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST); return; }}static ssize_tngx_http_read_request_header(ngx_http_request_t *r){ ssize_t n; ngx_event_t *rev; ngx_connection_t *c; ngx_http_core_srv_conf_t *cscf; c = r->connection; rev = c->read; n = r->header_in->last - r->header_in->pos; if (n > 0) { return n; } if (rev->ready) { n = c->recv(c, r->header_in->last, r->header_in->end - r->header_in->last); } else { n = NGX_AGAIN; } if (n == NGX_AGAIN) { if (!rev->timer_set) { cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module); ngx_add_timer(rev, cscf->client_header_timeout); } if (ngx_handle_read_event(rev, 0) == NGX_ERROR) { ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); return NGX_ERROR; } return NGX_AGAIN; } if (n == 0) { ngx_log_error(NGX_LOG_INFO, c->log, 0, "client closed prematurely connection");
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?