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 }