Mercurial > hg > nginx-quic
annotate src/http/modules/ngx_http_addition_filter_module.c @ 4311:45272aab5eea
Unlock of shared memory zones on process crash.
If process exited abnormally while holding lock on some shared memory zone -
unlock it. It may be not safe thing to do (as crash with lock held may
result in corrupted shared memory structure, and other processes will
subsequently crash while trying to access shared data), therefore complain
loudly if unlock succeeds.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Wed, 23 Nov 2011 14:09:19 +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 } |