Mercurial > hg > nginx-site
changeset 1929:7f290929b32d
HTTP section of the development guide.
author | Roman Arutyunyan <arut@nginx.com> |
---|---|
date | Tue, 14 Mar 2017 12:56:59 +0300 |
parents | 2c14a16c61eb |
children | f0366a3b2299 |
files | xml/en/docs/dev/development_guide.xml |
diffstat | 1 files changed, 861 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- 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 @@ </section> +<section name="HTTP" id="http"> + + +<section name="Connection" id="http_connection"> + +<para> +Each client HTTP connection runs through the following stages: +</para> + +<list type="bullet"> + +<listitem> +<literal>ngx_event_accept()</literal> accepts a client TCP connection. +This handler is called in response to a read notification on a listen socket. +A new <literal>ngx_connecton_t</literal> 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 <literal>ngx_http_init_connection(c)</literal> +</listitem> + +<listitem> +<literal>ngx_http_init_connection()</literal> performs early initialization of +an HTTP connection. +At this stage an <literal>ngx_http_connection_t</literal> object is created for +the connection and its reference is stored in connection's +<literal>data</literal> field. +Later it will be substituted with an HTTP request object. +PROXY protocol parser and SSL handshake are started at this stage as well +</listitem> + +<listitem> +<literal>ngx_http_wait_request_handler()</literal> is a read event handler, that +is called when data is available in the client socket. +At this stage an HTTP request object <literal>ngx_http_request_t</literal> is +created and set to connection's <literal>data</literal> field +</listitem> + +<listitem> +<literal>ngx_http_process_request_line()</literal> is a read event handler, +which reads client request line. +The handler is set by <literal>ngx_http_wait_request_handler()</literal>. +Reading is done into connection's <literal>buffer</literal>. +The size of the buffer is initially set by the directive +<link doc="../http/ngx_http_core_module.xml" id="client_header_buffer_size"/>. +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 <literal>large_client_header_buffers</literal> directive +</listitem> + +<listitem> +<literal>ngx_http_process_request_headers()</literal> is a read event handler, +which is set after <literal>ngx_http_process_request_line()</literal> to read +client request header +</listitem> + +<listitem> +<literal>ngx_http_core_run_phases()</literal> is called when the request header +is completely read and parsed. +This function runs request phases from +<literal>NGX_HTTP_POST_READ_PHASE</literal> to +<literal>NGX_HTTP_CONTENT_PHASE</literal>. +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 +</listitem> + +<listitem> +<literal>ngx_http_finalize_request()</literal> 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 <literal>ngx_http_writer()</literal> is activated to finish +sending outstanding data +</listitem> + +<listitem> +<literal>ngx_http_finalize_connection()</literal> is called when the response is +completely sent to the client and the request can be destroyed. +If client connection keepalive feature is enabled, +<literal>ngx_http_set_keepalive()</literal> is called, which destroys current +request and waits for the next request on the connection. +Otherwise, <literal>ngx_http_close_request()</literal> destroys both the +request and the connection +</listitem> + +</list> + +</section> + + +<section name="Request" id="http_request"> + +<para> +For each client HTTP request the <literal>ngx_http_request_t</literal> object is +created. Some of the fields of this object: +</para> + +<list type="bullet"> + +<listitem> + +<para> +<literal>connection</literal> - pointer to a <literal>ngx_connection_t</literal> +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. +</para> + +<para> +Note that for HTTP connections <literal>ngx_connection_t</literal>'s +<literal>data</literal> 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 +</para> + +</listitem> + +<listitem> + +<para> +<literal>ctx</literal> - array of HTTP module contexts. +Each module of type <literal>NGX_HTTP_MODULE</literal> can store any value +(normally, a pointer to a structure) in the request. +The value is stored in the <literal>ctx</literal> array at the module's +<literal>ctx_index</literal> position. +The following macros provide a convenient way to get and set request contexts: +</para> + +<list type="bullet"> + +<listitem> +<literal>ngx_http_get_module_ctx(r, module)</literal> - returns +<literal>module</literal>'s context +</listitem> + +<listitem> +<literal>ngx_http_set_ctx(r, c, module)</literal> - sets <literal>c</literal> +as <literal>module</literal>'s context +</listitem> + +</list> + +</listitem> + +<listitem> +<literal>main_conf, srv_conf, loc_conf</literal> - arrays of current request +configurations. +Configurations are stored at module's <literal>ctx_index</literal> positions +</listitem> + +<listitem> +<literal>read_event_handler</literal>, <literal>write_event_handler</literal> - +read and write event handlers for the request. +Normally, an HTTP connection has <literal>ngx_http_request_handler()</literal> +set as both read and write event handlers. +This function calls <literal>read_event_handler</literal> and +<literal>write_event_handler</literal> handlers of the currently active request +</listitem> + +<listitem> +<literal>cache</literal> - request cache object for caching upstream response +</listitem> + +<listitem> +<literal>upstream</literal> - request upstream object for proxying +</listitem> + +<listitem> +<literal>pool</literal> - 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, <literal>ngx_connection_t</literal>'s pool should be used instead +</listitem> + +<listitem> +<literal>header_in</literal> - buffer where client HTTP request header in read +</listitem> + +<listitem> +<literal>headers_in, headers_out</literal> - input and output HTTP headers +objects. +Both objects contain the <literal>headers</literal> field of type +<literal>ngx_list_t</literal> keeping the raw list of headers. +In addition to that, specific headers are available for getting and setting as +separate fields, for example <literal>content_length_n</literal>, +<literal>status</literal> etc +</listitem> + +<listitem> +<literal>request_body</literal> - client request body object +</listitem> + +<listitem> +<literal>start_sec, start_msec</literal> - time point when the request was +created. +Used for tracking request duration +</listitem> + +<listitem> +<literal>method, method_name</literal> - numeric and textual representation of +client HTTP request method. +Numeric values for methods are defined in +<literal>src/http/ngx_http_request.h</literal> with macros +<literal>NGX_HTTP_GET, NGX_HTTP_HEAD, NGX_HTTP_POST</literal> etc +</listitem> + +<listitem> +<literal>http_protocol, http_version, http_major, http_minor</literal> - +client HTTP protocol version in its original textual form ("HTTP/1.0", +"HTTP/1.1" etc), numeric form (<literal>NGX_HTTP_VERSION_10</literal>, +<literal>NGX_HTTP_VERSION_11</literal> etc) and separate major and minor +versions +</listitem> + +<listitem> +<literal>request_line, unparsed_uri</literal> - client original request line +and URI +</listitem> + +<listitem> +<literal>uri, args, exten</literal> - 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 +</listitem> + +<listitem> +<literal>main</literal> - 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 +</listitem> + +<listitem> +<literal>parent</literal> - pointer to a parent request of a subrequest +</listitem> + +<listitem> +<literal>postponed</literal> - 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 +</listitem> + +<listitem> +<literal>post_subrequest</literal> - pointer to a handler with context to be +called when a subrequest gets finalized. +Unused for main requests +</listitem> + +<listitem> + +<para> +<literal>posted_requests</literal> - list of requests to be started or +resumed. +Starting or resuming is done by calling the request's +<literal>write_event_handler</literal>. +Normally, this handler holds the request main function, which at first runs +request phases and then produces the output. +</para> + +<para> +A request is usually posted by the +<literal>ngx_http_post_request(r, NULL)</literal> call. +It is always posted to the main request <literal>posted_requests</literal> list. +The function <literal>ngx_http_run_posted_requests(c)</literal> 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 +</para> + +</listitem> + +<listitem> +<literal>phase_handler</literal> - index of current request phase +</listitem> + +<listitem> +<literal>ncaptures, captures, captures_data</literal> - 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 <literal>ncaptures</literal> holds the number of captures, +<literal>captures</literal> holds captures boundaries, +<literal>captures_data</literal> 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 +</listitem> + +<listitem> +<literal>count</literal> - request reference counter. +The field only makes sense for the main request. +Increasing the counter is done by simple <literal>r->main->count++</literal>. +To decrease the counter <literal>ngx_http_finalize_request(r, rc)</literal> +should be called. +Creation of a subrequest or running request body read process increase the +counter +</listitem> + +<listitem> +<literal>subrequests</literal> - 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 +<literal>NGX_HTTP_MAX_SUBREQUESTS</literal> constant +</listitem> + +<listitem> +<literal>uri_changes</literal> - number of URI changes left for the request. +The total number of times a request can change its URI is limited by the +<literal>NGX_HTTP_MAX_URI_CHANGES</literal> 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 +</listitem> + +<listitem> +<literal>blocked</literal> - 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 +</listitem> + +<listitem> +<literal>buffered</literal> - 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 +</listitem> + +<listitem> +<literal>header_only</literal> - flag showing that output does not require body. +For example, this flag is used by HTTP HEAD requests +</listitem> + +<listitem> +<para> +<literal>keepalive</literal> - flag showing if client connection keepalive is +supported. +The value is inferred from HTTP version and <header>Connection</header> header +value +</para> +</listitem> + +<listitem> +<literal>header_sent</literal> - flag showing that output header has already +been sent by the request +</listitem> + +<listitem> +<literal>internal</literal> - 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 +</listitem> + +<listitem> +<literal>allow_ranges</literal> - flag showing that partial response can be +sent to client, if requested by the HTTP Range header +</listitem> + +<listitem> +<literal>subrequest_ranges</literal> - flag showing that a partial response is +allowed to be sent while processing a subrequest +</listitem> + +<listitem> +<literal>single_range</literal> - 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 +</listitem> + +<listitem> +<literal>main_filter_need_in_memory, filter_need_in_memory</literal> - 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 +<literal>filter_need_in_memory</literal> requesting that only the current +request output should come in memory buffers. +Filters called later in filter chain set +<literal>main_filter_need_in_memory</literal> requiring that both the main +request and all the subrequest read files in memory while sending output +</listitem> + +<listitem> +<literal>filter_need_temporary</literal> - 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 </listitem> + +</list> + +</section> + + +<section name="Configuration" id="http_conf"> + +<para> +Each HTTP module may have three types of configuration: +</para> + +<list type="bullet"> + +<listitem> +Main configuration. +This configuration applies to the entire nginx http{} block. This is global +configuration. +It stores global settings for a module +</listitem> + +<listitem> +Server configuration. +This configuraion applies to a single nginx server{}. +It stores server-specific settings for a module +</listitem> + +<listitem> +Location configuration. +This configuraion applies to a single location{}, if{} or limit_except() block. +This configuration stores settings specific to a location +</listitem> + +</list> + +<para> +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 <literal>foo</literal> of unsiged integer +type. +</para> + +<programlisting> +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); +} +</programlisting> + +<para> +As seen in the example, <literal>ngx_http_foo_create_loc_conf()</literal> +function creates a new configuration structure and +<literal>ngx_http_foo_merge_loc_conf()</literal> 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 <literal>NGX_CONF_UNSET</literal> and +<literal>NGX_CONF_UNSET_UINT</literal>. +Standard nginx merge macros like <literal>ngx_conf_merge_value()</literal> and +<literal>ngx_conf_merge_uint_value()</literal> 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 +<literal>src/core/ngx_conf_file.h</literal>. +</para> + +<para> +To access configuration of any HTTP module at configuration time, the following +macros are available. +They receive <literal>ngx_conf_t</literal> reference as the first argument. +</para> + +<list type="bullet"> + +<listitem> +<literal>ngx_http_conf_get_module_main_conf(cf, module)</literal> +</listitem> + +<listitem> +<literal>ngx_http_conf_get_module_srv_conf(cf, module)</literal> +</listitem> + +<listitem> +<literal>ngx_http_conf_get_module_loc_conf(cf, module)</literal> +</listitem> + +</list> + +<para> +The following example gets a pointer to a location configuration of +standard nginx core module +<link doc="../http/ngx_http_core_module.xml">ngx_http_core_module</link> +and changes +location content handler kept in the <literal>handler</literal> field of the +structure. +</para> + +<programlisting> +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; +} +</programlisting> + +<para> +In runtime the following macros are available to get configurations of HTTP +modules. +</para> + +<list type="bullet"> + +<listitem> +<literal>ngx_http_get_module_main_conf(r, module)</literal> +</listitem> + +<listitem> +<literal>ngx_http_get_module_srv_conf(r, module)</literal> +</listitem> + +<listitem> +<literal>ngx_http_get_module_loc_conf(r, module)</literal> +</listitem> + +</list> + +<para> +These macros receive a reference to an HTTP request +<literal>ngx_http_request_t</literal>. +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. +</para> + +<programlisting> +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); + + ... +} +</programlisting> + +</section> + + +<section name="Phases" id="http_phases"> + +<para> +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. +</para> + +<list type="bullet"> + +<listitem> +<literal>NGX_HTTP_POST_READ_PHASE</literal> is the earliest phase. +The <link doc="../http/ngx_http_realip_module.xml">ngx_http_realip_module</link> +installs its handler at this phase. +This allows to substitute client address before any other module is invoked +</listitem> + +<listitem> +<literal>NGX_HTTP_SERVER_REWRITE_PHASE</literal> is used to run rewrite script, +defined at the server level, that is out of any location block. +The +<link doc="../http/ngx_http_rewrite_module.xml">ngx_http_rewrite_module</link> +installs its handler at this phase +</listitem> + +<listitem> +<literal>NGX_HTTP_FIND_CONFIG_PHASE</literal> - 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 +</listitem> + +<listitem> +<literal>NGX_HTTP_REWRITE_PHASE</literal> - same as +<literal>NGX_HTTP_SERVER_REWRITE_PHASE</literal>, but for a new location, +chosen at the prevous phase +</listitem> + +<listitem> +<literal>NGX_HTTP_POST_REWRITE_PHASE</literal> - 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 +<literal>NGX_HTTP_FIND_CONFIG_PHASE</literal>. +No handlers are allowed at this phase +</listitem> + +<listitem> +<literal>NGX_HTTP_PREACCESS_PHASE</literal> - a common phase for different +types of handlers, not associated with access check. +Standard nginx modules +<link doc="../http/ngx_http_limit_conn_module.xml">ngx_http_limit_conn_module +</link> and +<link doc="../http/ngx_http_limit_req_module.xml"> +ngx_http_limit_req_module</link> register their handlers at this phase +</listitem> + +<listitem> +<literal>NGX_HTTP_ACCESS_PHASE</literal> - used to check access permissions +for the request. +Standard nginx modules such as +<link doc="../http/ngx_http_access_module.xml">ngx_http_access_module</link> and +<link doc="../http/ngx_http_auth_basic_module.xml">ngx_http_auth_basic_module +</link> register their handlers at this phase. +If configured so by the +<link doc="../http/ngx_http_core_module.xml" id="satisfy"/> directive, only one +of access phase handlers may allow access to the request in order to confinue +processing +</listitem> + +<listitem> +<literal>NGX_HTTP_POST_ACCESS_PHASE</literal> - a special phase for the +<link doc="../http/ngx_http_core_module.xml" id="satisfy">satisfy any</link> +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 +</listitem> + +<listitem> +<literal>NGX_HTTP_TRY_FILES_PHASE</literal> - a special phase, for the +<link doc="../http/ngx_http_core_module.xml" id="try_files"/> feature. +No handlers are allowed at this phase +</listitem> + +<listitem> +<literal>NGX_HTTP_CONTENT_PHASE</literal> - a phase, at which the response +is supposed to be generated. +Multiple nginx standard modules register their handers at this phase, for +example +<link doc="../http/ngx_http_index_module.xml">ngx_http_index_module</link> or +<literal>ngx_http_static_module</literal>. +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 +<link doc="../http/ngx_http_core_module.xml">ngx_http_core_module</link>'s +location configuration has <literal>handler</literal> set, this handler is +called as the content handler and content phase handlers are ignored +</listitem> + +<listitem> +<literal>NGX_HTTP_LOG_PHASE</literal> is used to perform request logging. +Currently, only the +<link doc="../http/ngx_http_log_module.xml">ngx_http_log_module</link> +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 +</listitem> + +</list> + +<para> +Following is the example of a preaccess phase handler. +</para> + +<programlisting> +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; +} +</programlisting> + +<para> +Phase handlers are expected to return specific codes: +</para> + +<list type="bullet"> + +<listitem> +<literal>NGX_OK</literal> - proceed to the next phase +</listitem> + +<listitem> +<literal>NGX_DECLINED</literal> - proceed to the next handler of the current +phase. +If current handler is the last in current phase, move to the next phase +</listitem> + +<listitem> +<literal>NGX_AGAIN, NGX_DONE</literal> - 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 +<literal>ngx_http_core_run_phases()</literal> +</listitem> + +<listitem> +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 +</listitem> + +</list> + +<para> +Some phases treat return codes in a slightly different way. +At content phase, any return code other that <literal>NGX_DECLINED</literal> +is considered a finalization code. +As for the location content handlers, any return from them is considered a +finalization code. +At access phase, in +<link doc="../http/ngx_http_core_module.xml" id="satisfy">satisfy any</link> +mode, returning a code other +than <literal>NGX_OK, NGX_DECLINED, NGX_AGAIN, NGX_DONE</literal> 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. +</para> + +</section> + +</section> + + </article>