src/server/daemon/sessionhandler.c

changeset 193
aa8393527b1e
parent 181
12828065f120
parent 192
6a145e13d933
child 194
6345f50208d5
equal deleted inserted replaced
183:f33974f0dce0 193:aa8393527b1e
38 #include "log.h" 38 #include "log.h"
39 #include "error.h" 39 #include "error.h"
40 #include "httplistener.h" 40 #include "httplistener.h"
41 41
42 typedef struct _event_http_io { 42 typedef struct _event_http_io {
43 HTTPRequest *request; 43 HTTPRequest *request;
44 HttpParser *parser; 44 HttpParser *parser;
45 int error; 45 int error;
46 } EventHttpIO; 46 } EventHttpIO;
47 47
48 48
49 int connection_read(Connection *conn, void *buf, int len) { 49 int connection_read(Connection *conn, void *buf, int len) {
50 return (int)read(conn->fd, buf, len); 50 return (int)read(conn->fd, buf, len);
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) {
168 // TODO: send error 400 bad request 187 // TODO: send error 400 bad request
169 return NULL; 188 return NULL;
170 } 189 }
171 190
172 // process request 191 // process request
173 r = handle_request(&request, NULL); // TODO: use correct thread pool 192 r = handle_request(&request, NULL, NULL); // TODO: use correct thread pool
174 193
175 // TODO: free, see evt_request_finish 194 // TODO: free, see evt_request_finish
176 195
177 return NULL; 196 return NULL;
178 } 197 }
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;
270 if(r <= 0) { 327 if(r <= 0) {
271 if(conn->ssl) { 328 if(conn->ssl) {
272 // SSL specific error handling 329 // SSL specific error handling
273 switch(conn->ssl_error) { 330 switch(conn->ssl_error) {
274 case SSL_ERROR_WANT_READ: { 331 case SSL_ERROR_WANT_READ: {
275 event->poll = EVENT_POLLIN; 332 event->events = EVENT_POLLIN;
276 return 1; 333 return 1;
277 } 334 }
278 case SSL_ERROR_WANT_WRITE: { 335 case SSL_ERROR_WANT_WRITE: {
279 event->poll = EVENT_POLLOUT; 336 event->events = EVENT_POLLOUT;
280 return 1; 337 return 1;
281 } 338 }
282 } 339 }
283 } 340 }
284 341
300 } else if(state == 1) { 357 } else if(state == 1) {
301 /* 358 /*
302 * we need more data -> return 1 to tell the event handler to 359 * we need more data -> return 1 to tell the event handler to
303 * continue polling 360 * continue polling
304 */ 361 */
305 event->poll = EVENT_POLLIN; 362 event->events = EVENT_POLLIN;
306 return 1; 363 return 1;
307 } 364 }
308 365
309 // we are done with reading 366 // we are done with reading
310 367
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
360 free(event); 417 free(event);
361 418
362 return 0; 419 return 0;
363 } 420 }
364 421
365 int evt_request_error(event_handler_t *h, event_t *event) { 422 int evt_request_error(EventHandler *h, Event *event) {
366 EventHttpIO *io = event->cookie; 423 EventHttpIO *io = event->cookie;
367 HttpParser *parser = io->parser; 424 HttpParser *parser = io->parser;
368 HTTPRequest *request = io->request; 425 HTTPRequest *request = io->request;
369 426
370 if(event->error) { 427 if(event->error) {

mercurial