~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Nginx/http/ngx_http_postpone_filter_module.c

Version: ~ [ nginx-0.6.26 ] ~ [ nginx-0.5.35 ] ~ [ nginx-0.5.20 ] ~ [ nginx-0.5.19 ] ~

  1 
  2 /*
  3  * Copyright (C) Igor Sysoev
  4  */
  5 
  6 
  7 #include <ngx_config.h>
  8 #include <ngx_core.h>
  9 #include <ngx_http.h>
 10 
 11 
 12 static ngx_int_t
 13     ngx_http_postpone_filter_output_postponed_request(ngx_http_request_t *r);
 14 static ngx_int_t ngx_http_postpone_filter_init(ngx_conf_t *cf);
 15 
 16 
 17 static ngx_http_module_t  ngx_http_postpone_filter_module_ctx = {
 18     NULL,                                  /* preconfiguration */
 19     ngx_http_postpone_filter_init,         /* postconfiguration */
 20 
 21     NULL,                                  /* create main configuration */
 22     NULL,                                  /* init main configuration */
 23 
 24     NULL,                                  /* create server configuration */
 25     NULL,                                  /* merge server configuration */
 26 
 27     NULL,                                  /* create location configuration */
 28     NULL                                   /* merge location configuration */
 29 };
 30 
 31 
 32 ngx_module_t  ngx_http_postpone_filter_module = {
 33     NGX_MODULE_V1,
 34     &ngx_http_postpone_filter_module_ctx,  /* module context */
 35     NULL,                                  /* module directives */
 36     NGX_HTTP_MODULE,                       /* module type */
 37     NULL,                                  /* init master */
 38     NULL,                                  /* init module */
 39     NULL,                                  /* init process */
 40     NULL,                                  /* init thread */
 41     NULL,                                  /* exit thread */
 42     NULL,                                  /* exit process */
 43     NULL,                                  /* exit master */
 44     NGX_MODULE_V1_PADDING
 45 };
 46 
 47 
 48 static ngx_http_output_body_filter_pt    ngx_http_next_filter;
 49 
 50 
 51 static ngx_int_t
 52 ngx_http_postpone_filter(ngx_http_request_t *r, ngx_chain_t *in)
 53 {
 54     ngx_int_t                      rc;
 55     ngx_chain_t                   *out;
 56     ngx_http_postponed_request_t  *pr, **ppr;
 57 
 58     ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
 59                    "http postpone filter \"%V?%V\" %p", &r->uri, &r->args, in);
 60 
 61     if (r != r->connection->data || (r->postponed && in)) {
 62 
 63         if (r->postponed) {
 64             for (pr = r->postponed; pr->next; pr = pr->next) { /* void */ }
 65 
 66             ppr = pr->request ? &pr->next : NULL;
 67 
 68         } else {
 69             ppr = &r->postponed;
 70 #if (NGX_SUPPRESS_WARN)
 71             pr = NULL;
 72 #endif
 73         }
 74 
 75         if (ppr) {
 76             pr = ngx_palloc(r->pool, sizeof(ngx_http_postponed_request_t));
 77             if (pr == NULL) {
 78                 return NGX_ERROR;
 79             }
 80 
 81             *ppr = pr;
 82 
 83             pr->request = NULL;
 84             pr->out = NULL;
 85             pr->next = NULL;
 86         }
 87 
 88         if (ngx_chain_add_copy(r->pool, &pr->out, in) == NGX_ERROR) {
 89             return NGX_ERROR;
 90         }
 91 
 92 #if 1
 93         {
 94         ngx_chain_t  *cl;
 95         ngx_buf_t    *b = NULL;
 96         for (cl = pr->out; cl; cl = cl->next) {
 97             if (cl->buf == b) {
 98                 ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
 99                               "the same buf was used in postponed %p %p",
100                                b, b->pos);
101                 ngx_debug_point();
102                 return NGX_ERROR;
103             }
104             b = cl->buf;
105         }
106         }
107 #endif
108 
109         if (r != r->connection->data || r->postponed->request) {
110             return NGX_AGAIN;
111         }
112     }
113 
114     if (r->postponed) {
115         out = r->postponed->out;
116         if (out) {
117             r->postponed = r->postponed->next;
118         }
119 
120     } else {
121         out = in;
122     }
123 
124     rc = NGX_OK;
125 
126     if (out
127         || (r->connection->buffered
128             & (NGX_HTTP_LOWLEVEL_BUFFERED|NGX_LOWLEVEL_BUFFERED)))
129     {
130         ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
131                        "http postpone filter out \"%V?%V\"", &r->uri, &r->args);
132 
133         if (!(out && out->next == NULL && ngx_buf_sync_only(out->buf))) {
134 
135             rc = ngx_http_next_filter(r->main, out);
136 
137             if (rc == NGX_ERROR) {
138                 /* NGX_ERROR may be returned by any filter */
139                 r->connection->error = 1;
140             }
141         }
142     }
143 
144     if (r->postponed == NULL) {
145         return rc;
146     }
147 
148     rc = ngx_http_postpone_filter_output_postponed_request(r);
149 
150     if (rc == NGX_ERROR) {
151         /* NGX_ERROR may be returned by any filter */
152         r->connection->error = 1;
153     }
154 
155     return rc;
156 }
157 
158 
159 static ngx_int_t
160 ngx_http_postpone_filter_output_postponed_request(ngx_http_request_t *r)
161 {
162     ngx_int_t                      rc;
163     ngx_chain_t                   *out;
164     ngx_http_log_ctx_t            *ctx;
165     ngx_http_postponed_request_t  *pr;
166 
167     for ( ;; ) {
168         pr = r->postponed;
169 
170         if (pr == NULL) {
171             return NGX_OK;
172         }
173 
174         if (pr->request) {
175 
176             ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
177                            "http postpone filter handle \"%V?%V\"",
178                            &pr->request->uri, &pr->request->args);
179 
180             ctx = r->connection->log->data;
181             ctx->current_request = pr->request;
182 
183             if (!pr->request->done) {
184                 r->connection->data = pr->request;
185                 return NGX_AGAIN;
186             }
187 
188             rc = ngx_http_postpone_filter_output_postponed_request(pr->request);
189 
190             if (rc == NGX_AGAIN || rc == NGX_ERROR) {
191                 return rc;
192             }
193 
194             r->postponed = r->postponed->next;
195             pr = r->postponed;
196         }
197 
198         if (pr == NULL) {
199             return NGX_OK;
200         }
201 
202         out = pr->out;
203 
204         if (out) {
205             ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
206                            "http postpone filter out postponed \"%V?%V\"",
207                            &r->uri, &r->args);
208 
209             if (!(out && out->next == NULL && ngx_buf_sync_only(out->buf))) {
210                 if (ngx_http_next_filter(r->main, out) == NGX_ERROR) {
211                     return NGX_ERROR;
212                 }
213             }
214         }
215 
216         r->postponed = r->postponed->next;
217     }
218 }
219 
220 
221 static ngx_int_t
222 ngx_http_postpone_filter_init(ngx_conf_t *cf)
223 {
224     ngx_http_next_filter = ngx_http_top_body_filter;
225     ngx_http_top_body_filter = ngx_http_postpone_filter;
226 
227     return NGX_OK;
228 }
229 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.