Home  >  Article  >  Backend Development  >  request in nginx

request in nginx

WBOY
WBOYOriginal
2016-08-08 09:21:031190browse

In this section we talk about request. In nginx we refer to http request. The specific data structure in nginx is ngx_http_request_t. ngx_http_request_t is an encapsulation of an http request. We know that an http request contains request line, request header, request body, response line, response header, and response body.

http request is a typical request-response type network protocol, and http is a file protocol, so we analyze the request line and request header, and output the response line and response header, often processing them line by line. If we write an http server ourselves, usually after a connection is established, the client will send a request. Then we read a line of data and analyze the method, uri, and http_version information contained in the request line. Then process the request headers line by line, and determine whether there is a request body and the length of the request body based on the request method and request header information, and then read the request body. After getting the request, we process the request to generate the data that needs to be output, and then generate the response line, response header and response body. After the response is sent to the client, a complete request is processed. Of course, this is the simplest webserver processing method. In fact, nginx also does this, but there are some small differences. For example, when the request header is read, the request processing begins. nginx uses ngx_http_request_t to save data related to parsing requests and output responses.

Then next, let’s briefly talk about how nginx handles a complete request. For nginx, a request starts from ngx_http_init_request. In this function, the read event is set to ngx_http_process_request_line. That is to say, the next network event will be executed by ngx_http_process_request_line. From the function name of ngx_http_process_request_line, we can see that this is to process the request line. As mentioned before, the first thing to do when processing a request is to process the request line. Read request data through ngx_http_read_request_header. The ngx_http_parse_request_line function is then called to parse the request line. In order to improve efficiency, nginx uses a state machine to parse the request line. When comparing methods, it does not use string comparison directly. Instead, it converts four characters into an integer and then compares them once to reduce the number of CPU instructions. This has been said before. Many people may know that a request line contains the requested method, uri, and version, but they don't know that the request line can also contain a host. For example, a request like GET http://www.taobao.com/uri HTTP/1.0 is also legal, and the host is www.taobao.com. At this time, nginx will ignore the host field in the request header and use Use this in the request line to find the virtual host. In addition, for http0.9 version, request headers are not supported, so special treatment is required here. Therefore, when parsing the request header later, the protocol version will be 1.0 or 1.1. The parameters parsed from the entire request line will be saved in the ngx_http_request_t structure.

After parsing the request line, nginx will set the handler of the read event to ngx_http_process_request_headers, and then subsequent requests will be read and parsed in ngx_http_process_request_headers. The ngx_http_process_request_headers function is used to read request headers. Just like the request line, it still calls ngx_http_read_request_header to read the request headers, and calls ngx_http_parse_header_line to parse a line of request headers. The parsed request headers will be saved in the field headers_in of ngx_http_request_t. headers_in is a linked list structure. , save all request headers. Some requests in HTTP require special processing. These request headers and request processing functions are stored in a mapping table, namely ngx_http_headers_in. During initialization, a hash table will be generated. When a request header is parsed, it will be first Search in this hash table, and if found, call the corresponding processing function to process the request header. For example: the processing function of the Host header is ngx_http_process_host.

When nginx parses two carriage returns and line feeds, it indicates the end of the request header. At this time, ngx_http_process_request will be called to process the request. ngx_http_process_request will set the current connection's read and write event processing function to ngx_http_request_handler, and then call ngx_http_handler to actually start processing a complete http request. It may be strange here. The read and write event processing functions are both ngx_http_request_handler. In fact, in this function, the read_event_handler or write_event_handler in ngx_http_request_t will be called respectively depending on whether the current event is a read event or a write event. Since our request header has been read at this time, as mentioned before, nginx does not read the request body first, so here we set read_event_handler to ngx_http_block_reading, that is, no data is read. As mentioned just now, the real start of processing data is in the ngx_http_handler function. This function will set write_event_handler to ngx_http_core_run_phases and execute the ngx_http_core_run_phases function. The ngx_http_core_run_phases function will perform multi-stage request processing. nginx divides the processing of an http request into multiple stages, then this function executes these stages to generate data. Because ngx_http_core_run_phases will eventually generate data, it is easy for us to understand why the writing event processing function is set to ngx_http_core_run_phases. Here, I briefly explain the calling logic of the function. We need to understand that ngx_http_core_run_phases is ultimately called to process the request. The generated response header will be placed in the headers_out of ngx_http_request_t. I will discuss this part in the request processing process. . Various stages of nginx will process the request, and finally call filter to filter the data and process the data, such as truncated transmission, gzip compression, etc. The filter here includes header Filter and body filter, that is, process the response header or response body. Filter is a linked list structure, with header filter and body filter respectively. All filters in the header filter are executed first, and then all filters in the body filter are executed. The last filter in the header filter, namely ngx_http_header_filter, will traverse all response headers. The final response header that needs to be output is in a continuous memory, and then calls ngx_http_write_filter for output. ngx_http_write_filter is body The last one in the filter, so nginx’s first body information, after a series of body filters, will finally call ngx_http_write_filter for output (there is a picture to illustrate).

What should be noted here is that nginx will put the entire request header in a buffer. The size of this buffer is set through the configuration item client_header_buffer_size. If the user's request header is too large and the buffer cannot fit, then nginx will restart Allocate a new larger buffer to hold the request header. This large buffer can be set through large_client_header_buffers. This large_buffer group of buffers, for example, configuring 4 8k, means that four 8k buffers are available. Note that in order to preserve the integrity of the request line or header, a complete request line or header needs to be placed in a continuous memory. Therefore, a complete request line or header will only be saved in one buffer. In this way, if the request line is larger than the size of a buffer, a 414 error will be returned, and if a request header size is larger than a buffer size, a 400 error will be returned. After understanding the values ​​of these parameters and the actual practices of nginx, in the application scenario, we need to adjust these parameters according to actual needs to optimize our program.

Processing flow chart:

request in nginx

The above is the life cycle of an http request in nginx. Let's look at some concepts related to requests.

The above introduces the request in nginx, including the relevant content. I hope it will be helpful to friends who are interested in PHP tutorials.

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn