103 SSL_free(conn->ssl); |
103 SSL_free(conn->ssl); |
104 } |
104 } |
105 free(conn); |
105 free(conn); |
106 } |
106 } |
107 |
107 |
|
108 IOStream* create_connection_iostream( |
|
109 SessionHandler *sh, |
|
110 Connection *conn, |
|
111 pool_handle_t *pool, |
|
112 WSBool *ssl) |
|
113 { |
|
114 IOStream *io = NULL; |
|
115 if(conn->ssl) { |
|
116 io = sslstream_new(pool, conn->ssl); |
|
117 *ssl = 1; |
|
118 } else { |
|
119 io = sysstream_new(pool, conn->fd); |
|
120 *ssl = 0; |
|
121 } |
|
122 return io; |
|
123 } |
|
124 |
|
125 |
108 SessionHandler* create_basic_session_handler() { |
126 SessionHandler* create_basic_session_handler() { |
109 BasicSessionHandler *handler = malloc(sizeof(BasicSessionHandler)); |
127 BasicSessionHandler *handler = malloc(sizeof(BasicSessionHandler)); |
110 handler->threadpool = threadpool_new(4, 8); |
128 handler->threadpool = threadpool_new(4, 8); |
111 handler->sh.enqueue_connection = basic_enq_conn; |
129 handler->sh.enqueue_connection = basic_enq_conn; |
112 handler->sh.keep_alive = basic_keep_alive; |
130 handler->sh.keep_alive = basic_keep_alive; |
|
131 handler->sh.create_iostream = create_connection_iostream; |
113 |
132 |
114 return (SessionHandler*)handler; |
133 return (SessionHandler*)handler; |
115 } |
134 } |
116 |
135 |
117 void basic_enq_conn(SessionHandler *handler, Connection *conn) { |
136 void basic_enq_conn(SessionHandler *handler, Connection *conn) { |
187 SessionHandler* create_event_session_handler() { |
206 SessionHandler* create_event_session_handler() { |
188 EventSessionHandler *handler = malloc(sizeof(EventSessionHandler)); |
207 EventSessionHandler *handler = malloc(sizeof(EventSessionHandler)); |
189 handler->eventhandler = get_default_event_handler(); |
208 handler->eventhandler = get_default_event_handler(); |
190 handler->sh.enqueue_connection = evt_enq_conn; |
209 handler->sh.enqueue_connection = evt_enq_conn; |
191 handler->sh.keep_alive = evt_keep_alive; |
210 handler->sh.keep_alive = evt_keep_alive; |
|
211 handler->sh.create_iostream = create_connection_iostream; |
192 return (SessionHandler*)handler; |
212 return (SessionHandler*)handler; |
193 } |
213 } |
194 |
214 |
195 void evt_enq_conn(SessionHandler *handler, Connection *conn) { |
215 void evt_enq_conn(SessionHandler *handler, Connection *conn) { |
196 HTTPRequest *request = malloc(sizeof(HTTPRequest)); |
216 HTTPRequest *request = malloc(sizeof(HTTPRequest)); |
198 request->connection = conn; |
218 request->connection = conn; |
199 conn->session_handler = handler; |
219 conn->session_handler = handler; |
200 |
220 |
201 // set socket non blocking |
221 // set socket non blocking |
202 int flags; |
222 int flags; |
203 if (-1 == (flags = fcntl(conn->fd, F_GETFL, 0))) { |
223 if ((flags = fcntl(conn->fd, F_GETFL, 0)) == -1) { |
204 flags = 0; |
224 flags = 0; |
205 } |
225 } |
206 if (fcntl(conn->fd, F_SETFL, flags | O_NONBLOCK) != 0) { |
226 if (fcntl(conn->fd, F_SETFL, flags | O_NONBLOCK) != 0) { |
207 perror("Error: start_event_session: fcntl"); |
227 perror("Error: start_event_session: fcntl"); |
208 // TODO: error |
228 // TODO: error |
236 * to start the request handling, we begin with a poll on the socket, |
256 * to start the request handling, we begin with a poll on the socket, |
237 * |
257 * |
238 * evt_enq_conn() --> event handler --> handle_request() |
258 * evt_enq_conn() --> event handler --> handle_request() |
239 */ |
259 */ |
240 |
260 |
241 event_handler_t *ev = ((EventSessionHandler*)handler)->eventhandler; |
261 Event *event = malloc(sizeof(Event)); |
242 |
262 ZERO(event, sizeof(Event)); |
243 event_t *event = malloc(sizeof(event_t)); |
263 event->fn = conn->ssl ? evt_request_ssl_accept : evt_request_input; |
244 ZERO(event, sizeof(event_t)); |
|
245 event->fn = evt_request_input; |
|
246 event->finish = evt_request_finish; |
264 event->finish = evt_request_finish; |
247 event->cookie = io; |
265 event->cookie = io; |
|
266 |
|
267 EventHandler *ev = ev_instance(((EventSessionHandler*)handler)->eventhandler); |
248 |
268 |
249 if(ev_pollin(ev, conn->fd, event) != 0) { |
269 if(ev_pollin(ev, conn->fd, event) != 0) { |
250 // TODO: ev_pollin should log, intercept some errors here |
270 // TODO: ev_pollin should log, intercept some errors here |
251 log_ereport(LOG_FAILURE, "Cannot enqueue connection"); |
271 log_ereport(LOG_FAILURE, "Cannot enqueue connection"); |
252 connection_destroy(conn); |
272 connection_destroy(conn); |
253 // TODO: free stuff |
273 // TODO: free stuff |
254 } |
274 } |
255 } |
275 } |
256 |
276 |
257 int evt_request_input(event_handler_t *handler, event_t *event) { |
277 int evt_request_ssl_accept(EventHandler *handler, Event *event) { |
|
278 EventHttpIO *io = event->cookie; |
|
279 Connection *conn = io->request->connection; |
|
280 |
|
281 int ret = SSL_accept(conn->ssl); |
|
282 if(ret <= 0) { |
|
283 int error = SSL_get_error(conn->ssl, ret); |
|
284 char *errstr; |
|
285 switch(error) { |
|
286 default: errstr = "unknown"; break; |
|
287 case SSL_ERROR_WANT_READ: { |
|
288 event->events = EVENT_POLLIN; |
|
289 return 1; |
|
290 } |
|
291 case SSL_ERROR_WANT_WRITE: { |
|
292 event->events = EVENT_POLLOUT; |
|
293 return 1; |
|
294 } |
|
295 case SSL_ERROR_ZERO_RETURN: errstr = "SSL_ERROR_ZERO_RETURN"; break; |
|
296 case SSL_ERROR_WANT_CONNECT: errstr = "SSL_ERROR_WANT_CONNECT"; break; |
|
297 case SSL_ERROR_WANT_ACCEPT: errstr = "SSL_ERROR_WANT_ACCEPT"; break; |
|
298 case SSL_ERROR_WANT_X509_LOOKUP: errstr = "SSL_ERROR_WANT_X509_LOOKUP"; break; |
|
299 case SSL_ERROR_SYSCALL: errstr = "SSL_ERROR_SYSCALL"; break; |
|
300 case SSL_ERROR_SSL: errstr = "SSL_ERROR_SSL"; break; |
|
301 |
|
302 log_ereport(LOG_VERBOSE, "SSL accept error[%d]: %s", error, errstr); |
|
303 event->finish = evt_request_error; |
|
304 io->error = 1; |
|
305 return 0; |
|
306 } |
|
307 } |
|
308 |
|
309 // SSL_accept successful, start request input now |
|
310 event->fn = evt_request_input; |
|
311 return evt_request_input(handler, event); |
|
312 } |
|
313 |
|
314 int evt_request_input(EventHandler *handler, Event *event) { |
258 EventHttpIO *io = event->cookie; |
315 EventHttpIO *io = event->cookie; |
259 HttpParser *parser = io->parser; |
316 HttpParser *parser = io->parser; |
260 HTTPRequest *request = io->request; |
317 HTTPRequest *request = io->request; |
261 Connection *conn = io->request->connection; |
318 Connection *conn = io->request->connection; |
262 netbuf *buf = request->netbuf; |
319 netbuf *buf = request->netbuf; |
334 * polling and executes event->finish (evt_request_input_finish) |
391 * polling and executes event->finish (evt_request_input_finish) |
335 */ |
392 */ |
336 return 0; |
393 return 0; |
337 } |
394 } |
338 |
395 |
339 int evt_request_finish(event_handler_t *h, event_t *event) { |
396 int evt_request_finish(EventHandler *h, Event *event) { |
340 EventHttpIO *io = event->cookie; |
397 EventHttpIO *io = event->cookie; |
341 HttpParser *parser = io->parser; |
398 HttpParser *parser = io->parser; |
342 HTTPRequest *request = io->request; |
399 HTTPRequest *request = io->request; |
343 |
400 |
344 int r = handle_request(request, NULL); |
401 int r = handle_request(request, NULL, h); |
345 if(r != 0) { |
402 if(r != 0) { |
346 // TODO: error message |
403 // TODO: error message |
347 connection_destroy(request->connection); |
404 connection_destroy(request->connection); |
348 } |
405 } |
349 |
406 |