Mercurial > hg > nginx
comparison src/http/modules/ngx_http_range_filter_module.c @ 963:78e70dae89f0
move ranges array to ngx_http_range_filter_ctx_t
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Fri, 29 Dec 2006 08:02:31 +0000 |
parents | 69754fb59ba1 |
children | d0fb2cc2a098 |
comparison
equal
deleted
inserted
replaced
962:69754fb59ba1 | 963:78e70dae89f0 |
---|---|
43 * "--0123456789--" CRLF | 43 * "--0123456789--" CRLF |
44 */ | 44 */ |
45 | 45 |
46 | 46 |
47 typedef struct { | 47 typedef struct { |
48 off_t offset; | 48 off_t start; |
49 ngx_str_t boundary_header; | 49 off_t end; |
50 ngx_str_t content_range; | |
51 } ngx_http_range_t; | |
52 | |
53 | |
54 typedef struct { | |
55 off_t offset; | |
56 ngx_str_t boundary_header; | |
57 ngx_array_t ranges; | |
50 } ngx_http_range_filter_ctx_t; | 58 } ngx_http_range_filter_ctx_t; |
51 | 59 |
52 | 60 |
53 static ngx_int_t ngx_http_range_header_filter_init(ngx_conf_t *cf); | 61 static ngx_int_t ngx_http_range_header_filter_init(ngx_conf_t *cf); |
54 static ngx_int_t ngx_http_range_body_filter_init(ngx_conf_t *cf); | 62 static ngx_int_t ngx_http_range_body_filter_init(ngx_conf_t *cf); |
158 r->headers_out.accept_ranges->value.data = (u_char *) "bytes"; | 166 r->headers_out.accept_ranges->value.data = (u_char *) "bytes"; |
159 | 167 |
160 return ngx_http_next_header_filter(r); | 168 return ngx_http_next_header_filter(r); |
161 } | 169 } |
162 | 170 |
163 if (ngx_array_init(&r->headers_out.ranges, r->pool, 2, | 171 ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_range_filter_ctx_t)); |
164 sizeof(ngx_http_range_t)) | 172 if (ctx == NULL) { |
173 return NGX_ERROR; | |
174 } | |
175 | |
176 if (ngx_array_init(&ctx->ranges, r->pool, 1, sizeof(ngx_http_range_t)) | |
165 == NGX_ERROR) | 177 == NGX_ERROR) |
166 { | 178 { |
167 return NGX_ERROR; | 179 return NGX_ERROR; |
168 } | 180 } |
169 | 181 |
201 } | 213 } |
202 | 214 |
203 while (*p == ' ') { p++; } | 215 while (*p == ' ') { p++; } |
204 | 216 |
205 if (*p == ',' || *p == '\0') { | 217 if (*p == ',' || *p == '\0') { |
206 range = ngx_array_push(&r->headers_out.ranges); | 218 range = ngx_array_push(&ctx->ranges); |
207 if (range == NULL) { | 219 if (range == NULL) { |
208 return NGX_ERROR; | 220 return NGX_ERROR; |
209 } | 221 } |
210 | 222 |
211 range->start = start; | 223 range->start = start; |
247 if (start > end) { | 259 if (start > end) { |
248 rc = NGX_HTTP_RANGE_NOT_SATISFIABLE; | 260 rc = NGX_HTTP_RANGE_NOT_SATISFIABLE; |
249 break; | 261 break; |
250 } | 262 } |
251 | 263 |
252 range = ngx_array_push(&r->headers_out.ranges); | 264 range = ngx_array_push(&ctx->ranges); |
253 if (range == NULL) { | 265 if (range == NULL) { |
254 return NGX_ERROR; | 266 return NGX_ERROR; |
255 } | 267 } |
256 | 268 |
257 range->start = start; | 269 range->start = start; |
275 if (rc) { | 287 if (rc) { |
276 | 288 |
277 /* rc == NGX_HTTP_RANGE_NOT_SATISFIABLE */ | 289 /* rc == NGX_HTTP_RANGE_NOT_SATISFIABLE */ |
278 | 290 |
279 r->headers_out.status = rc; | 291 r->headers_out.status = rc; |
280 r->headers_out.ranges.nelts = 0; | |
281 | 292 |
282 content_range = ngx_list_push(&r->headers_out.headers); | 293 content_range = ngx_list_push(&r->headers_out.headers); |
283 if (content_range == NULL) { | 294 if (content_range == NULL) { |
284 return NGX_ERROR; | 295 return NGX_ERROR; |
285 } | 296 } |
304 ngx_http_clear_content_length(r); | 315 ngx_http_clear_content_length(r); |
305 | 316 |
306 return rc; | 317 return rc; |
307 } | 318 } |
308 | 319 |
309 | |
310 ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_range_filter_ctx_t)); | |
311 if (ctx == NULL) { | |
312 return NGX_ERROR; | |
313 } | |
314 | |
315 ngx_http_set_ctx(r, ctx, ngx_http_range_body_filter_module); | 320 ngx_http_set_ctx(r, ctx, ngx_http_range_body_filter_module); |
316 | 321 |
317 | |
318 r->headers_out.status = NGX_HTTP_PARTIAL_CONTENT; | 322 r->headers_out.status = NGX_HTTP_PARTIAL_CONTENT; |
319 | 323 |
320 if (r->headers_out.ranges.nelts == 1) { | 324 if (ctx->ranges.nelts == 1) { |
321 | 325 |
322 content_range = ngx_list_push(&r->headers_out.headers); | 326 content_range = ngx_list_push(&r->headers_out.headers); |
323 if (content_range == NULL) { | 327 if (content_range == NULL) { |
324 return NGX_ERROR; | 328 return NGX_ERROR; |
325 } | 329 } |
423 | 427 |
424 /* the size of the last boundary CRLF "--0123456789--" CRLF */ | 428 /* the size of the last boundary CRLF "--0123456789--" CRLF */ |
425 | 429 |
426 len = sizeof(CRLF "--") - 1 + NGX_ATOMIC_T_LEN + sizeof("--" CRLF) - 1; | 430 len = sizeof(CRLF "--") - 1 + NGX_ATOMIC_T_LEN + sizeof("--" CRLF) - 1; |
427 | 431 |
428 range = r->headers_out.ranges.elts; | 432 range = ctx->ranges.elts; |
429 for (i = 0; i < r->headers_out.ranges.nelts; i++) { | 433 for (i = 0; i < ctx->ranges.nelts; i++) { |
430 | 434 |
431 /* the size of the range: "SSSS-EEEE/TTTT" CRLF CRLF */ | 435 /* the size of the range: "SSSS-EEEE/TTTT" CRLF CRLF */ |
432 | 436 |
433 range[i].content_range.data = | 437 range[i].content_range.data = |
434 ngx_palloc(r->pool, 3 * NGX_OFF_T_LEN + 2 + 4); | 438 ngx_palloc(r->pool, 3 * NGX_OFF_T_LEN + 2 + 4); |
466 ngx_uint_t i; | 470 ngx_uint_t i; |
467 ngx_chain_t *out, *hcl, *rcl, *dcl, **ll; | 471 ngx_chain_t *out, *hcl, *rcl, *dcl, **ll; |
468 ngx_http_range_t *range; | 472 ngx_http_range_t *range; |
469 ngx_http_range_filter_ctx_t *ctx; | 473 ngx_http_range_filter_ctx_t *ctx; |
470 | 474 |
471 if (in == NULL || r->headers_out.ranges.nelts == 0) { | 475 if (in == NULL) { |
476 return ngx_http_next_body_filter(r, in); | |
477 } | |
478 | |
479 ctx = ngx_http_get_module_ctx(r, ngx_http_range_body_filter_module); | |
480 | |
481 if (ctx == NULL) { | |
472 return ngx_http_next_body_filter(r, in); | 482 return ngx_http_next_body_filter(r, in); |
473 } | 483 } |
474 | 484 |
475 buf = in->buf; | 485 buf = in->buf; |
476 | 486 |
477 if (ngx_buf_special(in->buf)) { | 487 if (ngx_buf_special(in->buf)) { |
478 return ngx_http_next_body_filter(r, in); | 488 return ngx_http_next_body_filter(r, in); |
479 } | 489 } |
480 | 490 |
481 ctx = ngx_http_get_module_ctx(r, ngx_http_range_body_filter_module); | |
482 if (ctx->offset) { | 491 if (ctx->offset) { |
483 goto overlapped; | 492 goto overlapped; |
484 } | 493 } |
485 | 494 |
486 range = r->headers_out.ranges.elts; | 495 range = ctx->ranges.elts; |
487 | 496 |
488 if (!buf->last_buf) { | 497 if (!buf->last_buf) { |
489 | 498 |
490 if (buf->in_file) { | 499 if (buf->in_file) { |
491 start = buf->file_pos + ctx->offset; | 500 start = buf->file_pos + ctx->offset; |
494 } else { | 503 } else { |
495 start = buf->pos - buf->start + ctx->offset; | 504 start = buf->pos - buf->start + ctx->offset; |
496 last = buf->last - buf->start + ctx->offset; | 505 last = buf->last - buf->start + ctx->offset; |
497 } | 506 } |
498 | 507 |
499 for (i = 0; i < r->headers_out.ranges.nelts; i++) { | 508 for (i = 0; i < ctx->ranges.nelts; i++) { |
500 if (start > range[i].start || last < range[i].end) { | 509 if (start > range[i].start || last < range[i].end) { |
501 goto overlapped; | 510 goto overlapped; |
502 } | 511 } |
503 } | 512 } |
504 } | 513 } |
508 * that are passed in the single buffer | 517 * that are passed in the single buffer |
509 */ | 518 */ |
510 | 519 |
511 ctx->offset = ngx_buf_size(buf); | 520 ctx->offset = ngx_buf_size(buf); |
512 | 521 |
513 if (r->headers_out.ranges.nelts == 1) { | 522 if (ctx->ranges.nelts == 1) { |
514 | 523 |
515 if (buf->in_file) { | 524 if (buf->in_file) { |
516 buf->file_pos = range->start; | 525 buf->file_pos = range->start; |
517 buf->file_last = range->end; | 526 buf->file_last = range->end; |
518 } | 527 } |
525 return ngx_http_next_body_filter(r, in); | 534 return ngx_http_next_body_filter(r, in); |
526 } | 535 } |
527 | 536 |
528 ll = &out; | 537 ll = &out; |
529 | 538 |
530 for (i = 0; i < r->headers_out.ranges.nelts; i++) { | 539 for (i = 0; i < ctx->ranges.nelts; i++) { |
531 | 540 |
532 /* | 541 /* |
533 * The boundary header of the range: | 542 * The boundary header of the range: |
534 * CRLF | 543 * CRLF |
535 * "--0123456789" CRLF | 544 * "--0123456789" CRLF |