ngx_http_process_request_headers函数被ngx_http_process_request_line函数调用,将请求头逐个放到r->headers_in.headers结构体中。由于不确定请求中一共有多少个header,所以这个函数主要功能也是在for(;;){}循环中完成,一下所有的代码都是在上述循环内部的。主要代码和解析如下:
判断是否超时,如果超时,报错并结束请求。
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; }
ngx_http_parse_header_line函数解析请求行,如果返回NGX_OK表示成功的解析出来一个header,如果返回NGX_HTTP_PARSE_HEADER_DONE表示所有的header都解析完了,如果返回NGX_AGAIN表示尚有header没有解析完,剩下的返回值说明出错了。
rc = ngx_http_parse_header_line(r, r->header_in, cscf->underscores_in_headers); if (rc == NGX_OK) { r->request_length += r->header_in->pos - r->header_name_start; if (r->invalid_header && cscf->ignore_invalid_headers) { /* there was error while a header line parsing */ ngx_log_error(NGX_LOG_INFO, c->log, 0, "client sent invalid header line: \"%*s\"", r->header_end - r->header_name_start, r->header_name_start); continue; }
r->headers_in.headers是一个ngx_list_t结构体,向其添加元素的顺序是先通过ngx_list_push函数返回一个元素,实际上在ngx_list_push中完成了开辟内存的工作,之后再对返回的元素进行赋值。
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;
r->header_name_end和r->header_name_start两个变量貌似就是专门为了指向每个头的key的开始和结束,其他地方没看到被使用过
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_pnalloc(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 { ngx_strlow(h->lowcase_key, h->key.data, h->key.len); }
针对某些头,可能又一些处理函数,比如说User-Agent头的处理函数会提取浏览器相关的一些信息
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; }
如果所有的header都解析完了,在经过一些简单的判断(ngx_http_process_request_header函数中完成)之后,就进入了正式的请求处理逻辑
if (rc == NGX_HTTP_PARSE_HEADER_DONE) { ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "http header done"); r->request_length += r->header_in->pos - r->header_name_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; }
时间: 2024-10-18 07:18:34