ebb 0.0.4 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,6 @@
1
1
  require 'cgi'
2
+ require 'rubygems'
3
+ require 'rack'
2
4
 
3
5
  # Adapter to run a Rails app with any supported Rack handler.
4
6
  # By default it will try to load the Rails application in the
data/src/ebb.c CHANGED
@@ -29,7 +29,6 @@
29
29
  #define min(a,b) (a < b ? a : b)
30
30
  #define ramp(a) (a > 0 ? a : 0)
31
31
 
32
- static int server_socket(const int port);
33
32
  static int server_socket_unix(const char *path, int access_mask);
34
33
 
35
34
  void env_add(ebb_client *client, const char *field, int flen, const char *value, int vlen)
@@ -61,6 +60,7 @@ void env_add_const(ebb_client *client, int type, const char *value, int vlen)
61
60
  client->env_size += 1;
62
61
  }
63
62
 
63
+
64
64
  void http_field_cb(void *data, const char *field, size_t flen, const char *value, size_t vlen)
65
65
  {
66
66
  ebb_client *client = (ebb_client*)(data);
@@ -116,17 +116,15 @@ void content_length_cb(void *data, const char *at, size_t length)
116
116
  {
117
117
  ebb_client *client = (ebb_client*)(data);
118
118
  env_add_const(client, EBB_CONTENT_LENGTH, at, length);
119
-
120
- /* i hate c. */
121
- char buf[20];
122
- strncpy(buf, at, length);
123
- buf[length] = '\0';
124
- client->content_length = atoi(buf);
119
+ /* atoi_length - why isn't this in the statndard library? i hate c */
120
+ assert(client->content_length == 0);
121
+ int i, mult;
122
+ for(mult=1, i=length-1; i>=0; i--, mult*=10)
123
+ client->content_length += (at[i] - '0') * mult;
125
124
  }
126
125
 
127
126
 
128
- const char* localhost_str = "0.0.0.0";
129
- void dispatch(ebb_client *client)
127
+ static void dispatch(ebb_client *client)
130
128
  {
131
129
  ebb_server *server = client->server;
132
130
 
@@ -135,20 +133,17 @@ void dispatch(ebb_client *client)
135
133
 
136
134
  /* Set the env variables */
137
135
  if(server->port) {
138
- env_add_const(client, EBB_SERVER_NAME
139
- , localhost_str
140
- , 7
141
- );
142
136
  env_add_const(client, EBB_SERVER_PORT
143
137
  , server->port
144
138
  , strlen(server->port)
145
139
  );
146
140
  }
141
+ client->in_use = TRUE;
147
142
  server->request_cb(client, server->request_cb_data);
148
143
  }
149
144
 
150
145
 
151
- void on_timeout(struct ev_loop *loop, ev_timer *watcher, int revents)
146
+ static void on_timeout(struct ev_loop *loop, ev_timer *watcher, int revents)
152
147
  {
153
148
  ebb_client *client = (ebb_client*)(watcher->data);
154
149
 
@@ -164,7 +159,7 @@ void on_timeout(struct ev_loop *loop, ev_timer *watcher, int revents)
164
159
  #define client_finished_parsing http_parser_is_finished(&client->parser)
165
160
  #define total_request_size (client->content_length + client->parser.nread)
166
161
 
167
- void* read_body_into_file(void *_client)
162
+ static void* read_body_into_file(void *_client)
168
163
  {
169
164
  ebb_client *client = (ebb_client*)_client;
170
165
  static unsigned int id;
@@ -199,8 +194,6 @@ void* read_body_into_file(void *_client)
199
194
  written += r;
200
195
  }
201
196
 
202
- // g_debug("wrote request header to file. written: %d, content_length: %d", written, client->content_length);
203
-
204
197
  int bufsize = 5*1024;
205
198
  char buffer[bufsize];
206
199
  size_t received;
@@ -236,10 +229,11 @@ error:
236
229
  }
237
230
 
238
231
 
239
- void on_readable(struct ev_loop *loop, ev_io *watcher, int revents)
232
+ static void on_client_readable(struct ev_loop *loop, ev_io *watcher, int revents)
240
233
  {
241
234
  ebb_client *client = (ebb_client*)(watcher->data);
242
235
 
236
+ assert(client->in_use == FALSE);
243
237
  assert(client->open);
244
238
  assert(client->server->open);
245
239
  assert(client->server->loop == loop);
@@ -250,8 +244,8 @@ void on_readable(struct ev_loop *loop, ev_io *watcher, int revents)
250
244
  , EBB_BUFFERSIZE - client->read
251
245
  , 0
252
246
  );
253
- if(read < 0) goto error; /* XXX is this the right action to take for read==0 ? */
254
- if(read == 0) return;
247
+ if(read < 0) goto error;
248
+ if(read == 0) goto error; /* XXX is this the right action to take for read==0 ? */
255
249
  client->read += read;
256
250
  ev_timer_again(loop, &client->timeout_watcher);
257
251
 
@@ -288,42 +282,10 @@ error:
288
282
  ebb_client_close(client);
289
283
  }
290
284
 
291
- void on_request(struct ev_loop *loop, ev_io *watcher, int revents)
285
+ static client_init(ebb_server *server, ebb_client *client)
292
286
  {
293
- ebb_server *server = (ebb_server*)(watcher->data);
294
- assert(server->open);
295
- assert(server->loop == loop);
296
- assert(&server->request_watcher == watcher);
297
-
298
- if(EV_ERROR & revents) {
299
- g_message("on_request() got error event, closing server.");
300
- ebb_server_unlisten(server);
301
- return;
302
- }
303
- /* Now we're going to initialize the client
304
- * and set up her callbacks for read and write
305
- * the client won't get passed back to the user, however,
306
- * until the request is complete and parsed.
307
- */
308
- int i;
309
- ebb_client *client;
310
- /* Get next availible peer */
311
- for(i=0; i < EBB_MAX_CLIENTS; i++)
312
- if(!server->clients[i].open) {
313
- client = &(server->clients[i]);
314
- break;
315
- }
316
- if(client == NULL) {
317
- g_message("Too many peers. Refusing connections.");
318
- return;
319
- }
320
-
287
+ assert(client->in_use == FALSE);
321
288
  #ifdef DEBUG
322
- int count = 0;
323
- for(i = 0; i < EBB_MAX_CLIENTS; i++)
324
- if(server->clients[i].open) count += 1;
325
- g_debug("%d open connections", count);
326
-
327
289
  /* does ragel fuck up if request buffer isn't null? */
328
290
  for(i=0; i< EBB_BUFFERSIZE; i++)
329
291
  client->request_buffer[i] = 'A';
@@ -335,7 +297,12 @@ void on_request(struct ev_loop *loop, ev_io *watcher, int revents)
335
297
  /* DO SOCKET STUFF */
336
298
  socklen_t len;
337
299
  client->fd = accept(server->fd, (struct sockaddr*)&(server->sockaddr), &len);
338
- assert(client->fd >= 0);
300
+ if(client->fd < 0) {
301
+ perror("accept()");
302
+ client->open = FALSE;
303
+ return;
304
+ }
305
+
339
306
  int flags = fcntl(client->fd, F_GETFL, 0);
340
307
  assert(0 <= fcntl(client->fd, F_SETFL, flags | O_NONBLOCK));
341
308
 
@@ -352,19 +319,22 @@ void on_request(struct ev_loop *loop, ev_io *watcher, int revents)
352
319
  client->parser.content_length = content_length_cb;
353
320
 
354
321
  /* OTHER */
355
-
356
322
  client->env_size = 0;
357
323
  client->read = client->nread_from_body = 0;
358
324
  client->response_buffer->len = 0; /* see note in ebb_client_close */
359
325
  client->content_length = 0;
326
+ if(client->request_buffer == NULL) {
327
+ client->request_buffer = (char*)malloc(EBB_BUFFERSIZE);
328
+ }
360
329
 
361
- client->status_sent = FALSE;
362
- client->headers_sent = FALSE;
363
- client->body_sent = FALSE;
330
+ client->status_written = FALSE;
331
+ client->headers_written = FALSE;
332
+ client->body_written = FALSE;
333
+ client->began_transmission = FALSE;
364
334
 
365
335
  /* SETUP READ AND TIMEOUT WATCHERS */
366
336
  client->read_watcher.data = client;
367
- ev_init(&client->read_watcher, on_readable);
337
+ ev_init(&client->read_watcher, on_client_readable);
368
338
  ev_io_set(&client->read_watcher, client->fd, EV_READ | EV_ERROR);
369
339
  ev_io_start(server->loop, &client->read_watcher);
370
340
 
@@ -373,6 +343,46 @@ void on_request(struct ev_loop *loop, ev_io *watcher, int revents)
373
343
  ev_timer_start(server->loop, &client->timeout_watcher);
374
344
  }
375
345
 
346
+ static void on_request(struct ev_loop *loop, ev_io *watcher, int revents)
347
+ {
348
+ ebb_server *server = (ebb_server*)(watcher->data);
349
+ assert(server->open);
350
+ assert(server->loop == loop);
351
+ assert(&server->request_watcher == watcher);
352
+
353
+ if(EV_ERROR & revents) {
354
+ g_message("on_request() got error event, closing server.");
355
+ ebb_server_unlisten(server);
356
+ return;
357
+ }
358
+ /* Now we're going to initialize the client
359
+ * and set up her callbacks for read and write
360
+ * the client won't get passed back to the user, however,
361
+ * until the request is complete and parsed.
362
+ */
363
+ int i;
364
+ ebb_client *client;
365
+ /* Get next availible peer */
366
+ for(i=0; i < EBB_MAX_CLIENTS; i++)
367
+ if(!server->clients[i].in_use && !server->clients[i].open) {
368
+ client = &(server->clients[i]);
369
+ break;
370
+ }
371
+ if(client == NULL) {
372
+ g_message("Too many peers. Refusing connections.");
373
+ return;
374
+ }
375
+
376
+ #ifdef DEBUG
377
+ int count = 0;
378
+ for(i = 0; i < EBB_MAX_CLIENTS; i++)
379
+ if(server->clients[i].open) count += 1;
380
+ g_debug("%d open connections", count);
381
+ #endif
382
+
383
+ client_init(server, client);
384
+ }
385
+
376
386
 
377
387
  ebb_server* ebb_server_alloc()
378
388
  {
@@ -388,8 +398,12 @@ void ebb_server_init( ebb_server *server
388
398
  )
389
399
  {
390
400
  int i;
391
- for(i=0; i < EBB_MAX_CLIENTS; i++)
401
+ for(i=0; i < EBB_MAX_CLIENTS; i++) {
402
+ server->clients[i].request_buffer = NULL;
392
403
  server->clients[i].response_buffer = g_string_new("");
404
+ server->clients[i].open = FALSE;
405
+ server->clients[i].in_use = FALSE;
406
+ }
393
407
 
394
408
  server->request_cb = request_cb;
395
409
  server->request_cb_data = request_cb_data;
@@ -431,11 +445,51 @@ void ebb_server_unlisten(ebb_server *server)
431
445
  }
432
446
  }
433
447
 
434
-
435
- void ebb_server_listen(ebb_server *server)
448
+ int ebb_server_listen_on_port(ebb_server *server, const int port)
436
449
  {
437
- int r = listen(server->fd, EBB_MAX_CLIENTS);
438
- assert(r >= 0);
450
+ int sfd = -1;
451
+ struct linger ling = {0, 0};
452
+ struct sockaddr_in addr;
453
+ int flags = 1;
454
+
455
+ if ((sfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
456
+ perror("socket()");
457
+ goto error;
458
+ }
459
+
460
+ flags = fcntl(sfd, F_GETFL, 0);
461
+ if(fcntl(sfd, F_SETFL, flags | O_NONBLOCK) < 0) {
462
+ perror("setting O_NONBLOCK");
463
+ goto error;
464
+ }
465
+
466
+ flags = 1;
467
+ setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, (void *)&flags, sizeof(flags));
468
+ setsockopt(sfd, SOL_SOCKET, SO_KEEPALIVE, (void *)&flags, sizeof(flags));
469
+ setsockopt(sfd, SOL_SOCKET, SO_LINGER, (void *)&ling, sizeof(ling));
470
+ setsockopt(sfd, IPPROTO_TCP, TCP_NODELAY, (void *)&flags, sizeof(flags));
471
+
472
+ /*
473
+ * the memset call clears nonstandard fields in some impementations
474
+ * that otherwise mess things up.
475
+ */
476
+ memset(&addr, 0, sizeof(addr));
477
+
478
+ addr.sin_family = AF_INET;
479
+ addr.sin_port = htons(port);
480
+ addr.sin_addr.s_addr = htonl(INADDR_ANY);
481
+
482
+ if (bind(sfd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
483
+ perror("bind()");
484
+ goto error;
485
+ }
486
+ if (listen(sfd, EBB_MAX_CLIENTS) < 0) {
487
+ perror("listen()");
488
+ goto error;
489
+ }
490
+ server->fd = sfd;
491
+ server->port = malloc(sizeof(char)*8); /* for easy access to the port */
492
+ sprintf(server->port, "%d", port);
439
493
  assert(server->open == FALSE);
440
494
  server->open = TRUE;
441
495
 
@@ -443,29 +497,31 @@ void ebb_server_listen(ebb_server *server)
443
497
  ev_init (&server->request_watcher, on_request);
444
498
  ev_io_set (&server->request_watcher, server->fd, EV_READ | EV_ERROR);
445
499
  ev_io_start (server->loop, &server->request_watcher);
500
+
501
+ return server->fd;
502
+ error:
503
+ if(sfd > 0) close(sfd);
504
+ return -1;
446
505
  }
447
506
 
448
507
 
449
- int ebb_server_listen_on_port(ebb_server *server, const int port)
508
+ int ebb_server_listen_on_socket(ebb_server *server, const char *socketpath)
450
509
  {
451
- int fd = server_socket(port);
452
- if(fd < 0) return 0;
453
- server->port = malloc(sizeof(char)*8); /* for easy access to the port */
454
- sprintf(server->port, "%d", port);
455
- server->fd = fd;
456
- ebb_server_listen(server);
457
- return fd;
510
+ // int fd = server_socket_unix(socketpath, 0755);
511
+ // if(fd < 0) return 0;
512
+ // server->socketpath = strdup(socketpath);
513
+ // server->fd = fd;
514
+ // server_listen(server);
515
+ // return fd;
458
516
  }
459
517
 
460
518
 
461
- int ebb_server_listen_on_socket(ebb_server *server, const char *socketpath)
519
+ void ebb_client_release(ebb_client *client)
462
520
  {
463
- int fd = server_socket_unix(socketpath, 0755);
464
- if(fd < 0) return 0;
465
- server->socketpath = strdup(socketpath);
466
- server->fd = fd;
467
- ebb_server_listen(server);
468
- return fd;
521
+ assert(client->in_use);
522
+ client->in_use = FALSE;
523
+ if(client->written == client->response_buffer->len)
524
+ ebb_client_close(client);
469
525
  }
470
526
 
471
527
 
@@ -494,13 +550,18 @@ void ebb_client_close(ebb_client *client)
494
550
  }
495
551
 
496
552
 
497
- void on_client_writable(struct ev_loop *loop, ev_io *watcher, int revents)
553
+ static void on_client_writable(struct ev_loop *loop, ev_io *watcher, int revents)
498
554
  {
499
555
  ebb_client *client = (ebb_client*)(watcher->data);
500
556
  ssize_t sent;
501
557
 
558
+ assert(client->status_written);
559
+ assert(client->headers_written);
560
+ assert(client->began_transmission);
561
+
502
562
  if(EV_ERROR & revents) {
503
563
  g_message("on_client_writable() got error event, closing peer");
564
+ ebb_client_close(client);
504
565
  return;
505
566
  }
506
567
 
@@ -518,6 +579,9 @@ void on_client_writable(struct ev_loop *loop, ev_io *watcher, int revents)
518
579
  #endif
519
580
  ebb_client_close(client);
520
581
  return;
582
+ } else if(sent == 0) {
583
+ g_message("Sent zero bytes? Closing connection");
584
+ ebb_client_close(client);
521
585
  }
522
586
  client->written += sent;
523
587
 
@@ -526,25 +590,32 @@ void on_client_writable(struct ev_loop *loop, ev_io *watcher, int revents)
526
590
 
527
591
  ev_timer_again(loop, &(client->timeout_watcher));
528
592
 
529
- if(client->written == client->response_buffer->len)
530
- ebb_client_close(client);
593
+ if(client->written == client->response_buffer->len) {
594
+ ev_io_stop(loop, watcher);
595
+ if(client->body_written)
596
+ ebb_client_close(client);
597
+ }
531
598
  }
532
599
 
533
600
  void ebb_client_write_status(ebb_client *client, int status, const char *human_status)
534
601
  {
535
- assert(client->status_sent == FALSE);
602
+ assert(client->in_use);
603
+ if(!client->open) return;
604
+ assert(client->status_written == FALSE);
536
605
  g_string_append_printf( client->response_buffer
537
606
  , "HTTP/1.1 %d %s\r\n"
538
607
  , status
539
608
  , human_status
540
609
  );
541
- client->status_sent = TRUE;
610
+ client->status_written = TRUE;
542
611
  }
543
612
 
544
613
  void ebb_client_write_header(ebb_client *client, const char *field, const char *value)
545
614
  {
546
- assert(client->status_sent == TRUE);
547
- assert(client->headers_sent == FALSE);
615
+ assert(client->in_use);
616
+ if(!client->open) return;
617
+ assert(client->status_written == TRUE);
618
+ assert(client->headers_written == FALSE);
548
619
  g_string_append_printf( client->response_buffer
549
620
  , "%s: %s\r\n"
550
621
  , field
@@ -554,18 +625,23 @@ void ebb_client_write_header(ebb_client *client, const char *field, const char *
554
625
 
555
626
  void ebb_client_write(ebb_client *client, const char *data, int length)
556
627
  {
628
+ assert(client->in_use);
629
+ if(!client->open) return;
557
630
  g_string_append_len(client->response_buffer, data, length);
631
+ if(client->began_transmission) {
632
+ /* restart the watcher if we're streaming */
633
+ ev_io_start(client->server->loop, &client->write_watcher);
634
+ }
558
635
  }
559
636
 
560
637
 
561
- void ebb_client_finished(ebb_client *client)
638
+ void ebb_client_begin_transmission(ebb_client *client)
562
639
  {
563
- assert(client->open);
564
- assert(FALSE == ev_is_active(&(client->write_watcher)));
640
+ assert(client->in_use);
641
+ if(!client->open) return;
642
+ assert(FALSE == ev_is_active(&client->write_watcher));
565
643
 
566
- /* assure the socket is still in non-blocking mode
567
- * in the ruby binding, for example, i change this flag
568
- */
644
+ /* assure the socket is still in non-blocking mode */
569
645
  int flags = fcntl(client->fd, F_GETFL, 0);
570
646
  if(0 > fcntl(client->fd, F_SETFL, flags | O_NONBLOCK)) {
571
647
  perror("fcntl()");
@@ -573,11 +649,13 @@ void ebb_client_finished(ebb_client *client)
573
649
  return;
574
650
  }
575
651
 
652
+ client->headers_written = TRUE;
653
+ client->began_transmission = TRUE;
576
654
  client->written = 0;
577
655
  client->write_watcher.data = client;
578
656
  ev_init (&(client->write_watcher), on_client_writable);
579
657
  ev_io_set (&(client->write_watcher), client->fd, EV_WRITE | EV_ERROR);
580
- ev_io_start(client->server->loop, &(client->write_watcher));
658
+ ev_io_start(client->server->loop, &client->write_watcher);
581
659
  }
582
660
 
583
661
 
@@ -589,7 +667,8 @@ int ebb_client_read(ebb_client *client, char *buffer, int length)
589
667
  {
590
668
  size_t read;
591
669
 
592
- assert(client->open);
670
+ assert(client->in_use);
671
+ if(!client->open) return -1;
593
672
  assert(client_finished_parsing);
594
673
 
595
674
  if(client->upload_file) {
@@ -611,53 +690,6 @@ int ebb_client_read(ebb_client *client, char *buffer, int length)
611
690
 
612
691
  /* The following socket creation routines are modified and stolen from memcached */
613
692
 
614
- static int server_socket(const int port) {
615
- int sfd;
616
- struct linger ling = {0, 0};
617
- struct sockaddr_in addr;
618
- int flags =1;
619
-
620
- if ((sfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
621
- perror("socket()");
622
- return -1;
623
- }
624
-
625
- if ((flags = fcntl(sfd, F_GETFL, 0)) < 0 ||
626
- fcntl(sfd, F_SETFL, flags | O_NONBLOCK) < 0) {
627
- perror("setting O_NONBLOCK");
628
- close(sfd);
629
- return -1;
630
- }
631
-
632
- flags = 1;
633
- setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, (void *)&flags, sizeof(flags));
634
- setsockopt(sfd, SOL_SOCKET, SO_KEEPALIVE, (void *)&flags, sizeof(flags));
635
- setsockopt(sfd, SOL_SOCKET, SO_LINGER, (void *)&ling, sizeof(ling));
636
- setsockopt(sfd, IPPROTO_TCP, TCP_NODELAY, (void *)&flags, sizeof(flags));
637
-
638
- /*
639
- * the memset call clears nonstandard fields in some impementations
640
- * that otherwise mess things up.
641
- */
642
- memset(&addr, 0, sizeof(addr));
643
-
644
- addr.sin_family = AF_INET;
645
- addr.sin_port = htons(port);
646
- addr.sin_addr.s_addr = htonl(INADDR_ANY);
647
-
648
- if (bind(sfd, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
649
- perror("bind()");
650
- close(sfd);
651
- return -1;
652
- }
653
- if (listen(sfd, EBB_MAX_CLIENTS) == -1) {
654
- perror("listen()");
655
- close(sfd);
656
- return -1;
657
- }
658
- return sfd;
659
- }
660
-
661
693
 
662
694
  static int server_socket_unix(const char *path, int access_mask) {
663
695
  int sfd;