Mercurial > hg > nginx
comparison src/http/ngx_http_header_filter.c @ 24:77c7629a2627
nginx-0.0.1-2002-12-10-21:05:12 import
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Tue, 10 Dec 2002 18:05:12 +0000 |
parents | d7908993fdeb |
children | 53cb81681040 |
comparison
equal
deleted
inserted
replaced
23:f540a63026c9 | 24:77c7629a2627 |
---|---|
2 #include <nginx.h> | 2 #include <nginx.h> |
3 | 3 |
4 #include <ngx_config.h> | 4 #include <ngx_config.h> |
5 #include <ngx_core.h> | 5 #include <ngx_core.h> |
6 #include <ngx_string.h> | 6 #include <ngx_string.h> |
7 #include <ngx_table.h> | |
7 #include <ngx_hunk.h> | 8 #include <ngx_hunk.h> |
8 #include <ngx_http.h> | 9 #include <ngx_http.h> |
9 | 10 |
10 | 11 |
11 typedef struct { | 12 #if 0 |
12 int len; | 13 |
13 char *line; | 14 ngx_http_module_t ngx_http_header_filter_module = { |
14 } line; | 15 NGX_HTTP_MODULE, |
16 | |
17 NULL, /* create server config */ | |
18 NULL, /* create location config */ | |
19 NULL, /* module directives */ | |
20 | |
21 NULL, /* init module */ | |
22 NULL, /* translate handler */ | |
23 | |
24 ngx_http_header_filter_init /* init output header filter */ | |
25 NULL /* init output body filter */ | |
26 }; | |
27 | |
28 #endif | |
15 | 29 |
16 | 30 |
17 static line http_codes[] = { | 31 static char server_string[] = "Server: " NGINX_VER CRLF; |
18 { 6, "200 OK" } | 32 |
33 | |
34 static ngx_str_t http_codes[] = { | |
35 { 6, "200 OK" }, | |
36 | |
37 { 21, "301 Moved Permanently" }, | |
38 | |
39 { 15, "400 Bad Request" }, | |
40 { 0, NULL }, | |
41 { 0, NULL }, | |
42 { 13, "403 Forbidden" }, | |
43 { 13, "404 Not Found" } | |
19 }; | 44 }; |
20 | 45 |
21 | 46 |
22 | 47 |
23 int ngx_http_header_filter(ngx_http_request_t *r) | 48 int ngx_http_header_filter(ngx_http_request_t *r) |
24 { | 49 { |
25 int status; | 50 int len, status, i; |
26 ngx_hunk_t *h; | 51 ngx_hunk_t *h; |
27 ngx_chain_t *ch; | 52 ngx_chain_t *ch; |
53 ngx_table_elt_t *header; | |
28 | 54 |
29 ngx_test_null(h, ngx_create_temp_hunk(r->pool, 1024, 0, 64), | 55 if (r->http_version < NGX_HTTP_VERSION_10) |
30 NGX_ERROR); | 56 return NGX_OK; |
31 | 57 |
32 status = r->headers_out.status - NGX_HTTP_OK; | 58 /* 9 is for "HTTP/1.1 ", 2 is for trailing "\r\n" |
59 and 2 is for end of header */ | |
60 len = 9 + 2 + 2; | |
33 | 61 |
62 /* status line */ | |
63 if (r->headers_out.status_line.len) { | |
64 len += r->headers_out.status_line.len; | |
65 } else { | |
66 if (r->headers_out.status < NGX_HTTP_MOVED_PERMANENTLY) | |
67 status = r->headers_out.status - NGX_HTTP_OK; | |
68 | |
69 else if (r->headers_out.status < NGX_HTTP_BAD_REQUEST) | |
70 status = r->headers_out.status - NGX_HTTP_MOVED_PERMANENTLY + 1; | |
71 | |
72 else | |
73 status = r->headers_out.status - NGX_HTTP_BAD_REQUEST + 1 + 1; | |
74 | |
75 len += http_codes[status].len; | |
76 } | |
77 | |
78 if (r->headers_out.server && r->headers_out.server->key.len) { | |
79 len += r->headers_out.server->key.len | |
80 + r->headers_out.server->value.len + 2; | |
81 } else { | |
82 len += sizeof(server_string) - 1; | |
83 } | |
84 | |
85 if (r->headers_out.date && r->headers_out.date->key.len) { | |
86 len += r->headers_out.date->key.len | |
87 + r->headers_out.date->value.len + 2; | |
88 } else { | |
89 /* "Date: ... \r\n"; */ | |
90 len += 37; | |
91 } | |
92 | |
93 /* 2^64 is 20 characters */ | |
94 if (r->headers_out.content_length >= 0) | |
95 len += 48; | |
96 | |
97 #if 0 | |
98 if (r->headers_out.content_type.len) | |
99 len += r->headers_out.content_type.len + 16; | |
100 #endif | |
101 | |
102 if (r->keepalive) | |
103 len += 24; | |
104 else | |
105 len += 19; | |
106 | |
107 header = (ngx_table_elt_t *) r->headers_out.headers->elts; | |
108 for (i = 0; i < r->headers_out.headers->nelts; i++) { | |
109 if (header[i].key.len == 0) | |
110 continue; | |
111 | |
112 len += header[i].key.len + 2 + header[i].value.len + 2; | |
113 } | |
114 | |
115 ngx_test_null(h, ngx_create_temp_hunk(r->pool, len, 0, 64), NGX_ERROR); | |
116 | |
117 /* "HTTP/1.1 " */ | |
34 ngx_memcpy(h->last.mem, "HTTP/1.1 ", 9); | 118 ngx_memcpy(h->last.mem, "HTTP/1.1 ", 9); |
35 h->last.mem += 9; | 119 h->last.mem += 9; |
36 ngx_memcpy(h->last.mem, http_codes[status].line, http_codes[status].len); | 120 |
37 h->last.mem += http_codes[status].len; | 121 /* status line */ |
122 if (r->headers_out.status_line.len) { | |
123 ngx_memcpy(h->last.mem, r->headers_out.status_line.data, | |
124 r->headers_out.status_line.len); | |
125 h->last.mem += r->headers_out.status_line.len; | |
126 | |
127 } else { | |
128 ngx_memcpy(h->last.mem, http_codes[status].data, | |
129 http_codes[status].len); | |
130 h->last.mem += http_codes[status].len; | |
131 } | |
38 *(h->last.mem++) = CR; *(h->last.mem++) = LF; | 132 *(h->last.mem++) = CR; *(h->last.mem++) = LF; |
39 | 133 |
40 #if 1 | 134 if (!(r->headers_out.server && r->headers_out.server->key.len)) { |
41 r->keepalive = 1; | 135 ngx_memcpy(h->last.mem, server_string, sizeof(server_string) - 1); |
42 ngx_memcpy(h->last.mem, "Connection: keep-alive" CRLF, 24); | 136 h->last.mem += sizeof(server_string) - 1; |
43 h->last.mem += 24; | 137 } |
138 | |
139 if (!(r->headers_out.date && r->headers_out.date->key.len)) { | |
140 ngx_memcpy(h->last.mem, "Date: ", 6); | |
141 h->last.mem += 6; | |
142 h->last.mem += ngx_http_get_time(h->last.mem, time(NULL)); | |
143 *(h->last.mem++) = CR; *(h->last.mem++) = LF; | |
144 } | |
145 | |
146 /* 2^64 is 20 characters */ | |
147 if (r->headers_out.content_length >= 0) | |
148 h->last.mem += ngx_snprintf(h->last.mem, 49, "Content-Length: %u" CRLF, | |
149 r->headers_out.content_length); | |
150 | |
151 #if 0 | |
152 if (r->headers_out.content_type.len) { | |
153 ngx_memcpy(h->last.mem, "Content-Type: ", 14); | |
154 h->last.mem += 14; | |
155 ngx_memcpy(h->last.mem, r->headers_out.content_type.data, | |
156 r->headers_out.content_type.len); | |
157 h->last.mem += r->headers_out.content_type.len; | |
158 *(h->last.mem++) = CR; *(h->last.mem++) = LF; | |
159 } | |
44 #endif | 160 #endif |
45 | 161 |
46 ngx_memcpy(h->last.mem, "Date: ", 6); | 162 if (r->keepalive) { |
47 h->last.mem += 6; | 163 ngx_memcpy(h->last.mem, "Connection: keep-alive" CRLF, 24); |
48 h->last.mem += ngx_http_get_time(h->last.mem, time(NULL)); | 164 h->last.mem += 24; |
49 *(h->last.mem++) = CR; *(h->last.mem++) = LF; | |
50 | |
51 /* 2^64 is 20 characters */ | |
52 if (r->headers_out.content_length) | |
53 h->last.mem += ngx_snprintf(h->last.mem, 49, "Content-Length: %d" CRLF, | |
54 r->headers_out.content_length); | |
55 | |
56 /* check */ | |
57 | |
58 if (r->headers_out.content_type) | |
59 h->last.mem += ngx_snprintf(h->last.mem, 100, "Content-Type: %s" CRLF, | |
60 r->headers_out.content_type); | |
61 | |
62 ngx_memcpy(h->last.mem, "Server: ", 8); | |
63 h->last.mem += 8; | |
64 if (r->headers_out.server) { | |
65 h->last.mem = ngx_cpystrn(h->last.mem, r->headers_out.server, | |
66 h->end - h->last.mem); | |
67 /* check space */ | |
68 | 165 |
69 } else { | 166 } else { |
70 ngx_memcpy(h->last.mem, NGINX_VER, sizeof(NGINX_VER) - 1); | 167 ngx_memcpy(h->last.mem, "Connection: close" CRLF, 19); |
71 h->last.mem += sizeof(NGINX_VER) - 1; | 168 h->last.mem += 19; |
72 } | 169 } |
73 *(h->last.mem++) = CR; *(h->last.mem++) = LF; | 170 |
171 for (i = 0; i < r->headers_out.headers->nelts; i++) { | |
172 if (header[i].key.len == 0) | |
173 continue; | |
174 | |
175 ngx_memcpy(h->last.mem, header[i].key.data, header[i].key.len); | |
176 h->last.mem += header[i].key.len; | |
177 *(h->last.mem++) = ':' ; *(h->last.mem++) = ' ' ; | |
178 | |
179 ngx_memcpy(h->last.mem, header[i].value.data, header[i].value.len); | |
180 h->last.mem += header[i].value.len; | |
181 *(h->last.mem++) = CR; *(h->last.mem++) = LF; | |
182 } | |
74 | 183 |
75 /* end of HTTP header */ | 184 /* end of HTTP header */ |
76 *(h->last.mem++) = CR; *(h->last.mem++) = LF; | 185 *(h->last.mem++) = CR; *(h->last.mem++) = LF; |
77 | 186 |
78 ngx_test_null(ch, ngx_palloc(r->pool, sizeof(ngx_chain_t)), | 187 ngx_test_null(ch, ngx_palloc(r->pool, sizeof(ngx_chain_t)), NGX_ERROR); |
79 /* STUB */ | |
80 -1); | |
81 /* | |
82 NGX_HTTP_FILTER_ERROR); | |
83 */ | |
84 | 188 |
85 ch->hunk = h; | 189 ch->hunk = h; |
86 ch->next = NULL; | 190 ch->next = NULL; |
87 | 191 |
88 return ngx_http_write_filter(r, ch); | 192 return ngx_http_write_filter(r, ch); |