Detailed analysis of each stage of nginx's processing of http request

  • 2021-09-16 08:30:16
  • OfStack

When writing the module of http of nginx, it is necessary to deal with http requests in various stages to achieve different purposes, such as whether there is access authority when the request is initiated, filtering or other processing when the content is generated, and so on. If the processing phase registered in the compilation nginx module is incorrect, the desired results will not be achieved, for example, when you want to process the content, there is actually no content at this time, and so on.

In nginx, multiple stage types are defined to meet different processing requirements (ngx_http_core_module. h, different versions are different):


typedef enum {
 NGX_HTTP_POST_READ_PHASE = 0,
 
 NGX_HTTP_SERVER_REWRITE_PHASE,
 
 NGX_HTTP_FIND_CONFIG_PHASE,
 NGX_HTTP_REWRITE_PHASE,
 NGX_HTTP_POST_REWRITE_PHASE,
 
 NGX_HTTP_PREACCESS_PHASE,
 
 NGX_HTTP_ACCESS_PHASE,
 NGX_HTTP_POST_ACCESS_PHASE,
 
 NGX_HTTP_TRY_FILES_PHASE,
 NGX_HTTP_CONTENT_PHASE,
 
 NGX_HTTP_LOG_PHASE
} ngx_http_phases;

The corresponding meanings are:


NGX_HTTP_POST_READ_PHASE = 0  // Read request stage 
NGX_HTTP_SERVER_REWRITE_PHASE //URI Transition phase 
NGX_HTTP_FIND_CONFIG_PHASE   // Find the appropriate configuration to execute the stage 
NGX_HTTP_REWRITE_PHASE    //URI Transition phase (not very clear here) 
NGX_HTTP_POST_REWRITE_PHASE  // For the converted URL The stage at which the results are processed 
NGX_HTTP_PREACCESS_PHASE   // Permission check preparation stage 
NGX_HTTP_ACCESS_PHASE    // Permission checking stage 
NGX_HTTP_POST_ACCESS_PHASE  // Process the permission check results 
NGX_HTTP_TRY_FILES_PHASE   // Process the in the configuration try_files Stage 
NGX_HTTP_CONTENT_PHASE    // Process Generate Return Data Stage ( It is not considered too fine here, of course there are filter It can also be ignored )
NGX_HTTP_LOG_PHASE     // Record log processing stage, which should be processed when the request is closed after the request is completed 

From this configuration, we can analyze the whole process of nginx processing requests, and the process is executed from beginning to end. It can be seen that LOG is executed at the back, and the processing of content segments is generally done in filter module. The processing segments registered in NGX_HTTP_LOG_PHASE stage cannot obtain the returned data, and the returned data is directly released after being sent to the client. Therefore, the data preparation at this stage should be clear when processing at each stage.

Under normal circumstances, we can register our own processing module in the following ways:


static ngx_int_t
ngx_http_xxx_init(ngx_conf_t *cf)
{
 ngx_http_handler_pt  *h;
 ngx_http_core_main_conf_t *cmcf;
 
 cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);
 
 h = ngx_array_push(&cmcf->phases[NGX_HTTP_CONTENT_PHASE].handlers);
 if (h == NULL) {
 return NGX_ERROR;
 }
 
 *h = ngx_http_xxx_handler;
 
 return NGX_OK;
}

And the return value of ngx_http_xxx_up_handler can only be the following:


NGX_OK        // Successful processing, enter the next 1 Stage 
NGX_DECLINED      // Discard processing 
NGX_AGAIN || NGX_DONE  // When processing is complete, returning this value triggers the request 
NGX_ERROR || NGX_HTTP_.. // Handling errors or HTTP Other state values of 

In addition, for NGX_HTTP_CONTENT_PHASE stage, there is actually another registration method, Just like this:


static char *
ngx_http_xxx_server(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
 ngx_str_t     *value;
 ngx_url_t     u;
 ngx_http_core_loc_conf_t *clcf;
 
 clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);
 
 clcf->handler = ngx_http_xxx_handler;
 
 if (clcf->name.data[clcf->name.len - 1] == '/') {
 clcf->auto_redirect = 1;
 }
 
 return NGX_CONF_OK;
}

However, in this way, you have too many things to do. In more cases, consider the combination of upstream or special processing of requests. For example, for the distribution of distributed storage, when the request processing needs to be associated with the file system, for example, when the requested data is directly handed over to the special SERVER to get the content. Hehe.


Related articles: