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(const int port
);
33 static int server_socket_unix(const char *path
, int access_mask
);
35 void env_add(ebb_client
*client
, const char *field
, int flen
, const char *value
, int vlen
)
37 if(client
->env_size
>= EBB_MAX_ENV
) {
38 client
->parser
.overflow_error
= TRUE
;
41 client
->env
[client
->env_size
].type
= EBB_FIELD_VALUE_PAIR
;
42 client
->env
[client
->env_size
].field
= field
;
43 client
->env
[client
->env_size
].field_length
= flen
;
44 client
->env
[client
->env_size
].value
= value
;
45 client
->env
[client
->env_size
].value_length
= vlen
;
46 client
->env_size
+= 1;
50 void env_add_const(ebb_client
*client
, int type
, const char *value
, int vlen
)
52 if(client
->env_size
>= EBB_MAX_ENV
) {
53 client
->parser
.overflow_error
= TRUE
;
56 client
->env
[client
->env_size
].type
= type
;
57 client
->env
[client
->env_size
].field
= NULL
;
58 client
->env
[client
->env_size
].field_length
= -1;
59 client
->env
[client
->env_size
].value
= value
;
60 client
->env
[client
->env_size
].value_length
= vlen
;
61 client
->env_size
+= 1;
65 void http_field_cb(void *data
, const char *field
, size_t flen
, const char *value
, size_t vlen
)
67 ebb_client
*client
= (ebb_client
*)(data
);
68 assert(field
!= NULL
);
69 assert(value
!= NULL
);
70 env_add(client
, field
, flen
, value
, vlen
);
74 void request_method_cb(void *data
, const char *at
, size_t length
)
76 ebb_client
*client
= (ebb_client
*)(data
);
77 env_add_const(client
, EBB_REQUEST_METHOD
, at
, length
);
81 void request_uri_cb(void *data
, const char *at
, size_t length
)
83 ebb_client
*client
= (ebb_client
*)(data
);
84 env_add_const(client
, EBB_REQUEST_URI
, at
, length
);
88 void fragment_cb(void *data
, const char *at
, size_t length
)
90 ebb_client
*client
= (ebb_client
*)(data
);
91 env_add_const(client
, EBB_FRAGMENT
, at
, length
);
95 void request_path_cb(void *data
, const char *at
, size_t length
)
97 ebb_client
*client
= (ebb_client
*)(data
);
98 env_add_const(client
, EBB_REQUEST_PATH
, at
, length
);
102 void query_string_cb(void *data
, const char *at
, size_t length
)
104 ebb_client
*client
= (ebb_client
*)(data
);
105 env_add_const(client
, EBB_QUERY_STRING
, at
, length
);
109 void http_version_cb(void *data
, const char *at
, size_t length
)
111 ebb_client
*client
= (ebb_client
*)(data
);
112 env_add_const(client
, EBB_HTTP_VERSION
, at
, length
);
116 void content_length_cb(void *data
, const char *at
, size_t length
)
118 ebb_client
*client
= (ebb_client
*)(data
);
119 env_add_const(client
, EBB_CONTENT_LENGTH
, at
, length
);
120 /* atoi_length - why isn't this in the statndard library? i hate c */
122 for(mult
=1, i
=length
-1; i
>=0; i
--, mult
*=10)
123 client
->content_length
+= (at
[i
] - '0') * mult
;
127 const char* localhost_str
= "0.0.0.0";
128 void dispatch(ebb_client
*client
)
130 ebb_server
*server
= client
->server
;
132 if(client
->open
== FALSE
)
135 /* Set the env variables */
137 env_add_const(client
, EBB_SERVER_NAME
141 env_add_const(client
, EBB_SERVER_PORT
143 , strlen(server
->port
)
146 server
->request_cb(client
, server
->request_cb_data
);
150 void on_timeout(struct ev_loop
*loop
, ev_timer
*watcher
, int revents
)
152 ebb_client
*client
= (ebb_client
*)(watcher
->data
);
154 assert(client
->server
->loop
== loop
);
155 assert(&(client
->timeout_watcher
) == watcher
);
157 ebb_client_close(client
);
159 g_message("peer timed out");
163 #define client_finished_parsing http_parser_is_finished(&client->parser)
164 #define total_request_size (client->content_length + client->parser.nread)
166 void* read_body_into_file(void *_client
)
168 ebb_client
*client
= (ebb_client
*)_client
;
169 static unsigned int id
;
172 assert(client
->open
);
173 assert(client
->server
->open
);
174 assert(client
->content_length
> 0);
175 assert(client_finished_parsing
);
177 /* set blocking socket */
178 int flags
= fcntl(client
->fd
, F_GETFL
, 0);
179 assert(0 <= fcntl(client
->fd
, F_SETFL
, flags
& ~O_NONBLOCK
));
181 sprintf(client
->upload_file_filename
, "/tmp/ebb_upload_%010d", id
++);
182 tmpfile
= fopen(client
->upload_file_filename
, "w+");
183 if(tmpfile
== NULL
) g_message("Cannot open tmpfile %s", client
->upload_file_filename
);
184 client
->upload_file
= tmpfile
;
186 size_t body_head_length
= client
->read
- client
->parser
.nread
;
187 size_t written
= 0, r
;
188 while(written
< body_head_length
) {
189 r
= fwrite( client
->request_buffer
+ sizeof(char)*(client
->parser
.nread
+ written
)
191 , body_head_length
- written
195 ebb_client_close(client
);
201 int bufsize
= 5*1024;
202 char buffer
[bufsize
];
204 while(written
< client
->content_length
) {
205 received
= recv(client
->fd
207 , min(client
->content_length
- written
, bufsize
)
210 if(received
< 0) goto error
;
211 client
->read
+= received
;
215 while(w
< received
) {
216 rv
= fwrite( buffer
+ w
*sizeof(char)
221 if(rv
<= 0) goto error
;
227 // g_debug("%d bytes written to file %s", written, client->upload_file_filename);
231 ebb_client_close(client
);
236 void on_readable(struct ev_loop
*loop
, ev_io
*watcher
, int revents
)
238 ebb_client
*client
= (ebb_client
*)(watcher
->data
);
240 assert(client
->open
);
241 assert(client
->server
->open
);
242 assert(client
->server
->loop
== loop
);
243 assert(&client
->read_watcher
== watcher
);
245 ssize_t read
= recv( client
->fd
246 , client
->request_buffer
+ client
->read
247 , EBB_BUFFERSIZE
- client
->read
250 if(read
< 0) goto error
; /* XXX is this the right action to take for read==0 ? */
251 if(read
== 0) return;
252 client
->read
+= read
;
253 ev_timer_again(loop
, &client
->timeout_watcher
);
255 if(client
->read
== EBB_BUFFERSIZE
) goto error
;
257 if(FALSE
== client_finished_parsing
) {
258 http_parser_execute( &client
->parser
259 , client
->request_buffer
261 , client
->parser
.nread
263 if(http_parser_has_error(&client
->parser
)) goto error
;
266 if(client_finished_parsing
) {
267 if(total_request_size
== client
->read
) {
268 ev_io_stop(loop
, watcher
);
269 client
->nread_from_body
= 0;
273 if(total_request_size
> EBB_BUFFERSIZE
) {
274 /* read body into file - in a thread */
275 ev_io_stop(loop
, watcher
);
277 assert(0 <= pthread_create(&thread
, NULL
, read_body_into_file
, client
));
278 pthread_detach(thread
);
284 if(read
< 0) g_message("Error recving data: %s", strerror(errno
));
285 ebb_client_close(client
);
289 void on_request(struct ev_loop
*loop
, ev_io
*watcher
, int revents
)
291 ebb_server
*server
= (ebb_server
*)(watcher
->data
);
292 assert(server
->open
);
293 assert(server
->loop
== loop
);
294 assert(&server
->request_watcher
== watcher
);
296 if(EV_ERROR
& revents
) {
297 g_message("on_request() got error event, closing server.");
298 ebb_server_unlisten(server
);
301 /* Now we're going to initialize the client
302 * and set up her callbacks for read and write
303 * the client won't get passed back to the user, however,
304 * until the request is complete and parsed.
308 /* Get next availible peer */
309 for(i
=0; i
< EBB_MAX_CLIENTS
; i
++)
310 if(!server
->clients
[i
].open
) {
311 client
= &(server
->clients
[i
]);
315 g_message("Too many peers. Refusing connections.");
321 for(i
= 0; i
< EBB_MAX_CLIENTS
; i
++)
322 if(server
->clients
[i
].open
) count
+= 1;
323 g_debug("%d open connections", count
);
325 /* does ragel fuck up if request buffer isn't null? */
326 for(i
=0; i
< EBB_BUFFERSIZE
; i
++)
327 client
->request_buffer
[i
] = 'A';
331 client
->server
= server
;
333 /* DO SOCKET STUFF */
335 client
->fd
= accept(server
->fd
, (struct sockaddr
*)&(server
->sockaddr
), &len
);
336 assert(client
->fd
>= 0);
337 int flags
= fcntl(client
->fd
, F_GETFL
, 0);
338 assert(0 <= fcntl(client
->fd
, F_SETFL
, flags
| O_NONBLOCK
));
340 /* INITIALIZE http_parser */
341 http_parser_init(&(client
->parser
));
342 client
->parser
.data
= client
;
343 client
->parser
.http_field
= http_field_cb
;
344 client
->parser
.request_method
= request_method_cb
;
345 client
->parser
.request_uri
= request_uri_cb
;
346 client
->parser
.fragment
= fragment_cb
;
347 client
->parser
.request_path
= request_path_cb
;
348 client
->parser
.query_string
= query_string_cb
;
349 client
->parser
.http_version
= http_version_cb
;
350 client
->parser
.content_length
= content_length_cb
;
354 client
->env_size
= 0;
355 client
->read
= client
->nread_from_body
= 0;
356 client
->response_buffer
->len
= 0; /* see note in ebb_client_close */
357 client
->content_length
= 0;
359 client
->status_sent
= FALSE
;
360 client
->headers_sent
= FALSE
;
361 client
->body_sent
= FALSE
;
363 /* SETUP READ AND TIMEOUT WATCHERS */
364 client
->read_watcher
.data
= client
;
365 ev_init(&client
->read_watcher
, on_readable
);
366 ev_io_set(&client
->read_watcher
, client
->fd
, EV_READ
| EV_ERROR
);
367 ev_io_start(server
->loop
, &client
->read_watcher
);
369 client
->timeout_watcher
.data
= client
;
370 ev_timer_init(&client
->timeout_watcher
, on_timeout
, EBB_TIMEOUT
, EBB_TIMEOUT
);
371 ev_timer_start(server
->loop
, &client
->timeout_watcher
);
375 ebb_server
* ebb_server_alloc()
377 ebb_server
*server
= g_new0(ebb_server
, 1);
382 void ebb_server_init( ebb_server
*server
383 , struct ev_loop
*loop
384 , ebb_request_cb request_cb
385 , void *request_cb_data
389 for(i
=0; i
< EBB_MAX_CLIENTS
; i
++)
390 server
->clients
[i
].response_buffer
= g_string_new("");
392 server
->request_cb
= request_cb
;
393 server
->request_cb_data
= request_cb_data
;
395 server
->open
= FALSE
;
399 ebb_server_free(server
);
404 void ebb_server_free(ebb_server
*server
)
406 ebb_server_unlisten(server
);
409 for(i
=0; i
< EBB_MAX_CLIENTS
; i
++)
410 g_string_free(server
->clients
[i
].response_buffer
, TRUE
);
413 if(server
->socketpath
)
414 free(server
->socketpath
);
419 void ebb_server_unlisten(ebb_server
*server
)
424 ev_io_stop(server
->loop
, &server
->request_watcher
);
426 if(server
->socketpath
)
427 unlink(server
->socketpath
);
428 server
->open
= FALSE
;
433 void ebb_server_listen(ebb_server
*server
)
435 int r
= listen(server
->fd
, EBB_MAX_CLIENTS
);
437 assert(server
->open
== FALSE
);
440 server
->request_watcher
.data
= server
;
441 ev_init (&server
->request_watcher
, on_request
);
442 ev_io_set (&server
->request_watcher
, server
->fd
, EV_READ
| EV_ERROR
);
443 ev_io_start (server
->loop
, &server
->request_watcher
);
447 int ebb_server_listen_on_port(ebb_server
*server
, const int port
)
450 struct linger ling
= {0, 0};
451 struct sockaddr_in addr
;
454 if ((sfd
= socket(AF_INET
, SOCK_STREAM
, 0)) == -1) {
459 flags
= fcntl(sfd
, F_GETFL
, 0);
460 if(fcntl(sfd
, F_SETFL
, flags
| O_NONBLOCK
) < 0) {
461 perror("setting O_NONBLOCK");
466 setsockopt(sfd
, SOL_SOCKET
, SO_REUSEADDR
, (void *)&flags
, sizeof(flags
));
467 setsockopt(sfd
, SOL_SOCKET
, SO_KEEPALIVE
, (void *)&flags
, sizeof(flags
));
468 setsockopt(sfd
, SOL_SOCKET
, SO_LINGER
, (void *)&ling
, sizeof(ling
));
469 setsockopt(sfd
, IPPROTO_TCP
, TCP_NODELAY
, (void *)&flags
, sizeof(flags
));
472 * the memset call clears nonstandard fields in some impementations
473 * that otherwise mess things up.
475 memset(&addr
, 0, sizeof(addr
));
477 addr
.sin_family
= AF_INET
;
478 addr
.sin_port
= htons(port
);
479 addr
.sin_addr
.s_addr
= htonl(INADDR_ANY
);
481 if (bind(sfd
, (struct sockaddr
*)&addr
, sizeof(addr
)) < 0) {
485 if (listen(sfd
, EBB_MAX_CLIENTS
) < 0) {
490 server
->port
= malloc(sizeof(char)*8); /* for easy access to the port */
491 sprintf(server
->port
, "%d", port
);
492 ebb_server_listen(server
);
495 if(sfd
> 0) close(sfd
);
500 int ebb_server_listen_on_socket(ebb_server
*server
, const char *socketpath
)
502 int fd
= server_socket_unix(socketpath
, 0755);
504 server
->socketpath
= strdup(socketpath
);
506 ebb_server_listen(server
);
511 void ebb_client_close(ebb_client
*client
)
514 ev_io_stop(client
->server
->loop
, &client
->read_watcher
);
515 ev_io_stop(client
->server
->loop
, &client
->write_watcher
);
516 ev_timer_stop(client
->server
->loop
, &client
->timeout_watcher
);
518 if(client
->upload_file
) {
519 fclose(client
->upload_file
);
520 unlink(client
->upload_file_filename
);
523 /* here we do not free the already allocated GString client->response_buffer
524 * that we're holding the response in. we reuse it again -
525 * presumably because the backend is going to keep sending such long
528 client
->response_buffer
->len
= 0;
531 client
->open
= FALSE
;
536 void on_client_writable(struct ev_loop
*loop
, ev_io
*watcher
, int revents
)
538 ebb_client
*client
= (ebb_client
*)(watcher
->data
);
541 if(EV_ERROR
& revents
) {
542 g_message("on_client_writable() got error event, closing peer");
546 //if(client->written != 0)
547 // g_debug("total written: %d", (int)(client->written));
549 sent
= send( client
->fd
550 , client
->response_buffer
->str
+ sizeof(gchar
)*(client
->written
)
551 , client
->response_buffer
->len
- client
->written
556 g_message("Error writing: %s", strerror(errno
));
558 ebb_client_close(client
);
561 client
->written
+= sent
;
563 assert(client
->written
<= client
->response_buffer
->len
);
564 //g_message("wrote %d bytes. total: %d", (int)sent, (int)(client->written));
566 ev_timer_again(loop
, &(client
->timeout_watcher
));
568 if(client
->written
== client
->response_buffer
->len
)
569 ebb_client_close(client
);
572 void ebb_client_write_status(ebb_client
*client
, int status
, const char *human_status
)
574 assert(client
->status_sent
== FALSE
);
575 g_string_append_printf( client
->response_buffer
576 , "HTTP/1.1 %d %s\r\n"
580 client
->status_sent
= TRUE
;
583 void ebb_client_write_header(ebb_client
*client
, const char *field
, const char *value
)
585 assert(client
->status_sent
== TRUE
);
586 assert(client
->headers_sent
== FALSE
);
587 g_string_append_printf( client
->response_buffer
594 void ebb_client_write(ebb_client
*client
, const char *data
, int length
)
596 g_string_append_len(client
->response_buffer
, data
, length
);
600 void ebb_client_finished(ebb_client
*client
)
602 assert(client
->open
);
603 assert(FALSE
== ev_is_active(&(client
->write_watcher
)));
605 /* assure the socket is still in non-blocking mode
606 * in the ruby binding, for example, i change this flag
608 int flags
= fcntl(client
->fd
, F_GETFL
, 0);
609 if(0 > fcntl(client
->fd
, F_SETFL
, flags
| O_NONBLOCK
)) {
611 ebb_client_close(client
);
616 client
->write_watcher
.data
= client
;
617 ev_init (&(client
->write_watcher
), on_client_writable
);
618 ev_io_set (&(client
->write_watcher
), client
->fd
, EV_WRITE
| EV_ERROR
);
619 ev_io_start(client
->server
->loop
, &(client
->write_watcher
));
623 /* pass an allocated buffer and the length to read. this function will try to
624 * fill the buffer with that length of data read from the body of the request.
625 * the return value says how much was actually written.
627 int ebb_client_read(ebb_client
*client
, char *buffer
, int length
)
631 assert(client
->open
);
632 assert(client_finished_parsing
);
634 if(client
->upload_file
) {
635 read
= fread(buffer
, 1, length
, client
->upload_file
);
636 /* TODO error checking! */
639 char* request_body
= client
->request_buffer
+ client
->parser
.nread
;
641 read
= ramp(min(length
, client
->content_length
- client
->nread_from_body
));
643 , request_body
+ client
->nread_from_body
646 client
->nread_from_body
+= read
;
651 /* The following socket creation routines are modified and stolen from memcached */
654 static int server_socket_unix(const char *path
, int access_mask
) {
656 struct linger ling
= {0, 0};
657 struct sockaddr_un addr
;
666 if ((sfd
= socket(AF_UNIX
, SOCK_STREAM
, 0)) == -1) {
671 if ((flags
= fcntl(sfd
, F_GETFL
, 0)) < 0 ||
672 fcntl(sfd
, F_SETFL
, flags
| O_NONBLOCK
) < 0) {
673 perror("setting O_NONBLOCK");
679 * Clean up a previous socket file if we left it around
681 if (lstat(path
, &tstat
) == 0) {
682 if (S_ISSOCK(tstat
.st_mode
))
687 setsockopt(sfd
, SOL_SOCKET
, SO_REUSEADDR
, (void *)&flags
, sizeof(flags
));
688 setsockopt(sfd
, SOL_SOCKET
, SO_KEEPALIVE
, (void *)&flags
, sizeof(flags
));
689 setsockopt(sfd
, SOL_SOCKET
, SO_LINGER
, (void *)&ling
, sizeof(ling
));
692 * the memset call clears nonstandard fields in some impementations
693 * that otherwise mess things up.
695 memset(&addr
, 0, sizeof(addr
));
697 addr
.sun_family
= AF_UNIX
;
698 strcpy(addr
.sun_path
, path
);
699 old_umask
=umask( ~(access_mask
&0777));
700 if (bind(sfd
, (struct sockaddr
*)&addr
, sizeof(addr
)) == -1) {
707 if (listen(sfd
, EBB_MAX_CLIENTS
) == -1) {