comparison xml/en/docs/dev/development_guide.xml @ 1968:69908bd68481

The HTTP subrequests section of the development guide.
author Roman Arutyunyan <arut@nginx.com>
date Wed, 19 Apr 2017 18:35:57 +0300
parents ef27e3ef0c46
children 275c928ab386
comparison
equal deleted inserted replaced
1967:ef27e3ef0c46 1968:69908bd68481
4731 4731
4732 <para> 4732 <para>
4733 Redirected and rewritten requests become internal and may access the 4733 Redirected and rewritten requests become internal and may access the
4734 <link doc="../http/ngx_http_core_module.xml" id="internal">internal</link> 4734 <link doc="../http/ngx_http_core_module.xml" id="internal">internal</link>
4735 locations. Internal requests have the <literal>internal</literal> flag set. 4735 locations. Internal requests have the <literal>internal</literal> flag set.
4736 </para>
4737
4738 </section>
4739
4740
4741 <section name="Subrequests" id="http_subrequests">
4742
4743 <para>
4744 Subrequests are primarily used to include output of one request into another,
4745 possibly mixed with other data.
4746 A subrequest looks like a normal request, but shares some data with its parent.
4747 Particularly, all fields related to client input are shared since a subrequest
4748 does not receive any other input from client.
4749 The request field <literal>parent</literal> for a subrequest keeps a link to its
4750 parent request and is NULL for the main request.
4751 The field <literal>main</literal> keeps a link to the main request in a group of
4752 requests.
4753 </para>
4754
4755 <para>
4756 A subrequest starts with <literal>NGX_HTTP_SERVER_REWRITE_PHASE</literal> phase.
4757 It passes through the same phases as a normal request and is assigned a location
4758 based on its own URI.
4759 </para>
4760
4761 <para>
4762 Subrequest output header is always ignored.
4763 Subrequest output body is placed by the
4764 <literal>ngx_http_postpone_filter</literal> into the right position in relation
4765 to other data produced by the parent request.
4766 </para>
4767
4768 <para>
4769 Subrequests are related to the concept of active requests.
4770 A request <literal>r</literal> is considered active if
4771 <literal>c->data == r</literal>, where <literal>c</literal> is the client
4772 connection object.
4773 At any point, only the active request in a request group is allowed to output
4774 its buffers to the client.
4775 A non-active request can still send its data to the filter chain, but they
4776 will not pass beyond the <literal>ngx_http_postpone_filter</literal> and will
4777 remain buffered by that filter until the request becomes active.
4778 Here are some rules of request activation:
4779 </para>
4780
4781 <list type="bullet">
4782
4783 <listitem>
4784 Initially, the main request is active
4785 </listitem>
4786
4787 <listitem>
4788 The first subrequest of an active request becomes active right after creation
4789 </listitem>
4790
4791 <listitem>
4792 The <literal>ngx_http_postpone_filter</literal> activates the next request
4793 in active request's subrequest list, once all data prior to that request are
4794 sent
4795 </listitem>
4796
4797 <listitem>
4798 When a request is finalized, its parent is activated
4799 </listitem>
4800
4801 </list>
4802
4803 <para>
4804 A subrequest is created by calling the function
4805 <literal>ngx_http_subrequest(r, uri, args, psr, ps, flags)</literal>, where
4806 <literal>r</literal> is the parent request, <literal>uri</literal> and
4807 <literal>args</literal> are URI and arguments of the
4808 subrequest, <literal>psr</literal> is the output parameter, receiving the
4809 newly created subrequest reference, <literal>ps</literal> is a callback object
4810 for notifying the parent request that the subrequest is being finalized,
4811 <literal>flags</literal> is subrequest creation flags bitmask.
4812 The following flags are available:
4813 </para>
4814
4815 <list type="bullet">
4816
4817 <listitem>
4818 <literal>NGX_HTTP_SUBREQUEST_IN_MEMORY</literal> - subrequest output should not
4819 be sent to the client, but rather stored in memory.
4820 This only works for proxying subrequests.
4821 After subrequest finalization its output is available in
4822 <literal>r->upstream->buffer</literal> buffer of type
4823 <literal>ngx_buf_t</literal>
4824 </listitem>
4825
4826 <listitem>
4827 <literal>NGX_HTTP_SUBREQUEST_WAITED</literal> - the subrequest
4828 <literal>done</literal> flag is set even if it is finalized being non-active.
4829 This subrequest flag is used by the SSI filter
4830 </listitem>
4831
4832 <listitem>
4833 <literal>NGX_HTTP_SUBREQUEST_CLONE</literal> - the subrequest is created as a
4834 clone of its parent.
4835 It is started at the same location and proceeds from the same phase as the
4836 parent request
4837 </listitem>
4838
4839 </list>
4840
4841 <para>
4842 The following example creates a subrequest with the URI of "/foo".
4843 </para>
4844
4845 <programlisting>
4846 ngx_int_t rc;
4847 ngx_str_t uri;
4848 ngx_http_request_t *sr;
4849
4850 ...
4851
4852 ngx_str_set(&amp;uri, "/foo");
4853
4854 rc = ngx_http_subrequest(r, &amp;uri, NULL, &amp;sr, NULL, 0);
4855 if (rc == NGX_ERROR) {
4856 /* error */
4857 }
4858 </programlisting>
4859
4860 <para>
4861 This example clones the current request and sets a finalization callback for the
4862 subrequest.
4863 </para>
4864
4865 <programlisting>
4866 ngx_int_t
4867 ngx_http_foo_clone(ngx_http_request_t *r)
4868 {
4869 ngx_http_request_t *sr;
4870 ngx_http_post_subrequest_t *ps;
4871
4872 ps = ngx_palloc(r->pool, sizeof(ngx_http_post_subrequest_t));
4873 if (ps == NULL) {
4874 return NGX_ERROR;
4875 }
4876
4877 ps->handler = ngx_http_foo_subrequest_done;
4878 ps->data = "foo";
4879
4880 return ngx_http_subrequest(r, &amp;r->uri, &amp;r->args, &amp;sr, ps,
4881 NGX_HTTP_SUBREQUEST_CLONE);
4882 }
4883
4884
4885 ngx_int_t
4886 ngx_http_foo_subrequest_done(ngx_http_request_t *r, void *data, ngx_int_t rc)
4887 {
4888 char *msg = (char *) data;
4889
4890 ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
4891 "done subrequest r:%p msg:%s rc:%i", r, msg, rc);
4892
4893 return rc;
4894 }
4895 </programlisting>
4896
4897 <para>
4898 Subrequests are normally created in a body filter.
4899 In this case subrequest output can be treated as any other explicit request
4900 output.
4901 This means that eventually the output of a subrequest is sent to the client
4902 after all explicit buffers passed prior to subrequest creation and before any
4903 buffers passed later.
4904 This ordering is preserved even for large hierarchies of subrequests.
4905 The following example inserts a subrequest output after all request data
4906 buffers, but before the final buffer with the <literal>last_buf</literal> flag.
4907 </para>
4908
4909 <programlisting>
4910 ngx_int_t
4911 ngx_http_foo_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
4912 {
4913 ngx_int_t rc;
4914 ngx_buf_t *b;
4915 ngx_uint_t last;
4916 ngx_chain_t *cl, out;
4917 ngx_http_request_t *sr;
4918 ngx_http_foo_filter_ctx_t *ctx;
4919
4920 ctx = ngx_http_get_module_ctx(r, ngx_http_foo_filter_module);
4921 if (ctx == NULL) {
4922 return ngx_http_next_body_filter(r, in);
4923 }
4924
4925 last = 0;
4926
4927 for (cl = in; cl; cl = cl->next) {
4928 if (cl->buf->last_buf) {
4929 cl->buf->last_buf = 0;
4930 cl->buf->last_in_chain = 1;
4931 cl->buf->sync = 1;
4932 last = 1;
4933 }
4934 }
4935
4936 /* Output explicit output buffers */
4937
4938 rc = ngx_http_next_body_filter(r, in);
4939
4940 if (rc == NGX_ERROR || !last) {
4941 return rc;
4942 }
4943
4944 /*
4945 * Create the subrequest. The output of the subrequest
4946 * will automatically be sent after all preceding buffers,
4947 * but before the last_buf buffer passed later in this function.
4948 */
4949
4950 if (ngx_http_subrequest(r, ctx->uri, NULL, &amp;sr, NULL, 0) != NGX_OK) {
4951 return NGX_ERROR;
4952 }
4953
4954 ngx_http_set_ctx(r, NULL, ngx_http_foo_filter_module);
4955
4956
4957 /* Output the final buffer with the last_buf flag */
4958
4959 b = ngx_calloc_buf(r->pool);
4960 if (b == NULL) {
4961 return NGX_ERROR;
4962 }
4963
4964 b->last_buf = 1;
4965
4966 out.buf = b;
4967 out.next = NULL;
4968
4969 return ngx_http_output_filter(r, &amp;out);
4970 }
4971 </programlisting>
4972
4973 <para>
4974 A subrequest may also be created for other purposes than data output.
4975 For example, the <link doc="../http/ngx_http_auth_request_module.xml">
4976 ngx_http_auth_request_module</link>
4977 creates a subrequest at <literal>NGX_HTTP_ACCESS_PHASE</literal> phase.
4978 To disable any output at this point, the subrequest
4979 <literal>header_only</literal> flag is set.
4980 This prevents subrequest body from being sent to the client.
4981 Its header is ignored anyway.
4982 The result of the subrequest can be analyzed in the callback handler.
4736 </para> 4983 </para>
4737 4984
4738 </section> 4985 </section>
4739 4986
4740 4987