src/http/ngx_http_postpone_filter_module.c - nginx-1.7.10

Global variables defined

Functions defined

Source code


  1. /*
  2. * Copyright (C) Igor Sysoev
  3. * Copyright (C) Nginx, Inc.
  4. */


  5. #include <ngx_config.h>
  6. #include <ngx_core.h>
  7. #include <ngx_http.h>


  8. static ngx_int_t ngx_http_postpone_filter_add(ngx_http_request_t *r,
  9.     ngx_chain_t *in);
  10. static ngx_int_t ngx_http_postpone_filter_init(ngx_conf_t *cf);


  11. static ngx_http_module_t  ngx_http_postpone_filter_module_ctx = {
  12.     NULL,                                  /* preconfiguration */
  13.     ngx_http_postpone_filter_init,         /* postconfiguration */

  14.     NULL,                                  /* create main configuration */
  15.     NULL,                                  /* init main configuration */

  16.     NULL,                                  /* create server configuration */
  17.     NULL,                                  /* merge server configuration */

  18.     NULL,                                  /* create location configuration */
  19.     NULL                                   /* merge location configuration */
  20. };


  21. ngx_module_t  ngx_http_postpone_filter_module = {
  22.     NGX_MODULE_V1,
  23.     &ngx_http_postpone_filter_module_ctx/* module context */
  24.     NULL,                                  /* module directives */
  25.     NGX_HTTP_MODULE,                       /* module type */
  26.     NULL,                                  /* init master */
  27.     NULL,                                  /* init module */
  28.     NULL,                                  /* init process */
  29.     NULL,                                  /* init thread */
  30.     NULL,                                  /* exit thread */
  31.     NULL,                                  /* exit process */
  32.     NULL,                                  /* exit master */
  33.     NGX_MODULE_V1_PADDING
  34. };


  35. static ngx_http_output_body_filter_pt    ngx_http_next_body_filter;


  36. static ngx_int_t
  37. ngx_http_postpone_filter(ngx_http_request_t *r, ngx_chain_t *in)
  38. {
  39.     ngx_connection_t              *c;
  40.     ngx_http_postponed_request_t  *pr;

  41.     c = r->connection;

  42.     ngx_log_debug3(NGX_LOG_DEBUG_HTTP, c->log, 0,
  43.                    "http postpone filter \"%V?%V\" %p", &r->uri, &r->args, in);

  44.     if (r != c->data) {

  45.         if (in) {
  46.             ngx_http_postpone_filter_add(r, in);
  47.             return NGX_OK;
  48.         }

  49. #if 0
  50.         /* TODO: SSI may pass NULL */
  51.         ngx_log_error(NGX_LOG_ALERT, c->log, 0,
  52.                       "http postpone filter NULL inactive request");
  53. #endif

  54.         return NGX_OK;
  55.     }

  56.     if (r->postponed == NULL) {

  57.         if (in || c->buffered) {
  58.             return ngx_http_next_body_filter(r->main, in);
  59.         }

  60.         return NGX_OK;
  61.     }

  62.     if (in) {
  63.         ngx_http_postpone_filter_add(r, in);
  64.     }

  65.     do {
  66.         pr = r->postponed;

  67.         if (pr->request) {

  68.             ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
  69.                            "http postpone filter wake \"%V?%V\"",
  70.                            &pr->request->uri, &pr->request->args);

  71.             r->postponed = pr->next;

  72.             c->data = pr->request;

  73.             return ngx_http_post_request(pr->request, NULL);
  74.         }

  75.         if (pr->out == NULL) {
  76.             ngx_log_error(NGX_LOG_ALERT, c->log, 0,
  77.                           "http postpone filter NULL output");

  78.         } else {
  79.             ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
  80.                            "http postpone filter output \"%V?%V\"",
  81.                            &r->uri, &r->args);

  82.             if (ngx_http_next_body_filter(r->main, pr->out) == NGX_ERROR) {
  83.                 return NGX_ERROR;
  84.             }
  85.         }

  86.         r->postponed = pr->next;

  87.     } while (r->postponed);

  88.     return NGX_OK;
  89. }


  90. static ngx_int_t
  91. ngx_http_postpone_filter_add(ngx_http_request_t *r, ngx_chain_t *in)
  92. {
  93.     ngx_http_postponed_request_t  *pr, **ppr;

  94.     if (r->postponed) {
  95.         for (pr = r->postponed; pr->next; pr = pr->next) { /* void */ }

  96.         if (pr->request == NULL) {
  97.             goto found;
  98.         }

  99.         ppr = &pr->next;

  100.     } else {
  101.         ppr = &r->postponed;
  102.     }

  103.     pr = ngx_palloc(r->pool, sizeof(ngx_http_postponed_request_t));
  104.     if (pr == NULL) {
  105.         return NGX_ERROR;
  106.     }

  107.     *ppr = pr;

  108.     pr->request = NULL;
  109.     pr->out = NULL;
  110.     pr->next = NULL;

  111. found:

  112.     if (ngx_chain_add_copy(r->pool, &pr->out, in) == NGX_OK) {
  113.         return NGX_OK;
  114.     }

  115.     return NGX_ERROR;
  116. }


  117. static ngx_int_t
  118. ngx_http_postpone_filter_init(ngx_conf_t *cf)
  119. {
  120.     ngx_http_next_body_filter = ngx_http_top_body_filter;
  121.     ngx_http_top_body_filter = ngx_http_postpone_filter;

  122.     return NGX_OK;
  123. }