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