Mercurial > hg > nginx-quic
comparison src/http/modules/ngx_http_chunked_filter.c @ 99:a059e1aa65d4
nginx-0.0.1-2003-06-02-19:24:30 import
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Mon, 02 Jun 2003 15:24:30 +0000 |
parents | |
children | 6dfda4cf5200 |
comparison
equal
deleted
inserted
replaced
98:c9b243802a17 | 99:a059e1aa65d4 |
---|---|
1 | |
2 #include <ngx_config.h> | |
3 #include <ngx_core.h> | |
4 #include <ngx_http.h> | |
5 | |
6 | |
7 static int ngx_http_chunked_filter_init(ngx_pool_t *pool); | |
8 | |
9 | |
10 static ngx_http_module_t ngx_http_chunked_filter_module_ctx = { | |
11 NULL, /* create main configuration */ | |
12 NULL, /* init main configuration */ | |
13 | |
14 NULL, /* create server configuration */ | |
15 NULL, /* merge server configuration */ | |
16 | |
17 NULL, /* create location configuration */ | |
18 NULL, /* merge location configuration */ | |
19 }; | |
20 | |
21 | |
22 ngx_module_t ngx_http_chunked_filter_module = { | |
23 NGX_MODULE, | |
24 &ngx_http_chunked_filter_module_ctx, /* module context */ | |
25 NULL, /* module directives */ | |
26 NGX_HTTP_MODULE, /* module type */ | |
27 ngx_http_chunked_filter_init /* init module */ | |
28 }; | |
29 | |
30 | |
31 static int (*next_header_filter) (ngx_http_request_t *r); | |
32 static int (*next_body_filter) (ngx_http_request_t *r, ngx_chain_t *ch); | |
33 | |
34 | |
35 static int ngx_http_chunked_header_filter(ngx_http_request_t *r) | |
36 { | |
37 if (r->headers_out.content_length == -1) { | |
38 if (r->http_version < NGX_HTTP_VERSION_11) { | |
39 r->keepalive = 0; | |
40 | |
41 } else { | |
42 r->chunked = 1; | |
43 } | |
44 } | |
45 | |
46 return next_header_filter(r); | |
47 } | |
48 | |
49 | |
50 static int ngx_http_chunked_body_filter(ngx_http_request_t *r, ngx_chain_t *in) | |
51 { | |
52 char *chunk; | |
53 size_t size, len; | |
54 ngx_hunk_t *h; | |
55 ngx_chain_t *out, *ce, *te, **le; | |
56 | |
57 if (in == NULL || !r->chunked) { | |
58 return next_body_filter(r, in); | |
59 } | |
60 | |
61 ngx_test_null(out, ngx_alloc_chain_entry(r->pool), NGX_ERROR); | |
62 le = &out->next; | |
63 | |
64 size = 0; | |
65 ce = in; | |
66 | |
67 for ( ;; ) { | |
68 | |
69 if (ce->hunk->type & NGX_HUNK_IN_MEMORY) { | |
70 size += ce->hunk->last - ce->hunk->pos; | |
71 } else { | |
72 size += (size_t) (ce->hunk->file_last - ce->hunk->file_pos); | |
73 } | |
74 | |
75 ngx_test_null(te, ngx_alloc_chain_entry(r->pool), NGX_ERROR); | |
76 te->hunk = ce->hunk; | |
77 *le = te; | |
78 le = &te->next; | |
79 | |
80 if (ce->next == NULL) { | |
81 break; | |
82 } | |
83 | |
84 ce = ce->next; | |
85 } | |
86 | |
87 ngx_test_null(chunk, ngx_palloc(r->pool, 11), NGX_ERROR); | |
88 len = ngx_snprintf(chunk, 11, "%x" CRLF, size); | |
89 | |
90 ngx_test_null(h, ngx_calloc_hunk(r->pool), NGX_ERROR); | |
91 h->type = NGX_HUNK_IN_MEMORY|NGX_HUNK_TEMP; | |
92 h->pos = chunk; | |
93 h->last = chunk + len; | |
94 | |
95 out->hunk = h; | |
96 | |
97 ngx_test_null(h, ngx_calloc_hunk(r->pool), NGX_ERROR); | |
98 | |
99 if (ce->hunk->type & NGX_HUNK_LAST) { | |
100 ce->hunk->type &= ~NGX_HUNK_LAST; | |
101 h->type = NGX_HUNK_IN_MEMORY|NGX_HUNK_MEMORY|NGX_HUNK_LAST; | |
102 h->pos = CRLF "0" CRLF CRLF; | |
103 h->last = h->pos + 7; | |
104 | |
105 } else { | |
106 h->type = NGX_HUNK_IN_MEMORY|NGX_HUNK_MEMORY; | |
107 h->pos = CRLF; | |
108 h->last = h->pos + 2; | |
109 } | |
110 | |
111 ngx_test_null(te, ngx_alloc_chain_entry(r->pool), NGX_ERROR); | |
112 te->hunk = h; | |
113 te->next = NULL; | |
114 *le = te; | |
115 | |
116 return next_body_filter(r, out); | |
117 } | |
118 | |
119 | |
120 static int ngx_http_chunked_filter_init(ngx_pool_t *pool) | |
121 { | |
122 next_header_filter = ngx_http_top_header_filter; | |
123 ngx_http_top_header_filter = ngx_http_chunked_header_filter; | |
124 | |
125 next_body_filter = ngx_http_top_body_filter; | |
126 ngx_http_top_body_filter = ngx_http_chunked_body_filter; | |
127 | |
128 return NGX_OK; | |
129 } |