Mercurial > hg > nginx-quic
annotate src/http/modules/ngx_http_sub_filter_module.c @ 5543:5730c0193842
Mp4: skip tracks shorter than seek position (ticket #414).
Mp4 module does not check movie and track durations when reading
file. Instead it generates errors when track metadata is shorter
than seek position. Now such tracks are skipped and movie duration
check is performed at file read stage.
author | Roman Arutyunyan <arut@nginx.com> |
---|---|
date | Wed, 29 Jan 2014 13:33:45 +0400 |
parents | 102d7117ffb8 |
children | 9e9c1310d17c |
rev | line source |
---|---|
1172 | 1 |
2 /* | |
3 * Copyright (C) Igor Sysoev | |
4412 | 4 * Copyright (C) Nginx, Inc. |
1172 | 5 */ |
6 | |
7 | |
8 #include <ngx_config.h> | |
9 #include <ngx_core.h> | |
10 #include <ngx_http.h> | |
11 | |
12 | |
13 typedef struct { | |
2588
a6954ce88b80
use complex values in add_header, auth_basic_user_file,
Igor Sysoev <igor@sysoev.ru>
parents:
2536
diff
changeset
|
14 ngx_str_t match; |
a6954ce88b80
use complex values in add_header, auth_basic_user_file,
Igor Sysoev <igor@sysoev.ru>
parents:
2536
diff
changeset
|
15 ngx_http_complex_value_t value; |
1172 | 16 |
2588
a6954ce88b80
use complex values in add_header, auth_basic_user_file,
Igor Sysoev <igor@sysoev.ru>
parents:
2536
diff
changeset
|
17 ngx_hash_t types; |
1172 | 18 |
2588
a6954ce88b80
use complex values in add_header, auth_basic_user_file,
Igor Sysoev <igor@sysoev.ru>
parents:
2536
diff
changeset
|
19 ngx_flag_t once; |
5229
4c1a604b0285
Sub filter: sub_filter_last_modified directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4947
diff
changeset
|
20 ngx_flag_t last_modified; |
2166
723df5089c05
use hash in gzip_types, ssi_types, and sub_filter_types
Igor Sysoev <igor@sysoev.ru>
parents:
2135
diff
changeset
|
21 |
2588
a6954ce88b80
use complex values in add_header, auth_basic_user_file,
Igor Sysoev <igor@sysoev.ru>
parents:
2536
diff
changeset
|
22 ngx_array_t *types_keys; |
1172 | 23 } ngx_http_sub_loc_conf_t; |
24 | |
25 | |
26 typedef enum { | |
27 sub_start_state = 0, | |
28 sub_match_state, | |
29 } ngx_http_sub_state_e; | |
30 | |
31 | |
32 typedef struct { | |
2588
a6954ce88b80
use complex values in add_header, auth_basic_user_file,
Igor Sysoev <igor@sysoev.ru>
parents:
2536
diff
changeset
|
33 ngx_str_t match; |
3675
08d7165b6be1
fix case of partially matched patterns on buffer border in sub_filter
Igor Sysoev <igor@sysoev.ru>
parents:
3642
diff
changeset
|
34 ngx_str_t saved; |
08d7165b6be1
fix case of partially matched patterns on buffer border in sub_filter
Igor Sysoev <igor@sysoev.ru>
parents:
3642
diff
changeset
|
35 ngx_str_t looked; |
1172 | 36 |
2588
a6954ce88b80
use complex values in add_header, auth_basic_user_file,
Igor Sysoev <igor@sysoev.ru>
parents:
2536
diff
changeset
|
37 ngx_uint_t once; /* unsigned once:1 */ |
1172 | 38 |
2588
a6954ce88b80
use complex values in add_header, auth_basic_user_file,
Igor Sysoev <igor@sysoev.ru>
parents:
2536
diff
changeset
|
39 ngx_buf_t *buf; |
1172 | 40 |
2588
a6954ce88b80
use complex values in add_header, auth_basic_user_file,
Igor Sysoev <igor@sysoev.ru>
parents:
2536
diff
changeset
|
41 u_char *pos; |
a6954ce88b80
use complex values in add_header, auth_basic_user_file,
Igor Sysoev <igor@sysoev.ru>
parents:
2536
diff
changeset
|
42 u_char *copy_start; |
a6954ce88b80
use complex values in add_header, auth_basic_user_file,
Igor Sysoev <igor@sysoev.ru>
parents:
2536
diff
changeset
|
43 u_char *copy_end; |
1172 | 44 |
2588
a6954ce88b80
use complex values in add_header, auth_basic_user_file,
Igor Sysoev <igor@sysoev.ru>
parents:
2536
diff
changeset
|
45 ngx_chain_t *in; |
a6954ce88b80
use complex values in add_header, auth_basic_user_file,
Igor Sysoev <igor@sysoev.ru>
parents:
2536
diff
changeset
|
46 ngx_chain_t *out; |
a6954ce88b80
use complex values in add_header, auth_basic_user_file,
Igor Sysoev <igor@sysoev.ru>
parents:
2536
diff
changeset
|
47 ngx_chain_t **last_out; |
a6954ce88b80
use complex values in add_header, auth_basic_user_file,
Igor Sysoev <igor@sysoev.ru>
parents:
2536
diff
changeset
|
48 ngx_chain_t *busy; |
a6954ce88b80
use complex values in add_header, auth_basic_user_file,
Igor Sysoev <igor@sysoev.ru>
parents:
2536
diff
changeset
|
49 ngx_chain_t *free; |
1172 | 50 |
2588
a6954ce88b80
use complex values in add_header, auth_basic_user_file,
Igor Sysoev <igor@sysoev.ru>
parents:
2536
diff
changeset
|
51 ngx_str_t sub; |
1172 | 52 |
2588
a6954ce88b80
use complex values in add_header, auth_basic_user_file,
Igor Sysoev <igor@sysoev.ru>
parents:
2536
diff
changeset
|
53 ngx_uint_t state; |
1172 | 54 } ngx_http_sub_ctx_t; |
55 | |
56 | |
57 static ngx_int_t ngx_http_sub_output(ngx_http_request_t *r, | |
58 ngx_http_sub_ctx_t *ctx); | |
59 static ngx_int_t ngx_http_sub_parse(ngx_http_request_t *r, | |
60 ngx_http_sub_ctx_t *ctx); | |
61 | |
62 static char * ngx_http_sub_filter(ngx_conf_t *cf, ngx_command_t *cmd, | |
63 void *conf); | |
64 static void *ngx_http_sub_create_conf(ngx_conf_t *cf); | |
65 static char *ngx_http_sub_merge_conf(ngx_conf_t *cf, | |
66 void *parent, void *child); | |
67 static ngx_int_t ngx_http_sub_filter_init(ngx_conf_t *cf); | |
68 | |
69 | |
70 static ngx_command_t ngx_http_sub_filter_commands[] = { | |
71 | |
72 { ngx_string("sub_filter"), | |
73 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE2, | |
74 ngx_http_sub_filter, | |
75 NGX_HTTP_LOC_CONF_OFFSET, | |
76 0, | |
77 NULL }, | |
78 | |
79 { ngx_string("sub_filter_types"), | |
80 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE, | |
2166
723df5089c05
use hash in gzip_types, ssi_types, and sub_filter_types
Igor Sysoev <igor@sysoev.ru>
parents:
2135
diff
changeset
|
81 ngx_http_types_slot, |
1172 | 82 NGX_HTTP_LOC_CONF_OFFSET, |
2166
723df5089c05
use hash in gzip_types, ssi_types, and sub_filter_types
Igor Sysoev <igor@sysoev.ru>
parents:
2135
diff
changeset
|
83 offsetof(ngx_http_sub_loc_conf_t, types_keys), |
723df5089c05
use hash in gzip_types, ssi_types, and sub_filter_types
Igor Sysoev <igor@sysoev.ru>
parents:
2135
diff
changeset
|
84 &ngx_http_html_default_types[0] }, |
1172 | 85 |
86 { ngx_string("sub_filter_once"), | |
87 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, | |
88 ngx_conf_set_flag_slot, | |
89 NGX_HTTP_LOC_CONF_OFFSET, | |
90 offsetof(ngx_http_sub_loc_conf_t, once), | |
91 NULL }, | |
92 | |
5229
4c1a604b0285
Sub filter: sub_filter_last_modified directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4947
diff
changeset
|
93 { ngx_string("sub_filter_last_modified"), |
4c1a604b0285
Sub filter: sub_filter_last_modified directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4947
diff
changeset
|
94 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, |
4c1a604b0285
Sub filter: sub_filter_last_modified directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4947
diff
changeset
|
95 ngx_conf_set_flag_slot, |
4c1a604b0285
Sub filter: sub_filter_last_modified directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4947
diff
changeset
|
96 NGX_HTTP_LOC_CONF_OFFSET, |
4c1a604b0285
Sub filter: sub_filter_last_modified directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4947
diff
changeset
|
97 offsetof(ngx_http_sub_loc_conf_t, last_modified), |
4c1a604b0285
Sub filter: sub_filter_last_modified directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4947
diff
changeset
|
98 NULL }, |
4c1a604b0285
Sub filter: sub_filter_last_modified directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4947
diff
changeset
|
99 |
1172 | 100 ngx_null_command |
101 }; | |
102 | |
103 | |
104 static ngx_http_module_t ngx_http_sub_filter_module_ctx = { | |
105 NULL, /* preconfiguration */ | |
106 ngx_http_sub_filter_init, /* postconfiguration */ | |
107 | |
108 NULL, /* create main configuration */ | |
109 NULL, /* init main configuration */ | |
110 | |
111 NULL, /* create server configuration */ | |
112 NULL, /* merge server configuration */ | |
113 | |
114 ngx_http_sub_create_conf, /* create location configuration */ | |
115 ngx_http_sub_merge_conf /* merge location configuration */ | |
116 }; | |
117 | |
118 | |
119 ngx_module_t ngx_http_sub_filter_module = { | |
120 NGX_MODULE_V1, | |
121 &ngx_http_sub_filter_module_ctx, /* module context */ | |
122 ngx_http_sub_filter_commands, /* module directives */ | |
123 NGX_HTTP_MODULE, /* module type */ | |
124 NULL, /* init master */ | |
125 NULL, /* init module */ | |
126 NULL, /* init process */ | |
127 NULL, /* init thread */ | |
128 NULL, /* exit thread */ | |
129 NULL, /* exit process */ | |
130 NULL, /* exit master */ | |
131 NGX_MODULE_V1_PADDING | |
132 }; | |
133 | |
134 | |
135 static ngx_http_output_header_filter_pt ngx_http_next_header_filter; | |
136 static ngx_http_output_body_filter_pt ngx_http_next_body_filter; | |
137 | |
138 | |
139 static ngx_int_t | |
140 ngx_http_sub_header_filter(ngx_http_request_t *r) | |
141 { | |
142 ngx_http_sub_ctx_t *ctx; | |
143 ngx_http_sub_loc_conf_t *slcf; | |
144 | |
145 slcf = ngx_http_get_module_loc_conf(r, ngx_http_sub_filter_module); | |
146 | |
147 if (slcf->match.len == 0 | |
2166
723df5089c05
use hash in gzip_types, ssi_types, and sub_filter_types
Igor Sysoev <igor@sysoev.ru>
parents:
2135
diff
changeset
|
148 || r->headers_out.content_length_n == 0 |
723df5089c05
use hash in gzip_types, ssi_types, and sub_filter_types
Igor Sysoev <igor@sysoev.ru>
parents:
2135
diff
changeset
|
149 || ngx_http_test_content_type(r, &slcf->types) == NULL) |
1172 | 150 { |
151 return ngx_http_next_header_filter(r); | |
152 } | |
153 | |
154 ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_sub_ctx_t)); | |
155 if (ctx == NULL) { | |
156 return NGX_ERROR; | |
157 } | |
158 | |
3675
08d7165b6be1
fix case of partially matched patterns on buffer border in sub_filter
Igor Sysoev <igor@sysoev.ru>
parents:
3642
diff
changeset
|
159 ctx->saved.data = ngx_pnalloc(r->pool, slcf->match.len); |
08d7165b6be1
fix case of partially matched patterns on buffer border in sub_filter
Igor Sysoev <igor@sysoev.ru>
parents:
3642
diff
changeset
|
160 if (ctx->saved.data == NULL) { |
08d7165b6be1
fix case of partially matched patterns on buffer border in sub_filter
Igor Sysoev <igor@sysoev.ru>
parents:
3642
diff
changeset
|
161 return NGX_ERROR; |
08d7165b6be1
fix case of partially matched patterns on buffer border in sub_filter
Igor Sysoev <igor@sysoev.ru>
parents:
3642
diff
changeset
|
162 } |
08d7165b6be1
fix case of partially matched patterns on buffer border in sub_filter
Igor Sysoev <igor@sysoev.ru>
parents:
3642
diff
changeset
|
163 |
08d7165b6be1
fix case of partially matched patterns on buffer border in sub_filter
Igor Sysoev <igor@sysoev.ru>
parents:
3642
diff
changeset
|
164 ctx->looked.data = ngx_pnalloc(r->pool, slcf->match.len); |
08d7165b6be1
fix case of partially matched patterns on buffer border in sub_filter
Igor Sysoev <igor@sysoev.ru>
parents:
3642
diff
changeset
|
165 if (ctx->looked.data == NULL) { |
08d7165b6be1
fix case of partially matched patterns on buffer border in sub_filter
Igor Sysoev <igor@sysoev.ru>
parents:
3642
diff
changeset
|
166 return NGX_ERROR; |
08d7165b6be1
fix case of partially matched patterns on buffer border in sub_filter
Igor Sysoev <igor@sysoev.ru>
parents:
3642
diff
changeset
|
167 } |
08d7165b6be1
fix case of partially matched patterns on buffer border in sub_filter
Igor Sysoev <igor@sysoev.ru>
parents:
3642
diff
changeset
|
168 |
1172 | 169 ngx_http_set_ctx(r, ctx, ngx_http_sub_filter_module); |
170 | |
171 ctx->match = slcf->match; | |
172 ctx->last_out = &ctx->out; | |
173 | |
174 r->filter_need_in_memory = 1; | |
175 | |
176 if (r == r->main) { | |
177 ngx_http_clear_content_length(r); | |
4746
4a18bf1833a9
Entity tags: clear on entity changes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4412
diff
changeset
|
178 ngx_http_clear_etag(r); |
5229
4c1a604b0285
Sub filter: sub_filter_last_modified directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4947
diff
changeset
|
179 |
4c1a604b0285
Sub filter: sub_filter_last_modified directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4947
diff
changeset
|
180 if (!slcf->last_modified) { |
4c1a604b0285
Sub filter: sub_filter_last_modified directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4947
diff
changeset
|
181 ngx_http_clear_last_modified(r); |
4c1a604b0285
Sub filter: sub_filter_last_modified directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4947
diff
changeset
|
182 } |
1172 | 183 } |
184 | |
185 return ngx_http_next_header_filter(r); | |
186 } | |
187 | |
188 | |
189 static ngx_int_t | |
190 ngx_http_sub_body_filter(ngx_http_request_t *r, ngx_chain_t *in) | |
191 { | |
192 ngx_int_t rc; | |
193 ngx_buf_t *b; | |
194 ngx_chain_t *cl; | |
195 ngx_http_sub_ctx_t *ctx; | |
196 ngx_http_sub_loc_conf_t *slcf; | |
197 | |
198 ctx = ngx_http_get_module_ctx(r, ngx_http_sub_filter_module); | |
199 | |
200 if (ctx == NULL) { | |
201 return ngx_http_next_body_filter(r, in); | |
202 } | |
203 | |
204 if ((in == NULL | |
205 && ctx->buf == NULL | |
206 && ctx->in == NULL | |
207 && ctx->busy == NULL)) | |
208 { | |
209 return ngx_http_next_body_filter(r, in); | |
210 } | |
211 | |
212 if (ctx->once && (ctx->buf == NULL || ctx->in == NULL)) { | |
213 | |
214 if (ctx->busy) { | |
215 if (ngx_http_sub_output(r, ctx) == NGX_ERROR) { | |
216 return NGX_ERROR; | |
217 } | |
218 } | |
219 | |
220 return ngx_http_next_body_filter(r, in); | |
221 } | |
222 | |
223 /* add the incoming chain to the chain ctx->in */ | |
224 | |
225 if (in) { | |
2536
a6d6d762c554
small optimization: " == NGX_ERROR" > " != NGX_OK"
Igor Sysoev <igor@sysoev.ru>
parents:
2414
diff
changeset
|
226 if (ngx_chain_add_copy(r->pool, &ctx->in, in) != NGX_OK) { |
1172 | 227 return NGX_ERROR; |
228 } | |
229 } | |
230 | |
231 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
232 "http sub filter \"%V\"", &r->uri); | |
233 | |
234 while (ctx->in || ctx->buf) { | |
235 | |
3642 | 236 if (ctx->buf == NULL) { |
1172 | 237 ctx->buf = ctx->in->buf; |
238 ctx->in = ctx->in->next; | |
239 ctx->pos = ctx->buf->pos; | |
240 } | |
241 | |
242 if (ctx->state == sub_start_state) { | |
243 ctx->copy_start = ctx->pos; | |
244 ctx->copy_end = ctx->pos; | |
245 } | |
246 | |
247 b = NULL; | |
248 | |
249 while (ctx->pos < ctx->buf->last) { | |
250 | |
251 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
3675
08d7165b6be1
fix case of partially matched patterns on buffer border in sub_filter
Igor Sysoev <igor@sysoev.ru>
parents:
3642
diff
changeset
|
252 "saved: \"%V\" state: %d", &ctx->saved, ctx->state); |
1172 | 253 |
254 rc = ngx_http_sub_parse(r, ctx); | |
255 | |
256 ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
3675
08d7165b6be1
fix case of partially matched patterns on buffer border in sub_filter
Igor Sysoev <igor@sysoev.ru>
parents:
3642
diff
changeset
|
257 "parse: %d, looked: \"%V\" %p-%p", |
08d7165b6be1
fix case of partially matched patterns on buffer border in sub_filter
Igor Sysoev <igor@sysoev.ru>
parents:
3642
diff
changeset
|
258 rc, &ctx->looked, ctx->copy_start, ctx->copy_end); |
1172 | 259 |
260 if (rc == NGX_ERROR) { | |
261 return rc; | |
262 } | |
263 | |
5288
102d7117ffb8
Sub filter: fixed matching after a partial match.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5287
diff
changeset
|
264 if (ctx->saved.len) { |
1172 | 265 |
266 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
3675
08d7165b6be1
fix case of partially matched patterns on buffer border in sub_filter
Igor Sysoev <igor@sysoev.ru>
parents:
3642
diff
changeset
|
267 "saved: \"%V\"", &ctx->saved); |
1172 | 268 |
5288
102d7117ffb8
Sub filter: fixed matching after a partial match.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5287
diff
changeset
|
269 cl = ngx_chain_get_free_buf(r->pool, &ctx->free); |
102d7117ffb8
Sub filter: fixed matching after a partial match.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5287
diff
changeset
|
270 if (cl == NULL) { |
102d7117ffb8
Sub filter: fixed matching after a partial match.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5287
diff
changeset
|
271 return NGX_ERROR; |
102d7117ffb8
Sub filter: fixed matching after a partial match.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5287
diff
changeset
|
272 } |
1172 | 273 |
5288
102d7117ffb8
Sub filter: fixed matching after a partial match.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5287
diff
changeset
|
274 b = cl->buf; |
1172 | 275 |
5288
102d7117ffb8
Sub filter: fixed matching after a partial match.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5287
diff
changeset
|
276 ngx_memzero(b, sizeof(ngx_buf_t)); |
1172 | 277 |
5288
102d7117ffb8
Sub filter: fixed matching after a partial match.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5287
diff
changeset
|
278 b->pos = ngx_pnalloc(r->pool, ctx->saved.len); |
102d7117ffb8
Sub filter: fixed matching after a partial match.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5287
diff
changeset
|
279 if (b->pos == NULL) { |
102d7117ffb8
Sub filter: fixed matching after a partial match.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5287
diff
changeset
|
280 return NGX_ERROR; |
102d7117ffb8
Sub filter: fixed matching after a partial match.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5287
diff
changeset
|
281 } |
3675
08d7165b6be1
fix case of partially matched patterns on buffer border in sub_filter
Igor Sysoev <igor@sysoev.ru>
parents:
3642
diff
changeset
|
282 |
5288
102d7117ffb8
Sub filter: fixed matching after a partial match.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5287
diff
changeset
|
283 ngx_memcpy(b->pos, ctx->saved.data, ctx->saved.len); |
102d7117ffb8
Sub filter: fixed matching after a partial match.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5287
diff
changeset
|
284 b->last = b->pos + ctx->saved.len; |
102d7117ffb8
Sub filter: fixed matching after a partial match.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5287
diff
changeset
|
285 b->memory = 1; |
1172 | 286 |
5288
102d7117ffb8
Sub filter: fixed matching after a partial match.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5287
diff
changeset
|
287 *ctx->last_out = cl; |
102d7117ffb8
Sub filter: fixed matching after a partial match.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5287
diff
changeset
|
288 ctx->last_out = &cl->next; |
1172 | 289 |
5288
102d7117ffb8
Sub filter: fixed matching after a partial match.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5287
diff
changeset
|
290 ctx->saved.len = 0; |
102d7117ffb8
Sub filter: fixed matching after a partial match.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5287
diff
changeset
|
291 } |
102d7117ffb8
Sub filter: fixed matching after a partial match.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5287
diff
changeset
|
292 |
102d7117ffb8
Sub filter: fixed matching after a partial match.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5287
diff
changeset
|
293 if (ctx->copy_start != ctx->copy_end) { |
1172 | 294 |
5285
d47ef93134e5
Sub filter: switched to ngx_chain_get_free_buf().
Maxim Dounin <mdounin@mdounin.ru>
parents:
5284
diff
changeset
|
295 cl = ngx_chain_get_free_buf(r->pool, &ctx->free); |
d47ef93134e5
Sub filter: switched to ngx_chain_get_free_buf().
Maxim Dounin <mdounin@mdounin.ru>
parents:
5284
diff
changeset
|
296 if (cl == NULL) { |
d47ef93134e5
Sub filter: switched to ngx_chain_get_free_buf().
Maxim Dounin <mdounin@mdounin.ru>
parents:
5284
diff
changeset
|
297 return NGX_ERROR; |
d47ef93134e5
Sub filter: switched to ngx_chain_get_free_buf().
Maxim Dounin <mdounin@mdounin.ru>
parents:
5284
diff
changeset
|
298 } |
1172 | 299 |
5285
d47ef93134e5
Sub filter: switched to ngx_chain_get_free_buf().
Maxim Dounin <mdounin@mdounin.ru>
parents:
5284
diff
changeset
|
300 b = cl->buf; |
1172 | 301 |
302 ngx_memcpy(b, ctx->buf, sizeof(ngx_buf_t)); | |
303 | |
304 b->pos = ctx->copy_start; | |
305 b->last = ctx->copy_end; | |
306 b->shadow = NULL; | |
307 b->last_buf = 0; | |
308 b->recycled = 0; | |
309 | |
310 if (b->in_file) { | |
2079
333ef9e18a59
fix error when response parsed by sub filter, then by SSI filter
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
311 b->file_last = b->file_pos + (b->last - ctx->buf->pos); |
333ef9e18a59
fix error when response parsed by sub filter, then by SSI filter
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
312 b->file_pos += b->pos - ctx->buf->pos; |
1172 | 313 } |
314 | |
315 *ctx->last_out = cl; | |
316 ctx->last_out = &cl->next; | |
317 } | |
318 | |
319 if (ctx->state == sub_start_state) { | |
320 ctx->copy_start = ctx->pos; | |
321 ctx->copy_end = ctx->pos; | |
322 | |
323 } else { | |
324 ctx->copy_start = NULL; | |
325 ctx->copy_end = NULL; | |
326 } | |
327 | |
5288
102d7117ffb8
Sub filter: fixed matching after a partial match.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5287
diff
changeset
|
328 if (ctx->looked.len > (size_t) (ctx->pos - ctx->buf->pos)) { |
102d7117ffb8
Sub filter: fixed matching after a partial match.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5287
diff
changeset
|
329 ctx->saved.len = ctx->looked.len - (ctx->pos - ctx->buf->pos); |
102d7117ffb8
Sub filter: fixed matching after a partial match.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5287
diff
changeset
|
330 ngx_memcpy(ctx->saved.data, ctx->looked.data, ctx->saved.len); |
102d7117ffb8
Sub filter: fixed matching after a partial match.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5287
diff
changeset
|
331 } |
102d7117ffb8
Sub filter: fixed matching after a partial match.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5287
diff
changeset
|
332 |
1172 | 333 if (rc == NGX_AGAIN) { |
334 continue; | |
335 } | |
336 | |
337 | |
338 /* rc == NGX_OK */ | |
339 | |
5285
d47ef93134e5
Sub filter: switched to ngx_chain_get_free_buf().
Maxim Dounin <mdounin@mdounin.ru>
parents:
5284
diff
changeset
|
340 cl = ngx_chain_get_free_buf(r->pool, &ctx->free); |
d47ef93134e5
Sub filter: switched to ngx_chain_get_free_buf().
Maxim Dounin <mdounin@mdounin.ru>
parents:
5284
diff
changeset
|
341 if (cl == NULL) { |
1172 | 342 return NGX_ERROR; |
343 } | |
344 | |
5285
d47ef93134e5
Sub filter: switched to ngx_chain_get_free_buf().
Maxim Dounin <mdounin@mdounin.ru>
parents:
5284
diff
changeset
|
345 b = cl->buf; |
d47ef93134e5
Sub filter: switched to ngx_chain_get_free_buf().
Maxim Dounin <mdounin@mdounin.ru>
parents:
5284
diff
changeset
|
346 |
d47ef93134e5
Sub filter: switched to ngx_chain_get_free_buf().
Maxim Dounin <mdounin@mdounin.ru>
parents:
5284
diff
changeset
|
347 ngx_memzero(b, sizeof(ngx_buf_t)); |
1172 | 348 |
349 slcf = ngx_http_get_module_loc_conf(r, ngx_http_sub_filter_module); | |
350 | |
351 if (ctx->sub.data == NULL) { | |
352 | |
2588
a6954ce88b80
use complex values in add_header, auth_basic_user_file,
Igor Sysoev <igor@sysoev.ru>
parents:
2536
diff
changeset
|
353 if (ngx_http_complex_value(r, &slcf->value, &ctx->sub) |
a6954ce88b80
use complex values in add_header, auth_basic_user_file,
Igor Sysoev <igor@sysoev.ru>
parents:
2536
diff
changeset
|
354 != NGX_OK) |
1172 | 355 { |
356 return NGX_ERROR; | |
357 } | |
358 } | |
359 | |
1555
76fe59c6fafb
fix empty string replacement in sub_filter
Igor Sysoev <igor@sysoev.ru>
parents:
1172
diff
changeset
|
360 if (ctx->sub.len) { |
76fe59c6fafb
fix empty string replacement in sub_filter
Igor Sysoev <igor@sysoev.ru>
parents:
1172
diff
changeset
|
361 b->memory = 1; |
76fe59c6fafb
fix empty string replacement in sub_filter
Igor Sysoev <igor@sysoev.ru>
parents:
1172
diff
changeset
|
362 b->pos = ctx->sub.data; |
76fe59c6fafb
fix empty string replacement in sub_filter
Igor Sysoev <igor@sysoev.ru>
parents:
1172
diff
changeset
|
363 b->last = ctx->sub.data + ctx->sub.len; |
76fe59c6fafb
fix empty string replacement in sub_filter
Igor Sysoev <igor@sysoev.ru>
parents:
1172
diff
changeset
|
364 |
76fe59c6fafb
fix empty string replacement in sub_filter
Igor Sysoev <igor@sysoev.ru>
parents:
1172
diff
changeset
|
365 } else { |
76fe59c6fafb
fix empty string replacement in sub_filter
Igor Sysoev <igor@sysoev.ru>
parents:
1172
diff
changeset
|
366 b->sync = 1; |
76fe59c6fafb
fix empty string replacement in sub_filter
Igor Sysoev <igor@sysoev.ru>
parents:
1172
diff
changeset
|
367 } |
1172 | 368 |
369 *ctx->last_out = cl; | |
370 ctx->last_out = &cl->next; | |
371 | |
372 ctx->once = slcf->once; | |
373 | |
374 continue; | |
375 } | |
376 | |
5287
2dbc5e38b65d
Sub filter: fixed incomplete last buffer on partial match.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5286
diff
changeset
|
377 if (ctx->buf->last_buf && ctx->looked.len) { |
2dbc5e38b65d
Sub filter: fixed incomplete last buffer on partial match.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5286
diff
changeset
|
378 cl = ngx_chain_get_free_buf(r->pool, &ctx->free); |
2dbc5e38b65d
Sub filter: fixed incomplete last buffer on partial match.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5286
diff
changeset
|
379 if (cl == NULL) { |
2dbc5e38b65d
Sub filter: fixed incomplete last buffer on partial match.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5286
diff
changeset
|
380 return NGX_ERROR; |
2dbc5e38b65d
Sub filter: fixed incomplete last buffer on partial match.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5286
diff
changeset
|
381 } |
2dbc5e38b65d
Sub filter: fixed incomplete last buffer on partial match.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5286
diff
changeset
|
382 |
2dbc5e38b65d
Sub filter: fixed incomplete last buffer on partial match.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5286
diff
changeset
|
383 b = cl->buf; |
2dbc5e38b65d
Sub filter: fixed incomplete last buffer on partial match.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5286
diff
changeset
|
384 |
2dbc5e38b65d
Sub filter: fixed incomplete last buffer on partial match.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5286
diff
changeset
|
385 ngx_memzero(b, sizeof(ngx_buf_t)); |
2dbc5e38b65d
Sub filter: fixed incomplete last buffer on partial match.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5286
diff
changeset
|
386 |
2dbc5e38b65d
Sub filter: fixed incomplete last buffer on partial match.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5286
diff
changeset
|
387 b->pos = ctx->looked.data; |
2dbc5e38b65d
Sub filter: fixed incomplete last buffer on partial match.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5286
diff
changeset
|
388 b->last = b->pos + ctx->looked.len; |
2dbc5e38b65d
Sub filter: fixed incomplete last buffer on partial match.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5286
diff
changeset
|
389 b->memory = 1; |
2dbc5e38b65d
Sub filter: fixed incomplete last buffer on partial match.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5286
diff
changeset
|
390 |
2dbc5e38b65d
Sub filter: fixed incomplete last buffer on partial match.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5286
diff
changeset
|
391 *ctx->last_out = cl; |
2dbc5e38b65d
Sub filter: fixed incomplete last buffer on partial match.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5286
diff
changeset
|
392 ctx->last_out = &cl->next; |
2dbc5e38b65d
Sub filter: fixed incomplete last buffer on partial match.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5286
diff
changeset
|
393 |
2dbc5e38b65d
Sub filter: fixed incomplete last buffer on partial match.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5286
diff
changeset
|
394 ctx->looked.len = 0; |
2dbc5e38b65d
Sub filter: fixed incomplete last buffer on partial match.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5286
diff
changeset
|
395 } |
2dbc5e38b65d
Sub filter: fixed incomplete last buffer on partial match.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5286
diff
changeset
|
396 |
5286
819c5b53d8b5
Sub filter: flush buffers handling.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5285
diff
changeset
|
397 if (ctx->buf->last_buf || ctx->buf->flush |
819c5b53d8b5
Sub filter: flush buffers handling.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5285
diff
changeset
|
398 || ngx_buf_in_memory(ctx->buf)) |
819c5b53d8b5
Sub filter: flush buffers handling.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5285
diff
changeset
|
399 { |
1172 | 400 if (b == NULL) { |
5285
d47ef93134e5
Sub filter: switched to ngx_chain_get_free_buf().
Maxim Dounin <mdounin@mdounin.ru>
parents:
5284
diff
changeset
|
401 cl = ngx_chain_get_free_buf(r->pool, &ctx->free); |
d47ef93134e5
Sub filter: switched to ngx_chain_get_free_buf().
Maxim Dounin <mdounin@mdounin.ru>
parents:
5284
diff
changeset
|
402 if (cl == NULL) { |
d47ef93134e5
Sub filter: switched to ngx_chain_get_free_buf().
Maxim Dounin <mdounin@mdounin.ru>
parents:
5284
diff
changeset
|
403 return NGX_ERROR; |
d47ef93134e5
Sub filter: switched to ngx_chain_get_free_buf().
Maxim Dounin <mdounin@mdounin.ru>
parents:
5284
diff
changeset
|
404 } |
1172 | 405 |
5285
d47ef93134e5
Sub filter: switched to ngx_chain_get_free_buf().
Maxim Dounin <mdounin@mdounin.ru>
parents:
5284
diff
changeset
|
406 b = cl->buf; |
1172 | 407 |
5285
d47ef93134e5
Sub filter: switched to ngx_chain_get_free_buf().
Maxim Dounin <mdounin@mdounin.ru>
parents:
5284
diff
changeset
|
408 ngx_memzero(b, sizeof(ngx_buf_t)); |
1172 | 409 |
410 b->sync = 1; | |
411 | |
412 *ctx->last_out = cl; | |
413 ctx->last_out = &cl->next; | |
414 } | |
415 | |
416 b->last_buf = ctx->buf->last_buf; | |
5286
819c5b53d8b5
Sub filter: flush buffers handling.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5285
diff
changeset
|
417 b->flush = ctx->buf->flush; |
1172 | 418 b->shadow = ctx->buf; |
419 | |
420 b->recycled = ctx->buf->recycled; | |
421 } | |
422 | |
423 ctx->buf = NULL; | |
424 | |
3675
08d7165b6be1
fix case of partially matched patterns on buffer border in sub_filter
Igor Sysoev <igor@sysoev.ru>
parents:
3642
diff
changeset
|
425 ctx->saved.len = ctx->looked.len; |
08d7165b6be1
fix case of partially matched patterns on buffer border in sub_filter
Igor Sysoev <igor@sysoev.ru>
parents:
3642
diff
changeset
|
426 ngx_memcpy(ctx->saved.data, ctx->looked.data, ctx->looked.len); |
1172 | 427 } |
428 | |
429 if (ctx->out == NULL && ctx->busy == NULL) { | |
430 return NGX_OK; | |
431 } | |
432 | |
433 return ngx_http_sub_output(r, ctx); | |
434 } | |
435 | |
436 | |
437 static ngx_int_t | |
438 ngx_http_sub_output(ngx_http_request_t *r, ngx_http_sub_ctx_t *ctx) | |
439 { | |
440 ngx_int_t rc; | |
441 ngx_buf_t *b; | |
442 ngx_chain_t *cl; | |
443 | |
444 #if 1 | |
445 b = NULL; | |
446 for (cl = ctx->out; cl; cl = cl->next) { | |
447 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
448 "sub out: %p %p", cl->buf, cl->buf->pos); | |
449 if (cl->buf == b) { | |
450 ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, | |
451 "the same buf was used in sub"); | |
452 ngx_debug_point(); | |
453 return NGX_ERROR; | |
454 } | |
455 b = cl->buf; | |
456 } | |
457 #endif | |
458 | |
459 rc = ngx_http_next_body_filter(r, ctx->out); | |
460 | |
461 if (ctx->busy == NULL) { | |
462 ctx->busy = ctx->out; | |
463 | |
464 } else { | |
465 for (cl = ctx->busy; cl->next; cl = cl->next) { /* void */ } | |
466 cl->next = ctx->out; | |
467 } | |
468 | |
469 ctx->out = NULL; | |
470 ctx->last_out = &ctx->out; | |
471 | |
472 while (ctx->busy) { | |
473 | |
474 cl = ctx->busy; | |
475 b = cl->buf; | |
476 | |
477 if (ngx_buf_size(b) != 0) { | |
478 break; | |
479 } | |
480 | |
481 if (b->shadow) { | |
482 b->shadow->pos = b->shadow->last; | |
483 } | |
484 | |
485 ctx->busy = cl->next; | |
486 | |
487 if (ngx_buf_in_memory(b) || b->in_file) { | |
488 /* add data bufs only to the free buf chain */ | |
489 | |
490 cl->next = ctx->free; | |
491 ctx->free = cl; | |
492 } | |
493 } | |
494 | |
495 if (ctx->in || ctx->buf) { | |
496 r->buffered |= NGX_HTTP_SUB_BUFFERED; | |
497 | |
498 } else { | |
499 r->buffered &= ~NGX_HTTP_SUB_BUFFERED; | |
500 } | |
501 | |
502 return rc; | |
503 } | |
504 | |
505 | |
506 static ngx_int_t | |
507 ngx_http_sub_parse(ngx_http_request_t *r, ngx_http_sub_ctx_t *ctx) | |
508 { | |
509 u_char *p, *last, *copy_end, ch, match; | |
5288
102d7117ffb8
Sub filter: fixed matching after a partial match.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5287
diff
changeset
|
510 size_t looked, i; |
1172 | 511 ngx_http_sub_state_e state; |
512 | |
513 if (ctx->once) { | |
514 ctx->copy_start = ctx->pos; | |
515 ctx->copy_end = ctx->buf->last; | |
516 ctx->pos = ctx->buf->last; | |
3675
08d7165b6be1
fix case of partially matched patterns on buffer border in sub_filter
Igor Sysoev <igor@sysoev.ru>
parents:
3642
diff
changeset
|
517 ctx->looked.len = 0; |
1172 | 518 |
519 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "once"); | |
520 | |
521 return NGX_AGAIN; | |
522 } | |
523 | |
524 state = ctx->state; | |
3675
08d7165b6be1
fix case of partially matched patterns on buffer border in sub_filter
Igor Sysoev <igor@sysoev.ru>
parents:
3642
diff
changeset
|
525 looked = ctx->looked.len; |
1172 | 526 last = ctx->buf->last; |
527 copy_end = ctx->copy_end; | |
528 | |
529 for (p = ctx->pos; p < last; p++) { | |
530 | |
531 ch = *p; | |
532 ch = ngx_tolower(ch); | |
533 | |
534 if (state == sub_start_state) { | |
535 | |
536 /* the tight loop */ | |
537 | |
538 match = ctx->match.data[0]; | |
539 | |
540 for ( ;; ) { | |
541 if (ch == match) { | |
542 copy_end = p; | |
3675
08d7165b6be1
fix case of partially matched patterns on buffer border in sub_filter
Igor Sysoev <igor@sysoev.ru>
parents:
3642
diff
changeset
|
543 ctx->looked.data[0] = *p; |
1172 | 544 looked = 1; |
545 state = sub_match_state; | |
546 | |
547 goto match_started; | |
548 } | |
549 | |
550 if (++p == last) { | |
551 break; | |
552 } | |
553 | |
554 ch = *p; | |
555 ch = ngx_tolower(ch); | |
556 } | |
557 | |
1557
9d094e581587
*) add sub_filter parser fix similar to r1261 in SSI parser
Igor Sysoev <igor@sysoev.ru>
parents:
1555
diff
changeset
|
558 ctx->state = state; |
1172 | 559 ctx->pos = p; |
3675
08d7165b6be1
fix case of partially matched patterns on buffer border in sub_filter
Igor Sysoev <igor@sysoev.ru>
parents:
3642
diff
changeset
|
560 ctx->looked.len = looked; |
1172 | 561 ctx->copy_end = p; |
562 | |
563 if (ctx->copy_start == NULL) { | |
564 ctx->copy_start = ctx->buf->pos; | |
565 } | |
566 | |
567 return NGX_AGAIN; | |
568 | |
569 match_started: | |
570 | |
571 continue; | |
572 } | |
573 | |
574 /* state == sub_match_state */ | |
575 | |
576 if (ch == ctx->match.data[looked]) { | |
3675
08d7165b6be1
fix case of partially matched patterns on buffer border in sub_filter
Igor Sysoev <igor@sysoev.ru>
parents:
3642
diff
changeset
|
577 ctx->looked.data[looked] = *p; |
1172 | 578 looked++; |
579 | |
580 if (looked == ctx->match.len) { | |
1557
9d094e581587
*) add sub_filter parser fix similar to r1261 in SSI parser
Igor Sysoev <igor@sysoev.ru>
parents:
1555
diff
changeset
|
581 |
1172 | 582 ctx->state = sub_start_state; |
583 ctx->pos = p + 1; | |
3675
08d7165b6be1
fix case of partially matched patterns on buffer border in sub_filter
Igor Sysoev <igor@sysoev.ru>
parents:
3642
diff
changeset
|
584 ctx->looked.len = 0; |
5288
102d7117ffb8
Sub filter: fixed matching after a partial match.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5287
diff
changeset
|
585 ctx->saved.len = 0; |
1172 | 586 ctx->copy_end = copy_end; |
587 | |
588 if (ctx->copy_start == NULL && copy_end) { | |
589 ctx->copy_start = ctx->buf->pos; | |
590 } | |
591 | |
592 return NGX_OK; | |
593 } | |
594 | |
5288
102d7117ffb8
Sub filter: fixed matching after a partial match.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5287
diff
changeset
|
595 } else { |
102d7117ffb8
Sub filter: fixed matching after a partial match.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5287
diff
changeset
|
596 /* |
102d7117ffb8
Sub filter: fixed matching after a partial match.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5287
diff
changeset
|
597 * check if there is another partial match in previously |
102d7117ffb8
Sub filter: fixed matching after a partial match.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5287
diff
changeset
|
598 * matched substring to catch cases like "aab" in "aaab" |
102d7117ffb8
Sub filter: fixed matching after a partial match.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5287
diff
changeset
|
599 */ |
102d7117ffb8
Sub filter: fixed matching after a partial match.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5287
diff
changeset
|
600 |
102d7117ffb8
Sub filter: fixed matching after a partial match.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5287
diff
changeset
|
601 ctx->looked.data[looked] = *p; |
102d7117ffb8
Sub filter: fixed matching after a partial match.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5287
diff
changeset
|
602 looked++; |
102d7117ffb8
Sub filter: fixed matching after a partial match.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5287
diff
changeset
|
603 |
102d7117ffb8
Sub filter: fixed matching after a partial match.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5287
diff
changeset
|
604 for (i = 1; i < looked; i++) { |
102d7117ffb8
Sub filter: fixed matching after a partial match.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5287
diff
changeset
|
605 if (ngx_strncasecmp(ctx->looked.data + i, |
102d7117ffb8
Sub filter: fixed matching after a partial match.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5287
diff
changeset
|
606 ctx->match.data, looked - i) |
102d7117ffb8
Sub filter: fixed matching after a partial match.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5287
diff
changeset
|
607 == 0) |
102d7117ffb8
Sub filter: fixed matching after a partial match.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5287
diff
changeset
|
608 { |
102d7117ffb8
Sub filter: fixed matching after a partial match.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5287
diff
changeset
|
609 break; |
102d7117ffb8
Sub filter: fixed matching after a partial match.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5287
diff
changeset
|
610 } |
102d7117ffb8
Sub filter: fixed matching after a partial match.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5287
diff
changeset
|
611 } |
1172 | 612 |
5288
102d7117ffb8
Sub filter: fixed matching after a partial match.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5287
diff
changeset
|
613 if (i < looked) { |
102d7117ffb8
Sub filter: fixed matching after a partial match.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5287
diff
changeset
|
614 if (ctx->saved.len > i) { |
102d7117ffb8
Sub filter: fixed matching after a partial match.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5287
diff
changeset
|
615 ctx->saved.len = i; |
102d7117ffb8
Sub filter: fixed matching after a partial match.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5287
diff
changeset
|
616 } |
102d7117ffb8
Sub filter: fixed matching after a partial match.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5287
diff
changeset
|
617 |
102d7117ffb8
Sub filter: fixed matching after a partial match.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5287
diff
changeset
|
618 if ((size_t) (p + 1 - ctx->buf->pos) >= looked - i) { |
102d7117ffb8
Sub filter: fixed matching after a partial match.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5287
diff
changeset
|
619 copy_end = p + 1 - (looked - i); |
102d7117ffb8
Sub filter: fixed matching after a partial match.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5287
diff
changeset
|
620 } |
102d7117ffb8
Sub filter: fixed matching after a partial match.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5287
diff
changeset
|
621 |
102d7117ffb8
Sub filter: fixed matching after a partial match.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5287
diff
changeset
|
622 ngx_memmove(ctx->looked.data, ctx->looked.data + i, looked - i); |
102d7117ffb8
Sub filter: fixed matching after a partial match.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5287
diff
changeset
|
623 looked = looked - i; |
102d7117ffb8
Sub filter: fixed matching after a partial match.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5287
diff
changeset
|
624 |
102d7117ffb8
Sub filter: fixed matching after a partial match.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5287
diff
changeset
|
625 } else { |
102d7117ffb8
Sub filter: fixed matching after a partial match.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5287
diff
changeset
|
626 copy_end = p; |
102d7117ffb8
Sub filter: fixed matching after a partial match.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5287
diff
changeset
|
627 looked = 0; |
102d7117ffb8
Sub filter: fixed matching after a partial match.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5287
diff
changeset
|
628 state = sub_start_state; |
102d7117ffb8
Sub filter: fixed matching after a partial match.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5287
diff
changeset
|
629 } |
102d7117ffb8
Sub filter: fixed matching after a partial match.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5287
diff
changeset
|
630 |
102d7117ffb8
Sub filter: fixed matching after a partial match.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5287
diff
changeset
|
631 if (ctx->saved.len) { |
102d7117ffb8
Sub filter: fixed matching after a partial match.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5287
diff
changeset
|
632 p++; |
102d7117ffb8
Sub filter: fixed matching after a partial match.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5287
diff
changeset
|
633 goto out; |
102d7117ffb8
Sub filter: fixed matching after a partial match.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5287
diff
changeset
|
634 } |
1172 | 635 } |
636 } | |
637 | |
5288
102d7117ffb8
Sub filter: fixed matching after a partial match.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5287
diff
changeset
|
638 ctx->saved.len = 0; |
102d7117ffb8
Sub filter: fixed matching after a partial match.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5287
diff
changeset
|
639 |
102d7117ffb8
Sub filter: fixed matching after a partial match.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5287
diff
changeset
|
640 out: |
102d7117ffb8
Sub filter: fixed matching after a partial match.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5287
diff
changeset
|
641 |
1172 | 642 ctx->state = state; |
643 ctx->pos = p; | |
3675
08d7165b6be1
fix case of partially matched patterns on buffer border in sub_filter
Igor Sysoev <igor@sysoev.ru>
parents:
3642
diff
changeset
|
644 ctx->looked.len = looked; |
1172 | 645 |
646 ctx->copy_end = (state == sub_start_state) ? p : copy_end; | |
647 | |
648 if (ctx->copy_start == NULL && ctx->copy_end) { | |
649 ctx->copy_start = ctx->buf->pos; | |
650 } | |
651 | |
652 return NGX_AGAIN; | |
653 } | |
654 | |
655 | |
656 static char * | |
657 ngx_http_sub_filter(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | |
658 { | |
659 ngx_http_sub_loc_conf_t *slcf = conf; | |
660 | |
2588
a6954ce88b80
use complex values in add_header, auth_basic_user_file,
Igor Sysoev <igor@sysoev.ru>
parents:
2536
diff
changeset
|
661 ngx_str_t *value; |
a6954ce88b80
use complex values in add_header, auth_basic_user_file,
Igor Sysoev <igor@sysoev.ru>
parents:
2536
diff
changeset
|
662 ngx_http_compile_complex_value_t ccv; |
1172 | 663 |
4947
4251e72b8bb4
Allow the complex value to be defined as an empty string.
Ruslan Ermilov <ru@nginx.com>
parents:
4746
diff
changeset
|
664 if (slcf->match.data) { |
1172 | 665 return "is duplicate"; |
666 } | |
667 | |
668 value = cf->args->elts; | |
669 | |
2135 | 670 ngx_strlow(value[1].data, value[1].data, value[1].len); |
1172 | 671 |
2135 | 672 slcf->match = value[1]; |
1172 | 673 |
2588
a6954ce88b80
use complex values in add_header, auth_basic_user_file,
Igor Sysoev <igor@sysoev.ru>
parents:
2536
diff
changeset
|
674 ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t)); |
1172 | 675 |
2588
a6954ce88b80
use complex values in add_header, auth_basic_user_file,
Igor Sysoev <igor@sysoev.ru>
parents:
2536
diff
changeset
|
676 ccv.cf = cf; |
a6954ce88b80
use complex values in add_header, auth_basic_user_file,
Igor Sysoev <igor@sysoev.ru>
parents:
2536
diff
changeset
|
677 ccv.value = &value[2]; |
a6954ce88b80
use complex values in add_header, auth_basic_user_file,
Igor Sysoev <igor@sysoev.ru>
parents:
2536
diff
changeset
|
678 ccv.complex_value = &slcf->value; |
1172 | 679 |
2588
a6954ce88b80
use complex values in add_header, auth_basic_user_file,
Igor Sysoev <igor@sysoev.ru>
parents:
2536
diff
changeset
|
680 if (ngx_http_compile_complex_value(&ccv) != NGX_OK) { |
1172 | 681 return NGX_CONF_ERROR; |
682 } | |
683 | |
684 return NGX_CONF_OK; | |
685 } | |
686 | |
687 | |
688 static void * | |
689 ngx_http_sub_create_conf(ngx_conf_t *cf) | |
690 { | |
691 ngx_http_sub_loc_conf_t *slcf; | |
692 | |
693 slcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_sub_loc_conf_t)); | |
694 if (slcf == NULL) { | |
2912
c7d57b539248
return NULL instead of NGX_CONF_ERROR on a create conf failure
Igor Sysoev <igor@sysoev.ru>
parents:
2588
diff
changeset
|
695 return NULL; |
1172 | 696 } |
697 | |
698 /* | |
699 * set by ngx_pcalloc(): | |
700 * | |
2166
723df5089c05
use hash in gzip_types, ssi_types, and sub_filter_types
Igor Sysoev <igor@sysoev.ru>
parents:
2135
diff
changeset
|
701 * conf->match = { 0, NULL }; |
723df5089c05
use hash in gzip_types, ssi_types, and sub_filter_types
Igor Sysoev <igor@sysoev.ru>
parents:
2135
diff
changeset
|
702 * conf->types = { NULL }; |
723df5089c05
use hash in gzip_types, ssi_types, and sub_filter_types
Igor Sysoev <igor@sysoev.ru>
parents:
2135
diff
changeset
|
703 * conf->types_keys = NULL; |
1172 | 704 */ |
705 | |
706 slcf->once = NGX_CONF_UNSET; | |
5229
4c1a604b0285
Sub filter: sub_filter_last_modified directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4947
diff
changeset
|
707 slcf->last_modified = NGX_CONF_UNSET; |
1172 | 708 |
709 return slcf; | |
710 } | |
711 | |
712 | |
713 static char * | |
714 ngx_http_sub_merge_conf(ngx_conf_t *cf, void *parent, void *child) | |
715 { | |
716 ngx_http_sub_loc_conf_t *prev = parent; | |
717 ngx_http_sub_loc_conf_t *conf = child; | |
718 | |
719 ngx_conf_merge_value(conf->once, prev->once, 1); | |
720 ngx_conf_merge_str_value(conf->match, prev->match, ""); | |
5229
4c1a604b0285
Sub filter: sub_filter_last_modified directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4947
diff
changeset
|
721 ngx_conf_merge_value(conf->last_modified, prev->last_modified, 0); |
1172 | 722 |
4947
4251e72b8bb4
Allow the complex value to be defined as an empty string.
Ruslan Ermilov <ru@nginx.com>
parents:
4746
diff
changeset
|
723 if (conf->value.value.data == NULL) { |
2588
a6954ce88b80
use complex values in add_header, auth_basic_user_file,
Igor Sysoev <igor@sysoev.ru>
parents:
2536
diff
changeset
|
724 conf->value = prev->value; |
1172 | 725 } |
726 | |
3372
6b8e5c882e47
support "*" in gzip_types, ssi_types, etc
Igor Sysoev <igor@sysoev.ru>
parents:
2912
diff
changeset
|
727 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:
2912
diff
changeset
|
728 &prev->types_keys, &prev->types, |
2166
723df5089c05
use hash in gzip_types, ssi_types, and sub_filter_types
Igor Sysoev <igor@sysoev.ru>
parents:
2135
diff
changeset
|
729 ngx_http_html_default_types) |
723df5089c05
use hash in gzip_types, ssi_types, and sub_filter_types
Igor Sysoev <igor@sysoev.ru>
parents:
2135
diff
changeset
|
730 != NGX_OK) |
723df5089c05
use hash in gzip_types, ssi_types, and sub_filter_types
Igor Sysoev <igor@sysoev.ru>
parents:
2135
diff
changeset
|
731 { |
723df5089c05
use hash in gzip_types, ssi_types, and sub_filter_types
Igor Sysoev <igor@sysoev.ru>
parents:
2135
diff
changeset
|
732 return NGX_CONF_ERROR; |
1172 | 733 } |
734 | |
735 return NGX_CONF_OK; | |
736 } | |
737 | |
738 | |
739 static ngx_int_t | |
740 ngx_http_sub_filter_init(ngx_conf_t *cf) | |
741 { | |
742 ngx_http_next_header_filter = ngx_http_top_header_filter; | |
743 ngx_http_top_header_filter = ngx_http_sub_header_filter; | |
744 | |
745 ngx_http_next_body_filter = ngx_http_top_body_filter; | |
746 ngx_http_top_body_filter = ngx_http_sub_body_filter; | |
747 | |
748 return NGX_OK; | |
749 } |