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
);
286 static void on_client_writable(struct ev_loop
*loop
, ev_io
*watcher
, int revents
)
288 ebb_client
*client
= (ebb_client
*)(watcher
->data
);
291 if(client
->status_written
== FALSE
|| client
->headers_written
== FALSE
) {
292 g_message("no status or headers - closing connection.");
296 if(EV_ERROR
& revents
) {
297 g_message("on_client_writable() got error event, closing peer");
301 //if(client->written != 0)
302 // g_debug("total written: %d", (int)(client->written));
304 sent
= send( client
->fd
305 , client
->response_buffer
->str
+ sizeof(gchar
)*(client
->written
)
306 , client
->response_buffer
->len
- client
->written
311 g_message("Error writing: %s", strerror(errno
));
314 } else if(sent
== 0) {
315 /* is this the wrong thing to do? */
316 g_message("Sent zero bytes? Closing connection");
319 client
->written
+= sent
;
321 assert(client
->written
<= client
->response_buffer
->len
);
322 //g_message("wrote %d bytes. total: %d", (int)sent, (int)(client->written));
324 ev_timer_again(loop
, &(client
->timeout_watcher
));
326 if(client
->written
== client
->response_buffer
->len
) {
327 ev_io_stop(loop
, watcher
);
328 if(client
->body_written
)
329 ebb_client_close(client
);
333 ebb_client_close(client
);
337 static client_init(ebb_server
*server
, ebb_client
*client
)
339 assert(client
->in_use
== FALSE
);
341 /* does ragel fuck up if request buffer isn't null? */
342 for(i
=0; i
< EBB_BUFFERSIZE
; i
++)
343 client
->request_buffer
[i
] = 'A';
347 client
->server
= server
;
349 /* DO SOCKET STUFF */
351 client
->fd
= accept(server
->fd
, (struct sockaddr
*)&(server
->sockaddr
), &len
);
354 client
->open
= FALSE
;
358 int flags
= fcntl(client
->fd
, F_GETFL
, 0);
359 assert(0 <= fcntl(client
->fd
, F_SETFL
, flags
| O_NONBLOCK
));
361 /* INITIALIZE http_parser */
362 http_parser_init(&(client
->parser
));
363 client
->parser
.data
= client
;
364 client
->parser
.http_field
= http_field_cb
;
365 client
->parser
.request_method
= request_method_cb
;
366 client
->parser
.request_uri
= request_uri_cb
;
367 client
->parser
.fragment
= fragment_cb
;
368 client
->parser
.request_path
= request_path_cb
;
369 client
->parser
.query_string
= query_string_cb
;
370 client
->parser
.http_version
= http_version_cb
;
371 client
->parser
.content_length
= content_length_cb
;
374 client
->env_size
= 0;
375 client
->read
= client
->nread_from_body
= 0;
376 client
->response_buffer
->len
= 0; /* see note in ebb_client_close */
377 client
->content_length
= 0;
378 if(client
->request_buffer
== NULL
) {
379 client
->request_buffer
= (char*)malloc(EBB_BUFFERSIZE
);
382 client
->status_written
= FALSE
;
383 client
->headers_written
= FALSE
;
384 client
->body_written
= FALSE
;
387 /* SETUP READ AND TIMEOUT WATCHERS */
388 client
->write_watcher
.data
= client
;
389 ev_init (&client
->write_watcher
, on_client_writable
);
390 ev_io_set (&client
->write_watcher
, client
->fd
, EV_WRITE
| EV_ERROR
);
391 /* Note, do not start write_watcher until there is something to be written.
392 * See ebb_client_write_body() */
394 client
->read_watcher
.data
= client
;
395 ev_init(&client
->read_watcher
, on_client_readable
);
396 ev_io_set(&client
->read_watcher
, client
->fd
, EV_READ
| EV_ERROR
);
397 ev_io_start(server
->loop
, &client
->read_watcher
);
399 client
->timeout_watcher
.data
= client
;
400 ev_timer_init(&client
->timeout_watcher
, on_timeout
, EBB_TIMEOUT
, EBB_TIMEOUT
);
401 ev_timer_start(server
->loop
, &client
->timeout_watcher
);
404 static void on_request(struct ev_loop
*loop
, ev_io
*watcher
, int revents
)
406 ebb_server
*server
= (ebb_server
*)(watcher
->data
);
407 assert(server
->open
);
408 assert(server
->loop
== loop
);
409 assert(&server
->request_watcher
== watcher
);
411 if(EV_ERROR
& revents
) {
412 g_message("on_request() got error event, closing server.");
413 ebb_server_unlisten(server
);
416 /* Now we're going to initialize the client
417 * and set up her callbacks for read and write
418 * the client won't get passed back to the user, however,
419 * until the request is complete and parsed.
423 /* Get next availible peer */
424 for(i
=0; i
< EBB_MAX_CLIENTS
; i
++)
425 if(!server
->clients
[i
].in_use
&& !server
->clients
[i
].open
) {
426 client
= &(server
->clients
[i
]);
430 g_message("Too many peers. Refusing connections.");
436 for(i
= 0; i
< EBB_MAX_CLIENTS
; i
++)
437 if(server
->clients
[i
].open
) count
+= 1;
438 g_debug("%d open connections", count
);
441 client_init(server
, client
);
445 ebb_server
* ebb_server_alloc()
447 ebb_server
*server
= g_new0(ebb_server
, 1);
452 void ebb_server_init( ebb_server
*server
453 , struct ev_loop
*loop
454 , ebb_request_cb request_cb
455 , void *request_cb_data
459 for(i
=0; i
< EBB_MAX_CLIENTS
; i
++) {
460 server
->clients
[i
].request_buffer
= NULL
;
461 server
->clients
[i
].response_buffer
= g_string_new("");
462 server
->clients
[i
].open
= FALSE
;
463 server
->clients
[i
].in_use
= FALSE
;
466 server
->request_cb
= request_cb
;
467 server
->request_cb_data
= request_cb_data
;
469 server
->open
= FALSE
;
473 ebb_server_free(server
);
478 void ebb_server_free(ebb_server
*server
)
480 ebb_server_unlisten(server
);
483 for(i
=0; i
< EBB_MAX_CLIENTS
; i
++)
484 g_string_free(server
->clients
[i
].response_buffer
, TRUE
);
487 if(server
->socketpath
)
488 free(server
->socketpath
);
493 void ebb_server_unlisten(ebb_server
*server
)
498 ev_io_stop(server
->loop
, &server
->request_watcher
);
500 if(server
->socketpath
)
501 unlink(server
->socketpath
);
502 server
->open
= FALSE
;
506 int ebb_server_listen_on_port(ebb_server
*server
, const int port
)
509 struct linger ling
= {0, 0};
510 struct sockaddr_in addr
;
513 if ((sfd
= socket(AF_INET
, SOCK_STREAM
, 0)) == -1) {
518 flags
= fcntl(sfd
, F_GETFL
, 0);
519 if(fcntl(sfd
, F_SETFL
, flags
| O_NONBLOCK
) < 0) {
520 perror("setting O_NONBLOCK");
525 setsockopt(sfd
, SOL_SOCKET
, SO_REUSEADDR
, (void *)&flags
, sizeof(flags
));
526 setsockopt(sfd
, SOL_SOCKET
, SO_KEEPALIVE
, (void *)&flags
, sizeof(flags
));
527 setsockopt(sfd
, SOL_SOCKET
, SO_LINGER
, (void *)&ling
, sizeof(ling
));
528 setsockopt(sfd
, IPPROTO_TCP
, TCP_NODELAY
, (void *)&flags
, sizeof(flags
));
531 * the memset call clears nonstandard fields in some impementations
532 * that otherwise mess things up.
534 memset(&addr
, 0, sizeof(addr
));
536 addr
.sin_family
= AF_INET
;
537 addr
.sin_port
= htons(port
);
538 addr
.sin_addr
.s_addr
= htonl(INADDR_ANY
);
540 if (bind(sfd
, (struct sockaddr
*)&addr
, sizeof(addr
)) < 0) {
544 if (listen(sfd
, EBB_MAX_CLIENTS
) < 0) {
549 server
->port
= malloc(sizeof(char)*8); /* for easy access to the port */
550 sprintf(server
->port
, "%d", port
);
551 assert(server
->open
== FALSE
);
554 server
->request_watcher
.data
= server
;
555 ev_init (&server
->request_watcher
, on_request
);
556 ev_io_set (&server
->request_watcher
, server
->fd
, EV_READ
| EV_ERROR
);
557 ev_io_start (server
->loop
, &server
->request_watcher
);
561 if(sfd
> 0) close(sfd
);
566 int ebb_server_listen_on_socket(ebb_server
*server
, const char *socketpath
)
568 // int fd = server_socket_unix(socketpath, 0755);
569 // if(fd < 0) return 0;
570 // server->socketpath = strdup(socketpath);
572 // server_listen(server);
577 void ebb_client_release(ebb_client
*client
)
579 assert(client
->in_use
);
580 client
->in_use
= FALSE
;
581 client
->body_written
= TRUE
;
582 if(client
->written
== client
->response_buffer
->len
)
583 ebb_client_close(client
);
587 void ebb_client_close(ebb_client
*client
)
590 ev_io_stop(client
->server
->loop
, &client
->read_watcher
);
591 ev_io_stop(client
->server
->loop
, &client
->write_watcher
);
592 ev_timer_stop(client
->server
->loop
, &client
->timeout_watcher
);
594 if(client
->upload_file
) {
595 fclose(client
->upload_file
);
596 unlink(client
->upload_file_filename
);
599 /* here we do not free the already allocated GString client->response_buffer
600 * that we're holding the response in. we reuse it again -
601 * presumably because the backend is going to keep sending such long
604 client
->response_buffer
->len
= 0;
607 client
->open
= FALSE
;
612 void ebb_client_write_status(ebb_client
*client
, int status
, const char *human_status
)
614 assert(client
->in_use
);
615 if(!client
->open
) return;
616 assert(client
->status_written
== FALSE
);
617 g_string_append_printf( client
->response_buffer
618 , "HTTP/1.1 %d %s\r\n"
622 client
->status_written
= TRUE
;
625 void ebb_client_write_header(ebb_client
*client
, const char *field
, const char *value
)
627 assert(client
->in_use
);
628 if(!client
->open
) return;
629 assert(client
->status_written
== TRUE
);
630 assert(client
->headers_written
== FALSE
);
631 g_string_append_printf( client
->response_buffer
639 void ebb_client_write_body(ebb_client
*client
, const char *data
, int length
)
641 assert(client
->in_use
);
642 if(!client
->open
) return;
644 if(client
->headers_written
== FALSE
) {
645 g_string_append(client
->response_buffer
, "\r\n");
648 g_string_append_len(client
->response_buffer
, data
, length
);
650 /* If the write_watcher isn't yet active, then start it. It could be that
651 * we're streaming and the watcher has been stopped. In that case we
652 * start it again since we have more to write. */
653 if(ev_is_active(&client
->write_watcher
) == FALSE
) {
654 /* assure the socket is still in non-blocking mode */
655 int flags
= fcntl(client
->fd
, F_GETFL
, 0);
656 if(0 > fcntl(client
->fd
, F_SETFL
, flags
| O_NONBLOCK
))
657 perror("fcntl() setting non-block");
658 client
->headers_written
= TRUE
;
659 ev_io_start(client
->server
->loop
, &client
->write_watcher
);
664 /* pass an allocated buffer and the length to read. this function will try to
665 * fill the buffer with that length of data read from the body of the request.
666 * the return value says how much was actually written.
668 int ebb_client_read(ebb_client
*client
, char *buffer
, int length
)
672 assert(client
->in_use
);
673 if(!client
->open
) return -1;
674 assert(client_finished_parsing
);
676 if(client
->upload_file
) {
677 read
= fread(buffer
, 1, length
, client
->upload_file
);
678 /* TODO error checking! */
681 char* request_body
= client
->request_buffer
+ client
->parser
.nread
;
683 read
= ramp(min(length
, client
->content_length
- client
->nread_from_body
));
685 , request_body
+ client
->nread_from_body
688 client
->nread_from_body
+= read
;
693 /* The following socket creation routines are modified and stolen from memcached */
696 static int server_socket_unix(const char *path
, int access_mask
) {
698 struct linger ling
= {0, 0};
699 struct sockaddr_un addr
;
708 if ((sfd
= socket(AF_UNIX
, SOCK_STREAM
, 0)) == -1) {
713 if ((flags
= fcntl(sfd
, F_GETFL
, 0)) < 0 ||
714 fcntl(sfd
, F_SETFL
, flags
| O_NONBLOCK
) < 0) {
715 perror("setting O_NONBLOCK");
721 * Clean up a previous socket file if we left it around
723 if (lstat(path
, &tstat
) == 0) {
724 if (S_ISSOCK(tstat
.st_mode
))
729 setsockopt(sfd
, SOL_SOCKET
, SO_REUSEADDR
, (void *)&flags
, sizeof(flags
));
730 setsockopt(sfd
, SOL_SOCKET
, SO_KEEPALIVE
, (void *)&flags
, sizeof(flags
));
731 setsockopt(sfd
, SOL_SOCKET
, SO_LINGER
, (void *)&ling
, sizeof(ling
));
734 * the memset call clears nonstandard fields in some impementations
735 * that otherwise mess things up.
737 memset(&addr
, 0, sizeof(addr
));
739 addr
.sun_family
= AF_UNIX
;
740 strcpy(addr
.sun_path
, path
);
741 old_umask
=umask( ~(access_mask
&0777));
742 if (bind(sfd
, (struct sockaddr
*)&addr
, sizeof(addr
)) == -1) {
749 if (listen(sfd
, EBB_MAX_CLIENTS
) == -1) {