Back to home page

Nginx displayed by LXR

Source navigation ]
Diff markup ]
Identifier search ]
general search ]
 
 
Version: nginx-1.13.12 ]​[ nginx-1.12.2 ]​

0001 
0002 /*
0003  * Copyright (C) Igor Sysoev
0004  * Copyright (C) Nginx, Inc.
0005  */
0006 
0007 
0008 #include <ngx_config.h>
0009 #include <ngx_core.h>
0010 #include <ngx_http.h>
0011 
0012 
0013 static ngx_int_t ngx_http_postpone_filter_add(ngx_http_request_t *r,
0014     ngx_chain_t *in);
0015 static ngx_int_t ngx_http_postpone_filter_init(ngx_conf_t *cf);
0016 
0017 
0018 static ngx_http_module_t  ngx_http_postpone_filter_module_ctx = {
0019     NULL,                                  /* preconfiguration */
0020     ngx_http_postpone_filter_init,         /* postconfiguration */
0021 
0022     NULL,                                  /* create main configuration */
0023     NULL,                                  /* init main configuration */
0024 
0025     NULL,                                  /* create server configuration */
0026     NULL,                                  /* merge server configuration */
0027 
0028     NULL,                                  /* create location configuration */
0029     NULL                                   /* merge location configuration */
0030 };
0031 
0032 
0033 ngx_module_t  ngx_http_postpone_filter_module = {
0034     NGX_MODULE_V1,
0035     &ngx_http_postpone_filter_module_ctx,  /* module context */
0036     NULL,                                  /* module directives */
0037     NGX_HTTP_MODULE,                       /* module type */
0038     NULL,                                  /* init master */
0039     NULL,                                  /* init module */
0040     NULL,                                  /* init process */
0041     NULL,                                  /* init thread */
0042     NULL,                                  /* exit thread */
0043     NULL,                                  /* exit process */
0044     NULL,                                  /* exit master */
0045     NGX_MODULE_V1_PADDING
0046 };
0047 
0048 
0049 static ngx_http_output_body_filter_pt    ngx_http_next_body_filter;
0050 
0051 
0052 static ngx_int_t
0053 ngx_http_postpone_filter(ngx_http_request_t *r, ngx_chain_t *in)
0054 {
0055     ngx_connection_t              *c;
0056     ngx_http_postponed_request_t  *pr;
0057 
0058     c = r->connection;
0059 
0060     ngx_log_debug3(NGX_LOG_DEBUG_HTTP, c->log, 0,
0061                    "http postpone filter \"%V?%V\" %p", &r->uri, &r->args, in);
0062 
0063     if (r != c->data) {
0064 
0065         if (in) {
0066             ngx_http_postpone_filter_add(r, in);
0067             return NGX_OK;
0068         }
0069 
0070 #if 0
0071         /* TODO: SSI may pass NULL */
0072         ngx_log_error(NGX_LOG_ALERT, c->log, 0,
0073                       "http postpone filter NULL inactive request");
0074 #endif
0075 
0076         return NGX_OK;
0077     }
0078 
0079     if (r->postponed == NULL) {
0080 
0081         if (in || c->buffered) {
0082             return ngx_http_next_body_filter(r->main, in);
0083         }
0084 
0085         return NGX_OK;
0086     }
0087 
0088     if (in) {
0089         ngx_http_postpone_filter_add(r, in);
0090     }
0091 
0092     do {
0093         pr = r->postponed;
0094 
0095         if (pr->request) {
0096 
0097             ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
0098                            "http postpone filter wake \"%V?%V\"",
0099                            &pr->request->uri, &pr->request->args);
0100 
0101             r->postponed = pr->next;
0102 
0103             c->data = pr->request;
0104 
0105             return ngx_http_post_request(pr->request, NULL);
0106         }
0107 
0108         if (pr->out == NULL) {
0109             ngx_log_error(NGX_LOG_ALERT, c->log, 0,
0110                           "http postpone filter NULL output");
0111 
0112         } else {
0113             ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
0114                            "http postpone filter output \"%V?%V\"",
0115                            &r->uri, &r->args);
0116 
0117             if (ngx_http_next_body_filter(r->main, pr->out) == NGX_ERROR) {
0118                 return NGX_ERROR;
0119             }
0120         }
0121 
0122         r->postponed = pr->next;
0123 
0124     } while (r->postponed);
0125 
0126     return NGX_OK;
0127 }
0128 
0129 
0130 static ngx_int_t
0131 ngx_http_postpone_filter_add(ngx_http_request_t *r, ngx_chain_t *in)
0132 {
0133     ngx_http_postponed_request_t  *pr, **ppr;
0134 
0135     if (r->postponed) {
0136         for (pr = r->postponed; pr->next; pr = pr->next) { /* void */ }
0137 
0138         if (pr->request == NULL) {
0139             goto found;
0140         }
0141 
0142         ppr = &pr->next;
0143 
0144     } else {
0145         ppr = &r->postponed;
0146     }
0147 
0148     pr = ngx_palloc(r->pool, sizeof(ngx_http_postponed_request_t));
0149     if (pr == NULL) {
0150         return NGX_ERROR;
0151     }
0152 
0153     *ppr = pr;
0154 
0155     pr->request = NULL;
0156     pr->out = NULL;
0157     pr->next = NULL;
0158 
0159 found:
0160 
0161     if (ngx_chain_add_copy(r->pool, &pr->out, in) == NGX_OK) {
0162         return NGX_OK;
0163     }
0164 
0165     return NGX_ERROR;
0166 }
0167 
0168 
0169 static ngx_int_t
0170 ngx_http_postpone_filter_init(ngx_conf_t *cf)
0171 {
0172     ngx_http_next_body_filter = ngx_http_top_body_filter;
0173     ngx_http_top_body_filter = ngx_http_postpone_filter;
0174 
0175     return NGX_OK;
0176 }