ngx_http_request.c
来自「Nginx是一个高性能的HTTP和反向代理服务器」· C语言 代码 · 共 2,528 行 · 第 1/5 页
C
2,528 行
} if (n == 0 || n == NGX_ERROR) { c->error = 1; c->log->action = "reading client request headers"; ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST); return NGX_ERROR; } r->header_in->last += n; return n;}static ngx_int_tngx_http_alloc_large_header_buffer(ngx_http_request_t *r, ngx_uint_t request_line){ u_char *old, *new; ngx_buf_t *b; ngx_http_connection_t *hc; ngx_http_core_srv_conf_t *cscf; ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "http alloc large header buffer"); if (request_line && r->state == 0) { /* the client fills up the buffer with "\r\n" */ r->request_length += r->header_in->end - r->header_in->start; r->header_in->pos = r->header_in->start; r->header_in->last = r->header_in->start; return NGX_OK; } old = request_line ? r->request_start : r->header_name_start; cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module); if (r->state != 0 && (size_t) (r->header_in->pos - old) >= cscf->large_client_header_buffers.size) { return NGX_DECLINED; } hc = r->http_connection; if (hc->nfree) { b = hc->free[--hc->nfree]; ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "http large header free: %p %uz", b->pos, b->end - b->last); } else if (hc->nbusy < cscf->large_client_header_buffers.num) { if (hc->busy == NULL) { hc->busy = ngx_palloc(r->connection->pool, cscf->large_client_header_buffers.num * sizeof(ngx_buf_t *)); if (hc->busy == NULL) { return NGX_ERROR; } } b = ngx_create_temp_buf(r->connection->pool, cscf->large_client_header_buffers.size); if (b == NULL) { return NGX_ERROR; } ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "http large header alloc: %p %uz", b->pos, b->end - b->last); } else { return NGX_DECLINED; } hc->busy[hc->nbusy++] = b; if (r->state == 0) { /* * r->state == 0 means that a header line was parsed successfully * and we do not need to copy incomplete header line and * to relocate the parser header pointers */ r->request_length += r->header_in->end - r->header_in->start; r->header_in = b; return NGX_OK; } ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "http large header copy: %d", r->header_in->pos - old); r->request_length += old - r->header_in->start; new = b->start; ngx_memcpy(new, old, r->header_in->pos - old); b->pos = new + (r->header_in->pos - old); b->last = new + (r->header_in->pos - old); if (request_line) { r->request_start = new; if (r->request_end) { r->request_end = new + (r->request_end - old); } r->method_end = new + (r->method_end - old); r->uri_start = new + (r->uri_start - old); r->uri_end = new + (r->uri_end - old); if (r->schema_start) { r->schema_start = new + (r->schema_start - old); r->schema_end = new + (r->schema_end - old); } if (r->host_start) { r->host_start = new + (r->host_start - old); if (r->host_end) { r->host_end = new + (r->host_end - old); } } if (r->port_start) { r->port_start = new + (r->port_start - old); r->port_end = new + (r->port_end - old); } if (r->uri_ext) { r->uri_ext = new + (r->uri_ext - old); } if (r->args_start) { r->args_start = new + (r->args_start - old); } if (r->http_protocol.data) { r->http_protocol.data = new + (r->http_protocol.data - old); } } else { r->header_name_start = new; r->header_name_end = new + (r->header_name_end - old); r->header_start = new + (r->header_start - old); r->header_end = new + (r->header_end - old); } r->header_in = b; return NGX_OK;}static ngx_int_tngx_http_process_header_line(ngx_http_request_t *r, ngx_table_elt_t *h, ngx_uint_t offset){ ngx_table_elt_t **ph; ph = (ngx_table_elt_t **) ((char *) &r->headers_in + offset); if (*ph == NULL) { *ph = h; } return NGX_OK;}static ngx_int_tngx_http_process_unique_header_line(ngx_http_request_t *r, ngx_table_elt_t *h, ngx_uint_t offset){ ngx_table_elt_t **ph; ph = (ngx_table_elt_t **) ((char *) &r->headers_in + offset); if (*ph == NULL) { *ph = h; return NGX_OK; } ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, "client sent duplicate header line: \"%V: %V\", " "previous value: \"%V: %V\"", &h->key, &h->value, &(*ph)->key, &(*ph)->value); ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST); return NGX_ERROR;}static ngx_int_tngx_http_process_connection(ngx_http_request_t *r, ngx_table_elt_t *h, ngx_uint_t offset){ if (ngx_strcasestrn(h->value.data, "close", 5 - 1)) { r->headers_in.connection_type = NGX_HTTP_CONNECTION_CLOSE; } else if (ngx_strcasestrn(h->value.data, "keep-alive", 10 - 1)) { r->headers_in.connection_type = NGX_HTTP_CONNECTION_KEEP_ALIVE; } return NGX_OK;}static ngx_int_tngx_http_process_cookie(ngx_http_request_t *r, ngx_table_elt_t *h, ngx_uint_t offset){ ngx_table_elt_t **cookie; cookie = ngx_array_push(&r->headers_in.cookies); if (cookie) { *cookie = h; return NGX_OK; } ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); return NGX_ERROR;}static ngx_int_tngx_http_process_request_header(ngx_http_request_t *r){ size_t len; u_char *host, *ua, *user_agent, ch; ngx_uint_t hash; if (r->headers_in.host) { hash = 0; for (len = 0; len < r->headers_in.host->value.len; len++) { ch = r->headers_in.host->value.data[len]; if (ch == ':') { break; } ch = ngx_tolower(ch); r->headers_in.host->value.data[len] = ch; hash = ngx_hash(hash, ch); } if (len && r->headers_in.host->value.data[len - 1] == '.') { len--; hash = ngx_hash_key(r->headers_in.host->value.data, len); } r->headers_in.host_name_len = len; if (r->virtual_names) { host = r->host_start; if (host == NULL) { host = r->headers_in.host->value.data; len = r->headers_in.host_name_len; } else { len = r->host_end - host; } ngx_http_find_virtual_server(r, host, len, hash); } } else { if (r->http_version > NGX_HTTP_VERSION_10) { ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, "client sent HTTP/1.1 request without \"Host\" header"); ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST); return NGX_ERROR; } r->headers_in.host_name_len = 0; } if (r->headers_in.content_length) { r->headers_in.content_length_n = ngx_atoof(r->headers_in.content_length->value.data, r->headers_in.content_length->value.len); if (r->headers_in.content_length_n == NGX_ERROR) { ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, "client sent invalid \"Content-Length\" header"); ngx_http_finalize_request(r, NGX_HTTP_LENGTH_REQUIRED); return NGX_ERROR; } } if (r->method & (NGX_HTTP_POST|NGX_HTTP_PUT) && r->headers_in.content_length_n == -1) { ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, "client sent %V method without \"Content-Length\" header", &r->method_name); ngx_http_finalize_request(r, NGX_HTTP_LENGTH_REQUIRED); return NGX_ERROR; } if (r->method & NGX_HTTP_TRACE) { ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, "client sent TRACE method"); ngx_http_finalize_request(r, NGX_HTTP_NOT_ALLOWED); return NGX_ERROR; } if (r->headers_in.transfer_encoding && ngx_strcasestrn(r->headers_in.transfer_encoding->value.data, "chunked", 7 - 1)) { ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, "client sent \"Transfer-Encoding: chunked\" header"); ngx_http_finalize_request(r, NGX_HTTP_LENGTH_REQUIRED); return NGX_ERROR; } if (r->headers_in.connection_type == NGX_HTTP_CONNECTION_KEEP_ALIVE) { if (r->headers_in.keep_alive) { r->headers_in.keep_alive_n = ngx_atotm(r->headers_in.keep_alive->value.data, r->headers_in.keep_alive->value.len); } } if (r->headers_in.user_agent) { /* * check some widespread browsers while the headers are still * in CPU cache */ user_agent = r->headers_in.user_agent->value.data; ua = ngx_strstrn(user_agent, "MSIE", 4 - 1); if (ua && ua + 8 < user_agent + r->headers_in.user_agent->value.len) { r->headers_in.msie = 1; if (ua[4] == ' ' && ua[5] == '4' && ua[6] == '.') { r->headers_in.msie4 = 1; }#if 0 /* MSIE ignores the SSL "close notify" alert */ if (c->ssl) { c->ssl->no_send_shutdown = 1; }#endif } if (ngx_strstrn(user_agent, "Opera", 5 - 1)) { r->headers_in.opera = 1; r->headers_in.msie = 0; r->headers_in.msie4 = 0; } if (!r->headers_in.msie && !r->headers_in.opera) { if (ngx_strstrn(user_agent, "Gecko/", 6 - 1)) { r->headers_in.gecko = 1; } else if (ngx_strstrn(user_agent, "Konqueror", 9 - 1)) { r->headers_in.konqueror = 1; } } } return NGX_OK;}static voidngx_http_process_request(ngx_http_request_t *r){ ngx_connection_t *c; c = r->connection; if (r->plain_http) { ngx_log_error(NGX_LOG_INFO, c->log, 0, "client sent plain HTTP request to HTTPS port"); ngx_http_finalize_request(r, NGX_HTTP_TO_HTTPS); return; }#if (NGX_HTTP_SSL) if (c->ssl) { long rc; X509 *cert; ngx_http_ssl_srv_conf_t *sscf; sscf = ngx_http_get_module_srv_conf(r, ngx_http_ssl_module); if (sscf->verify) { rc = SSL_get_verify_result(c->ssl->connection); if (rc != X509_V_OK) { ngx_log_error(NGX_LOG_INFO, c->log, 0, "client SSL certificate verify error: (%l:%s)", rc, X509_verify_cert_error_string(rc)); ngx_ssl_remove_cached_session(sscf->ssl.ctx, (SSL_get0_session(c->ssl->connection))); ngx_http_finalize_request(r, NGX_HTTPS_CERT_ERROR); return; } cert = SSL_get_peer_certificate(c->ssl->connection); if (cert == NULL) { ngx_log_error(NGX_LOG_INFO, c->log, 0, "client sent no required SSL certificate"); ngx_ssl_remove_cached_session(sscf->ssl.ctx, (SSL_get0_session(c->ssl->connection))); ngx_http_finalize_request(r, NGX_HTTPS_NO_CERT); return; } X509_free(cert); } }#endif if (c->read->timer_set) { ngx_del_timer(c->read); }#if (NGX_STAT_STUB) ngx_atomic_fetch_add(ngx_stat_reading, -1); r->stat_reading = 0; ngx_atomic_fetch_add(ngx_stat_writing, 1); r->stat_writing = 1;#endif c->read->handler = ngx_http_request_handler; c->write->handler = ngx_http_request_handler; r->read_event_handler = ngx_http_block_reading; ngx_http_handler(r); return;}static voidngx_http_find_virtual_server(ngx_http_request_t *r, u_char *host, size_t len, ngx_uint_t hash){ ngx_http_core_loc_conf_t *clcf; ngx_http_core_srv_conf_t *cscf; cscf = ngx_hash_find_combined(&r->virtual_names->names, hash, host, len); if (cscf) { goto found; }#if (NGX_PCRE) if (r->virtual_names->nregex) { ngx_int_t n; ngx_uint_t i; ngx_str_t name; ngx_http_server_name_t *sn; name.len = len; name.data = host; sn = r->virtual_names->regex; for (i = 0; i < r->virtual_names->nregex; i++) { n = ngx_regex_exec(sn[i].regex, &name, NULL, 0); if (n == NGX_REGEX_NO_MATCHED) { continue; } if (n < 0) { ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, ngx_regex_exec_n
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?