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);