comparison xml/en/docs/dev/development_guide.xml @ 1960:9550ea66abdd

HTTP response section of the development guide.
author Roman Arutyunyan <arut@nginx.com>
date Mon, 10 Apr 2017 15:09:06 +0300
parents d0aebb2337ec
children ef27e3ef0c46
comparison
equal deleted inserted replaced
1959:d0aebb2337ec 1960:9550ea66abdd
4632 </para> 4632 </para>
4633 4633
4634 </section> 4634 </section>
4635 4635
4636 4636
4637 <section name="Response" id="http_response">
4638
4639 <para>
4640 An HTTP response in nginx is produced by sending the response header followed by
4641 the optional response body.
4642 Both header and body are passed through a chain of filters and eventually get
4643 written to the client socket.
4644 An nginx module can install its handler into the header or body filter chain
4645 and process the output coming from the previous handler.
4646 </para>
4647
4648
4649 <section name="Response header" id="http_response_header">
4650
4651 <para>
4652 Output header is sent by the function
4653 <literal>ngx_http_send_header(r)</literal>.
4654 Prior to calling this function, <literal>r->headers_out</literal> should contain
4655 all the data required to produce the HTTP response header.
4656 It's always required to set the <literal>status</literal> field of
4657 <literal>r->headers_out</literal>.
4658 If the response status suggests that a response body follows the header,
4659 <literal>content_length_n</literal> can be set as well.
4660 The default value for this field is -1, which means that the body size is
4661 unknown.
4662 In this case, chunked transfer encoding is used.
4663 To output an arbitrary header, <literal>headers</literal> list should be
4664 appended.
4665 </para>
4666
4667 <programlisting>
4668 static ngx_int_t
4669 ngx_http_foo_content_handler(ngx_http_request_t *r)
4670 {
4671 ngx_int_t rc;
4672 ngx_table_elt_t *h;
4673
4674 /* send header */
4675
4676 r->headers_out.status = NGX_HTTP_OK;
4677 r->headers_out.content_length_n = 3;
4678
4679 /* X-Foo: foo */
4680
4681 h = ngx_list_push(&amp;r->headers_out.headers);
4682 if (h == NULL) {
4683 return NGX_ERROR;
4684 }
4685
4686 h->hash = 1;
4687 ngx_str_set(&amp;h->key, "X-Foo");
4688 ngx_str_set(&amp;h->value, "foo");
4689
4690 rc = ngx_http_send_header(r);
4691
4692 if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {
4693 return rc;
4694 }
4695
4696 /* send body */
4697
4698 ...
4699 }
4700 </programlisting>
4701
4702 </section>
4703
4704
4705 <section name="Header filters" id="http_header_filters">
4706
4707 <para>
4708 The <literal>ngx_http_send_header(r)</literal> function invokes the header
4709 filter chain by calling the top header filter handler
4710 <literal>ngx_http_top_header_filter</literal>.
4711 It's assumed that every header handler calls the next handler in chain until
4712 the final handler <literal>ngx_http_header_filter(r)</literal> is called.
4713 The final header handler constructs the HTTP response based on
4714 <literal>r->headers_out</literal> and passes it to the
4715 <literal>ngx_http_writer_filter</literal> for output.
4716 </para>
4717
4718 <para>
4719 To add a handler to the header filter chain, one should store its address in
4720 <literal>ngx_http_top_header_filter</literal> global variable at configuration
4721 time.
4722 The previous handler address is normally stored in a module's static variable
4723 and is called by the newly added handler before exiting.
4724 </para>
4725
4726 <para>
4727 The following is an example header filter module, adding the HTTP header
4728 "X-Foo: foo" to every output with the status 200.
4729 </para>
4730
4731 <programlisting>
4732 #include &lt;ngx_config.h&gt;
4733 #include &lt;ngx_core.h&gt;
4734 #include &lt;ngx_http.h&gt;
4735
4736
4737 static ngx_int_t ngx_http_foo_header_filter(ngx_http_request_t *r);
4738 static ngx_int_t ngx_http_foo_header_filter_init(ngx_conf_t *cf);
4739
4740
4741 static ngx_http_module_t ngx_http_foo_header_filter_module_ctx = {
4742 NULL, /* preconfiguration */
4743 ngx_http_foo_header_filter_init, /* postconfiguration */
4744
4745 NULL, /* create main configuration */
4746 NULL, /* init main configuration */
4747
4748 NULL, /* create server configuration */
4749 NULL, /* merge server configuration */
4750
4751 NULL, /* create location configuration */
4752 NULL /* merge location configuration */
4753 };
4754
4755
4756 ngx_module_t ngx_http_foo_header_filter_module = {
4757 NGX_MODULE_V1,
4758 &amp;ngx_http_foo_header_filter_module_ctx, /* module context */
4759 NULL, /* module directives */
4760 NGX_HTTP_MODULE, /* module type */
4761 NULL, /* init master */
4762 NULL, /* init module */
4763 NULL, /* init process */
4764 NULL, /* init thread */
4765 NULL, /* exit thread */
4766 NULL, /* exit process */
4767 NULL, /* exit master */
4768 NGX_MODULE_V1_PADDING
4769 };
4770
4771
4772 static ngx_http_output_header_filter_pt ngx_http_next_header_filter;
4773
4774
4775 static ngx_int_t
4776 ngx_http_foo_header_filter(ngx_http_request_t *r)
4777 {
4778 ngx_table_elt_t *h;
4779
4780 /*
4781 * The filter handler adds "X-Foo: foo" header
4782 * to every HTTP 200 response
4783 */
4784
4785 if (r->headers_out.status != NGX_HTTP_OK) {
4786 return ngx_http_next_header_filter(r);
4787 }
4788
4789 h = ngx_list_push(&amp;r->headers_out.headers);
4790 if (h == NULL) {
4791 return NGX_ERROR;
4792 }
4793
4794 h->hash = 1;
4795 ngx_str_set(&amp;h->key, "X-Foo");
4796 ngx_str_set(&amp;h->value, "foo");
4797
4798 return ngx_http_next_header_filter(r);
4799 }
4800
4801
4802 static ngx_int_t
4803 ngx_http_foo_header_filter_init(ngx_conf_t *cf)
4804 {
4805 ngx_http_next_header_filter = ngx_http_top_header_filter;
4806 ngx_http_top_header_filter = ngx_http_foo_header_filter;
4807
4808 return NGX_OK;
4809 }
4810 </programlisting>
4811
4812 </section>
4813
4814 </section>
4815
4816
4817 <section name="Response body" id="http_response_body">
4818
4819 <para>
4820 Response body is sent by calling the function
4821 <literal>ngx_http_output_filter(r, cl)</literal>.
4822 The function can be called multiple times.
4823 Each time it sends a part of the response body passed as a buffer chain.
4824 The last body buffer should have the <literal>last_buf</literal> flag set.
4825 </para>
4826
4827 <para>
4828 The following example produces a complete HTTP output with "foo" as its body.
4829 In order for the example to work not only as a main request but as a subrequest
4830 as well, the <literal>last_in_chain_flag</literal> is set in the last buffer
4831 of the output.
4832 The <literal>last_buf</literal> flag is set only for the main request since
4833 a subrequest's last buffers does not end the entire output.
4834 </para>
4835
4836 <programlisting>
4837 static ngx_int_t
4838 ngx_http_bar_content_handler(ngx_http_request_t *r)
4839 {
4840 ngx_int_t rc;
4841 ngx_buf_t *b;
4842 ngx_chain_t out;
4843
4844 /* send header */
4845
4846 r->headers_out.status = NGX_HTTP_OK;
4847 r->headers_out.content_length_n = 3;
4848
4849 rc = ngx_http_send_header(r);
4850
4851 if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {
4852 return rc;
4853 }
4854
4855 /* send body */
4856
4857 b = ngx_calloc_buf(r->pool);
4858 if (b == NULL) {
4859 return NGX_ERROR;
4860 }
4861
4862 b->last_buf = (r == r->main) ? 1: 0;
4863 b->last_in_chain = 1;
4864
4865 b->memory = 1;
4866
4867 b->pos = (u_char *) "foo";
4868 b->last = b->pos + 3;
4869
4870 out.buf = b;
4871 out.next = NULL;
4872
4873 return ngx_http_output_filter(r, &amp;out);
4874 }
4875 </programlisting>
4876
4877 </section>
4878
4879
4880 <section name="Body filters" id="http_body_filters">
4881
4882 <para>
4883 The function <literal>ngx_http_output_filter(r, cl)</literal> invokes the
4884 body filter chain by calling the top body filter handler
4885 <literal>ngx_http_top_body_filter</literal>.
4886 It's assumed that every body handler calls the next handler in chain until
4887 the final handler <literal>ngx_http_write_filter(r, cl)</literal> is called.
4888 </para>
4889
4890 <para>
4891 A body filter handler receives a chain of buffers.
4892 The handler is supposed to process the buffers and pass a possibly new chain to
4893 the next handler.
4894 It's worth noting that the chain links <literal>ngx_chain_t</literal> of the
4895 incoming chain belong to the caller.
4896 They should never be reused or changed.
4897 Right after the handler completes, the caller can use its output chain links
4898 to keep track of the buffers it has sent.
4899 To save the buffer chain or to substitute some buffers before sending further,
4900 a handler should allocate its own chain links.
4901 </para>
4902
4903 <para>
4904 Following is the example of a simple body filter counting the number of
4905 body bytes.
4906 The result is available as the <literal>$counter</literal> variable which can be
4907 used in the access log.
4908 </para>
4909
4910 <programlisting>
4911 #include &lt;ngx_config.h&gt;
4912 #include &lt;ngx_core.h&gt;
4913 #include &lt;ngx_http.h&gt;
4914
4915
4916 typedef struct {
4917 off_t count;
4918 } ngx_http_counter_filter_ctx_t;
4919
4920
4921 static ngx_int_t ngx_http_counter_body_filter(ngx_http_request_t *r,
4922 ngx_chain_t *in);
4923 static ngx_int_t ngx_http_counter_variable(ngx_http_request_t *r,
4924 ngx_http_variable_value_t *v, uintptr_t data);
4925 static ngx_int_t ngx_http_counter_add_variables(ngx_conf_t *cf);
4926 static ngx_int_t ngx_http_counter_filter_init(ngx_conf_t *cf);
4927
4928
4929 static ngx_http_module_t ngx_http_counter_filter_module_ctx = {
4930 ngx_http_counter_add_variables, /* preconfiguration */
4931 ngx_http_counter_filter_init, /* postconfiguration */
4932
4933 NULL, /* create main configuration */
4934 NULL, /* init main configuration */
4935
4936 NULL, /* create server configuration */
4937 NULL, /* merge server configuration */
4938
4939 NULL, /* create location configuration */
4940 NULL /* merge location configuration */
4941 };
4942
4943
4944 ngx_module_t ngx_http_counter_filter_module = {
4945 NGX_MODULE_V1,
4946 &amp;ngx_http_counter_filter_module_ctx, /* module context */
4947 NULL, /* module directives */
4948 NGX_HTTP_MODULE, /* module type */
4949 NULL, /* init master */
4950 NULL, /* init module */
4951 NULL, /* init process */
4952 NULL, /* init thread */
4953 NULL, /* exit thread */
4954 NULL, /* exit process */
4955 NULL, /* exit master */
4956 NGX_MODULE_V1_PADDING
4957 };
4958
4959
4960 static ngx_http_output_body_filter_pt ngx_http_next_body_filter;
4961
4962 static ngx_str_t ngx_http_counter_name = ngx_string("counter");
4963
4964
4965 static ngx_int_t
4966 ngx_http_counter_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
4967 {
4968 ngx_chain_t *cl;
4969 ngx_http_counter_filter_ctx_t *ctx;
4970
4971 ctx = ngx_http_get_module_ctx(r, ngx_http_counter_filter_module);
4972 if (ctx == NULL) {
4973 ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_counter_filter_ctx_t));
4974 if (ctx == NULL) {
4975 return NGX_ERROR;
4976 }
4977
4978 ngx_http_set_ctx(r, ctx, ngx_http_counter_filter_module);
4979 }
4980
4981 for (cl = in; cl; cl = cl->next) {
4982 ctx->count += ngx_buf_size(cl->buf);
4983 }
4984
4985 return ngx_http_next_body_filter(r, in);
4986 }
4987
4988
4989 static ngx_int_t
4990 ngx_http_counter_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v,
4991 uintptr_t data)
4992 {
4993 u_char *p;
4994 ngx_http_counter_filter_ctx_t *ctx;
4995
4996 ctx = ngx_http_get_module_ctx(r, ngx_http_counter_filter_module);
4997 if (ctx == NULL) {
4998 v->not_found = 1;
4999 return NGX_OK;
5000 }
5001
5002 p = ngx_pnalloc(r->pool, NGX_OFF_T_LEN);
5003 if (p == NULL) {
5004 return NGX_ERROR;
5005 }
5006
5007 v->data = p;
5008 v->len = ngx_sprintf(p, "%O", ctx->count) - p;
5009 v->valid = 1;
5010 v->no_cacheable = 0;
5011 v->not_found = 0;
5012
5013 return NGX_OK;
5014 }
5015
5016
5017 static ngx_int_t
5018 ngx_http_counter_add_variables(ngx_conf_t *cf)
5019 {
5020 ngx_http_variable_t *var;
5021
5022 var = ngx_http_add_variable(cf, &amp;ngx_http_counter_name, 0);
5023 if (var == NULL) {
5024 return NGX_ERROR;
5025 }
5026
5027 var->get_handler = ngx_http_counter_variable;
5028
5029 return NGX_OK;
5030 }
5031
5032
5033 static ngx_int_t
5034 ngx_http_counter_filter_init(ngx_conf_t *cf)
5035 {
5036 ngx_http_next_body_filter = ngx_http_top_body_filter;
5037 ngx_http_top_body_filter = ngx_http_counter_body_filter;
5038
5039 return NGX_OK;
5040 }
5041 </programlisting>
5042
5043 </section>
5044
5045
5046 <section name="Building filter modules" id="http_building_filter_modules">
5047
5048 <para>
5049 When writing a body or header filter, a special care should be taken of the
5050 filters order.
5051 There's a number of header and body filters registered by nginx standard
5052 modules.
5053 It's important to register a filter module in the right place in respect to
5054 other filters.
5055 Normally, filters are registered by modules in their postconfiguration handlers.
5056 The order in which filters are called is obviously the reverse of when they are
5057 registered.
5058 </para>
5059
5060 <para>
5061 A special slot <literal>HTTP_AUX_FILTER_MODULES</literal> for third-party filter
5062 modules is provided by nginx.
5063 To register a filter module in this slot, the <literal>ngx_module_type</literal>
5064 variable should be set to the value of <literal>HTTP_AUX_FILTER</literal> in
5065 module's configuration.
5066 </para>
5067
5068 <para>
5069 The following example shows a filter module config file assuming it only has
5070 one source file <literal>ngx_http_foo_filter_module.c</literal>
5071 </para>
5072
5073 <programlisting>
5074 ngx_module_type=HTTP_AUX_FILTER
5075 ngx_module_name=ngx_http_foo_filter_module
5076 ngx_module_srcs="$ngx_addon_dir/ngx_http_foo_filter_module.c"
5077
5078 . auto/module
5079 </programlisting>
5080
5081 </section>
5082
5083
5084 <section name="Buffer reuse" id="http_body_buffers_reuse">
5085
5086 <para>
5087 When issuing or altering a stream of buffers, it's often desirable to reuse the
5088 allocated buffers.
5089 A standard approach widely adopted in nginx code is to keep two buffer chains
5090 for this purpose: <literal>free</literal> and <literal>busy</literal>.
5091 The <literal>free</literal> chain keeps all free buffers.
5092 These buffers can be reused.
5093 The <literal>busy</literal> chain keeps all buffers sent by the current
5094 module which are still in use by some other filter handler.
5095 A buffer is considered in use if its size is greater than zero.
5096 Normally, when a buffer is consumed by a filter, its <literal>pos</literal>
5097 (or <literal>file_pos</literal> for a file buffer) is moved towards
5098 <literal>last</literal> (<literal>file_last</literal> for a file buffer).
5099 Once a buffer is completely consumed, it's ready to be reused.
5100 To update the <literal>free</literal> chain with newly freed buffers,
5101 it's enough to iterate over the <literal>busy</literal> chain and move the zero
5102 size buffers at the head of it to <literal>free</literal>.
5103 This operation is so common that there is a special function
5104 <literal>ngx_chain_update_chains(free, busy, out, tag)</literal> which does
5105 this.
5106 The function appends the output chain <literal>out</literal> to
5107 <literal>busy</literal> and moves free buffers from the top of
5108 <literal>busy</literal> to <literal>free</literal>.
5109 Only the buffers with the given <literal>tag</literal> are reused.
5110 This lets a module reuse only the buffers allocated by itself.
5111 </para>
5112
5113 <para>
5114 The following example is a body filter inserting the “foo” string before each
5115 incoming buffer.
5116 The new buffers allocated by the module are reused if possible.
5117 Note that for this example to work properly, it's also required to set up a
5118 header filter and reset <literal>content_length_n</literal> to -1, which is
5119 beyond the scope of this section.
5120 </para>
5121
5122 <programlisting>
5123 typedef struct {
5124 ngx_chain_t *free;
5125 ngx_chain_t *busy;
5126 } ngx_http_foo_filter_ctx_t;
5127
5128
5129 ngx_int_t
5130 ngx_http_foo_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
5131 {
5132 ngx_int_t rc;
5133 ngx_buf_t *b;
5134 ngx_chain_t *cl, *tl, *out, **ll;
5135 ngx_http_foo_filter_ctx_t *ctx;
5136
5137 ctx = ngx_http_get_module_ctx(r, ngx_http_foo_filter_module);
5138 if (ctx == NULL) {
5139 ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_foo_filter_ctx_t));
5140 if (ctx == NULL) {
5141 return NGX_ERROR;
5142 }
5143
5144 ngx_http_set_ctx(r, ctx, ngx_http_foo_filter_module);
5145 }
5146
5147 /* create a new chain "out" from "in" with all the changes */
5148
5149 ll = &amp;out;
5150
5151 for (cl = in; cl; cl = cl->next) {
5152
5153 /* append "foo" in a reused buffer if possible */
5154
5155 tl = ngx_chain_get_free_buf(r->pool, &amp;ctx->free);
5156 if (tl == NULL) {
5157 return NGX_ERROR;
5158 }
5159
5160 b = tl->buf;
5161 b->tag = (ngx_buf_tag_t) &amp;ngx_http_foo_filter_module;
5162 b->memory = 1;
5163 b->pos = (u_char *) "foo";
5164 b->last = b->pos + 3;
5165
5166 *ll = tl;
5167 ll = &amp;tl->next;
5168
5169 /* append the next incoming buffer */
5170
5171 tl = ngx_alloc_chain_link(r->pool);
5172 if (tl == NULL) {
5173 return NGX_ERROR;
5174 }
5175
5176 tl->buf = cl->buf;
5177 *ll = tl;
5178 ll = &amp;tl->next;
5179 }
5180
5181 *ll = NULL;
5182
5183 /* send the new chain */
5184
5185 rc = ngx_http_next_body_filter(r, out);
5186
5187 /* update "busy" and "free" chains for reuse */
5188
5189 ngx_chain_update_chains(r->pool, &amp;ctx->free, &amp;ctx->busy, &amp;out,
5190 (ngx_buf_tag_t) &amp;ngx_http_foo_filter_module);
5191
5192 return rc;
5193 }
5194 </programlisting>
5195
5196 </section>
5197
5198
4637 <section name="Load balancing" id="http_load_balancing"> 5199 <section name="Load balancing" id="http_load_balancing">
4638 5200
4639 <para> 5201 <para>
4640 The 5202 The
4641 <link doc="../http/ngx_http_upstream_module.xml">ngx_http_upstream_module</link> 5203 <link doc="../http/ngx_http_upstream_module.xml">ngx_http_upstream_module</link>