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>
23 #define EV_STANDALONE 1
29 #define min(a,b) (a < b ? a : b)
30 #define ramp(a) (a > 0 ? a : 0)
32 static int server_socket_unix(const char *path
, int access_mask
);
34 void env_add(ebb_client
*client
, const char *field
, int flen
, const char *value
, int vlen
)
36 if(client
->env_size
>= EBB_MAX_ENV
) {
37 client
->parser
.overflow_error
= TRUE
;
40 client
->env
[client
->env_size
].type
= EBB_FIELD_VALUE_PAIR
;
41 client
->env
[client
->env_size
].field
= field
;
42 client
->env
[client
->env_size
].field_length
= flen
;
43 client
->env
[client
->env_size
].value
= value
;
44 client
->env
[client
->env_size
].value_length
= vlen
;
45 client
->env_size
+= 1;
49 void env_add_const(ebb_client
*client
, int type
, const char *value
, int vlen
)
51 if(client
->env_size
>= EBB_MAX_ENV
) {
52 client
->parser
.overflow_error
= TRUE
;
55 client
->env
[client
->env_size
].type
= type
;
56 client
->env
[client
->env_size
].field
= NULL
;
57 client
->env
[client
->env_size
].field_length
= -1;
58 client
->env
[client
->env_size
].value
= value
;
59 client
->env
[client
->env_size
].value_length
= vlen
;
60 client
->env_size
+= 1;
64 void http_field_cb(void *data
, const char *field
, size_t flen
, const char *value
, size_t vlen
)
66 ebb_client
*client
= (ebb_client
*)(data
);
67 assert(field
!= NULL
);
68 assert(value
!= NULL
);
69 env_add(client
, field
, flen
, value
, vlen
);
73 void request_method_cb(void *data
, const char *at
, size_t length
)
75 ebb_client
*client
= (ebb_client
*)(data
);
76 env_add_const(client
, EBB_REQUEST_METHOD
, at
, length
);
80 void request_uri_cb(void *data
, const char *at
, size_t length
)
82 ebb_client
*client
= (ebb_client
*)(data
);
83 env_add_const(client
, EBB_REQUEST_URI
, at
, length
);
87 void fragment_cb(void *data
, const char *at
, size_t length
)
89 ebb_client
*client
= (ebb_client
*)(data
);
90 env_add_const(client
, EBB_FRAGMENT
, at
, length
);
94 void request_path_cb(void *data
, const char *at
, size_t length
)
96 ebb_client
*client
= (ebb_client
*)(data
);
97 env_add_const(client
, EBB_REQUEST_PATH
, at
, length
);
101 void query_string_cb(void *data
, const char *at
, size_t length
)
103 ebb_client
*client
= (ebb_client
*)(data
);
104 env_add_const(client
, EBB_QUERY_STRING
, at
, length
);
108 void http_version_cb(void *data
, const char *at
, size_t length
)
110 ebb_client
*client
= (ebb_client
*)(data
);
111 env_add_const(client
, EBB_HTTP_VERSION
, at
, length
);
115 void content_length_cb(void *data
, const char *at
, size_t length
)
117 ebb_client
*client
= (ebb_client
*)(data
);
118 env_add_const(client
, EBB_CONTENT_LENGTH
, at
, length
);
119 /* atoi_length - why isn't this in the statndard library? i hate c */
120 assert(client
->content_length
== 0);
122 for(mult
=1, i
=length
-1; i
>=0; i
--, mult
*=10)
123 client
->content_length
+= (at
[i
] - '0') * mult
;
127 static void dispatch(ebb_client
*client
)
129 ebb_server
*server
= client
->server
;
131 if(client
->open
== FALSE
)
134 /* Set the env variables */
136 env_add_const(client
, EBB_SERVER_PORT
138 , strlen(server
->port
)
141 client
->in_use
= TRUE
;
142 server
->request_cb(client
, server
->request_cb_data
);
146 static void on_timeout(struct ev_loop
*loop
, ev_timer
*watcher
, int revents
)
148 ebb_client
*client
= (ebb_client
*)(watcher
->data
);
150 assert(client
->server
->loop
== loop
);
151 assert(&(client
->timeout_watcher
) == watcher
);
153 ebb_client_close(client
);
155 g_message("peer timed out");
159 #define client_finished_parsing http_parser_is_finished(&client->parser)
160 #define total_request_size (client->content_length + client->parser.nread)
162 static void* read_body_into_file(void *_client
)
164 ebb_client
*client
= (ebb_client
*)_client
;
165 static unsigned int id
;
168 assert(client
->open
);
169 assert(client
->server
->open
);
170 assert(client
->content_length
> 0);
171 assert(client_finished_parsing
);
173 /* set blocking socket */
174 int flags
= fcntl(client
->fd
, F_GETFL
, 0);
175 assert(0 <= fcntl(client
->fd
, F_SETFL
, flags
& ~O_NONBLOCK
));
177 sprintf(client
->upload_file_filename
, "/tmp/ebb_upload_%010d", id
++);
178 tmpfile
= fopen(client
->upload_file_filename
, "w+");
179 if(tmpfile
== NULL
) g_message("Cannot open tmpfile %s", client
->upload_file_filename
);
180 client
->upload_file
= tmpfile
;
182 size_t body_head_length
= client
->read
- client
->parser
.nread
;
183 size_t written
= 0, r
;
184 while(written
< body_head_length
) {
185 r
= fwrite( client
->request_buffer
+ sizeof(char)*(client
->parser
.nread
+ written
)
187 , body_head_length
- written
191 ebb_client_close(client
);
197 int bufsize
= 5*1024;
198 char buffer
[bufsize
];
200 while(written
< client
->content_length
) {
201 received
= recv(client
->fd
203 , min(client
->content_length
- written
, bufsize
)
206 if(received
< 0) goto error
;
207 client
->read
+= received
;
211 while(w
< received
) {
212 rv
= fwrite( buffer
+ w
*sizeof(char)
217 if(rv
<= 0) goto error
;
223 // g_debug("%d bytes written to file %s", written, client->upload_file_filename);
227 ebb_client_close(client
);
232 static void on_client_readable(struct ev_loop
*loop
, ev_io
*watcher
, int revents
)
234 ebb_client
*client
= (ebb_client
*)(watcher
->data
);
236 assert(client
->in_use
== FALSE
);
237 assert(client
->open
);
238 assert(client
->server
->open
);
239 assert(client
->server
->loop
== loop
);
240 assert(&client
->read_watcher
== watcher
);
242 ssize_t read
= recv( client
->fd
243 , client
->request_buffer
+ client
->read
244 , EBB_BUFFERSIZE
- client
->read
247 if(read
< 0) goto error
;
248 if(read
== 0) goto error
; /* XXX is this the right action to take for read==0 ? */
249 client
->read
+= read
;
250 ev_timer_again(loop
, &client
->timeout_watcher
);
252 if(client
->read
== EBB_BUFFERSIZE
) goto error
;
254 if(FALSE
== client_finished_parsing
) {
255 http_parser_execute( &client
->parser
256 , client
->request_buffer
258 , client
->parser
.nread
260 if(http_parser_has_error(&client
->parser
)) goto error
;
263 if(client_finished_parsing
) {
264 if(total_request_size
== client
->read
) {
265 ev_io_stop(loop
, watcher
);
266 client
->nread_from_body
= 0;
270 if(total_request_size
> EBB_BUFFERSIZE
) {
271 /* read body into file - in a thread */
272 ev_io_stop(loop
, watcher
);
274 assert(0 <= pthread_create(&thread
, NULL
, read_body_into_file
, client
));
275 pthread_detach(thread
);
281 if(read
< 0) g_message("Error recving data: %s", strerror(errno
));
282 ebb_client_close(client
);
285 static client_init(ebb_server
*server
, ebb_client
*client
)
287 assert(client
->in_use
== FALSE
);
289 /* does ragel fuck up if request buffer isn't null? */
290 for(i
=0; i
< EBB_BUFFERSIZE
; i
++)
291 client
->request_buffer
[i
] = 'A';
295 client
->server
= server
;
297 /* DO SOCKET STUFF */
299 client
->fd
= accept(server
->fd
, (struct sockaddr
*)&(server
->sockaddr
), &len
);
300 assert(client
->fd
>= 0);
301 int flags
= fcntl(client
->fd
, F_GETFL
, 0);
302 assert(0 <= fcntl(client
->fd
, F_SETFL
, flags
| O_NONBLOCK
));
304 /* INITIALIZE http_parser */
305 http_parser_init(&(client
->parser
));
306 client
->parser
.data
= client
;
307 client
->parser
.http_field
= http_field_cb
;
308 client
->parser
.request_method
= request_method_cb
;
309 client
->parser
.request_uri
= request_uri_cb
;
310 client
->parser
.fragment
= fragment_cb
;
311 client
->parser
.request_path
= request_path_cb
;
312 client
->parser
.query_string
= query_string_cb
;
313 client
->parser
.http_version
= http_version_cb
;
314 client
->parser
.content_length
= content_length_cb
;
317 client
->env_size
= 0;
318 client
->read
= client
->nread_from_body
= 0;
319 client
->response_buffer
->len
= 0; /* see note in ebb_client_close */
320 client
->content_length
= 0;
322 client
->status_written
= FALSE
;
323 client
->headers_written
= FALSE
;
324 client
->body_written
= FALSE
;
325 client
->began_transmission
= FALSE
;
327 /* SETUP READ AND TIMEOUT WATCHERS */
328 client
->read_watcher
.data
= client
;
329 ev_init(&client
->read_watcher
, on_client_readable
);
330 ev_io_set(&client
->read_watcher
, client
->fd
, EV_READ
| EV_ERROR
);
331 ev_io_start(server
->loop
, &client
->read_watcher
);
333 client
->timeout_watcher
.data
= client
;
334 ev_timer_init(&client
->timeout_watcher
, on_timeout
, EBB_TIMEOUT
, EBB_TIMEOUT
);
335 ev_timer_start(server
->loop
, &client
->timeout_watcher
);
338 static void on_request(struct ev_loop
*loop
, ev_io
*watcher
, int revents
)
340 ebb_server
*server
= (ebb_server
*)(watcher
->data
);
341 assert(server
->open
);
342 assert(server
->loop
== loop
);
343 assert(&server
->request_watcher
== watcher
);
345 if(EV_ERROR
& revents
) {
346 g_message("on_request() got error event, closing server.");
347 ebb_server_unlisten(server
);
350 /* Now we're going to initialize the client
351 * and set up her callbacks for read and write
352 * the client won't get passed back to the user, however,
353 * until the request is complete and parsed.
357 /* Get next availible peer */
358 for(i
=0; i
< EBB_MAX_CLIENTS
; i
++)
359 if(!server
->clients
[i
].in_use
&& !server
->clients
[i
].open
) {
360 client
= &(server
->clients
[i
]);
364 g_message("Too many peers. Refusing connections.");
370 for(i
= 0; i
< EBB_MAX_CLIENTS
; i
++)
371 if(server
->clients
[i
].open
) count
+= 1;
372 g_debug("%d open connections", count
);
375 client_init(server
, client
);
379 ebb_server
* ebb_server_alloc()
381 ebb_server
*server
= g_new0(ebb_server
, 1);
386 void ebb_server_init( ebb_server
*server
387 , struct ev_loop
*loop
388 , ebb_request_cb request_cb
389 , void *request_cb_data
393 for(i
=0; i
< EBB_MAX_CLIENTS
; i
++) {
394 server
->clients
[i
].response_buffer
= g_string_new("");
395 server
->clients
[i
].open
= FALSE
;
396 server
->clients
[i
].in_use
= FALSE
;
399 server
->request_cb
= request_cb
;
400 server
->request_cb_data
= request_cb_data
;
402 server
->open
= FALSE
;
406 ebb_server_free(server
);
411 void ebb_server_free(ebb_server
*server
)
413 ebb_server_unlisten(server
);
416 for(i
=0; i
< EBB_MAX_CLIENTS
; i
++)
417 g_string_free(server
->clients
[i
].response_buffer
, TRUE
);
420 if(server
->socketpath
)
421 free(server
->socketpath
);
426 void ebb_server_unlisten(ebb_server
*server
)
431 ev_io_stop(server
->loop
, &server
->request_watcher
);
433 if(server
->socketpath
)
434 unlink(server
->socketpath
);
435 server
->open
= FALSE
;
439 int ebb_server_listen_on_port(ebb_server
*server
, const int port
)
442 struct linger ling
= {0, 0};
443 struct sockaddr_in addr
;
446 if ((sfd
= socket(AF_INET
, SOCK_STREAM
, 0)) == -1) {
451 flags
= fcntl(sfd
, F_GETFL
, 0);
452 if(fcntl(sfd
, F_SETFL
, flags
| O_NONBLOCK
) < 0) {
453 perror("setting O_NONBLOCK");
458 setsockopt(sfd
, SOL_SOCKET
, SO_REUSEADDR
, (void *)&flags
, sizeof(flags
));
459 setsockopt(sfd
, SOL_SOCKET
, SO_KEEPALIVE
, (void *)&flags
, sizeof(flags
));
460 setsockopt(sfd
, SOL_SOCKET
, SO_LINGER
, (void *)&ling
, sizeof(ling
));
461 setsockopt(sfd
, IPPROTO_TCP
, TCP_NODELAY
, (void *)&flags
, sizeof(flags
));
464 * the memset call clears nonstandard fields in some impementations
465 * that otherwise mess things up.
467 memset(&addr
, 0, sizeof(addr
));
469 addr
.sin_family
= AF_INET
;
470 addr
.sin_port
= htons(port
);
471 addr
.sin_addr
.s_addr
= htonl(INADDR_ANY
);
473 if (bind(sfd
, (struct sockaddr
*)&addr
, sizeof(addr
)) < 0) {
477 if (listen(sfd
, EBB_MAX_CLIENTS
) < 0) {
482 server
->port
= malloc(sizeof(char)*8); /* for easy access to the port */
483 sprintf(server
->port
, "%d", port
);
484 assert(server
->open
== FALSE
);
487 server
->request_watcher
.data
= server
;
488 ev_init (&server
->request_watcher
, on_request
);
489 ev_io_set (&server
->request_watcher
, server
->fd
, EV_READ
| EV_ERROR
);
490 ev_io_start (server
->loop
, &server
->request_watcher
);
494 if(sfd
> 0) close(sfd
);
499 int ebb_server_listen_on_socket(ebb_server
*server
, const char *socketpath
)
501 // int fd = server_socket_unix(socketpath, 0755);
502 // if(fd < 0) return 0;
503 // server->socketpath = strdup(socketpath);
505 // server_listen(server);
510 void ebb_client_release(ebb_client
*client
)
512 assert(client
->in_use
);
513 client
->in_use
= FALSE
;
514 if(client
->written
== client
->response_buffer
->len
)
515 ebb_client_close(client
);
519 void ebb_client_close(ebb_client
*client
)
522 ev_io_stop(client
->server
->loop
, &client
->read_watcher
);
523 ev_io_stop(client
->server
->loop
, &client
->write_watcher
);
524 ev_timer_stop(client
->server
->loop
, &client
->timeout_watcher
);
526 if(client
->upload_file
) {
527 fclose(client
->upload_file
);
528 unlink(client
->upload_file_filename
);
531 /* here we do not free the already allocated GString client->response_buffer
532 * that we're holding the response in. we reuse it again -
533 * presumably because the backend is going to keep sending such long
536 client
->response_buffer
->len
= 0;
539 client
->open
= FALSE
;
544 static void on_client_writable(struct ev_loop
*loop
, ev_io
*watcher
, int revents
)
546 ebb_client
*client
= (ebb_client
*)(watcher
->data
);
549 assert(client
->status_written
);
550 assert(client
->headers_written
);
551 assert(client
->began_transmission
);
553 if(EV_ERROR
& revents
) {
554 g_message("on_client_writable() got error event, closing peer");
555 ebb_client_close(client
);
559 //if(client->written != 0)
560 // g_debug("total written: %d", (int)(client->written));
562 sent
= send( client
->fd
563 , client
->response_buffer
->str
+ sizeof(gchar
)*(client
->written
)
564 , client
->response_buffer
->len
- client
->written
569 g_message("Error writing: %s", strerror(errno
));
571 ebb_client_close(client
);
573 } else if(sent
== 0) {
574 g_message("Sent zero bytes? Closing connection");
575 ebb_client_close(client
);
577 client
->written
+= sent
;
579 assert(client
->written
<= client
->response_buffer
->len
);
580 //g_message("wrote %d bytes. total: %d", (int)sent, (int)(client->written));
582 ev_timer_again(loop
, &(client
->timeout_watcher
));
584 if(client
->written
== client
->response_buffer
->len
) {
585 ev_io_stop(loop
, watcher
);
586 if(client
->body_written
)
587 ebb_client_close(client
);
591 void ebb_client_write_status(ebb_client
*client
, int status
, const char *human_status
)
593 assert(client
->in_use
);
594 if(!client
->open
) return;
595 assert(client
->status_written
== FALSE
);
596 g_string_append_printf( client
->response_buffer
597 , "HTTP/1.1 %d %s\r\n"
601 client
->status_written
= TRUE
;
604 void ebb_client_write_header(ebb_client
*client
, const char *field
, const char *value
)
606 assert(client
->in_use
);
607 if(!client
->open
) return;
608 assert(client
->status_written
== TRUE
);
609 assert(client
->headers_written
== FALSE
);
610 g_string_append_printf( client
->response_buffer
617 void ebb_client_write(ebb_client
*client
, const char *data
, int length
)
619 assert(client
->in_use
);
620 if(!client
->open
) return;
621 g_string_append_len(client
->response_buffer
, data
, length
);
622 if(client
->began_transmission
) {
623 /* restart the watcher if we're streaming */
624 ev_io_start(client
->server
->loop
, &client
->write_watcher
);
629 void ebb_client_begin_transmission(ebb_client
*client
)
631 assert(client
->in_use
);
632 if(!client
->open
) return;
633 assert(FALSE
== ev_is_active(&client
->write_watcher
));
635 /* assure the socket is still in non-blocking mode */
636 int flags
= fcntl(client
->fd
, F_GETFL
, 0);
637 if(0 > fcntl(client
->fd
, F_SETFL
, flags
| O_NONBLOCK
)) {
639 ebb_client_close(client
);
643 client
->headers_written
= TRUE
;
644 client
->began_transmission
= TRUE
;
646 client
->write_watcher
.data
= client
;
647 ev_init (&(client
->write_watcher
), on_client_writable
);
648 ev_io_set (&(client
->write_watcher
), client
->fd
, EV_WRITE
| EV_ERROR
);
649 ev_io_start(client
->server
->loop
, &client
->write_watcher
);
653 /* pass an allocated buffer and the length to read. this function will try to
654 * fill the buffer with that length of data read from the body of the request.
655 * the return value says how much was actually written.
657 int ebb_client_read(ebb_client
*client
, char *buffer
, int length
)
661 assert(client
->in_use
);
662 if(!client
->open
) return -1;
663 assert(client_finished_parsing
);
665 if(client
->upload_file
) {
666 read
= fread(buffer
, 1, length
, client
->upload_file
);
667 /* TODO error checking! */
670 char* request_body
= client
->request_buffer
+ client
->parser
.nread
;
672 read
= ramp(min(length
, client
->content_length
- client
->nread_from_body
));
674 , request_body
+ client
->nread_from_body
677 client
->nread_from_body
+= read
;
682 /* The following socket creation routines are modified and stolen from memcached */
685 static int server_socket_unix(const char *path
, int access_mask
) {
687 struct linger ling
= {0, 0};
688 struct sockaddr_un addr
;
697 if ((sfd
= socket(AF_UNIX
, SOCK_STREAM
, 0)) == -1) {
702 if ((flags
= fcntl(sfd
, F_GETFL
, 0)) < 0 ||
703 fcntl(sfd
, F_SETFL
, flags
| O_NONBLOCK
) < 0) {
704 perror("setting O_NONBLOCK");
710 * Clean up a previous socket file if we left it around
712 if (lstat(path
, &tstat
) == 0) {
713 if (S_ISSOCK(tstat
.st_mode
))
718 setsockopt(sfd
, SOL_SOCKET
, SO_REUSEADDR
, (void *)&flags
, sizeof(flags
));
719 setsockopt(sfd
, SOL_SOCKET
, SO_KEEPALIVE
, (void *)&flags
, sizeof(flags
));
720 setsockopt(sfd
, SOL_SOCKET
, SO_LINGER
, (void *)&ling
, sizeof(ling
));
723 * the memset call clears nonstandard fields in some impementations
724 * that otherwise mess things up.
726 memset(&addr
, 0, sizeof(addr
));
728 addr
.sun_family
= AF_UNIX
;
729 strcpy(addr
.sun_path
, path
);
730 old_umask
=umask( ~(access_mask
&0777));
731 if (bind(sfd
, (struct sockaddr
*)&addr
, sizeof(addr
)) == -1) {
738 if (listen(sfd
, EBB_MAX_CLIENTS
) == -1) {