Mercurial > hg > nginx
annotate src/http/modules/ngx_http_addition_filter_module.c @ 4437:3a1507f48686 stable-1.0
Merge of r4372, r4373, r4374:
SCGI fixes:
*) Fixed incorrect use of r->http_version in scgi module.
The r->http_version is a version of client's request, and modules
must not set it unless they are really willing to downgrade protocol
version used for a response (i.e. to HTTP/0.9 if no response headers
are available). In neither case r->http_version may be upgraded.
The former code downgraded response from HTTP/1.1 to HTTP/1.0 for no
reason, causing various problems (see ticket #66). It was also
possible that HTTP/0.9 requests were upgraded to HTTP/1.0.
*) Removed duplicate function declaration.
*) Removed error if there is no Status header.
The SCGI specification doesn't specify format of the response, and
assuming CGI specs should be used there is no reason to complain.
RFC 3875 explicitly states that "A Status header field is optional,
and status 200 'OK' is assumed if it is omitted".
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Sun, 05 Feb 2012 13:53:50 +0000 |
parents | 6b8e5c882e47 |
children | d620f497c50f |
rev | line source |
---|---|
629 | 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 typedef struct { | |
2167 | 13 ngx_str_t before_body; |
14 ngx_str_t after_body; | |
15 | |
16 ngx_hash_t types; | |
17 ngx_array_t *types_keys; | |
629 | 18 } ngx_http_addition_conf_t; |
19 | |
20 | |
21 typedef struct { | |
2167 | 22 ngx_uint_t before_body_sent; |
629 | 23 } ngx_http_addition_ctx_t; |
24 | |
25 | |
26 static void *ngx_http_addition_create_conf(ngx_conf_t *cf); | |
27 static char *ngx_http_addition_merge_conf(ngx_conf_t *cf, void *parent, | |
28 void *child); | |
681 | 29 static ngx_int_t ngx_http_addition_filter_init(ngx_conf_t *cf); |
629 | 30 |
31 | |
32 static ngx_command_t ngx_http_addition_commands[] = { | |
33 | |
34 { ngx_string("add_before_body"), | |
35 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, | |
36 ngx_conf_set_str_slot, | |
37 NGX_HTTP_LOC_CONF_OFFSET, | |
38 offsetof(ngx_http_addition_conf_t, before_body), | |
39 NULL }, | |
40 | |
41 { ngx_string("add_after_body"), | |
42 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, | |
43 ngx_conf_set_str_slot, | |
44 NGX_HTTP_LOC_CONF_OFFSET, | |
45 offsetof(ngx_http_addition_conf_t, after_body), | |
46 NULL }, | |
47 | |
3146
29ba1de1ab0b
fix typo in addition_types directive name
Igor Sysoev <igor@sysoev.ru>
parents:
2912
diff
changeset
|
48 { ngx_string("addition_types"), |
2167 | 49 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE, |
50 ngx_http_types_slot, | |
51 NGX_HTTP_LOC_CONF_OFFSET, | |
52 offsetof(ngx_http_addition_conf_t, types_keys), | |
53 &ngx_http_html_default_types[0] }, | |
54 | |
629 | 55 ngx_null_command |
56 }; | |
57 | |
58 | |
59 static ngx_http_module_t ngx_http_addition_filter_module_ctx = { | |
60 NULL, /* preconfiguration */ | |
681 | 61 ngx_http_addition_filter_init, /* postconfiguration */ |
629 | 62 |
63 NULL, /* create main configuration */ | |
64 NULL, /* init main configuration */ | |
65 | |
66 NULL, /* create server configuration */ | |
67 NULL, /* merge server configuration */ | |
68 | |
69 ngx_http_addition_create_conf, /* create location configuration */ | |
70 ngx_http_addition_merge_conf /* merge location configuration */ | |
71 }; | |
72 | |
73 | |
74 ngx_module_t ngx_http_addition_filter_module = { | |
75 NGX_MODULE_V1, | |
76 &ngx_http_addition_filter_module_ctx, /* module context */ | |
77 ngx_http_addition_commands, /* module directives */ | |
78 NGX_HTTP_MODULE, /* module type */ | |
79 NULL, /* init master */ | |
681 | 80 NULL, /* init module */ |
629 | 81 NULL, /* init process */ |
82 NULL, /* init thread */ | |
83 NULL, /* exit thread */ | |
84 NULL, /* exit process */ | |
85 NULL, /* exit master */ | |
86 NGX_MODULE_V1_PADDING | |
87 }; | |
88 | |
89 | |
90 static ngx_http_output_header_filter_pt ngx_http_next_header_filter; | |
91 static ngx_http_output_body_filter_pt ngx_http_next_body_filter; | |
92 | |
93 | |
94 static ngx_int_t | |
95 ngx_http_addition_header_filter(ngx_http_request_t *r) | |
96 { | |
97 ngx_http_addition_ctx_t *ctx; | |
98 ngx_http_addition_conf_t *conf; | |
99 | |
2167 | 100 if (r->headers_out.status != NGX_HTTP_OK || r != r->main) { |
629 | 101 return ngx_http_next_header_filter(r); |
102 } | |
103 | |
631 | 104 conf = ngx_http_get_module_loc_conf(r, ngx_http_addition_filter_module); |
105 | |
106 if (conf->before_body.len == 0 && conf->after_body.len == 0) { | |
107 return ngx_http_next_header_filter(r); | |
108 } | |
109 | |
2167 | 110 if (ngx_http_test_content_type(r, &conf->types) == NULL) { |
629 | 111 return ngx_http_next_header_filter(r); |
112 } | |
113 | |
114 ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_addition_ctx_t)); | |
115 if (ctx == NULL) { | |
116 return NGX_ERROR; | |
117 } | |
118 | |
119 ngx_http_set_ctx(r, ctx, ngx_http_addition_filter_module); | |
120 | |
121 ngx_http_clear_content_length(r); | |
122 ngx_http_clear_accept_ranges(r); | |
123 | |
124 return ngx_http_next_header_filter(r); | |
125 } | |
126 | |
127 | |
128 static ngx_int_t | |
129 ngx_http_addition_body_filter(ngx_http_request_t *r, ngx_chain_t *in) | |
130 { | |
131 ngx_int_t rc; | |
132 ngx_uint_t last; | |
133 ngx_chain_t *cl; | |
758
86bb73dc8d40
fix <!--#include virtual=... wait="yes" -->
Igor Sysoev <igor@sysoev.ru>
parents:
681
diff
changeset
|
134 ngx_http_request_t *sr; |
629 | 135 ngx_http_addition_ctx_t *ctx; |
136 ngx_http_addition_conf_t *conf; | |
137 | |
138 if (in == NULL || r->header_only) { | |
139 return ngx_http_next_body_filter(r, in); | |
140 } | |
141 | |
142 ctx = ngx_http_get_module_ctx(r, ngx_http_addition_filter_module); | |
143 | |
144 if (ctx == NULL) { | |
145 return ngx_http_next_body_filter(r, in); | |
146 } | |
147 | |
148 conf = ngx_http_get_module_loc_conf(r, ngx_http_addition_filter_module); | |
149 | |
150 if (!ctx->before_body_sent) { | |
151 ctx->before_body_sent = 1; | |
152 | |
153 if (conf->before_body.len) { | |
2377
87b8c44906b5
*) refactor subrequest handling, now they run as separate posted requests
Igor Sysoev <igor@sysoev.ru>
parents:
2167
diff
changeset
|
154 if (ngx_http_subrequest(r, &conf->before_body, NULL, &sr, NULL, 0) |
87b8c44906b5
*) refactor subrequest handling, now they run as separate posted requests
Igor Sysoev <igor@sysoev.ru>
parents:
2167
diff
changeset
|
155 != NGX_OK) |
87b8c44906b5
*) refactor subrequest handling, now they run as separate posted requests
Igor Sysoev <igor@sysoev.ru>
parents:
2167
diff
changeset
|
156 { |
87b8c44906b5
*) refactor subrequest handling, now they run as separate posted requests
Igor Sysoev <igor@sysoev.ru>
parents:
2167
diff
changeset
|
157 return NGX_ERROR; |
629 | 158 } |
159 } | |
160 } | |
161 | |
846
c2cae54f2045
fix add_before_body without add_after_body
Igor Sysoev <igor@sysoev.ru>
parents:
777
diff
changeset
|
162 if (conf->after_body.len == 0) { |
c2cae54f2045
fix add_before_body without add_after_body
Igor Sysoev <igor@sysoev.ru>
parents:
777
diff
changeset
|
163 ngx_http_set_ctx(r, NULL, ngx_http_addition_filter_module); |
c2cae54f2045
fix add_before_body without add_after_body
Igor Sysoev <igor@sysoev.ru>
parents:
777
diff
changeset
|
164 return ngx_http_next_body_filter(r, in); |
c2cae54f2045
fix add_before_body without add_after_body
Igor Sysoev <igor@sysoev.ru>
parents:
777
diff
changeset
|
165 } |
c2cae54f2045
fix add_before_body without add_after_body
Igor Sysoev <igor@sysoev.ru>
parents:
777
diff
changeset
|
166 |
629 | 167 last = 0; |
168 | |
169 for (cl = in; cl; cl = cl->next) { | |
170 if (cl->buf->last_buf) { | |
171 cl->buf->last_buf = 0; | |
631 | 172 cl->buf->sync = 1; |
629 | 173 last = 1; |
174 } | |
175 } | |
176 | |
177 rc = ngx_http_next_body_filter(r, in); | |
178 | |
631 | 179 if (rc == NGX_ERROR || !last || conf->after_body.len == 0) { |
629 | 180 return rc; |
181 } | |
182 | |
2377
87b8c44906b5
*) refactor subrequest handling, now they run as separate posted requests
Igor Sysoev <igor@sysoev.ru>
parents:
2167
diff
changeset
|
183 if (ngx_http_subrequest(r, &conf->after_body, NULL, &sr, NULL, 0) |
87b8c44906b5
*) refactor subrequest handling, now they run as separate posted requests
Igor Sysoev <igor@sysoev.ru>
parents:
2167
diff
changeset
|
184 != NGX_OK) |
87b8c44906b5
*) refactor subrequest handling, now they run as separate posted requests
Igor Sysoev <igor@sysoev.ru>
parents:
2167
diff
changeset
|
185 { |
87b8c44906b5
*) refactor subrequest handling, now they run as separate posted requests
Igor Sysoev <igor@sysoev.ru>
parents:
2167
diff
changeset
|
186 return NGX_ERROR; |
629 | 187 } |
188 | |
631 | 189 ngx_http_set_ctx(r, NULL, ngx_http_addition_filter_module); |
629 | 190 |
191 return ngx_http_send_special(r, NGX_HTTP_LAST); | |
192 } | |
193 | |
194 | |
195 static ngx_int_t | |
681 | 196 ngx_http_addition_filter_init(ngx_conf_t *cf) |
629 | 197 { |
198 ngx_http_next_header_filter = ngx_http_top_header_filter; | |
199 ngx_http_top_header_filter = ngx_http_addition_header_filter; | |
200 | |
201 ngx_http_next_body_filter = ngx_http_top_body_filter; | |
202 ngx_http_top_body_filter = ngx_http_addition_body_filter; | |
203 | |
204 return NGX_OK; | |
205 } | |
206 | |
207 | |
208 static void * | |
209 ngx_http_addition_create_conf(ngx_conf_t *cf) | |
210 { | |
211 ngx_http_addition_conf_t *conf; | |
212 | |
213 conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_addition_conf_t)); | |
214 if (conf == NULL) { | |
2912
c7d57b539248
return NULL instead of NGX_CONF_ERROR on a create conf failure
Igor Sysoev <igor@sysoev.ru>
parents:
2377
diff
changeset
|
215 return NULL; |
629 | 216 } |
217 | |
218 /* | |
219 * set by ngx_pcalloc(): | |
220 * | |
2167 | 221 * conf->before_body = { 0, NULL }; |
222 * conf->after_body = { 0, NULL }; | |
223 * conf->types = { NULL }; | |
224 * conf->types_keys = NULL; | |
629 | 225 */ |
226 | |
227 return conf; | |
228 } | |
229 | |
230 | |
231 static char * | |
232 ngx_http_addition_merge_conf(ngx_conf_t *cf, void *parent, void *child) | |
233 { | |
234 ngx_http_addition_conf_t *prev = parent; | |
235 ngx_http_addition_conf_t *conf = child; | |
236 | |
237 ngx_conf_merge_str_value(conf->before_body, prev->before_body, ""); | |
238 ngx_conf_merge_str_value(conf->after_body, prev->after_body, ""); | |
239 | |
3372
6b8e5c882e47
support "*" in gzip_types, ssi_types, etc
Igor Sysoev <igor@sysoev.ru>
parents:
3146
diff
changeset
|
240 if (ngx_http_merge_types(cf, &conf->types_keys, &conf->types, |
6b8e5c882e47
support "*" in gzip_types, ssi_types, etc
Igor Sysoev <igor@sysoev.ru>
parents:
3146
diff
changeset
|
241 &prev->types_keys, &prev->types, |
2167 | 242 ngx_http_html_default_types) |
243 != NGX_OK) | |
244 { | |
245 return NGX_CONF_ERROR; | |
246 } | |
247 | |
629 | 248 return NGX_CONF_OK; |
249 } |