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 }