comparison xml/en/docs/dev/development_guide.xml @ 2765:5e3591372bf6

Development guide: request body filters section.
author Roman Arutyunyan <arut@nginx.com>
date Wed, 01 Sep 2021 17:07:19 +0300
parents 454af1d39021
children b7ff3d1915a1
comparison
equal deleted inserted replaced
2764:bc9c5d11b67c 2765:5e3591372bf6
5686 </para> 5686 </para>
5687 5687
5688 </section> 5688 </section>
5689 5689
5690 5690
5691 <section name="Request body filters" id="http_request_body_filters">
5692
5693 <para>
5694 After a request body part is read, it's passed to the request
5695 body filter chain by calling the first body filter handler stored in
5696 the <literal>ngx_http_top_request_body_filter</literal> variable.
5697 It's assumed that every body handler calls the next handler in the chain until
5698 the final handler <literal>ngx_http_request_body_save_filter(r, cl)</literal>
5699 is called.
5700 This handler collects the buffers in
5701 <literal>r->request_body->bufs</literal>
5702 and writes them to a file if necessary.
5703 The last request body buffer has nonzero <literal>last_buf</literal> flag.
5704 </para>
5705
5706 <para>
5707 If a filter is planning to delay data buffers, it should set the flag
5708 <literal>r->request_body->filter_need_buffering</literal> to
5709 <literal>1</literal> when called for the first time.
5710 </para>
5711
5712 <para>
5713 Following is an example of a simple request body filter that delays request
5714 body by one second.
5715 </para>
5716
5717 <programlisting>
5718 #include &lt;ngx_config.h&gt;
5719 #include &lt;ngx_core.h&gt;
5720 #include &lt;ngx_http.h&gt;
5721
5722
5723 #define NGX_HTTP_DELAY_BODY 1000
5724
5725
5726 typedef struct {
5727 ngx_event_t event;
5728 ngx_chain_t *out;
5729 } ngx_http_delay_body_ctx_t;
5730
5731
5732 static ngx_int_t ngx_http_delay_body_filter(ngx_http_request_t *r,
5733 ngx_chain_t *in);
5734 static void ngx_http_delay_body_cleanup(void *data);
5735 static void ngx_http_delay_body_event_handler(ngx_event_t *ev);
5736 static ngx_int_t ngx_http_delay_body_init(ngx_conf_t *cf);
5737
5738
5739 static ngx_http_module_t ngx_http_delay_body_module_ctx = {
5740 NULL, /* preconfiguration */
5741 ngx_http_delay_body_init, /* postconfiguration */
5742
5743 NULL, /* create main configuration */
5744 NULL, /* init main configuration */
5745
5746 NULL, /* create server configuration */
5747 NULL, /* merge server configuration */
5748
5749 NULL, /* create location configuration */
5750 NULL /* merge location configuration */
5751 };
5752
5753
5754 ngx_module_t ngx_http_delay_body_filter_module = {
5755 NGX_MODULE_V1,
5756 &amp;ngx_http_delay_body_module_ctx, /* module context */
5757 NULL, /* module directives */
5758 NGX_HTTP_MODULE, /* module type */
5759 NULL, /* init master */
5760 NULL, /* init module */
5761 NULL, /* init process */
5762 NULL, /* init thread */
5763 NULL, /* exit thread */
5764 NULL, /* exit process */
5765 NULL, /* exit master */
5766 NGX_MODULE_V1_PADDING
5767 };
5768
5769
5770 static ngx_http_request_body_filter_pt ngx_http_next_request_body_filter;
5771
5772
5773 static ngx_int_t
5774 ngx_http_delay_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
5775 {
5776 ngx_int_t rc;
5777 ngx_chain_t *cl, *ln;
5778 ngx_http_cleanup_t *cln;
5779 ngx_http_delay_body_ctx_t *ctx;
5780
5781 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
5782 "delay request body filter");
5783
5784 ctx = ngx_http_get_module_ctx(r, ngx_http_delay_body_filter_module);
5785
5786 if (ctx == NULL) {
5787 ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_delay_body_ctx_t));
5788 if (ctx == NULL) {
5789 return NGX_HTTP_INTERNAL_SERVER_ERROR;
5790 }
5791
5792 ngx_http_set_ctx(r, ctx, ngx_http_delay_body_filter_module);
5793
5794 r->request_body->filter_need_buffering = 1;
5795 }
5796
5797 if (ngx_chain_add_copy(r->pool, &amp;ctx->out, in) != NGX_OK) {
5798 return NGX_HTTP_INTERNAL_SERVER_ERROR;
5799 }
5800
5801 if (!ctx->event.timedout) {
5802 if (!ctx->event.timer_set) {
5803
5804 /* cleanup to remove the timer in case of abnormal termination */
5805
5806 cln = ngx_http_cleanup_add(r, 0);
5807 if (cln == NULL) {
5808 return NGX_HTTP_INTERNAL_SERVER_ERROR;
5809 }
5810
5811 cln->handler = ngx_http_delay_body_cleanup;
5812 cln->data = ctx;
5813
5814 /* add timer */
5815
5816 ctx->event.handler = ngx_http_delay_body_event_handler;
5817 ctx->event.data = r;
5818 ctx->event.log = r->connection->log;
5819
5820 ngx_add_timer(&amp;ctx->event, NGX_HTTP_DELAY_BODY);
5821 }
5822
5823 return ngx_http_next_request_body_filter(r, NULL);
5824 }
5825
5826 rc = ngx_http_next_request_body_filter(r, ctx->out);
5827
5828 for (cl = ctx->out; cl; /* void */) {
5829 ln = cl;
5830 cl = cl->next;
5831 ngx_free_chain(r->pool, ln);
5832 }
5833
5834 ctx->out = NULL;
5835
5836 return rc;
5837 }
5838
5839
5840 static void
5841 ngx_http_delay_body_cleanup(void *data)
5842 {
5843 ngx_http_delay_body_ctx_t *ctx = data;
5844
5845 if (ctx->event.timer_set) {
5846 ngx_del_timer(&amp;ctx->event);
5847 }
5848 }
5849
5850
5851 static void
5852 ngx_http_delay_body_event_handler(ngx_event_t *ev)
5853 {
5854 ngx_connection_t *c;
5855 ngx_http_request_t *r;
5856
5857 r = ev->data;
5858 c = r->connection;
5859
5860 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
5861 "delay request body event");
5862
5863 ngx_post_event(c->read, &amp;ngx_posted_events);
5864 }
5865
5866
5867 static ngx_int_t
5868 ngx_http_delay_body_init(ngx_conf_t *cf)
5869 {
5870 ngx_http_next_request_body_filter = ngx_http_top_request_body_filter;
5871 ngx_http_top_request_body_filter = ngx_http_delay_body_filter;
5872
5873 return NGX_OK;
5874 }
5875 </programlisting>
5876
5877 </section>
5878
5879
5691 <section name="Response" id="http_response"> 5880 <section name="Response" id="http_response">
5692 5881
5693 <para> 5882 <para>
5694 In nginx an HTTP response is produced by sending the response header followed by 5883 In nginx an HTTP response is produced by sending the response header followed by
5695 the optional response body. 5884 the optional response body.
5929 </programlisting> 6118 </programlisting>
5930 6119
5931 </section> 6120 </section>
5932 6121
5933 6122
5934 <section name="Body filters" id="http_body_filters"> 6123 <section name="Response body filters" id="http_response_body_filters">
5935 6124
5936 <para> 6125 <para>
5937 The function <literal>ngx_http_output_filter(r, cl)</literal> invokes the 6126 The function <literal>ngx_http_output_filter(r, cl)</literal> invokes the
5938 body filter chain by calling the first body filter handler stored in 6127 body filter chain by calling the first body filter handler stored in
5939 the <literal>ngx_http_top_body_filter</literal> variable. 6128 the <literal>ngx_http_top_body_filter</literal> variable.