Mercurial > hg > nginx-quic
comparison src/http/ngx_http_event.c @ 0:4eff17414a43
nginx-0.0.1-2002-08-06-20:39:45 import
The first code that uses "ngx_" prefix, the previous one used "gx_" prefix.
At that point the code is not yet usable. The first draft ideas are dated
back to 23.10.2001.
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Tue, 06 Aug 2002 16:39:45 +0000 |
parents | |
children | d220029ac7f3 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:4eff17414a43 |
---|---|
1 | |
2 #include <ngx_config.h> | |
3 #include <ngx_log.h> | |
4 #include <ngx_alloc.h> | |
5 #include <ngx_hunk.h> | |
6 #include <ngx_connection.h> | |
7 | |
8 #include <ngx_http.h> | |
9 | |
10 /* | |
11 ngx_read should check errors (if we ask) and return | |
12 -2 EAGAIN | |
13 -1 error | |
14 0 EOF | |
15 >0 number of bytes | |
16 */ | |
17 | |
18 int ngx_http_init_connection(ngx_connection_t *c); | |
19 static int ngx_http_init_request(ngx_event_t *ev); | |
20 static int ngx_http_process_request(ngx_event_t *ev); | |
21 | |
22 static int ngx_process_http_request_line(ngx_http_request_t *r); | |
23 static int ngx_process_http_request_header(ngx_http_request_t *r); | |
24 | |
25 static int ngx_process_http_request(ngx_http_request_t *r); | |
26 | |
27 static int ngx_http_close_request(ngx_event_t *ev); | |
28 | |
29 /* | |
30 returns | |
31 -1 if error | |
32 0 need more data or EOF (filter is deleted) | |
33 1 there is unread data | |
34 */ | |
35 | |
36 int ngx_http_init_connection(ngx_connection_t *c) | |
37 { | |
38 ngx_event_t *ev; | |
39 | |
40 ev = c->read; | |
41 /* | |
42 ev->event_handler = ngx_http_init_request; | |
43 */ | |
44 ev->event_handler = NULL; | |
45 ev->log->action = "reading client request line"; | |
46 | |
47 ngx_log_debug(ev->log, "ngx_http_init_connection: entered"); | |
48 | |
49 /* XXX: ev->timer ? */ | |
50 if (ngx_add_event(ev, NGX_TIMER_EVENT, ev->timer) == -1) | |
51 return -1; | |
52 | |
53 #if (HAVE_DEFERRED_ACCEPT) | |
54 if (ev->ready) | |
55 return ngx_http_init_request(ev); | |
56 else | |
57 #endif | |
58 #if (NGX_CLEAR_EVENT) | |
59 return ngx_add_event(ev, NGX_READ_EVENT, NGX_CLEAR_EVENT); | |
60 #else | |
61 return ngx_add_event(ev, NGX_READ_EVENT, NGX_ONESHOT_EVENT); | |
62 #endif | |
63 } | |
64 | |
65 #if 0 | |
66 | |
67 int ngx_http_init_request(ngx_event_t *ev) | |
68 { | |
69 ngx_connection_t *c = (ngx_connection_t *) ev->data; | |
70 ngx_http_request_t *r; | |
71 | |
72 ngx_log_debug(ev->log, "ngx_http_init_request: entered"); | |
73 | |
74 ngx_test_null(r, ngx_pcalloc(c->pool, sizeof(ngx_http_request_t)), -1); | |
75 | |
76 c->data = r; | |
77 r->connection = c; | |
78 | |
79 ngx_test_null(r->buff, ngx_palloc(r->pool, sizeof(ngx_buff_t)), -1); | |
80 ngx_test_null(r->buff->buff, | |
81 ngx_pcalloc(r->pool, sizeof(c->server->buff_size)), -1); | |
82 | |
83 r->buff->pos = r->buff->last = r->buff->buff; | |
84 r->buff->end = r->buff->buff + c->server->buff_size; | |
85 | |
86 r->state_handler = ngx_process_http_request_line; | |
87 | |
88 ev->event_handler = ngx_http_process_request; | |
89 ev->close_handler = ngx_http_close_request; | |
90 c->write->close_handler = ngx_http_close_request; | |
91 return ngx_http_process_request(ev); | |
92 } | |
93 | |
94 int ngx_http_process_request(ngx_event_t *ev) | |
95 { | |
96 int n; | |
97 ngx_connection_t *c = (ngx_connection_t *) ev->data; | |
98 ngx_http_request_t *r = (ngx_http_request_t *) c->data; | |
99 | |
100 ngx_log_debug(ev->log, "http process request"); | |
101 | |
102 ngx_log_debug(ev->log, "http: eof:%d, avail:%d", ev->eof, ev->available); | |
103 | |
104 if (ev->eof && ev->available == 0) { | |
105 if (ev->err_no) | |
106 ngx_log_error(NGX_LOG_ERR, ev->log, ev->err_no, | |
107 "ngx_http_process_request: " | |
108 "read failed while %s", ev->action); | |
109 | |
110 return -1; | |
111 } | |
112 | |
113 if ((n = read(c->fd, r->buff->last, r->buff->end - r->buff->last)) == -1) { | |
114 | |
115 if (errno == NGX_EWOULDBLOCK) { | |
116 ngx_log_error(NGX_LOG_INFO, ev->log, errno, | |
117 "ngx_http_process_request: " | |
118 "EAGAIN while %s", ev->action); | |
119 return 0; | |
120 } | |
121 | |
122 ngx_log_error(NGX_LOG_ERR, ev->log, errno, | |
123 "ngx_http_process_request: " | |
124 "read failed while %s", ev->action); | |
125 return -1; | |
126 } | |
127 | |
128 ngx_log_debug(ev->log, "http read %d", n); | |
129 | |
130 if (n == 0) { | |
131 if (ev->unexpected_eof) { | |
132 ngx_log_error(NGX_LOG_INFO, ev->log, 0, | |
133 "ngx_http_process_request: " | |
134 "connection is closed while %s", ev->action); | |
135 return -1; | |
136 } | |
137 | |
138 return ngx_http_close_request(ev); | |
139 } | |
140 | |
141 n == r->buff->end - r->buff->last; | |
142 | |
143 if (!ev->read_discarded) { | |
144 r->buff->last += n; | |
145 | |
146 /* state_handlers are called in following order: | |
147 ngx_process_http_request_line() | |
148 ngx_process_http_request_header() */ | |
149 | |
150 do { | |
151 if ((r->state_handler)(r) < 0) | |
152 return -1; | |
153 } while (r->buff->pos < r->buff->last); | |
154 } | |
155 | |
156 if (ngx_del_event(ev, NGX_TIMER_EVENT) == -1) | |
157 return -1; | |
158 | |
159 if (ngx_add_event(ev, NGX_TIMER_EVENT, ev->timer) == -1) | |
160 return -1; | |
161 | |
162 return 0; | |
163 } | |
164 | |
165 static int ngx_process_http_request_line(ngx_http_request_t *r) | |
166 { | |
167 int n; | |
168 | |
169 if ((n = ngx_read_http_request_line(r)) == 1) { | |
170 *r->uri_end = '\0'; | |
171 ngx_log_debug(r->connection->log, "HTTP: %d, %d, %s", | |
172 r->method, r->http_version, r->uri_start); | |
173 r->state_handler = ngx_process_http_request_header; | |
174 r->connection->read->action = "reading client request headers"; | |
175 } | |
176 | |
177 return n; | |
178 } | |
179 | |
180 static int ngx_process_http_request_header(ngx_http_request_t *r) | |
181 { | |
182 int n; | |
183 | |
184 while ((n = ngx_read_http_header_line(r)) == 1) { | |
185 *r->header_name_end = '\0'; | |
186 *r->header_end = '\0'; | |
187 ngx_log_debug(r->connection->log, "HTTP header: '%s: %s'", | |
188 r->header_name_start, r->header_start); | |
189 } | |
190 | |
191 if (n != 2) | |
192 return n; | |
193 | |
194 r->state_handler = NULL; | |
195 r->connection->read->action = "reading client request body"; | |
196 | |
197 r->connection->read->read_discarded = 1; | |
198 r->connection->read->unexpected_eof = 0; | |
199 ngx_log_debug(r->connection->log, "HTTP header done"); | |
200 | |
201 return ngx_process_http_request(r); | |
202 } | |
203 | |
204 static int ngx_process_http_request(ngx_http_request_t *r) | |
205 { | |
206 int fd; | |
207 struct stat sb; | |
208 ngx_http_header_out_t *header_out; | |
209 ngx_chunk_t *header, *ch; | |
210 | |
211 int index = (*(r->uri_end - 1) == '/') ? sizeof(NGX_INDEX) : 1; | |
212 char *name = ngx_palloc(r->pool, | |
213 r->uri_end - r->uri_start + strlen(ngx_root) + index); | |
214 strcpy(name, ngx_root); | |
215 strcat(name, r->uri_start); | |
216 if (*(r->uri_end - 1) == '/') | |
217 strcat(name, NGX_INDEX); | |
218 | |
219 ngx_log_debug(r->connection->log, "HTTP URI: '%s'", name); | |
220 | |
221 if ((fd = open(name, O_RDONLY)) == -1) { | |
222 ngx_log_error(NGX_LOG_ERR, r->connection->log, errno, | |
223 "open %s failed", name); | |
224 return -1; | |
225 } | |
226 | |
227 if (fstat(fd, &sb) == -1) { | |
228 ngx_log_error(NGX_LOG_ERR, r->connection->log, errno, | |
229 "fstat %s failed", name); | |
230 return -1; | |
231 } | |
232 | |
233 header_out = ngx_palloc(r->pool, sizeof(ngx_http_header_out_t)); | |
234 | |
235 header_out->status = NGX_HTTP_OK; | |
236 header_out->content_length = sb.st_size; | |
237 header_out->last_modified = sb.st_mtime; | |
238 header_out->content_type = "text/html"; | |
239 header_out->charset = "koi8-r"; | |
240 header_out->date = time(NULL); | |
241 header_out->connection = NGX_HTTP_CONN_CLOSE; | |
242 | |
243 /* | |
244 header_out->connection = NGX_HTTP_CONN_KEEP_ALIVE; | |
245 r->connection->read->event_handler = ngx_http_init_request; | |
246 */ | |
247 | |
248 header = ngx_http_header(r, header_out); | |
249 ch = ngx_palloc(r->pool, sizeof(ngx_chunk_t)); | |
250 ch->ident = fd; | |
251 ch->offset = 0; | |
252 ch->size = sb.st_size; | |
253 ch->next = NULL; | |
254 header->next = ch; | |
255 | |
256 ngx_event_write(r->connection, header); | |
257 | |
258 return 0; | |
259 } | |
260 | |
261 static int ngx_http_close_request(ngx_event_t *ev) | |
262 { | |
263 ngx_connection_t *c = (ngx_connection_t *) ev->data; | |
264 | |
265 ngx_log_debug(ev->log, "http close"); | |
266 | |
267 ngx_del_event(c->read, NGX_TIMER_EVENT); | |
268 ngx_del_event(c->write, NGX_TIMER_EVENT); | |
269 | |
270 return ngx_event_close(ev); | |
271 } | |
272 | |
273 #endif |