3 * Copyright (C) Igor Sysoev
4 * Copyright (C) Nginx, Inc.
8 #include <ngx_config.h>
13 static ngx_int_t
ngx_http_postpone_filter_add(ngx_http_request_t
*r
,
15 static ngx_int_t
ngx_http_postpone_filter_init(ngx_conf_t
*cf
);
18 static ngx_http_module_t ngx_http_postpone_filter_module_ctx
= {
19 NULL
, /* preconfiguration */
20 ngx_http_postpone_filter_init
, /* postconfiguration */
22 NULL
, /* create main configuration */
23 NULL
, /* init main configuration */
25 NULL
, /* create server configuration */
26 NULL
, /* merge server configuration */
28 NULL
, /* create location configuration */
29 NULL
/* merge location configuration */
33 ngx_module_t ngx_http_postpone_filter_module
= {
35 &ngx_http_postpone_filter_module_ctx
, /* module context */
36 NULL
, /* module directives */
37 NGX_HTTP_MODULE
, /* module type */
38 NULL
, /* init master */
39 NULL
, /* init module */
40 NULL
, /* init process */
41 NULL
, /* init thread */
42 NULL
, /* exit thread */
43 NULL
, /* exit process */
44 NULL
, /* exit master */
49 static ngx_http_output_body_filter_pt ngx_http_next_body_filter
;
53 ngx_http_postpone_filter(ngx_http_request_t
*r
, ngx_chain_t
*in
)
56 ngx_http_postponed_request_t
*pr
;
60 ngx_log_debug3(NGX_LOG_DEBUG_HTTP
, c
->log
, 0,
61 "http postpone filter \"%V?%V\" %p", &r
->uri
, &r
->args
, in
);
66 ngx_http_postpone_filter_add(r
, in
);
71 /* TODO: SSI may pass NULL */
72 ngx_log_error(NGX_LOG_ALERT
, c
->log
, 0,
73 "http postpone filter NULL inactive request",
80 if (r
->postponed
== NULL
) {
82 if (in
|| c
->buffered
) {
83 return ngx_http_next_body_filter(r
->main
, in
);
90 ngx_http_postpone_filter_add(r
, in
);
98 ngx_log_debug2(NGX_LOG_DEBUG_HTTP
, c
->log
, 0,
99 "http postpone filter wake \"%V?%V\"",
100 &pr
->request
->uri
, &pr
->request
->args
);
102 r
->postponed
= pr
->next
;
104 c
->data
= pr
->request
;
106 return ngx_http_post_request(pr
->request
, NULL
);
109 if (pr
->out
== NULL
) {
110 ngx_log_error(NGX_LOG_ALERT
, c
->log
, 0,
111 "http postpone filter NULL output",
115 ngx_log_debug2(NGX_LOG_DEBUG_HTTP
, c
->log
, 0,
116 "http postpone filter output \"%V?%V\"",
119 if (ngx_http_next_body_filter(r
->main
, pr
->out
) == NGX_ERROR
) {
124 r
->postponed
= pr
->next
;
126 } while (r
->postponed
);
133 ngx_http_postpone_filter_add(ngx_http_request_t
*r
, ngx_chain_t
*in
)
135 ngx_http_postponed_request_t
*pr
, **ppr
;
138 for (pr
= r
->postponed
; pr
->next
; pr
= pr
->next
) { /* void */ }
140 if (pr
->request
== NULL
) {
150 pr
= ngx_palloc(r
->pool
, sizeof(ngx_http_postponed_request_t
));
163 if (ngx_chain_add_copy(r
->pool
, &pr
->out
, in
) == NGX_OK
) {
172 ngx_http_postpone_filter_init(ngx_conf_t
*cf
)
174 ngx_http_next_body_filter
= ngx_http_top_body_filter
;
175 ngx_http_top_body_filter
= ngx_http_postpone_filter
;