Mercurial > hg > nginx-quic
annotate src/http/modules/ngx_http_slice_filter_module.c @ 7726:f388c0ad3477 quic
Added processing of client transport parameters.
note:
+ parameters are available in SSL connection since they are obtained by ssl
stack
quote:
During connection establishment, both endpoints make authenticated
declarations of their transport parameters. These declarations are
made unilaterally by each endpoint.
and really, we send our parameters before we read client's.
no handling of incoming parameters is made by this patch.
author | Vladimir Homutov <vl@nginx.com> |
---|---|
date | Sat, 21 Mar 2020 20:51:59 +0300 |
parents | f583559aadc7 |
children | 32a343635b50 |
rev | line source |
---|---|
6317 | 1 |
2 /* | |
3 * Copyright (C) Roman Arutyunyan | |
4 * Copyright (C) Nginx, Inc. | |
5 */ | |
6 | |
7 | |
8 #include <ngx_config.h> | |
9 #include <ngx_core.h> | |
10 #include <ngx_http.h> | |
11 | |
12 | |
13 typedef struct { | |
6962
a97ad1663ef4
Slice filter: allowed at most one subrequest at a time.
Roman Arutyunyan <arut@nginx.com>
parents:
6907
diff
changeset
|
14 size_t size; |
6317 | 15 } ngx_http_slice_loc_conf_t; |
16 | |
17 | |
18 typedef struct { | |
6962
a97ad1663ef4
Slice filter: allowed at most one subrequest at a time.
Roman Arutyunyan <arut@nginx.com>
parents:
6907
diff
changeset
|
19 off_t start; |
a97ad1663ef4
Slice filter: allowed at most one subrequest at a time.
Roman Arutyunyan <arut@nginx.com>
parents:
6907
diff
changeset
|
20 off_t end; |
a97ad1663ef4
Slice filter: allowed at most one subrequest at a time.
Roman Arutyunyan <arut@nginx.com>
parents:
6907
diff
changeset
|
21 ngx_str_t range; |
a97ad1663ef4
Slice filter: allowed at most one subrequest at a time.
Roman Arutyunyan <arut@nginx.com>
parents:
6907
diff
changeset
|
22 ngx_str_t etag; |
6963
3ff293cfdab8
Slice filter: prevented slice redirection (ticket #1219).
Roman Arutyunyan <arut@nginx.com>
parents:
6962
diff
changeset
|
23 unsigned last:1; |
3ff293cfdab8
Slice filter: prevented slice redirection (ticket #1219).
Roman Arutyunyan <arut@nginx.com>
parents:
6962
diff
changeset
|
24 unsigned active:1; |
6962
a97ad1663ef4
Slice filter: allowed at most one subrequest at a time.
Roman Arutyunyan <arut@nginx.com>
parents:
6907
diff
changeset
|
25 ngx_http_request_t *sr; |
6317 | 26 } ngx_http_slice_ctx_t; |
27 | |
28 | |
29 typedef struct { | |
6962
a97ad1663ef4
Slice filter: allowed at most one subrequest at a time.
Roman Arutyunyan <arut@nginx.com>
parents:
6907
diff
changeset
|
30 off_t start; |
a97ad1663ef4
Slice filter: allowed at most one subrequest at a time.
Roman Arutyunyan <arut@nginx.com>
parents:
6907
diff
changeset
|
31 off_t end; |
a97ad1663ef4
Slice filter: allowed at most one subrequest at a time.
Roman Arutyunyan <arut@nginx.com>
parents:
6907
diff
changeset
|
32 off_t complete_length; |
6317 | 33 } ngx_http_slice_content_range_t; |
34 | |
35 | |
36 static ngx_int_t ngx_http_slice_header_filter(ngx_http_request_t *r); | |
37 static ngx_int_t ngx_http_slice_body_filter(ngx_http_request_t *r, | |
38 ngx_chain_t *in); | |
39 static ngx_int_t ngx_http_slice_parse_content_range(ngx_http_request_t *r, | |
40 ngx_http_slice_content_range_t *cr); | |
41 static ngx_int_t ngx_http_slice_range_variable(ngx_http_request_t *r, | |
42 ngx_http_variable_value_t *v, uintptr_t data); | |
43 static off_t ngx_http_slice_get_start(ngx_http_request_t *r); | |
44 static void *ngx_http_slice_create_loc_conf(ngx_conf_t *cf); | |
45 static char *ngx_http_slice_merge_loc_conf(ngx_conf_t *cf, void *parent, | |
46 void *child); | |
47 static ngx_int_t ngx_http_slice_add_variables(ngx_conf_t *cf); | |
48 static ngx_int_t ngx_http_slice_init(ngx_conf_t *cf); | |
49 | |
50 | |
51 static ngx_command_t ngx_http_slice_filter_commands[] = { | |
52 | |
53 { ngx_string("slice"), | |
54 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, | |
55 ngx_conf_set_size_slot, | |
56 NGX_HTTP_LOC_CONF_OFFSET, | |
57 offsetof(ngx_http_slice_loc_conf_t, size), | |
58 NULL }, | |
59 | |
60 ngx_null_command | |
61 }; | |
62 | |
63 | |
64 static ngx_http_module_t ngx_http_slice_filter_module_ctx = { | |
65 ngx_http_slice_add_variables, /* preconfiguration */ | |
66 ngx_http_slice_init, /* postconfiguration */ | |
67 | |
68 NULL, /* create main configuration */ | |
69 NULL, /* init main configuration */ | |
70 | |
71 NULL, /* create server configuration */ | |
72 NULL, /* merge server configuration */ | |
73 | |
74 ngx_http_slice_create_loc_conf, /* create location configuration */ | |
75 ngx_http_slice_merge_loc_conf /* merge location configuration */ | |
76 }; | |
77 | |
78 | |
79 ngx_module_t ngx_http_slice_filter_module = { | |
80 NGX_MODULE_V1, | |
81 &ngx_http_slice_filter_module_ctx, /* module context */ | |
82 ngx_http_slice_filter_commands, /* module directives */ | |
83 NGX_HTTP_MODULE, /* module type */ | |
84 NULL, /* init master */ | |
85 NULL, /* init module */ | |
86 NULL, /* init process */ | |
87 NULL, /* init thread */ | |
88 NULL, /* exit thread */ | |
89 NULL, /* exit process */ | |
90 NULL, /* exit master */ | |
91 NGX_MODULE_V1_PADDING | |
92 }; | |
93 | |
94 | |
95 static ngx_str_t ngx_http_slice_range_name = ngx_string("slice_range"); | |
96 | |
97 static ngx_http_output_header_filter_pt ngx_http_next_header_filter; | |
98 static ngx_http_output_body_filter_pt ngx_http_next_body_filter; | |
99 | |
100 | |
101 static ngx_int_t | |
102 ngx_http_slice_header_filter(ngx_http_request_t *r) | |
103 { | |
104 off_t end; | |
105 ngx_int_t rc; | |
106 ngx_table_elt_t *h; | |
107 ngx_http_slice_ctx_t *ctx; | |
108 ngx_http_slice_loc_conf_t *slcf; | |
109 ngx_http_slice_content_range_t cr; | |
110 | |
111 ctx = ngx_http_get_module_ctx(r, ngx_http_slice_filter_module); | |
112 if (ctx == NULL) { | |
113 return ngx_http_next_header_filter(r); | |
114 } | |
115 | |
116 if (r->headers_out.status != NGX_HTTP_PARTIAL_CONTENT) { | |
117 if (r == r->main) { | |
118 ngx_http_set_ctx(r, NULL, ngx_http_slice_filter_module); | |
119 return ngx_http_next_header_filter(r); | |
120 } | |
121 | |
122 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, | |
123 "unexpected status code %ui in slice response", | |
124 r->headers_out.status); | |
125 return NGX_ERROR; | |
126 } | |
127 | |
128 h = r->headers_out.etag; | |
129 | |
130 if (ctx->etag.len) { | |
131 if (h == NULL | |
132 || h->value.len != ctx->etag.len | |
133 || ngx_strncmp(h->value.data, ctx->etag.data, ctx->etag.len) | |
134 != 0) | |
135 { | |
136 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, | |
137 "etag mismatch in slice response"); | |
138 return NGX_ERROR; | |
139 } | |
140 } | |
141 | |
142 if (h) { | |
143 ctx->etag = h->value; | |
144 } | |
145 | |
146 if (ngx_http_slice_parse_content_range(r, &cr) != NGX_OK) { | |
147 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, | |
148 "invalid range in slice response"); | |
149 return NGX_ERROR; | |
150 } | |
151 | |
152 if (cr.complete_length == -1) { | |
153 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, | |
154 "no complete length in slice response"); | |
155 return NGX_ERROR; | |
156 } | |
157 | |
158 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
159 "http slice response range: %O-%O/%O", | |
160 cr.start, cr.end, cr.complete_length); | |
161 | |
162 slcf = ngx_http_get_module_loc_conf(r, ngx_http_slice_filter_module); | |
163 | |
164 end = ngx_min(cr.start + (off_t) slcf->size, cr.complete_length); | |
165 | |
166 if (cr.start != ctx->start || cr.end != end) { | |
167 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, | |
168 "unexpected range in slice response: %O-%O", | |
169 cr.start, cr.end); | |
170 return NGX_ERROR; | |
171 } | |
172 | |
173 ctx->start = end; | |
6963
3ff293cfdab8
Slice filter: prevented slice redirection (ticket #1219).
Roman Arutyunyan <arut@nginx.com>
parents:
6962
diff
changeset
|
174 ctx->active = 1; |
6317 | 175 |
176 r->headers_out.status = NGX_HTTP_OK; | |
177 r->headers_out.status_line.len = 0; | |
178 r->headers_out.content_length_n = cr.complete_length; | |
179 r->headers_out.content_offset = cr.start; | |
180 r->headers_out.content_range->hash = 0; | |
181 r->headers_out.content_range = NULL; | |
182 | |
183 r->allow_ranges = 1; | |
184 r->subrequest_ranges = 1; | |
185 r->single_range = 1; | |
186 | |
187 rc = ngx_http_next_header_filter(r); | |
188 | |
189 if (r != r->main) { | |
190 return rc; | |
191 } | |
192 | |
7070
f583559aadc7
Upstream: keep request body file from removal if requested.
Roman Arutyunyan <arut@nginx.com>
parents:
7067
diff
changeset
|
193 r->preserve_body = 1; |
f583559aadc7
Upstream: keep request body file from removal if requested.
Roman Arutyunyan <arut@nginx.com>
parents:
7067
diff
changeset
|
194 |
6317 | 195 if (r->headers_out.status == NGX_HTTP_PARTIAL_CONTENT) { |
196 if (ctx->start + (off_t) slcf->size <= r->headers_out.content_offset) { | |
197 ctx->start = slcf->size | |
198 * (r->headers_out.content_offset / slcf->size); | |
199 } | |
200 | |
201 ctx->end = r->headers_out.content_offset | |
202 + r->headers_out.content_length_n; | |
203 | |
204 } else { | |
205 ctx->end = cr.complete_length; | |
206 } | |
207 | |
208 return rc; | |
209 } | |
210 | |
211 | |
212 static ngx_int_t | |
213 ngx_http_slice_body_filter(ngx_http_request_t *r, ngx_chain_t *in) | |
214 { | |
215 ngx_int_t rc; | |
216 ngx_chain_t *cl; | |
217 ngx_http_slice_ctx_t *ctx; | |
218 ngx_http_slice_loc_conf_t *slcf; | |
219 | |
220 ctx = ngx_http_get_module_ctx(r, ngx_http_slice_filter_module); | |
221 | |
222 if (ctx == NULL || r != r->main) { | |
223 return ngx_http_next_body_filter(r, in); | |
224 } | |
225 | |
226 for (cl = in; cl; cl = cl->next) { | |
227 if (cl->buf->last_buf) { | |
228 cl->buf->last_buf = 0; | |
6322
4f0f4f02c98f
Slice filter: terminate first slice with last_in_chain flag.
Roman Arutyunyan <arut@nginx.com>
parents:
6321
diff
changeset
|
229 cl->buf->last_in_chain = 1; |
6317 | 230 cl->buf->sync = 1; |
231 ctx->last = 1; | |
232 } | |
233 } | |
234 | |
235 rc = ngx_http_next_body_filter(r, in); | |
236 | |
237 if (rc == NGX_ERROR || !ctx->last) { | |
238 return rc; | |
239 } | |
240 | |
6962
a97ad1663ef4
Slice filter: allowed at most one subrequest at a time.
Roman Arutyunyan <arut@nginx.com>
parents:
6907
diff
changeset
|
241 if (ctx->sr && !ctx->sr->done) { |
a97ad1663ef4
Slice filter: allowed at most one subrequest at a time.
Roman Arutyunyan <arut@nginx.com>
parents:
6907
diff
changeset
|
242 return rc; |
a97ad1663ef4
Slice filter: allowed at most one subrequest at a time.
Roman Arutyunyan <arut@nginx.com>
parents:
6907
diff
changeset
|
243 } |
a97ad1663ef4
Slice filter: allowed at most one subrequest at a time.
Roman Arutyunyan <arut@nginx.com>
parents:
6907
diff
changeset
|
244 |
6963
3ff293cfdab8
Slice filter: prevented slice redirection (ticket #1219).
Roman Arutyunyan <arut@nginx.com>
parents:
6962
diff
changeset
|
245 if (!ctx->active) { |
3ff293cfdab8
Slice filter: prevented slice redirection (ticket #1219).
Roman Arutyunyan <arut@nginx.com>
parents:
6962
diff
changeset
|
246 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, |
3ff293cfdab8
Slice filter: prevented slice redirection (ticket #1219).
Roman Arutyunyan <arut@nginx.com>
parents:
6962
diff
changeset
|
247 "missing slice response"); |
3ff293cfdab8
Slice filter: prevented slice redirection (ticket #1219).
Roman Arutyunyan <arut@nginx.com>
parents:
6962
diff
changeset
|
248 return NGX_ERROR; |
3ff293cfdab8
Slice filter: prevented slice redirection (ticket #1219).
Roman Arutyunyan <arut@nginx.com>
parents:
6962
diff
changeset
|
249 } |
3ff293cfdab8
Slice filter: prevented slice redirection (ticket #1219).
Roman Arutyunyan <arut@nginx.com>
parents:
6962
diff
changeset
|
250 |
6317 | 251 if (ctx->start >= ctx->end) { |
252 ngx_http_set_ctx(r, NULL, ngx_http_slice_filter_module); | |
253 ngx_http_send_special(r, NGX_HTTP_LAST); | |
254 return rc; | |
255 } | |
256 | |
6321
bc9ea464e354
Slice filter: never run subrequests when main request is buffered.
Roman Arutyunyan <arut@nginx.com>
parents:
6317
diff
changeset
|
257 if (r->buffered) { |
bc9ea464e354
Slice filter: never run subrequests when main request is buffered.
Roman Arutyunyan <arut@nginx.com>
parents:
6317
diff
changeset
|
258 return rc; |
bc9ea464e354
Slice filter: never run subrequests when main request is buffered.
Roman Arutyunyan <arut@nginx.com>
parents:
6317
diff
changeset
|
259 } |
bc9ea464e354
Slice filter: never run subrequests when main request is buffered.
Roman Arutyunyan <arut@nginx.com>
parents:
6317
diff
changeset
|
260 |
6962
a97ad1663ef4
Slice filter: allowed at most one subrequest at a time.
Roman Arutyunyan <arut@nginx.com>
parents:
6907
diff
changeset
|
261 if (ngx_http_subrequest(r, &r->uri, &r->args, &ctx->sr, NULL, |
6907
d16ba0ea3434
Slice filter: fetch slices in cloned subrequests.
Roman Arutyunyan <arut@nginx.com>
parents:
6322
diff
changeset
|
262 NGX_HTTP_SUBREQUEST_CLONE) |
d16ba0ea3434
Slice filter: fetch slices in cloned subrequests.
Roman Arutyunyan <arut@nginx.com>
parents:
6322
diff
changeset
|
263 != NGX_OK) |
d16ba0ea3434
Slice filter: fetch slices in cloned subrequests.
Roman Arutyunyan <arut@nginx.com>
parents:
6322
diff
changeset
|
264 { |
6317 | 265 return NGX_ERROR; |
266 } | |
267 | |
6962
a97ad1663ef4
Slice filter: allowed at most one subrequest at a time.
Roman Arutyunyan <arut@nginx.com>
parents:
6907
diff
changeset
|
268 ngx_http_set_ctx(ctx->sr, ctx, ngx_http_slice_filter_module); |
6317 | 269 |
270 slcf = ngx_http_get_module_loc_conf(r, ngx_http_slice_filter_module); | |
271 | |
272 ctx->range.len = ngx_sprintf(ctx->range.data, "bytes=%O-%O", ctx->start, | |
273 ctx->start + (off_t) slcf->size - 1) | |
274 - ctx->range.data; | |
275 | |
6963
3ff293cfdab8
Slice filter: prevented slice redirection (ticket #1219).
Roman Arutyunyan <arut@nginx.com>
parents:
6962
diff
changeset
|
276 ctx->active = 0; |
3ff293cfdab8
Slice filter: prevented slice redirection (ticket #1219).
Roman Arutyunyan <arut@nginx.com>
parents:
6962
diff
changeset
|
277 |
6317 | 278 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
279 "http slice subrequest: \"%V\"", &ctx->range); | |
280 | |
281 return rc; | |
282 } | |
283 | |
284 | |
285 static ngx_int_t | |
286 ngx_http_slice_parse_content_range(ngx_http_request_t *r, | |
287 ngx_http_slice_content_range_t *cr) | |
288 { | |
289 off_t start, end, complete_length, cutoff, cutlim; | |
290 u_char *p; | |
291 ngx_table_elt_t *h; | |
292 | |
293 h = r->headers_out.content_range; | |
294 | |
295 if (h == NULL | |
296 || h->value.len < 7 | |
297 || ngx_strncmp(h->value.data, "bytes ", 6) != 0) | |
298 { | |
299 return NGX_ERROR; | |
300 } | |
301 | |
302 p = h->value.data + 6; | |
303 | |
304 cutoff = NGX_MAX_OFF_T_VALUE / 10; | |
305 cutlim = NGX_MAX_OFF_T_VALUE % 10; | |
306 | |
307 start = 0; | |
308 end = 0; | |
309 complete_length = 0; | |
310 | |
311 while (*p == ' ') { p++; } | |
312 | |
313 if (*p < '0' || *p > '9') { | |
314 return NGX_ERROR; | |
315 } | |
316 | |
317 while (*p >= '0' && *p <= '9') { | |
318 if (start >= cutoff && (start > cutoff || *p - '0' > cutlim)) { | |
319 return NGX_ERROR; | |
320 } | |
321 | |
7067
e3723f2a11b7
Parenthesized ASCII-related calculations.
Valentin Bartenev <vbart@nginx.com>
parents:
6963
diff
changeset
|
322 start = start * 10 + (*p++ - '0'); |
6317 | 323 } |
324 | |
325 while (*p == ' ') { p++; } | |
326 | |
327 if (*p++ != '-') { | |
328 return NGX_ERROR; | |
329 } | |
330 | |
331 while (*p == ' ') { p++; } | |
332 | |
333 if (*p < '0' || *p > '9') { | |
334 return NGX_ERROR; | |
335 } | |
336 | |
337 while (*p >= '0' && *p <= '9') { | |
338 if (end >= cutoff && (end > cutoff || *p - '0' > cutlim)) { | |
339 return NGX_ERROR; | |
340 } | |
341 | |
7067
e3723f2a11b7
Parenthesized ASCII-related calculations.
Valentin Bartenev <vbart@nginx.com>
parents:
6963
diff
changeset
|
342 end = end * 10 + (*p++ - '0'); |
6317 | 343 } |
344 | |
345 end++; | |
346 | |
347 while (*p == ' ') { p++; } | |
348 | |
349 if (*p++ != '/') { | |
350 return NGX_ERROR; | |
351 } | |
352 | |
353 while (*p == ' ') { p++; } | |
354 | |
355 if (*p != '*') { | |
356 if (*p < '0' || *p > '9') { | |
357 return NGX_ERROR; | |
358 } | |
359 | |
360 while (*p >= '0' && *p <= '9') { | |
361 if (complete_length >= cutoff | |
362 && (complete_length > cutoff || *p - '0' > cutlim)) | |
363 { | |
364 return NGX_ERROR; | |
365 } | |
366 | |
7067
e3723f2a11b7
Parenthesized ASCII-related calculations.
Valentin Bartenev <vbart@nginx.com>
parents:
6963
diff
changeset
|
367 complete_length = complete_length * 10 + (*p++ - '0'); |
6317 | 368 } |
369 | |
370 } else { | |
371 complete_length = -1; | |
372 p++; | |
373 } | |
374 | |
375 while (*p == ' ') { p++; } | |
376 | |
377 if (*p != '\0') { | |
378 return NGX_ERROR; | |
379 } | |
380 | |
381 cr->start = start; | |
382 cr->end = end; | |
383 cr->complete_length = complete_length; | |
384 | |
385 return NGX_OK; | |
386 } | |
387 | |
388 | |
389 static ngx_int_t | |
390 ngx_http_slice_range_variable(ngx_http_request_t *r, | |
391 ngx_http_variable_value_t *v, uintptr_t data) | |
392 { | |
393 u_char *p; | |
394 ngx_http_slice_ctx_t *ctx; | |
395 ngx_http_slice_loc_conf_t *slcf; | |
396 | |
397 ctx = ngx_http_get_module_ctx(r, ngx_http_slice_filter_module); | |
398 | |
399 if (ctx == NULL) { | |
400 if (r != r->main || r->headers_out.status) { | |
401 v->not_found = 1; | |
402 return NGX_OK; | |
403 } | |
404 | |
405 slcf = ngx_http_get_module_loc_conf(r, ngx_http_slice_filter_module); | |
406 | |
407 if (slcf->size == 0) { | |
408 v->not_found = 1; | |
409 return NGX_OK; | |
410 } | |
411 | |
412 ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_slice_ctx_t)); | |
413 if (ctx == NULL) { | |
414 return NGX_ERROR; | |
415 } | |
416 | |
417 ngx_http_set_ctx(r, ctx, ngx_http_slice_filter_module); | |
418 | |
419 p = ngx_pnalloc(r->pool, sizeof("bytes=-") - 1 + 2 * NGX_OFF_T_LEN); | |
420 if (p == NULL) { | |
421 return NGX_ERROR; | |
422 } | |
423 | |
424 ctx->start = slcf->size * (ngx_http_slice_get_start(r) / slcf->size); | |
425 | |
426 ctx->range.data = p; | |
427 ctx->range.len = ngx_sprintf(p, "bytes=%O-%O", ctx->start, | |
428 ctx->start + (off_t) slcf->size - 1) | |
429 - p; | |
430 } | |
431 | |
432 v->data = ctx->range.data; | |
433 v->valid = 1; | |
434 v->not_found = 0; | |
435 v->no_cacheable = 1; | |
436 v->len = ctx->range.len; | |
437 | |
438 return NGX_OK; | |
439 } | |
440 | |
441 | |
442 static off_t | |
443 ngx_http_slice_get_start(ngx_http_request_t *r) | |
444 { | |
445 off_t start, cutoff, cutlim; | |
446 u_char *p; | |
447 ngx_table_elt_t *h; | |
448 | |
449 if (r->headers_in.if_range) { | |
450 return 0; | |
451 } | |
452 | |
453 h = r->headers_in.range; | |
454 | |
455 if (h == NULL | |
456 || h->value.len < 7 | |
457 || ngx_strncasecmp(h->value.data, (u_char *) "bytes=", 6) != 0) | |
458 { | |
459 return 0; | |
460 } | |
461 | |
462 p = h->value.data + 6; | |
463 | |
464 if (ngx_strchr(p, ',')) { | |
465 return 0; | |
466 } | |
467 | |
468 while (*p == ' ') { p++; } | |
469 | |
470 if (*p == '-') { | |
471 return 0; | |
472 } | |
473 | |
474 cutoff = NGX_MAX_OFF_T_VALUE / 10; | |
475 cutlim = NGX_MAX_OFF_T_VALUE % 10; | |
476 | |
477 start = 0; | |
478 | |
479 while (*p >= '0' && *p <= '9') { | |
480 if (start >= cutoff && (start > cutoff || *p - '0' > cutlim)) { | |
481 return 0; | |
482 } | |
483 | |
7067
e3723f2a11b7
Parenthesized ASCII-related calculations.
Valentin Bartenev <vbart@nginx.com>
parents:
6963
diff
changeset
|
484 start = start * 10 + (*p++ - '0'); |
6317 | 485 } |
486 | |
487 return start; | |
488 } | |
489 | |
490 | |
491 static void * | |
492 ngx_http_slice_create_loc_conf(ngx_conf_t *cf) | |
493 { | |
494 ngx_http_slice_loc_conf_t *slcf; | |
495 | |
496 slcf = ngx_palloc(cf->pool, sizeof(ngx_http_slice_loc_conf_t)); | |
497 if (slcf == NULL) { | |
498 return NULL; | |
499 } | |
500 | |
501 slcf->size = NGX_CONF_UNSET_SIZE; | |
502 | |
503 return slcf; | |
504 } | |
505 | |
506 | |
507 static char * | |
508 ngx_http_slice_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child) | |
509 { | |
510 ngx_http_slice_loc_conf_t *prev = parent; | |
511 ngx_http_slice_loc_conf_t *conf = child; | |
512 | |
513 ngx_conf_merge_size_value(conf->size, prev->size, 0); | |
514 | |
515 return NGX_CONF_OK; | |
516 } | |
517 | |
518 | |
519 static ngx_int_t | |
520 ngx_http_slice_add_variables(ngx_conf_t *cf) | |
521 { | |
522 ngx_http_variable_t *var; | |
523 | |
524 var = ngx_http_add_variable(cf, &ngx_http_slice_range_name, 0); | |
525 if (var == NULL) { | |
526 return NGX_ERROR; | |
527 } | |
528 | |
529 var->get_handler = ngx_http_slice_range_variable; | |
530 | |
531 return NGX_OK; | |
532 } | |
533 | |
534 | |
535 static ngx_int_t | |
536 ngx_http_slice_init(ngx_conf_t *cf) | |
537 { | |
538 ngx_http_next_header_filter = ngx_http_top_header_filter; | |
539 ngx_http_top_header_filter = ngx_http_slice_header_filter; | |
540 | |
541 ngx_http_next_body_filter = ngx_http_top_body_filter; | |
542 ngx_http_top_body_filter = ngx_http_slice_body_filter; | |
543 | |
544 return NGX_OK; | |
545 } |