2 * Copyright (c) 2008 Ry Dahl. This software is released under the MIT
3 * License. See README file for details.
9 #include <netinet/tcp.h>
20 #define EV_STANDALONE 1
27 #define min(a,b) (a < b ? a : b)
28 #define ramp(a) (a > 0 ? a : 0)
30 static void client_init(ebb_client
*client
);
32 static void set_nonblock(int fd
)
34 int flags
= fcntl(fd
, F_GETFL
, 0);
35 assert(0 <= fcntl(fd
, F_SETFL
, flags
| O_NONBLOCK
) && "Setting socket non-block failed!");
39 void env_add(ebb_client
*client
, const char *field
, int flen
, const char *value
, int vlen
)
41 if(client
->env_size
>= EBB_MAX_ENV
) {
42 client
->parser
.overflow_error
= TRUE
;
45 client
->env
[client
->env_size
].type
= -1;
46 client
->env
[client
->env_size
].field
= field
;
47 client
->env
[client
->env_size
].field_length
= flen
;
48 client
->env
[client
->env_size
].value
= value
;
49 client
->env
[client
->env_size
].value_length
= vlen
;
50 client
->env_size
+= 1;
54 void env_add_const(ebb_client
*client
, int type
, const char *value
, int vlen
)
56 if(client
->env_size
>= EBB_MAX_ENV
) {
57 client
->parser
.overflow_error
= TRUE
;
60 client
->env
[client
->env_size
].type
= type
;
61 client
->env
[client
->env_size
].field
= NULL
;
62 client
->env
[client
->env_size
].field_length
= -1;
63 client
->env
[client
->env_size
].value
= value
;
64 client
->env
[client
->env_size
].value_length
= vlen
;
65 client
->env_size
+= 1;
69 void http_field_cb(void *data
, const char *field
, size_t flen
, const char *value
, size_t vlen
)
71 ebb_client
*client
= (ebb_client
*)(data
);
72 assert(field
!= NULL
);
73 assert(value
!= NULL
);
74 env_add(client
, field
, flen
, value
, vlen
);
78 void on_element(void *data
, int type
, const char *at
, size_t length
)
80 ebb_client
*client
= (ebb_client
*)(data
);
81 env_add_const(client
, type
, at
, length
);
85 static void dispatch(ebb_client
*client
)
87 ebb_server
*server
= client
->server
;
88 if(client
->open
== FALSE
)
90 client
->in_use
= TRUE
;
92 /* XXX decide if to use keep-alive or not? */
94 server
->request_cb(client
, server
->request_cb_data
);
98 static void on_timeout(struct ev_loop
*loop
, ev_timer
*watcher
, int revents
)
100 ebb_client
*client
= (ebb_client
*)(watcher
->data
);
102 assert(client
->server
->loop
== loop
);
103 assert(&(client
->timeout_watcher
) == watcher
);
105 ebb_client_close(client
);
107 g_message("peer timed out");
111 #define client_finished_parsing http_parser_is_finished(&client->parser)
112 #define total_request_size (client->parser.content_length + client->parser.nread)
114 static void on_client_readable(struct ev_loop
*loop
, ev_io
*watcher
, int revents
)
116 ebb_client
*client
= (ebb_client
*)(watcher
->data
);
118 assert(client
->in_use
== FALSE
);
119 assert(client
->open
);
120 assert(client
->server
->open
);
121 assert(client
->server
->loop
== loop
);
122 assert(&client
->read_watcher
== watcher
);
124 ssize_t read
= recv( client
->fd
125 , client
->request_buffer
+ client
->read
126 , EBB_BUFFERSIZE
- client
->read
129 if(read
< 0) goto error
;
130 if(read
== 0) goto error
; /* XXX is this the right action to take for read==0 ? */
131 client
->read
+= read
;
132 ev_timer_again(loop
, &client
->timeout_watcher
);
134 // if(client->read == EBB_BUFFERSIZE) goto error;
136 if(FALSE
== client_finished_parsing
) {
137 http_parser_execute( &client
->parser
138 , client
->request_buffer
140 , client
->parser
.nread
142 if(http_parser_has_error(&client
->parser
)) goto error
;
145 if(client_finished_parsing
) {
146 assert(client
->read
<= total_request_size
);
147 if(total_request_size
== client
->read
|| total_request_size
> EBB_BUFFERSIZE
) {
148 client
->body_head
= client
->request_buffer
+ client
->parser
.nread
;
149 client
->body_head_len
= client
->read
- client
->parser
.nread
;
150 ev_io_stop(loop
, watcher
);
158 if(read
< 0) g_message("Error recving data: %s", strerror(errno
));
160 ebb_client_close(client
);
164 static void on_client_writable(struct ev_loop
*loop
, ev_io
*watcher
, int revents
)
166 ebb_client
*client
= (ebb_client
*)(watcher
->data
);
169 if(client
->status_written
== FALSE
|| client
->headers_written
== FALSE
) {
170 g_message("no status or headers - closing connection.");
174 if(EV_ERROR
& revents
) {
175 g_message("on_client_writable() got error event, closing peer");
179 //if(client->written != 0)
180 // g_debug("total written: %d", (int)(client->written));
182 sent
= send( client
->fd
183 , client
->response_buffer
->str
+ sizeof(gchar
)*(client
->written
)
184 , client
->response_buffer
->len
- client
->written
189 g_message("Error writing: %s", strerror(errno
));
192 } else if(sent
== 0) {
193 /* is this the wrong thing to do? */
194 g_message("Sent zero bytes? Closing connection");
197 client
->written
+= sent
;
199 assert(client
->written
<= client
->response_buffer
->len
);
200 //g_message("wrote %d bytes. total: %d", (int)sent, (int)(client->written));
202 ev_timer_again(loop
, &client
->timeout_watcher
);
204 if(client
->written
== client
->response_buffer
->len
) {
205 /* stop the write watcher. to be restarted by the next call to ebb_client_write_body
206 * or if client->body_written is set (by using ebb_client_release) then
207 * we close the connection
209 ev_io_stop(loop
, watcher
);
210 if(client
->body_written
) {
211 client
->keep_alive
? client_init(client
) : ebb_client_close(client
);
216 ebb_client_close(client
);
220 static void client_init(ebb_client
*client
)
222 assert(client
->in_use
== FALSE
);
224 /* If the client is already open, reuse the fd, just reset all the parameters
225 * this would happen in the case of a keep_alive request
228 /* DO SOCKET STUFF */
230 int fd
= accept(client
->server
->fd
, (struct sockaddr
*)&(client
->sockaddr
), &len
);
239 set_nonblock(client
->fd
);
242 if(client
->server
->port
)
243 client
->ip
= inet_ntoa(client
->sockaddr
.sin_addr
);
245 /* INITIALIZE http_parser */
246 http_parser_init(&client
->parser
);
247 client
->parser
.data
= client
;
248 client
->parser
.http_field
= http_field_cb
;
249 client
->parser
.on_element
= on_element
;
252 client
->env_size
= 0;
254 if(client
->request_buffer
== NULL
) {
255 /* Only allocate the request_buffer once */
256 client
->request_buffer
= (char*)malloc(EBB_BUFFERSIZE
);
258 client
->keep_alive
= FALSE
;
259 client
->status_written
= client
->headers_written
= client
->body_written
= FALSE
;
262 if(client
->response_buffer
!= NULL
)
263 g_string_free(client
->response_buffer
, TRUE
);
264 client
->response_buffer
= g_string_new("");
266 /* SETUP READ AND TIMEOUT WATCHERS */
267 client
->write_watcher
.data
= client
;
268 ev_init (&client
->write_watcher
, on_client_writable
);
269 ev_io_set (&client
->write_watcher
, client
->fd
, EV_WRITE
| EV_ERROR
);
270 /* Note, do not start write_watcher until there is something to be written.
271 * See ebb_client_write_body() */
273 client
->read_watcher
.data
= client
;
274 ev_init(&client
->read_watcher
, on_client_readable
);
275 ev_io_set(&client
->read_watcher
, client
->fd
, EV_READ
| EV_ERROR
);
276 ev_io_start(client
->server
->loop
, &client
->read_watcher
);
278 client
->timeout_watcher
.data
= client
;
279 ev_timer_init(&client
->timeout_watcher
, on_timeout
, EBB_TIMEOUT
, EBB_TIMEOUT
);
280 ev_timer_start(client
->server
->loop
, &client
->timeout_watcher
);
284 static void on_request(struct ev_loop
*loop
, ev_io
*watcher
, int revents
)
286 ebb_server
*server
= (ebb_server
*)(watcher
->data
);
287 assert(server
->open
);
288 assert(server
->loop
== loop
);
289 assert(&server
->request_watcher
== watcher
);
291 if(EV_ERROR
& revents
) {
292 g_message("on_request() got error event, closing server.");
293 ebb_server_unlisten(server
);
296 /* Now we're going to initialize the client
297 * and set up her callbacks for read and write
298 * the client won't get passed back to the user, however,
299 * until the request is complete and parsed.
303 /* Get next availible peer */
304 for(i
=0; i
< EBB_MAX_CLIENTS
; i
++)
305 if(!server
->clients
[i
].in_use
&& !server
->clients
[i
].open
) {
306 client
= &(server
->clients
[i
]);
310 g_message("Too many peers. Refusing connections.");
316 for(i
= 0; i
< EBB_MAX_CLIENTS
; i
++)
317 if(server
->clients
[i
].open
) count
+= 1;
318 g_debug("%d open connections", count
);
325 ebb_server
* ebb_server_alloc()
327 ebb_server
*server
= g_new0(ebb_server
, 1);
332 void ebb_server_init( ebb_server
*server
333 , struct ev_loop
*loop
334 , ebb_request_cb request_cb
335 , void *request_cb_data
339 for(i
=0; i
< EBB_MAX_CLIENTS
; i
++) {
340 server
->clients
[i
].request_buffer
= NULL
;
341 server
->clients
[i
].response_buffer
= NULL
;
342 server
->clients
[i
].open
= FALSE
;
343 server
->clients
[i
].in_use
= FALSE
;
344 server
->clients
[i
].server
= server
;
347 server
->request_cb
= request_cb
;
348 server
->request_cb_data
= request_cb_data
;
350 server
->open
= FALSE
;
354 ebb_server_free(server
);
359 void ebb_server_free(ebb_server
*server
)
361 ebb_server_unlisten(server
);
365 if(server
->socketpath
)
366 free(server
->socketpath
);
371 void ebb_server_unlisten(ebb_server
*server
)
376 ev_io_stop(server
->loop
, &server
->request_watcher
);
378 if(server
->socketpath
) {
379 unlink(server
->socketpath
);
380 server
->socketpath
= NULL
;
386 server
->open
= FALSE
;
391 int ebb_server_listen_on_fd(ebb_server
*server
, const int sfd
)
393 if (listen(sfd
, EBB_MAX_CLIENTS
) < 0) {
398 set_nonblock(sfd
); /* XXX: superfluous? */
401 assert(server
->port
== NULL
);
402 assert(server
->socketpath
== NULL
);
403 assert(server
->open
== FALSE
);
406 server
->request_watcher
.data
= server
;
407 ev_init (&server
->request_watcher
, on_request
);
408 ev_io_set (&server
->request_watcher
, server
->fd
, EV_READ
| EV_ERROR
);
409 ev_io_start (server
->loop
, &server
->request_watcher
);
415 int ebb_server_listen_on_port(ebb_server
*server
, const int port
)
418 struct linger ling
= {0, 0};
419 struct sockaddr_in addr
;
422 if ((sfd
= socket(AF_INET
, SOCK_STREAM
, 0)) == -1) {
428 setsockopt(sfd
, SOL_SOCKET
, SO_REUSEADDR
, (void *)&flags
, sizeof(flags
));
429 setsockopt(sfd
, SOL_SOCKET
, SO_KEEPALIVE
, (void *)&flags
, sizeof(flags
));
430 setsockopt(sfd
, SOL_SOCKET
, SO_LINGER
, (void *)&ling
, sizeof(ling
));
431 setsockopt(sfd
, IPPROTO_TCP
, TCP_NODELAY
, (void *)&flags
, sizeof(flags
));
434 * the memset call clears nonstandard fields in some impementations
435 * that otherwise mess things up.
437 memset(&addr
, 0, sizeof(addr
));
439 addr
.sin_family
= AF_INET
;
440 addr
.sin_port
= htons(port
);
441 addr
.sin_addr
.s_addr
= htonl(INADDR_ANY
);
443 if (bind(sfd
, (struct sockaddr
*)&addr
, sizeof(addr
)) < 0) {
448 int ret
= ebb_server_listen_on_fd(server
, sfd
);
450 assert(server
->port
== NULL
);
451 server
->port
= malloc(sizeof(char)*8); /* for easy access to the port */
452 sprintf(server
->port
, "%d", port
);
456 if(sfd
> 0) close(sfd
);
461 int ebb_server_listen_on_unix_socket(ebb_server
*server
, const char *socketpath
)
464 struct linger ling
= {0, 0};
465 struct sockaddr_un addr
;
469 int access_mask
= 0777;
471 if(( sfd
= socket(AF_UNIX
, SOCK_STREAM
, 0) ) == -1) {
476 /* Clean up a previous socket file if we left it around */
477 if(lstat(socketpath
, &tstat
) == 0 && S_ISSOCK(tstat
.st_mode
)) {
482 setsockopt(sfd
, SOL_SOCKET
, SO_REUSEADDR
, (void *)&flags
, sizeof(flags
));
483 setsockopt(sfd
, SOL_SOCKET
, SO_KEEPALIVE
, (void *)&flags
, sizeof(flags
));
484 setsockopt(sfd
, SOL_SOCKET
, SO_LINGER
, (void *)&ling
, sizeof(ling
));
487 * the memset call clears nonstandard fields in some impementations
488 * that otherwise mess things up.
490 memset(&addr
, 0, sizeof(addr
));
492 addr
.sun_family
= AF_UNIX
;
493 strcpy(addr
.sun_path
, socketpath
);
494 old_umask
= umask( ~(access_mask
& 0777) );
496 if(bind(sfd
, (struct sockaddr
*)&addr
, sizeof(addr
)) == -1) {
502 int ret
= ebb_server_listen_on_fd(server
, sfd
);
504 assert(server
->socketpath
== NULL
);
505 server
->socketpath
= strdup(socketpath
);
509 if(sfd
> 0) close(sfd
);
514 int ebb_server_clients_in_use_p(ebb_server
*server
)
517 for(i
= 0; i
< EBB_MAX_CLIENTS
; i
++)
518 if(server
->clients
[i
].in_use
) return TRUE
;
523 void ebb_client_release(ebb_client
*client
)
525 assert(client
->in_use
);
526 client
->in_use
= FALSE
;
528 if(client
->headers_written
== FALSE
) {
529 g_string_append(client
->response_buffer
, "\r\n");
530 client
->headers_written
= TRUE
;
532 client
->body_written
= TRUE
;
534 /* If the write_watcher isn't yet active, then start it. It could be that
535 * we're streaming and the watcher has been stopped. In that case we
536 * start it again since we have more to write. */
537 if(ev_is_active(&client
->write_watcher
) == FALSE
) {
538 set_nonblock(client
->fd
);
539 ev_io_start(client
->server
->loop
, &client
->write_watcher
);
542 if(client
->written
== client
->response_buffer
->len
)
543 ebb_client_close(client
);
547 void ebb_client_close(ebb_client
*client
)
550 ev_io_stop(client
->server
->loop
, &client
->read_watcher
);
551 ev_io_stop(client
->server
->loop
, &client
->write_watcher
);
552 ev_timer_stop(client
->server
->loop
, &client
->timeout_watcher
);
556 g_string_free(client
->response_buffer
, TRUE
);
557 client
->response_buffer
= NULL
;
560 client
->open
= FALSE
;
565 void ebb_client_write_status(ebb_client
*client
, int status
, const char *reason_phrase
)
567 assert(client
->in_use
);
568 if(!client
->open
) return;
569 assert(client
->status_written
== FALSE
);
570 g_string_append_printf( client
->response_buffer
571 , "HTTP/1.1 %d %s\r\n"
575 client
->status_written
= TRUE
;
579 void ebb_client_write_header(ebb_client
*client
, const char *field
, const char *value
)
581 assert(client
->in_use
);
582 if(!client
->open
) return;
583 assert(client
->status_written
== TRUE
);
584 assert(client
->headers_written
== FALSE
);
586 if(strcmp(field
, "Connection") == 0 && strcmp(value
, "Keep-Alive") == 0) {
587 client
->keep_alive
= TRUE
;
589 g_string_append_printf( client
->response_buffer
597 void ebb_client_write_body(ebb_client
*client
, const char *data
, int length
)
599 assert(client
->in_use
);
600 if(!client
->open
) return;
602 if(client
->headers_written
== FALSE
) {
603 g_string_append(client
->response_buffer
, "\r\n");
604 client
->headers_written
= TRUE
;
607 g_string_append_len(client
->response_buffer
, data
, length
);
609 /* If the write_watcher isn't yet active, then start it. It could be that
610 * we're streaming and the watcher has been stopped. In that case we
611 * start it again since we have more to write. */
612 if(ev_is_active(&client
->write_watcher
) == FALSE
) {
613 set_nonblock(client
->fd
);
614 ev_io_start(client
->server
->loop
, &client
->write_watcher
);
618 // int ebb_client_should_keep_alive(ebb_client*)
620 // /* TODO - return boolean */
621 // if env['HTTP_VERSION'] == 'HTTP/1.0'
622 // return true if env['HTTP_CONNECTION'] =~ /Keep-Alive/i
624 // return true unless env['HTTP_CONNECTION'] =~ /close/i