Mercurial > hg > nginx
comparison src/http/modules/ngx_http_range_filter.c @ 155:46eb23d9471d
nginx-0.0.1-2003-10-22-20:38:26 import
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Wed, 22 Oct 2003 16:38:26 +0000 |
parents | c71aeb75c071 |
children | e7e094d34162 |
comparison
equal
deleted
inserted
replaced
154:eac26585476e | 155:46eb23d9471d |
---|---|
32 ngx_http_range_filter_init, /* init module */ | 32 ngx_http_range_filter_init, /* init module */ |
33 NULL /* init child */ | 33 NULL /* init child */ |
34 }; | 34 }; |
35 | 35 |
36 | 36 |
37 static int (*next_header_filter) (ngx_http_request_t *r); | 37 static ngx_http_output_header_filter_pt ngx_http_next_header_filter; |
38 static int (*next_body_filter) (ngx_http_request_t *r, ngx_chain_t *ch); | 38 static ngx_http_output_body_filter_pt ngx_http_next_body_filter; |
39 | 39 |
40 | 40 |
41 static int ngx_http_range_header_filter(ngx_http_request_t *r) | 41 static int ngx_http_range_header_filter(ngx_http_request_t *r) |
42 { | 42 { |
43 int rc, boundary, len, i; | 43 int rc, boundary, len, i; |
51 || r->headers_out.status != NGX_HTTP_OK | 51 || r->headers_out.status != NGX_HTTP_OK |
52 || r->headers_out.content_length_n == -1 | 52 || r->headers_out.content_length_n == -1 |
53 /* STUB: we currently support ranges for file hunks only */ | 53 /* STUB: we currently support ranges for file hunks only */ |
54 || r->filter & NGX_HTTP_FILTER_NEED_IN_MEMORY) | 54 || r->filter & NGX_HTTP_FILTER_NEED_IN_MEMORY) |
55 { | 55 { |
56 return next_header_filter(r); | 56 return ngx_http_next_header_filter(r); |
57 } | 57 } |
58 | 58 |
59 if (r->headers_in.range == NULL | 59 if (r->headers_in.range == NULL |
60 || r->headers_in.range->value.len < 7 | 60 || r->headers_in.range->value.len < 7 |
61 || ngx_strncasecmp(r->headers_in.range->value.data, "bytes=", 6) != 0) | 61 || ngx_strncasecmp(r->headers_in.range->value.data, "bytes=", 6) != 0) |
67 r->headers_out.accept_ranges->key.len = sizeof("Accept-Ranges") - 1; | 67 r->headers_out.accept_ranges->key.len = sizeof("Accept-Ranges") - 1; |
68 r->headers_out.accept_ranges->key.data = "Accept-Ranges"; | 68 r->headers_out.accept_ranges->key.data = "Accept-Ranges"; |
69 r->headers_out.accept_ranges->value.len = sizeof("bytes") - 1; | 69 r->headers_out.accept_ranges->value.len = sizeof("bytes") - 1; |
70 r->headers_out.accept_ranges->value.data = "bytes"; | 70 r->headers_out.accept_ranges->value.data = "bytes"; |
71 | 71 |
72 return next_header_filter(r); | 72 return ngx_http_next_header_filter(r); |
73 } | 73 } |
74 | 74 |
75 ngx_init_array(r->headers_out.ranges, r->pool, 5, sizeof(ngx_http_range_t), | 75 ngx_init_array(r->headers_out.ranges, r->pool, 5, sizeof(ngx_http_range_t), |
76 NGX_ERROR); | 76 NGX_ERROR); |
77 | 77 |
277 r->headers_out.content_length_n = len; | 277 r->headers_out.content_length_n = len; |
278 r->headers_out.content_length = NULL; | 278 r->headers_out.content_length = NULL; |
279 } | 279 } |
280 } | 280 } |
281 | 281 |
282 return next_header_filter(r); | 282 return ngx_http_next_header_filter(r); |
283 } | 283 } |
284 | 284 |
285 | 285 |
286 static int ngx_http_range_body_filter(ngx_http_request_t *r, ngx_chain_t *in) | 286 static int ngx_http_range_body_filter(ngx_http_request_t *r, ngx_chain_t *in) |
287 { | 287 { |
288 int i; | 288 int i; |
289 ngx_hunk_t *h; | 289 ngx_hunk_t *h; |
290 ngx_chain_t *out, *hce, *rce, *dce, **le; | 290 ngx_chain_t *out, *hcl, *rcl, *dcl, **ll; |
291 ngx_http_range_t *range; | 291 ngx_http_range_t *range; |
292 ngx_http_range_filter_ctx_t *ctx; | 292 ngx_http_range_filter_ctx_t *ctx; |
293 | 293 |
294 if (r->headers_out.ranges.nelts == 0) { | 294 if (r->headers_out.ranges.nelts == 0) { |
295 return next_body_filter(r, in); | 295 return ngx_http_next_body_filter(r, in); |
296 } | 296 } |
297 | 297 |
298 /* the optimized version for the static files only | 298 /* |
299 that are passed in the single file hunk */ | 299 * the optimized version for the static files only |
300 * that are passed in the single file hunk | |
301 */ | |
300 | 302 |
301 if (in | 303 if (in |
302 && in->hunk->type & NGX_HUNK_FILE | 304 && in->hunk->type & NGX_HUNK_FILE |
303 && in->hunk->type & NGX_HUNK_LAST) | 305 && in->hunk->type & NGX_HUNK_LAST) |
304 { | 306 { |
305 if (r->headers_out.ranges.nelts == 1) { | 307 if (r->headers_out.ranges.nelts == 1) { |
306 range = r->headers_out.ranges.elts; | 308 range = r->headers_out.ranges.elts; |
307 in->hunk->file_pos = range->start; | 309 in->hunk->file_pos = range->start; |
308 in->hunk->file_last = range->end; | 310 in->hunk->file_last = range->end; |
309 | 311 |
310 return next_body_filter(r, in); | 312 return ngx_http_next_body_filter(r, in); |
311 } | 313 } |
312 | 314 |
313 ctx = ngx_http_get_module_ctx(r, ngx_http_range_filter_module); | 315 ctx = ngx_http_get_module_ctx(r, ngx_http_range_filter_module); |
314 le = &out; | 316 ll = &out; |
315 | 317 |
316 range = r->headers_out.ranges.elts; | 318 range = r->headers_out.ranges.elts; |
317 for (i = 0; i < r->headers_out.ranges.nelts; i++) { | 319 for (i = 0; i < r->headers_out.ranges.nelts; i++) { |
318 | 320 |
319 ngx_test_null(h, ngx_calloc_hunk(r->pool), NGX_ERROR); | 321 ngx_test_null(h, ngx_calloc_hunk(r->pool), NGX_ERROR); |
320 h->type = NGX_HUNK_IN_MEMORY|NGX_HUNK_MEMORY; | 322 h->type = NGX_HUNK_IN_MEMORY|NGX_HUNK_MEMORY; |
321 h->pos = ctx->boundary_header.data; | 323 h->pos = ctx->boundary_header.data; |
322 h->last = ctx->boundary_header.data + ctx->boundary_header.len; | 324 h->last = ctx->boundary_header.data + ctx->boundary_header.len; |
323 | 325 |
324 ngx_test_null(hce, ngx_alloc_chain_entry(r->pool), NGX_ERROR); | 326 ngx_test_null(hcl, ngx_alloc_chain_link(r->pool), NGX_ERROR); |
325 hce->hunk = h; | 327 hcl->hunk = h; |
326 | 328 |
327 ngx_test_null(h, ngx_calloc_hunk(r->pool), NGX_ERROR); | 329 ngx_test_null(h, ngx_calloc_hunk(r->pool), NGX_ERROR); |
328 h->type = NGX_HUNK_IN_MEMORY|NGX_HUNK_TEMP; | 330 h->type = NGX_HUNK_IN_MEMORY|NGX_HUNK_TEMP; |
329 h->pos = range[i].content_range.data; | 331 h->pos = range[i].content_range.data; |
330 h->last = range[i].content_range.data + range[i].content_range.len; | 332 h->last = range[i].content_range.data + range[i].content_range.len; |
331 | 333 |
332 ngx_test_null(rce, ngx_alloc_chain_entry(r->pool), NGX_ERROR); | 334 ngx_test_null(rcl, ngx_alloc_chain_link(r->pool), NGX_ERROR); |
333 rce->hunk = h; | 335 rcl->hunk = h; |
334 | 336 |
335 ngx_test_null(h, ngx_calloc_hunk(r->pool), NGX_ERROR); | 337 ngx_test_null(h, ngx_calloc_hunk(r->pool), NGX_ERROR); |
336 h->type = NGX_HUNK_FILE; | 338 h->type = NGX_HUNK_FILE; |
337 h->file_pos = range[i].start; | 339 h->file_pos = range[i].start; |
338 h->file_last = range[i].end; | 340 h->file_last = range[i].end; |
339 h->file = in->hunk->file; | 341 h->file = in->hunk->file; |
340 | 342 |
341 ngx_test_null(dce, ngx_alloc_chain_entry(r->pool), NGX_ERROR); | 343 ngx_alloc_link_and_set_hunk(dcl, h, r->pool, NGX_ERROR); |
342 dce->hunk = h; | 344 |
343 dce->next = NULL; | 345 *ll = hcl; |
344 | 346 hcl->next = rcl; |
345 *le = hce; | 347 rcl->next = dcl; |
346 hce->next = rce; | 348 ll = &dcl->next; |
347 rce->next = dce; | |
348 le = &dce->next; | |
349 } | 349 } |
350 | 350 |
351 ngx_test_null(h, ngx_calloc_hunk(r->pool), NGX_ERROR); | 351 ngx_test_null(h, ngx_calloc_hunk(r->pool), NGX_ERROR); |
352 h->type = NGX_HUNK_IN_MEMORY|NGX_HUNK_TEMP|NGX_HUNK_LAST; | 352 h->type = NGX_HUNK_IN_MEMORY|NGX_HUNK_TEMP|NGX_HUNK_LAST; |
353 ngx_test_null(h->pos, ngx_palloc(r->pool, 4 + 10 + 4), NGX_ERROR); | 353 ngx_test_null(h->pos, ngx_palloc(r->pool, 4 + 10 + 4), NGX_ERROR); |
354 h->last = ngx_cpymem(h->pos, ctx->boundary_header.data, 4 + 10); | 354 h->last = ngx_cpymem(h->pos, ctx->boundary_header.data, 4 + 10); |
355 *h->last++ = '-'; *h->last++ = '-'; | 355 *h->last++ = '-'; *h->last++ = '-'; |
356 *h->last++ = CR; *h->last++ = LF; | 356 *h->last++ = CR; *h->last++ = LF; |
357 | 357 |
358 ngx_test_null(hce, ngx_alloc_chain_entry(r->pool), NGX_ERROR); | 358 ngx_alloc_link_and_set_hunk(hcl, h, r->pool, NGX_ERROR); |
359 hce->hunk = h; | 359 *ll = hcl; |
360 hce->next = NULL; | 360 |
361 *le = hce; | 361 return ngx_http_next_body_filter(r, out); |
362 | |
363 return next_body_filter(r, out); | |
364 } | 362 } |
365 | 363 |
366 /* TODO: several incoming hunks of proxied responses | 364 /* TODO: several incoming hunks of proxied responses |
367 and memory hunks on platforms that have no sendfile() */ | 365 and memory hunks on platforms that have no sendfile() */ |
368 | 366 |
369 return next_body_filter(r, in); | 367 return ngx_http_next_body_filter(r, in); |
370 } | 368 } |
371 | 369 |
372 | 370 |
373 static int ngx_http_range_filter_init(ngx_cycle_t *cycle) | 371 static int ngx_http_range_filter_init(ngx_cycle_t *cycle) |
374 { | 372 { |
375 next_header_filter = ngx_http_top_header_filter; | 373 ngx_http_next_header_filter = ngx_http_top_header_filter; |
376 ngx_http_top_header_filter = ngx_http_range_header_filter; | 374 ngx_http_top_header_filter = ngx_http_range_header_filter; |
377 | 375 |
378 next_body_filter = ngx_http_top_body_filter; | 376 ngx_http_next_body_filter = ngx_http_top_body_filter; |
379 ngx_http_top_body_filter = ngx_http_range_body_filter; | 377 ngx_http_top_body_filter = ngx_http_range_body_filter; |
380 | 378 |
381 return NGX_OK; | 379 return NGX_OK; |
382 } | 380 } |