# HG changeset patch # User Roman Arutyunyan # Date 1489485419 -10800 # Node ID 7f290929b32d6a916b32147715472bedd7b3b7da # Parent 2c14a16c61eb4e52f1de17201af017e77b190970 HTTP section of the development guide. diff -r 2c14a16c61eb -r 7f290929b32d xml/en/docs/dev/development_guide.xml --- a/xml/en/docs/dev/development_guide.xml Fri Mar 10 16:33:09 2017 +0300 +++ b/xml/en/docs/dev/development_guide.xml Tue Mar 14 12:56:59 2017 +0300 @@ -3387,4 +3387,865 @@ +
+ + +
+ + +Each client HTTP connection runs through the following stages: + + + + + +ngx_event_accept() accepts a client TCP connection. +This handler is called in response to a read notification on a listen socket. +A new ngx_connecton_t object is created at this stage. +The object wraps the newly accepted client socket. +Each nginx listener provides a handler to pass the new connection object to. +For HTTP connections it's ngx_http_init_connection(c) + + + +ngx_http_init_connection() performs early initialization of +an HTTP connection. +At this stage an ngx_http_connection_t object is created for +the connection and its reference is stored in connection's +data field. +Later it will be substituted with an HTTP request object. +PROXY protocol parser and SSL handshake are started at this stage as well + + + +ngx_http_wait_request_handler() is a read event handler, that +is called when data is available in the client socket. +At this stage an HTTP request object ngx_http_request_t is +created and set to connection's data field + + + +ngx_http_process_request_line() is a read event handler, +which reads client request line. +The handler is set by ngx_http_wait_request_handler(). +Reading is done into connection's buffer. +The size of the buffer is initially set by the directive +. +The entire client header is supposed to fit the buffer. +If the initial size is not enough, a bigger buffer is allocated, whose size is +set by the large_client_header_buffers directive + + + +ngx_http_process_request_headers() is a read event handler, +which is set after ngx_http_process_request_line() to read +client request header + + + +ngx_http_core_run_phases() is called when the request header +is completely read and parsed. +This function runs request phases from +NGX_HTTP_POST_READ_PHASE to +NGX_HTTP_CONTENT_PHASE. +The last phase is supposed to generate response and pass it along the filter +chain. +The response in not necessarily sent to the client at this phase. +It may remain buffered and will be sent at the finalization stage + + + +ngx_http_finalize_request() is usually called when the +request has generated all the output or produced an error. +In the latter case an appropriate error page is looked up and used as the +response. +If the response is not completely sent to the client by this point, an +HTTP writer ngx_http_writer() is activated to finish +sending outstanding data + + + +ngx_http_finalize_connection() is called when the response is +completely sent to the client and the request can be destroyed. +If client connection keepalive feature is enabled, +ngx_http_set_keepalive() is called, which destroys current +request and waits for the next request on the connection. +Otherwise, ngx_http_close_request() destroys both the +request and the connection + + + + +
+ + +
+ + +For each client HTTP request the ngx_http_request_t object is +created. Some of the fields of this object: + + + + + + + +connection - pointer to a ngx_connection_t +client connection object. +Several requests may reference the same connection object at the same time - +one main request and its subrequests. +After a request is deleted, a new request may be created on the same connection. + + + +Note that for HTTP connections ngx_connection_t's +data field points back to the request. +Such request is called active, as opposed to the other requests tied with the +connection. +Active request is used to handle client connection events and is allowed to +output its response to the client. +Normally, each request becomes active at some point to be able to send its +output + + + + + + + +ctx - array of HTTP module contexts. +Each module of type NGX_HTTP_MODULE can store any value +(normally, a pointer to a structure) in the request. +The value is stored in the ctx array at the module's +ctx_index position. +The following macros provide a convenient way to get and set request contexts: + + + + + +ngx_http_get_module_ctx(r, module) - returns +module's context + + + +ngx_http_set_ctx(r, c, module) - sets c +as module's context + + + + + + + +main_conf, srv_conf, loc_conf - arrays of current request +configurations. +Configurations are stored at module's ctx_index positions + + + +read_event_handler, write_event_handler - +read and write event handlers for the request. +Normally, an HTTP connection has ngx_http_request_handler() +set as both read and write event handlers. +This function calls read_event_handler and +write_event_handler handlers of the currently active request + + + +cache - request cache object for caching upstream response + + + +upstream - request upstream object for proxying + + + +pool - request pool. +This pool is destroyed when the request is deleted. +The request object itself is allocated in this pool. +For allocations which should be available throughout the client connection's +lifetime, ngx_connection_t's pool should be used instead + + + +header_in - buffer where client HTTP request header in read + + + +headers_in, headers_out - input and output HTTP headers +objects. +Both objects contain the headers field of type +ngx_list_t keeping the raw list of headers. +In addition to that, specific headers are available for getting and setting as +separate fields, for example content_length_n, +status etc + + + +request_body - client request body object + + + +start_sec, start_msec - time point when the request was +created. +Used for tracking request duration + + + +method, method_name - numeric and textual representation of +client HTTP request method. +Numeric values for methods are defined in +src/http/ngx_http_request.h with macros +NGX_HTTP_GET, NGX_HTTP_HEAD, NGX_HTTP_POST etc + + + +http_protocol, http_version, http_major, http_minor - +client HTTP protocol version in its original textual form ("HTTP/1.0", +"HTTP/1.1" etc), numeric form (NGX_HTTP_VERSION_10, +NGX_HTTP_VERSION_11 etc) and separate major and minor +versions + + + +request_line, unparsed_uri - client original request line +and URI + + + +uri, args, exten - current request URI, arguments and file +extention. +The URI value here might differ from the original URI sent by the client due to +normalization. +Throughout request processing, these value can change while performing internal +redirects + + + +main - pointer to a main request object. +This object is created to process client HTTP request, as opposed to +subrequests, created to perform a specific sub-task within the main request + + + +parent - pointer to a parent request of a subrequest + + + +postponed - list of output buffers and subrequests in the +order they are sent and created. +The list is used by the postpone filter to provide consistent request output, +when parts of it are created by subrequests + + + +post_subrequest - pointer to a handler with context to be +called when a subrequest gets finalized. +Unused for main requests + + + + + +posted_requests - list of requests to be started or +resumed. +Starting or resuming is done by calling the request's +write_event_handler. +Normally, this handler holds the request main function, which at first runs +request phases and then produces the output. + + + +A request is usually posted by the +ngx_http_post_request(r, NULL) call. +It is always posted to the main request posted_requests list. +The function ngx_http_run_posted_requests(c) runs all +requests, posted in the main request of the passed connection's active request. +This function should be called in all event handlers, which can lead to new +posted requests. +Normally, it's called always after invoking a request's read or write handler + + + + + +phase_handler - index of current request phase + + + +ncaptures, captures, captures_data - regex captures produced +by the last regex match of the request. +While processing a request, there's a number of places where a regex match can +happen: map lookup, server lookup by SNI or HTTP Host, rewrite, proxy_redirect +etc. +Captures produced by a lookup are stored in the above mentioned fields. +The field ncaptures holds the number of captures, +captures holds captures boundaries, +captures_data holds a string, against which the regex was +matched and which should be used to extract captures. +After each new regex match request captures are reset to hold new values + + + +count - request reference counter. +The field only makes sense for the main request. +Increasing the counter is done by simple r->main->count++. +To decrease the counter ngx_http_finalize_request(r, rc) +should be called. +Creation of a subrequest or running request body read process increase the +counter + + + +subrequests - current subrequest nesting level. +Each subrequest gets the nesting level of its parent decreased by one. +Once the value reaches zero an error is generated. +The value for the main request is defined by the +NGX_HTTP_MAX_SUBREQUESTS constant + + + +uri_changes - number of URI changes left for the request. +The total number of times a request can change its URI is limited by the +NGX_HTTP_MAX_URI_CHANGES constant. +With each change the value is decreased until it reaches zero. +In the latter case an error is generated. +The actions considered as URI changes are rewrites and internal redirects to +normal or named locations + + + +blocked - counter of blocks held on the request. +While this value is non-zero, request cannot be terminated. +Currently, this value is increased by pending AIO operations (POSIX AIO and +thread operations) and active cache lock + + + +buffered - bitmask showing which modules have buffered the +output produced by the request. +A number of filters can buffer output, for example sub_filter can buffer data +due to a partial string match, copy filter can buffer data because of the lack +of free output_buffers etc. +As long as this value is non-zero, request is not finalized, expecting the flush + + + +header_only - flag showing that output does not require body. +For example, this flag is used by HTTP HEAD requests + + + + +keepalive - flag showing if client connection keepalive is +supported. +The value is inferred from HTTP version and
Connection
header +value +
+
+ + +header_sent - flag showing that output header has already +been sent by the request + + + +internal - flag showing that current request is internal. +To enter the internal state, a request should pass through an internal +redirect or be a subrequest. +Internal requests are allowed to enter internal locations + + + +allow_ranges - flag showing that partial response can be +sent to client, if requested by the HTTP Range header + + + +subrequest_ranges - flag showing that a partial response is +allowed to be sent while processing a subrequest + + + +single_range - flag showing that only a single continuous +range of output data can be sent to the client. +This flag is usually set when sending a stream of data, for example from a +proxied server, and the entire response is not available at once + + + +main_filter_need_in_memory, filter_need_in_memory - flags +showing that the output should be produced in memory buffers but not in files. +This is a signal to the copy filter to read data from file buffers even if +sendfile is enabled. +The difference between these two flags is the location of filter modules which +set them. +Filters called before the postpone filter in filter chain, set +filter_need_in_memory requesting that only the current +request output should come in memory buffers. +Filters called later in filter chain set +main_filter_need_in_memory requiring that both the main +request and all the subrequest read files in memory while sending output + + + +filter_need_temporary - flag showing that the request output +should be produced in temporary buffers, but not in readonly memory buffers or +file buffers. +This is used by filters which may change output directly in the buffers, where +it's sent + +
+ +
+ + +
+ + +Each HTTP module may have three types of configuration: + + + + + +Main configuration. +This configuration applies to the entire nginx http{} block. This is global +configuration. +It stores global settings for a module + + + +Server configuration. +This configuraion applies to a single nginx server{}. +It stores server-specific settings for a module + + + +Location configuration. +This configuraion applies to a single location{}, if{} or limit_except() block. +This configuration stores settings specific to a location + + + + + +Configuration structures are created at nginx configuration stage by calling +functions, which allocate these structures, initialize them and merge. +The following example shows how to create a simple module location +configuration. +The configuration has one setting foo of unsiged integer +type. + + + +typedef struct { + ngx_uint_t foo; +} ngx_http_foo_loc_conf_t; + + +static ngx_http_module_t ngx_http_foo_module_ctx = { + NULL, /* preconfiguration */ + NULL, /* postconfiguration */ + + NULL, /* create main configuration */ + NULL, /* init main configuration */ + + NULL, /* create server configuration */ + NULL, /* merge server configuration */ + + ngx_http_foo_create_loc_conf, /* create location configuration */ + ngx_http_foo_merge_loc_conf /* merge location configuration */ +}; + + +static void * +ngx_http_foo_create_loc_conf(ngx_conf_t *cf) +{ + ngx_http_foo_loc_conf_t *conf; + + conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_foo_loc_conf_t)); + if (conf == NULL) { + return NULL; + } + + conf->foo = NGX_CONF_UNSET_UINT; + + return conf; +} + + +static char * +ngx_http_foo_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child) +{ + ngx_http_foo_loc_conf_t *prev = parent; + ngx_http_foo_loc_conf_t *conf = child; + + ngx_conf_merge_uint_value(conf->foo, prev->foo, 1); +} + + + +As seen in the example, ngx_http_foo_create_loc_conf() +function creates a new configuration structure and +ngx_http_foo_merge_loc_conf() merges a configuration with +another configuration from a higher level. +In fact, server and location configuration do not only exist at server and +location levels, but also created for all the levels above. +Specifically, a server configuration is created at the main level as well and +location configurations are created for main, server and location levels. +These configurations make it possible to specify server and location-specific +settings at any level of nginx configuration file. +Eventually configurations are merged down. +To indicate a missing setting and ignore it while merging, nginx provides a +number of macros like NGX_CONF_UNSET and +NGX_CONF_UNSET_UINT. +Standard nginx merge macros like ngx_conf_merge_value() and +ngx_conf_merge_uint_value() provide a convenient way to +merge a setting and set the default value if none of configurations provided an +explicit value. +For complete list of macros for different types see +src/core/ngx_conf_file.h. + + + +To access configuration of any HTTP module at configuration time, the following +macros are available. +They receive ngx_conf_t reference as the first argument. + + + + + +ngx_http_conf_get_module_main_conf(cf, module) + + + +ngx_http_conf_get_module_srv_conf(cf, module) + + + +ngx_http_conf_get_module_loc_conf(cf, module) + + + + + +The following example gets a pointer to a location configuration of +standard nginx core module +ngx_http_core_module +and changes +location content handler kept in the handler field of the +structure. + + + +static ngx_int_t ngx_http_foo_handler(ngx_http_request_t *r); + + +static ngx_command_t ngx_http_foo_commands[] = { + + { ngx_string("foo"), + NGX_HTTP_LOC_CONF|NGX_CONF_NOARGS, + ngx_http_foo, + 0, + 0, + NULL }, + + ngx_null_command +}; + + +static char * +ngx_http_foo(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) +{ + ngx_http_core_loc_conf_t *clcf; + + clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module); + clcf->handler = ngx_http_bar_handler; + + return NGX_CONF_OK; +} + + + +In runtime the following macros are available to get configurations of HTTP +modules. + + + + + +ngx_http_get_module_main_conf(r, module) + + + +ngx_http_get_module_srv_conf(r, module) + + + +ngx_http_get_module_loc_conf(r, module) + + + + + +These macros receive a reference to an HTTP request +ngx_http_request_t. +Main configuration of a request never changes. +Server configuration may change from a default one after choosing a virtual +server for a request. +Request location configuration may change multiple times as a result of a +rewrite or internal redirect. +The following example shows how to access HTTP configuration in runtime. + + + +static ngx_int_t +ngx_http_foo_handler(ngx_http_request_t *r) +{ + ngx_http_foo_loc_conf_t *flcf; + + flcf = ngx_http_get_module_loc_conf(r, ngx_http_foo_module); + + ... +} + + +
+ + +
+ + +Each HTTP request passes through a list of HTTP phases. +Each phase is specialized in a particular type of processing. +Most phases allow installing handlers. +The phase handlers are called successively once the request reaches the phase. +Many standard nginx modules install their phase handlers as a way to get called +at a specific request processing stage. +Following is the list of nginx HTTP phases. + + + + + +NGX_HTTP_POST_READ_PHASE is the earliest phase. +The ngx_http_realip_module +installs its handler at this phase. +This allows to substitute client address before any other module is invoked + + + +NGX_HTTP_SERVER_REWRITE_PHASE is used to run rewrite script, +defined at the server level, that is out of any location block. +The +ngx_http_rewrite_module +installs its handler at this phase + + + +NGX_HTTP_FIND_CONFIG_PHASE - a special phase used to choose a +location based on request URI. +This phase does not allow installing any handlers. +It only performs the default action of choosing a location. +Before this phase, the server default location is assigned to the request. +Any module requesting a location configuration, will receive the default server +location configuration. +After this phase a new location is assigned to the request + + + +NGX_HTTP_REWRITE_PHASE - same as +NGX_HTTP_SERVER_REWRITE_PHASE, but for a new location, +chosen at the prevous phase + + + +NGX_HTTP_POST_REWRITE_PHASE - a special phase, used to +redirect the request to a new location, if the URI was changed during rewrite. +The redirect is done by going back to +NGX_HTTP_FIND_CONFIG_PHASE. +No handlers are allowed at this phase + + + +NGX_HTTP_PREACCESS_PHASE - a common phase for different +types of handlers, not associated with access check. +Standard nginx modules +ngx_http_limit_conn_module + and + +ngx_http_limit_req_module register their handlers at this phase + + + +NGX_HTTP_ACCESS_PHASE - used to check access permissions +for the request. +Standard nginx modules such as +ngx_http_access_module and +ngx_http_auth_basic_module + register their handlers at this phase. +If configured so by the + directive, only one +of access phase handlers may allow access to the request in order to confinue +processing + + + +NGX_HTTP_POST_ACCESS_PHASE - a special phase for the +satisfy any +case. +If some access phase handlers denied the access and none of them allowed, the +request is finalized. +No handlers are supported at this phase + + + +NGX_HTTP_TRY_FILES_PHASE - a special phase, for the + feature. +No handlers are allowed at this phase + + + +NGX_HTTP_CONTENT_PHASE - a phase, at which the response +is supposed to be generated. +Multiple nginx standard modules register their handers at this phase, for +example +ngx_http_index_module or +ngx_http_static_module. +All these handlers are called sequentially until one of them finally produces +the output. +It's also possible to set content handlers on a per-location basis. +If the +ngx_http_core_module's +location configuration has handler set, this handler is +called as the content handler and content phase handlers are ignored + + + +NGX_HTTP_LOG_PHASE is used to perform request logging. +Currently, only the +ngx_http_log_module +registers its handler +at this stage for access logging. +Log phase handlers are called at the very end of request processing, right +before freeing the request + + + + + +Following is the example of a preaccess phase handler. + + + +static ngx_http_module_t ngx_http_foo_module_ctx = { + NULL, /* preconfiguration */ + ngx_http_foo_init, /* postconfiguration */ + + NULL, /* create main configuration */ + NULL, /* init main configuration */ + + NULL, /* create server configuration */ + NULL, /* merge server configuration */ + + NULL, /* create location configuration */ + NULL /* merge location configuration */ +}; + + +static ngx_int_t +ngx_http_foo_handler(ngx_http_request_t *r) +{ + ngx_str_t *ua; + + ua = r->headers_in->user_agent; + + if (ua == NULL) { + return NGX_DECLINED; + } + + /* reject requests with "User-Agent: foo" */ + if (ua->value.len == 3 && ngx_strncmp(ua->value.data, "foo", 3) == 0) { + return NGX_HTTP_FORBIDDEN; + } + + return NGX_DECLINED; +} + + +static ngx_int_t +ngx_http_foo_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_PREACCESS_PHASE].handlers); + if (h == NULL) { + return NGX_ERROR; + } + + *h = ngx_http_foo_handler; + + return NGX_OK; +} + + + +Phase handlers are expected to return specific codes: + + + + + +NGX_OK - proceed to the next phase + + + +NGX_DECLINED - proceed to the next handler of the current +phase. +If current handler is the last in current phase, move to the next phase + + + +NGX_AGAIN, NGX_DONE - suspend phase handling until some +future event. +This can be for example asynchronous I/O operation or just a delay. +It is supposed, that phase handling will be resumed later by calling +ngx_http_core_run_phases() + + + +Any other value returned by the phase handler is treated as a request +finalization code, in particular, HTTP response code. +The request is finalized with the code provided + + + + + +Some phases treat return codes in a slightly different way. +At content phase, any return code other that NGX_DECLINED +is considered a finalization code. +As for the location content handlers, any return from them is considered a +finalization code. +At access phase, in +satisfy any +mode, returning a code other +than NGX_OK, NGX_DECLINED, NGX_AGAIN, NGX_DONE is considered +a denial. +If none of future access handlers allow access or deny with a new +code, the denial code will become the finalization code. + + +
+ +
+ +