Mercurial > hg > nginx-quic
comparison src/http/ngx_http_header_filter.c @ 96:a23d010f356d
nginx-0.0.1-2003-05-27-16:18:54 import
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Tue, 27 May 2003 12:18:54 +0000 |
parents | 637625a2acdb |
children | c9b243802a17 |
comparison
equal
deleted
inserted
replaced
95:b48066122884 | 96:a23d010f356d |
---|---|
17 static int ngx_http_header_filter_init(ngx_pool_t *pool); | 17 static int ngx_http_header_filter_init(ngx_pool_t *pool); |
18 static int ngx_http_header_filter(ngx_http_request_t *r); | 18 static int ngx_http_header_filter(ngx_http_request_t *r); |
19 | 19 |
20 | 20 |
21 static ngx_http_module_t ngx_http_header_filter_module_ctx = { | 21 static ngx_http_module_t ngx_http_header_filter_module_ctx = { |
22 NGX_HTTP_MODULE, | |
23 | |
24 NULL, /* create main configuration */ | 22 NULL, /* create main configuration */ |
25 NULL, /* init main configuration */ | 23 NULL, /* init main configuration */ |
26 | 24 |
27 NULL, /* create server configuration */ | 25 NULL, /* create server configuration */ |
28 NULL, /* merge server configuration */ | 26 NULL, /* merge server configuration */ |
31 NULL, /* merge location configuration */ | 29 NULL, /* merge location configuration */ |
32 }; | 30 }; |
33 | 31 |
34 | 32 |
35 ngx_module_t ngx_http_header_filter_module = { | 33 ngx_module_t ngx_http_header_filter_module = { |
34 NGX_MODULE, | |
36 &ngx_http_header_filter_module_ctx, /* module context */ | 35 &ngx_http_header_filter_module_ctx, /* module context */ |
37 0, /* module index */ | |
38 NULL, /* module directives */ | 36 NULL, /* module directives */ |
39 NGX_HTTP_MODULE_TYPE, /* module type */ | 37 NGX_HTTP_MODULE, /* module type */ |
40 ngx_http_header_filter_init /* init module */ | 38 ngx_http_header_filter_init /* init module */ |
41 }; | 39 }; |
42 | 40 |
43 | 41 |
44 static char server_string[] = "Server: " NGINX_VER CRLF; | 42 static char server_string[] = "Server: " NGINX_VER CRLF; |
45 | 43 |
46 | 44 |
47 static ngx_str_t http_codes[] = { | 45 static ngx_str_t http_codes[] = { |
48 | 46 |
49 ngx_string("200 OK"), | 47 ngx_string("200 OK"), |
48 ngx_null_string, /* "201 Created" */ | |
49 ngx_null_string, /* "202 Accepted" */ | |
50 ngx_null_string, /* "203 Non-Authoritative Information" */ | |
51 ngx_null_string, /* "204 No Content" */ | |
52 ngx_null_string, /* "205 Reset Content" */ | |
53 ngx_string("206 Partial Content"), | |
54 ngx_null_string, /* "207 Multi-Status" */ | |
55 | |
56 #if 0 | |
57 ngx_null_string, /* "300 Multiple Choices" */ | |
58 #endif | |
50 | 59 |
51 ngx_string("301 Moved Permanently"), | 60 ngx_string("301 Moved Permanently"), |
52 ngx_string("302 Moved Temporarily"), | 61 ngx_string("302 Moved Temporarily"), |
53 ngx_null_string, /* 303 */ | 62 ngx_null_string, /* "303 See Other" */ |
54 ngx_string("304 Not Modified"), | 63 ngx_string("304 Not Modified"), |
55 | 64 |
56 ngx_string("400 Bad Request"), | 65 ngx_string("400 Bad Request"), |
57 ngx_null_string, /* 401 */ | 66 ngx_string("401 Unauthorized"), |
58 ngx_null_string, /* 402 */ | 67 ngx_null_string, /* "402 Payment Required" */ |
59 ngx_string("403 Forbidden"), | 68 ngx_string("403 Forbidden"), |
60 ngx_string("404 Not Found"), | 69 ngx_string("404 Not Found"), |
61 ngx_null_string, /* 405 */ | 70 ngx_string("405 Not Allowed"), |
62 ngx_null_string, /* 406 */ | 71 ngx_null_string, /* "406 Not Acceptable" */ |
63 ngx_null_string, /* 407 */ | 72 ngx_null_string, /* "407 Proxy Authentication Required" */ |
64 ngx_string("408 Request Time-out"), | 73 ngx_string("408 Request Time-out"), |
65 ngx_null_string, /* 409 */ | 74 ngx_null_string, /* "409 Conflict" */ |
66 ngx_null_string, /* 410 */ | 75 ngx_null_string, /* "410 Gone" */ |
67 ngx_string("411 Length Required"), | 76 ngx_string("411 Length Required"), |
68 ngx_null_string, /* 412 */ | 77 ngx_null_string, /* "412 Precondition Failed" */ |
69 ngx_string("413 Request Entity Too Large"), | 78 ngx_string("413 Request Entity Too Large"), |
70 ngx_null_string, /* "414 Request-URI Too Large" but we never send it | 79 ngx_null_string, /* "414 Request-URI Too Large" but we never send it |
71 because we treat such requests as the HTTP/0.9 requests | 80 because we treat such requests as the HTTP/0.9 requests |
72 and send only the body without the header */ | 81 and send only the body without the header */ |
73 ngx_null_string, /* 415 */ | 82 ngx_null_string, /* "415 Unsupported Media Type" */ |
74 ngx_string("416 Requested Range Not Satisfiable"), | 83 ngx_string("416 Requested Range Not Satisfiable"), |
75 | 84 |
76 ngx_string("500 Internal Server Error"), | 85 ngx_string("500 Internal Server Error"), |
77 ngx_string("501 Method Not Implemented"), | 86 ngx_string("501 Method Not Implemented"), |
78 ngx_string("502 Bad Gateway"), | 87 ngx_string("502 Bad Gateway"), |
82 | 91 |
83 | 92 |
84 | 93 |
85 static int ngx_http_header_filter(ngx_http_request_t *r) | 94 static int ngx_http_header_filter(ngx_http_request_t *r) |
86 { | 95 { |
87 int len, status, i; | 96 int len, status, text, i; |
88 time_t ims; | 97 time_t ims; |
89 ngx_hunk_t *h; | 98 ngx_hunk_t *h; |
90 ngx_chain_t *ch; | 99 ngx_chain_t *ch; |
91 ngx_table_elt_t *header; | 100 ngx_table_elt_t *header; |
92 | 101 |
93 if (r->http_version < NGX_HTTP_VERSION_10) { | 102 if (r->http_version < NGX_HTTP_VERSION_10) { |
94 return NGX_OK; | 103 return NGX_OK; |
104 } | |
105 | |
106 if (r->method == NGX_HTTP_HEAD) { | |
107 r->header_only = 1; | |
95 } | 108 } |
96 | 109 |
97 /* 9 is for "HTTP/1.x ", 2 is for trailing "\r\n" | 110 /* 9 is for "HTTP/1.x ", 2 is for trailing "\r\n" |
98 and 2 is for end of header */ | 111 and 2 is for end of header */ |
99 len = 9 + 2 + 2; | 112 len = 9 + 2 + 2; |
130 /* 2XX */ | 143 /* 2XX */ |
131 status = r->headers_out.status - NGX_HTTP_OK; | 144 status = r->headers_out.status - NGX_HTTP_OK; |
132 | 145 |
133 } else if (r->headers_out.status < NGX_HTTP_BAD_REQUEST) { | 146 } else if (r->headers_out.status < NGX_HTTP_BAD_REQUEST) { |
134 /* 3XX */ | 147 /* 3XX */ |
135 status = r->headers_out.status - NGX_HTTP_MOVED_PERMANENTLY + 1; | 148 status = r->headers_out.status - NGX_HTTP_MOVED_PERMANENTLY + 8; |
136 r->header_only = 1; | 149 r->header_only = 1; |
137 | 150 |
138 } else if (r->headers_out.status < NGX_HTTP_INTERNAL_SERVER_ERROR) { | 151 } else if (r->headers_out.status < NGX_HTTP_INTERNAL_SERVER_ERROR) { |
139 /* 4XX */ | 152 /* 4XX */ |
140 status = r->headers_out.status - NGX_HTTP_BAD_REQUEST + 1 + 4; | 153 status = r->headers_out.status - NGX_HTTP_BAD_REQUEST + 8 + 4; |
141 | 154 |
142 } else { | 155 } else { |
143 /* 5XX */ | 156 /* 5XX */ |
144 status = r->headers_out.status | 157 status = r->headers_out.status |
145 - NGX_HTTP_INTERNAL_SERVER_ERROR + 1 + 4 + 17; | 158 - NGX_HTTP_INTERNAL_SERVER_ERROR + 8 + 4 + 17; |
146 } | 159 } |
147 | 160 |
148 len += http_codes[status].len; | 161 len += http_codes[status].len; |
149 } | 162 } |
150 | 163 |
157 | 170 |
158 if (r->headers_out.date && r->headers_out.date->key.len) { | 171 if (r->headers_out.date && r->headers_out.date->key.len) { |
159 len += r->headers_out.date->key.len | 172 len += r->headers_out.date->key.len |
160 + r->headers_out.date->value.len + 2; | 173 + r->headers_out.date->value.len + 2; |
161 } else { | 174 } else { |
162 /* "Date: ... \r\n"; */ | 175 /* "Date: ... \r\n" */ |
163 len += 37; | 176 len += 37; |
164 } | 177 } |
165 | 178 |
166 /* 2^64 is 20 characters */ | |
167 if (r->headers_out.content_length >= 0) { | 179 if (r->headers_out.content_length >= 0) { |
180 /* "Content-Length: ... \r\n", 2^64 is 20 characters */ | |
168 len += 48; | 181 len += 48; |
169 } | 182 } |
170 | 183 |
171 #if 0 | 184 text = 0; |
172 if (r->headers_out.content_type.len) | 185 if (r->headers_out.content_type && r->headers_out.content_type->value.len) { |
173 len += r->headers_out.content_type.len + 16; | 186 r->headers_out.content_type->key.len = 0; |
174 #endif | 187 len += 16 + r->headers_out.content_type->value.len; |
188 if (ngx_strncasecmp(r->headers_out.content_type->value.data, | |
189 "text/", 5) == 0) { | |
190 text = 1; | |
191 /* "; charset=koi8-r" */ | |
192 len += 16; | |
193 } | |
194 } | |
195 | |
196 if (r->headers_out.location | |
197 && r->headers_out.location->value.len | |
198 && r->headers_out.location->value.data[0] == '/') | |
199 { | |
200 r->headers_out.location->key.len = 0; | |
201 /* "Location: http:// ... \r\n" */ | |
202 len += 17 + r->server_name->len | |
203 + r->headers_out.location->value.len + 2; | |
204 | |
205 if (r->port != 80) { | |
206 len += r->port_name->len; | |
207 } | |
208 } | |
175 | 209 |
176 if (r->headers_out.last_modified && r->headers_out.last_modified->key.len) { | 210 if (r->headers_out.last_modified && r->headers_out.last_modified->key.len) { |
177 len += r->headers_out.last_modified->key.len | 211 len += r->headers_out.last_modified->key.len |
178 + r->headers_out.last_modified->value.len + 2; | 212 + r->headers_out.last_modified->value.len + 2; |
213 | |
179 } else if (r->headers_out.last_modified_time != -1) { | 214 } else if (r->headers_out.last_modified_time != -1) { |
180 /* "Last-Modified: ... \r\n"; */ | 215 /* "Last-Modified: ... \r\n" */ |
181 len += 46; | 216 len += 46; |
182 } | 217 } |
183 | 218 |
184 if (r->keepalive == 0) { | 219 if (r->keepalive == 0) { |
220 /* "Connection: close\r\n" */ | |
185 len += 19; | 221 len += 19; |
186 } else { | 222 } else { |
223 /* "Connection: keep-alive\r\n" */ | |
187 len += 24; | 224 len += 24; |
188 } | 225 } |
189 | 226 |
190 header = (ngx_table_elt_t *) r->headers_out.headers->elts; | 227 header = (ngx_table_elt_t *) r->headers_out.headers->elts; |
191 for (i = 0; i < r->headers_out.headers->nelts; i++) { | 228 for (i = 0; i < r->headers_out.headers->nelts; i++) { |
197 } | 234 } |
198 | 235 |
199 ngx_test_null(h, ngx_create_temp_hunk(r->pool, len, 0, 64), NGX_ERROR); | 236 ngx_test_null(h, ngx_create_temp_hunk(r->pool, len, 0, 64), NGX_ERROR); |
200 | 237 |
201 /* "HTTP/1.x " */ | 238 /* "HTTP/1.x " */ |
202 ngx_memcpy(h->last, "HTTP/1.1 ", 9); | 239 h->last = ngx_cpymem(h->last, "HTTP/1.1 ", 9); |
203 h->last += 9; | |
204 | 240 |
205 /* status line */ | 241 /* status line */ |
206 if (r->headers_out.status_line.len) { | 242 if (r->headers_out.status_line.len) { |
207 ngx_memcpy(h->last, r->headers_out.status_line.data, | 243 h->last = ngx_cpymem(h->last, r->headers_out.status_line.data, |
208 r->headers_out.status_line.len); | 244 r->headers_out.status_line.len); |
209 h->last += r->headers_out.status_line.len; | 245 |
210 | 246 } else { |
211 } else { | 247 h->last = ngx_cpymem(h->last, http_codes[status].data, |
212 ngx_memcpy(h->last, http_codes[status].data, | 248 http_codes[status].len); |
213 http_codes[status].len); | |
214 h->last += http_codes[status].len; | |
215 } | 249 } |
216 *(h->last++) = CR; *(h->last++) = LF; | 250 *(h->last++) = CR; *(h->last++) = LF; |
217 | 251 |
218 if (!(r->headers_out.server && r->headers_out.server->key.len)) { | 252 if (!(r->headers_out.server && r->headers_out.server->key.len)) { |
219 ngx_memcpy(h->last, server_string, sizeof(server_string) - 1); | 253 h->last = ngx_cpymem(h->last, server_string, sizeof(server_string) - 1); |
220 h->last += sizeof(server_string) - 1; | |
221 } | 254 } |
222 | 255 |
223 if (!(r->headers_out.date && r->headers_out.date->key.len)) { | 256 if (!(r->headers_out.date && r->headers_out.date->key.len)) { |
224 ngx_memcpy(h->last, "Date: ", 6); | 257 h->last = ngx_cpymem(h->last, "Date: ", 6); |
225 h->last += 6; | |
226 h->last += ngx_http_get_time(h->last, time(NULL)); | 258 h->last += ngx_http_get_time(h->last, time(NULL)); |
227 *(h->last++) = CR; *(h->last++) = LF; | 259 *(h->last++) = CR; *(h->last++) = LF; |
228 } | 260 } |
229 | 261 |
230 /* 2^64 is 20 characters */ | 262 /* 2^64 is 20 characters */ |
231 if (r->headers_out.content_length >= 0) { | 263 if (r->headers_out.content_length >= 0) { |
232 h->last += ngx_snprintf(h->last, 49, | 264 h->last += ngx_snprintf(h->last, 49, |
233 "Content-Length: " OFF_FMT CRLF, | 265 "Content-Length: " OFF_FMT CRLF, |
234 r->headers_out.content_length); | 266 r->headers_out.content_length); |
235 } | 267 } |
236 | 268 |
237 #if 0 | 269 if (r->headers_out.content_type && r->headers_out.content_type->value.len) { |
238 if (r->headers_out.content_type.len) { | 270 h->last = ngx_cpymem(h->last, "Content-Type: ", 14); |
239 ngx_memcpy(h->last, "Content-Type: ", 14); | 271 h->last = ngx_cpymem(h->last, r->headers_out.content_type->value.data, |
240 h->last += 14; | 272 r->headers_out.content_type->value.len); |
241 ngx_memcpy(h->last, r->headers_out.content_type.data, | 273 |
242 r->headers_out.content_type.len); | 274 if (text) { |
243 h->last += r->headers_out.content_type.len; | 275 h->last = ngx_cpymem(h->last, "; charset=koi8-r", 16); |
244 *(h->last++) = CR; *(h->last++) = LF; | 276 } |
245 } | 277 |
246 #endif | 278 *(h->last++) = CR; *(h->last++) = LF; |
247 | 279 } |
248 if (!(r->headers_out.last_modified | 280 |
249 && r->headers_out.last_modified->key.len) | 281 if (r->headers_out.location |
282 && r->headers_out.location->value.len | |
283 && r->headers_out.location->value.data[0] == '/') | |
284 { | |
285 h->last = ngx_cpymem(h->last, "Location: http://", 17); | |
286 h->last = ngx_cpymem(h->last, r->server_name->data, | |
287 r->server_name->len); | |
288 if (r->port != 80) { | |
289 h->last = ngx_cpymem(h->last, r->port_name->data, | |
290 r->port_name->len); | |
291 } | |
292 | |
293 h->last = ngx_cpymem(h->last, r->headers_out.location->value.data, | |
294 r->headers_out.location->value.len); | |
295 | |
296 *(h->last++) = CR; *(h->last++) = LF; | |
297 } | |
298 | |
299 if (!(r->headers_out.last_modified && r->headers_out.last_modified->key.len) | |
250 && r->headers_out.last_modified_time != -1) | 300 && r->headers_out.last_modified_time != -1) |
251 { | 301 { |
252 ngx_memcpy(h->last, "Last-Modified: ", 15); | 302 h->last = ngx_cpymem(h->last, "Last-Modified: ", 15); |
253 h->last += 15; | |
254 h->last += ngx_http_get_time(h->last, | 303 h->last += ngx_http_get_time(h->last, |
255 r->headers_out.last_modified_time); | 304 r->headers_out.last_modified_time); |
256 *(h->last++) = CR; *(h->last++) = LF; | 305 *(h->last++) = CR; *(h->last++) = LF; |
257 } | 306 } |
258 | 307 |
259 if (r->keepalive == 0) { | 308 if (r->keepalive == 0) { |
260 ngx_memcpy(h->last, "Connection: close" CRLF, 19); | 309 h->last = ngx_cpymem(h->last, "Connection: close" CRLF, 19); |
261 h->last += 19; | 310 |
262 | 311 } else { |
263 } else { | 312 h->last = ngx_cpymem(h->last, "Connection: keep-alive" CRLF, 24); |
264 ngx_memcpy(h->last, "Connection: keep-alive" CRLF, 24); | |
265 h->last += 24; | |
266 } | 313 } |
267 | 314 |
268 for (i = 0; i < r->headers_out.headers->nelts; i++) { | 315 for (i = 0; i < r->headers_out.headers->nelts; i++) { |
269 if (header[i].key.len == 0) { | 316 if (header[i].key.len == 0) { |
270 continue; | 317 continue; |
271 } | 318 } |
272 | 319 |
273 ngx_memcpy(h->last, header[i].key.data, header[i].key.len); | 320 h->last = ngx_cpymem(h->last, header[i].key.data, header[i].key.len); |
274 h->last += header[i].key.len; | |
275 *(h->last++) = ':' ; *(h->last++) = ' ' ; | 321 *(h->last++) = ':' ; *(h->last++) = ' ' ; |
276 | 322 |
277 ngx_memcpy(h->last, header[i].value.data, header[i].value.len); | 323 h->last = ngx_cpymem(h->last, header[i].value.data, |
278 h->last += header[i].value.len; | 324 header[i].value.len); |
279 *(h->last++) = CR; *(h->last++) = LF; | 325 *(h->last++) = CR; *(h->last++) = LF; |
280 } | 326 } |
281 | 327 |
282 /* STUB */ | 328 /* STUB */ |
283 *(h->last) = '\0'; | 329 *(h->last) = '\0'; |
284 ngx_log_debug(r->connection->log, "%s\n" _ h->pos); | 330 ngx_log_debug(r->connection->log, "%s\n" _ h->pos); |
285 /**/ | 331 /**/ |
286 | 332 |
287 /* end of HTTP header */ | 333 /* the end of HTTP header */ |
288 *(h->last++) = CR; *(h->last++) = LF; | 334 *(h->last++) = CR; *(h->last++) = LF; |
289 | 335 |
290 if (r->header_only) { | 336 if (r->header_only) { |
291 h->type |= NGX_HUNK_LAST; | 337 h->type |= NGX_HUNK_LAST; |
292 } | 338 } |