bossan 0.1.4 → 0.1.5

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.
@@ -10,18 +10,20 @@
10
10
  #include <inttypes.h>
11
11
  #include <arpa/inet.h>
12
12
  #include <signal.h>
13
- #include <sys/sendfile.h>
14
13
  #include <sys/socket.h>
15
14
  #include <sys/types.h>
15
+ #ifdef linux
16
+ #include <sys/sendfile.h>
16
17
  #include <sys/prctl.h>
18
+ #elif defined(__APPLE__) || defined(__FreeBSD__)
19
+ #include <sys/uio.h>
20
+ #endif
17
21
  #include <sys/un.h>
18
22
  #include <sys/stat.h>
19
23
  #include <sys/file.h>
20
- #include <sys/uio.h>
21
24
  #include <netinet/in.h>
22
25
  #include <netinet/tcp.h>
23
26
  #include <netdb.h>
24
-
25
27
  #include "time_cache.h"
26
28
  #include "http_parser.h"
27
29
  #include "picoev.h"
@@ -59,7 +61,7 @@
59
61
 
60
62
  #define MSG_413 ("HTTP/1.0 413 Request Entity Too Large\r\nContent-Type: text/html\r\nServer: " SERVER "\r\n\r\n<html><head><title>Request Entity Too Large</title></head><body><p>Request Entity Too Large.</p></body></html>")
61
63
 
62
- #define SERVER "bossan/0.1.4"
64
+ #define SERVER "bossan/0.1.5"
63
65
 
64
66
  VALUE server; // Bossan
65
67
 
@@ -205,7 +207,7 @@ typedef struct {
205
207
  uint32_t total_size;
206
208
  } write_bucket;
207
209
 
208
- inline buffer *
210
+ buffer *
209
211
  new_buffer(size_t buf_size, size_t limit)
210
212
  {
211
213
  buffer *buf;
@@ -221,7 +223,7 @@ new_buffer(size_t buf_size, size_t limit)
221
223
  return buf;
222
224
  }
223
225
 
224
- inline buffer_result
226
+ buffer_result
225
227
  write2buf(buffer *buf, const char *c, size_t l) {
226
228
  size_t newl;
227
229
  char *newbuf;
@@ -248,14 +250,14 @@ write2buf(buffer *buf, const char *c, size_t l) {
248
250
  return ret;
249
251
  }
250
252
 
251
- inline void
253
+ void
252
254
  free_buffer(buffer *buf)
253
255
  {
254
256
  ruby_xfree(buf->buf);
255
257
  ruby_xfree(buf);
256
258
  }
257
259
 
258
- inline VALUE
260
+ VALUE
259
261
  getRbString(buffer *buf)
260
262
  {
261
263
  VALUE o;
@@ -264,7 +266,7 @@ getRbString(buffer *buf)
264
266
  return o;
265
267
  }
266
268
 
267
- inline char *
269
+ char *
268
270
  getString(buffer *buf)
269
271
  {
270
272
  buf->buf[buf->len] = '\0';
@@ -277,7 +279,7 @@ open_log_file(const char *path)
277
279
  return open(path, O_CREAT|O_APPEND|O_WRONLY, 0744);
278
280
  }
279
281
 
280
- static inline int
282
+ static int
281
283
  write_log(const char *new_path, int fd, const char *data, size_t len)
282
284
  {
283
285
  int openfd;
@@ -356,7 +358,7 @@ write_access_log(client_t *cli, int log_fd, const char *log_path)
356
358
  return 0;
357
359
  }
358
360
 
359
- static inline int
361
+ static int
360
362
  blocking_write(client_t *client, char *data, size_t len)
361
363
  {
362
364
  size_t r = 0, send_len = len;
@@ -425,7 +427,7 @@ send_error_page(client_t *client)
425
427
  client->keep_alive = 0;
426
428
  }
427
429
 
428
- static inline void
430
+ static void
429
431
  extent_sndbuf(client_t *client)
430
432
  {
431
433
  int bufsize = 1024 * 1024 * 2, r;
@@ -433,15 +435,19 @@ extent_sndbuf(client_t *client)
433
435
  assert(r == 0);
434
436
  }
435
437
 
436
- static inline void
438
+ static void
437
439
  enable_cork(client_t *client)
438
440
  {
439
441
  int on = 1, r;
442
+ #ifdef linux
440
443
  r = setsockopt(client->fd, IPPROTO_TCP, TCP_CORK, &on, sizeof(on));
444
+ #elif defined(__APPLE__) || defined(__FreeBSD__)
445
+ r = setsockopt(client->fd, IPPROTO_TCP, TCP_NOPUSH, &on, sizeof(on));
446
+ #endif
441
447
  assert(r == 0);
442
448
  }
443
449
 
444
- static inline write_bucket *
450
+ static write_bucket *
445
451
  new_write_bucket(int fd, int cnt)
446
452
  {
447
453
  write_bucket *bucket;
@@ -454,14 +460,14 @@ new_write_bucket(int fd, int cnt)
454
460
  return bucket;
455
461
  }
456
462
 
457
- static inline void
463
+ static void
458
464
  free_write_bucket(write_bucket *bucket)
459
465
  {
460
466
  ruby_xfree(bucket->iov);
461
467
  ruby_xfree(bucket);
462
468
  }
463
469
 
464
- static inline void
470
+ static void
465
471
  set2bucket(write_bucket *bucket, char *buf, size_t len)
466
472
  {
467
473
  bucket->iov[bucket->iov_cnt].iov_base = buf;
@@ -471,7 +477,7 @@ set2bucket(write_bucket *bucket, char *buf, size_t len)
471
477
  bucket->total_size += len;
472
478
  }
473
479
 
474
- static inline void
480
+ static void
475
481
  add_header(write_bucket *bucket, char *key, size_t keylen, char *val, size_t vallen)
476
482
  {
477
483
  set2bucket(bucket, key, keylen);
@@ -480,7 +486,7 @@ add_header(write_bucket *bucket, char *key, size_t keylen, char *val, size_t val
480
486
  set2bucket(bucket, CRLF, 2);
481
487
  }
482
488
 
483
- static inline int
489
+ static int
484
490
  writev_bucket(write_bucket *data)
485
491
  {
486
492
  size_t w;
@@ -528,7 +534,7 @@ writev_bucket(write_bucket *data)
528
534
  return 1;
529
535
  }
530
536
 
531
- static inline int
537
+ static int
532
538
  write_headers(client_t *client)
533
539
  {
534
540
  if(client->header_done){
@@ -645,7 +651,7 @@ write_headers(client_t *client)
645
651
  return -1;
646
652
  }
647
653
 
648
- /* static inline int */
654
+ /* static int */
649
655
  /* write_sendfile(int out_fd, int in_fd, size_t count) */
650
656
  /* { */
651
657
  /* int size = (int)count; */
@@ -664,7 +670,7 @@ write_headers(client_t *client)
664
670
  /* return sendfile(out_fd, in_fd, NULL, count); */
665
671
  /* } */
666
672
 
667
- static inline void
673
+ static void
668
674
  close_response(client_t *client)
669
675
  {
670
676
  //send all response
@@ -682,7 +688,7 @@ collect_body(VALUE i, VALUE str, int argc, VALUE *argv)
682
688
  return Qnil;
683
689
  }
684
690
 
685
- static inline int
691
+ static int
686
692
  processs_write(client_t *client)
687
693
  {
688
694
  VALUE iterator = NULL;
@@ -736,7 +742,7 @@ processs_write(client_t *client)
736
742
  return 1;
737
743
  }
738
744
 
739
- inline int
745
+ int
740
746
  process_body(client_t *client)
741
747
  {
742
748
  int ret;
@@ -759,7 +765,7 @@ process_body(client_t *client)
759
765
  return ret;
760
766
  }
761
767
 
762
- static inline int
768
+ static int
763
769
  start_response_write(client_t *client)
764
770
  {
765
771
  VALUE iterator;
@@ -788,7 +794,7 @@ start_response_write(client_t *client)
788
794
  return write_headers(client);
789
795
  }
790
796
 
791
- inline int
797
+ int
792
798
  response_start(client_t *client)
793
799
  {
794
800
  int ret;
@@ -807,7 +813,7 @@ response_start(client_t *client)
807
813
  return ret;
808
814
  }
809
815
 
810
- inline request *
816
+ request *
811
817
  new_request(void)
812
818
  {
813
819
  request *req = (request *)ruby_xmalloc(sizeof(request));
@@ -815,7 +821,7 @@ new_request(void)
815
821
  return req;
816
822
  }
817
823
 
818
- inline header *
824
+ header *
819
825
  new_header(size_t fsize, size_t flimit, size_t vsize, size_t vlimit)
820
826
  {
821
827
  header *h;
@@ -825,13 +831,13 @@ new_header(size_t fsize, size_t flimit, size_t vsize, size_t vlimit)
825
831
  return h;
826
832
  }
827
833
 
828
- inline void
834
+ void
829
835
  free_header(header *h)
830
836
  {
831
837
  ruby_xfree(h);
832
838
  }
833
839
 
834
- inline void
840
+ void
835
841
  free_request(request *req)
836
842
  {
837
843
  uint32_t i;
@@ -864,7 +870,7 @@ free_request(request *req)
864
870
  ruby_xfree(req);
865
871
  }
866
872
 
867
- static inline void
873
+ static void
868
874
  key_upper(char *s, const char *key, size_t len)
869
875
  {
870
876
  int i = 0;
@@ -883,7 +889,7 @@ key_upper(char *s, const char *key, size_t len)
883
889
  }
884
890
  }
885
891
 
886
- static inline int
892
+ static int
887
893
  write_body2file(client_t *client, const char *buffer, size_t buffer_len)
888
894
  {
889
895
  FILE *tmp = (FILE *)client->body;
@@ -895,7 +901,7 @@ write_body2file(client_t *client, const char *buffer, size_t buffer_len)
895
901
  return client->body_readed;
896
902
  }
897
903
 
898
- static inline int
904
+ static int
899
905
  write_body2mem(client_t *client, const char *buffer, size_t buffer_len)
900
906
  {
901
907
  printf("body2mem called\n");
@@ -908,7 +914,7 @@ write_body2mem(client_t *client, const char *buffer, size_t buffer_len)
908
914
  return client->body_readed;
909
915
  }
910
916
 
911
- static inline int
917
+ static int
912
918
  write_body(client_t *cli, const char *buffer, size_t buffer_len)
913
919
  {
914
920
  return write_body2mem(cli, buffer, buffer_len);
@@ -920,7 +926,7 @@ typedef enum{
920
926
  OTHER
921
927
  } rack_header_type;
922
928
 
923
- static inline rack_header_type
929
+ static rack_header_type
924
930
  check_header_type(const char *buf)
925
931
  {
926
932
  if(*buf++ != 'C'){
@@ -956,7 +962,7 @@ check_header_type(const char *buf)
956
962
  return OTHER;
957
963
  }
958
964
 
959
- static inline client_t *
965
+ static client_t *
960
966
  get_client(http_parser *p)
961
967
  {
962
968
  return (client_t *)p->data;
@@ -1319,7 +1325,7 @@ static http_parser_settings settings =
1319
1325
  ,.on_message_complete = message_complete_cb
1320
1326
  };
1321
1327
 
1322
- inline int
1328
+ int
1323
1329
  init_parser(client_t *cli, const char *name, const short port)
1324
1330
  {
1325
1331
  register VALUE object;
@@ -1360,19 +1366,19 @@ init_parser(client_t *cli, const char *name, const short port)
1360
1366
  return 0;
1361
1367
  }
1362
1368
 
1363
- inline size_t
1369
+ size_t
1364
1370
  execute_parse(client_t *cli, const char *data, size_t len)
1365
1371
  {
1366
1372
  return http_parser_execute(cli->http, &settings, data, len);
1367
1373
  }
1368
1374
 
1369
- inline int
1375
+ int
1370
1376
  parser_finish(client_t *cli)
1371
1377
  {
1372
1378
  return cli->complete;
1373
1379
  }
1374
1380
 
1375
- inline void
1381
+ void
1376
1382
  setup_static_env(char *name, int port)
1377
1383
  {
1378
1384
  version_val = rb_obj_freeze(rb_ary_new3(2, INT2FIX(1), INT2FIX(1)));
@@ -1418,7 +1424,7 @@ setup_static_env(char *name, int port)
1418
1424
  http_user_agent = rb_obj_freeze(rb_str_new2("HTTP_USER_AGENT"));
1419
1425
  }
1420
1426
 
1421
- static inline int
1427
+ static int
1422
1428
  setsig(int sig, void* handler)
1423
1429
  {
1424
1430
  struct sigaction context, ocontext;
@@ -1428,7 +1434,7 @@ setsig(int sig, void* handler)
1428
1434
  return sigaction(sig, &context, &ocontext);
1429
1435
  }
1430
1436
 
1431
- static inline void
1437
+ static void
1432
1438
  setup_sock(int fd)
1433
1439
  {
1434
1440
  int on = 1, r;
@@ -1438,19 +1444,22 @@ setup_sock(int fd)
1438
1444
  assert(r == 0);
1439
1445
  }
1440
1446
 
1441
- static inline void
1447
+ static void
1442
1448
  disable_cork(client_t *client)
1443
1449
  {
1444
1450
  int off = 0;
1445
1451
  int on = 1, r;
1452
+ #ifdef linux
1446
1453
  r = setsockopt(client->fd, IPPROTO_TCP, TCP_CORK, &off, sizeof(off));
1454
+ #elif defined(__APPLE__) || defined(__FreeBSD__)
1455
+ r = setsockopt(client->fd, IPPROTO_TCP, TCP_NOPUSH, &off, sizeof(off));
1456
+ #endif
1447
1457
  assert(r == 0);
1448
-
1449
1458
  r = setsockopt(client->fd, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on));
1450
1459
  assert(r == 0);
1451
1460
  }
1452
1461
 
1453
- static inline client_t *
1462
+ static client_t *
1454
1463
  new_client_t(int client_fd, struct sockaddr_in client_addr){
1455
1464
  client_t *client;
1456
1465
 
@@ -1469,7 +1478,7 @@ new_client_t(int client_fd, struct sockaddr_in client_addr){
1469
1478
  return client;
1470
1479
  }
1471
1480
 
1472
- static inline void
1481
+ static void
1473
1482
  clean_cli(client_t *client)
1474
1483
  {
1475
1484
  write_access_log(client, log_fd, log_path);
@@ -1484,7 +1493,7 @@ clean_cli(client_t *client)
1484
1493
  }
1485
1494
  }
1486
1495
 
1487
- static inline void
1496
+ static void
1488
1497
  close_conn(client_t *cli, picoev_loop* loop)
1489
1498
  {
1490
1499
  if(!cli->keep_alive){
@@ -1515,7 +1524,7 @@ close_conn(client_t *cli, picoev_loop* loop)
1515
1524
  }
1516
1525
  }
1517
1526
 
1518
- static inline int
1527
+ static int
1519
1528
  process_rack_app(client_t *cli)
1520
1529
  {
1521
1530
  VALUE args = NULL;
@@ -1587,7 +1596,7 @@ w_callback(picoev_loop* loop, int fd, int events, void* cb_arg)
1587
1596
  }
1588
1597
  }
1589
1598
 
1590
- static inline void
1599
+ static void
1591
1600
  call_rack_app(client_t *client, picoev_loop* loop)
1592
1601
  {
1593
1602
  int ret;
@@ -1622,7 +1631,7 @@ call_rack_app(client_t *client, picoev_loop* loop)
1622
1631
  }
1623
1632
  }
1624
1633
 
1625
- static inline void
1634
+ static void
1626
1635
  prepare_call_rack(client_t *client)
1627
1636
  {
1628
1637
  VALUE input = NULL, object = NULL, c = NULL;
@@ -1744,7 +1753,8 @@ accept_callback(picoev_loop* loop, int fd, int events, void* cb_arg)
1744
1753
  return;
1745
1754
  }else if ((events & PICOEV_READ) != 0) {
1746
1755
  socklen_t client_len = sizeof(client_addr);
1747
- client_fd = accept4(fd, (struct sockaddr *)&client_addr, &client_len, SOCK_NONBLOCK | SOCK_CLOEXEC);
1756
+ //client_fd = accept4(fd, (struct sockaddr *)&client_addr, &client_len, SOCK_NONBLOCK | SOCK_CLOEXEC);
1757
+ client_fd = accept(fd, (struct sockaddr *)&client_addr, &client_len);
1748
1758
  if (client_fd != -1) {
1749
1759
  #ifdef DEBUG
1750
1760
  printf("accept fd %d \n", client_fd);
@@ -1771,7 +1781,7 @@ accept_callback(picoev_loop* loop, int fd, int events, void* cb_arg)
1771
1781
  }
1772
1782
  }
1773
1783
 
1774
- static inline void
1784
+ static void
1775
1785
  setup_server_env(void)
1776
1786
  {
1777
1787
  setup_sock(listen_sock);
@@ -1780,7 +1790,7 @@ setup_server_env(void)
1780
1790
  setup_static_env(server_name, server_port);
1781
1791
  }
1782
1792
 
1783
- static inline int
1793
+ static int
1784
1794
  inet_listen(void)
1785
1795
  {
1786
1796
  struct addrinfo hints, *servinfo, *p;
@@ -1849,7 +1859,7 @@ inet_listen(void)
1849
1859
  return 1;
1850
1860
  }
1851
1861
 
1852
- static inline int
1862
+ static int
1853
1863
  check_unix_sockpath(char *sock_name)
1854
1864
  {
1855
1865
  if(!access(sock_name, F_OK)){
@@ -1860,7 +1870,7 @@ check_unix_sockpath(char *sock_name)
1860
1870
  return 1;
1861
1871
  }
1862
1872
 
1863
- static inline int
1873
+ static int
1864
1874
  unix_listen(char *sock_name)
1865
1875
  {
1866
1876
  int flag = 1;
@@ -1,7 +1,4 @@
1
1
  /* Copyright 2009,2010 Ryan Dahl <ry@tinyclouds.org>
2
- *
3
- * Some parts of this source file were taken from NGINX
4
- * (src/http/ngx_http_parser.c) copyright (C) 2002-2009 Igor Sysoev.
5
2
  *
6
3
  * Permission is hereby granted, free of charge, to any person obtaining a copy
7
4
  * of this software and associated documentation files (the "Software"), to
@@ -122,18 +119,44 @@ static const char *method_strings[] =
122
119
  };
123
120
 
124
121
 
125
- static const char lowcase[256] =
126
- "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
127
- " \0\0\0\0\0\0\0\0\0\0\0\0-\0\0" "0123456789\0\0\0\0\0\0"
128
- "\0abcdefghijklmnopqrstuvwxyz\0\0\0\0_"
129
- "\0abcdefghijklmnopqrstuvwxyz\0\0\0\0\0"
130
- "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
131
- "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
132
- "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
133
- "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
134
-
135
-
136
- static const int unhex[] =
122
+ /* ' ', '_', '-' and all alpha-numeric ascii characters are accepted by acceptable_header.
123
+ The 'A'-'Z' are lower-cased. */
124
+ static const char acceptable_header[256] = {
125
+ /* 0 nul 1 soh 2 stx 3 etx 4 eot 5 enq 6 ack 7 bel */
126
+ 0, 0, 0, 0, 0, 0, 0, 0,
127
+ /* 8 bs 9 ht 10 nl 11 vt 12 np 13 cr 14 so 15 si */
128
+ 0, 0, 0, 0, 0, 0, 0, 0,
129
+ /* 16 dle 17 dc1 18 dc2 19 dc3 20 dc4 21 nak 22 syn 23 etb */
130
+ 0, 0, 0, 0, 0, 0, 0, 0,
131
+ /* 24 can 25 em 26 sub 27 esc 28 fs 29 gs 30 rs 31 us */
132
+ 0, 0, 0, 0, 0, 0, 0, 0,
133
+ /* 32 sp 33 ! 34 " 35 # 36 $ 37 % 38 & 39 ' */
134
+ ' ', 0, 0, 0, 0, 0, 0, 0,
135
+ /* 40 ( 41 ) 42 * 43 + 44 , 45 - 46 . 47 / */
136
+ 0, 0, 0, 0, 0, '-', 0, 0,
137
+ /* 48 0 49 1 50 2 51 3 52 4 53 5 54 6 55 7 */
138
+ '0', '1', '2', '3', '4', '5', '6', '7',
139
+ /* 56 8 57 9 58 : 59 ; 60 < 61 = 62 > 63 ? */
140
+ '8', '9', 0, 0, 0, 0, 0, 0,
141
+ /* 64 @ 65 A 66 B 67 C 68 D 69 E 70 F 71 G */
142
+ 0, 'a', 'b', 'c', 'd', 'e', 'f', 'g',
143
+ /* 72 H 73 I 74 J 75 K 76 L 77 M 78 N 79 O */
144
+ 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
145
+ /* 80 P 81 Q 82 R 83 S 84 T 85 U 86 V 87 W */
146
+ 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
147
+ /* 88 X 89 Y 90 Z 91 [ 92 \ 93 ] 94 ^ 95 _ */
148
+ 'x', 'y', 'z', 0, 0, 0, 0, '_',
149
+ /* 96 ` 97 a 98 b 99 c 100 d 101 e 102 f 103 g */
150
+ 0, 'a', 'b', 'c', 'd', 'e', 'f', 'g',
151
+ /* 104 h 105 i 106 j 107 k 108 l 109 m 110 n 111 o */
152
+ 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
153
+ /* 112 p 113 q 114 r 115 s 116 t 117 u 118 v 119 w */
154
+ 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
155
+ /* 120 x 121 y 122 z 123 { 124 | 125 } 126 ~ 127 del */
156
+ 'x', 'y', 'z', 0, 0, 0, 0, 0 };
157
+
158
+
159
+ static const int8_t unhex[256] =
137
160
  {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
138
161
  ,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
139
162
  ,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
@@ -145,26 +168,39 @@ static const int unhex[] =
145
168
  };
146
169
 
147
170
 
148
-
149
- static const uint32_t usual[] = {
150
- 0xffffdbfe, /* 1111 1111 1111 1111 1101 1011 1111 1110 */
151
-
152
- /* ?>=< ;:98 7654 3210 /.-, +*)( '&%$ #"! */
153
- 0x7ffffff6, /* 0111 1111 1111 1111 1111 1111 1111 0110 */
154
-
155
- /* _^]\ [ZYX WVUT SRQP ONML KJIH GFED CBA@ */
156
- 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
157
-
158
- /* ~}| {zyx wvut srqp onml kjih gfed cba` */
159
- 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
160
-
161
- 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
162
- 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
163
- 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
164
- 0xffffffff /* 1111 1111 1111 1111 1111 1111 1111 1111 */
165
- };
166
-
167
- #define USUAL(c) (usual[c >> 5] & (1 << (c & 0x1f)))
171
+ static const uint8_t normal_url_char[256] = {
172
+ /* 0 nul 1 soh 2 stx 3 etx 4 eot 5 enq 6 ack 7 bel */
173
+ 0, 0, 0, 0, 0, 0, 0, 0,
174
+ /* 8 bs 9 ht 10 nl 11 vt 12 np 13 cr 14 so 15 si */
175
+ 0, 0, 0, 0, 0, 0, 0, 0,
176
+ /* 16 dle 17 dc1 18 dc2 19 dc3 20 dc4 21 nak 22 syn 23 etb */
177
+ 0, 0, 0, 0, 0, 0, 0, 0,
178
+ /* 24 can 25 em 26 sub 27 esc 28 fs 29 gs 30 rs 31 us */
179
+ 0, 0, 0, 0, 0, 0, 0, 0,
180
+ /* 32 sp 33 ! 34 " 35 # 36 $ 37 % 38 & 39 ' */
181
+ 0, 1, 1, 0, 1, 1, 1, 1,
182
+ /* 40 ( 41 ) 42 * 43 + 44 , 45 - 46 . 47 / */
183
+ 1, 1, 1, 1, 1, 1, 1, 1,
184
+ /* 48 0 49 1 50 2 51 3 52 4 53 5 54 6 55 7 */
185
+ 1, 1, 1, 1, 1, 1, 1, 1,
186
+ /* 56 8 57 9 58 : 59 ; 60 < 61 = 62 > 63 ? */
187
+ 1, 1, 1, 1, 1, 1, 1, 0,
188
+ /* 64 @ 65 A 66 B 67 C 68 D 69 E 70 F 71 G */
189
+ 1, 1, 1, 1, 1, 1, 1, 1,
190
+ /* 72 H 73 I 74 J 75 K 76 L 77 M 78 N 79 O */
191
+ 1, 1, 1, 1, 1, 1, 1, 1,
192
+ /* 80 P 81 Q 82 R 83 S 84 T 85 U 86 V 87 W */
193
+ 1, 1, 1, 1, 1, 1, 1, 1,
194
+ /* 88 X 89 Y 90 Z 91 [ 92 \ 93 ] 94 ^ 95 _ */
195
+ 1, 1, 1, 1, 1, 1, 1, 1,
196
+ /* 96 ` 97 a 98 b 99 c 100 d 101 e 102 f 103 g */
197
+ 1, 1, 1, 1, 1, 1, 1, 1,
198
+ /* 104 h 105 i 106 j 107 k 108 l 109 m 110 n 111 o */
199
+ 1, 1, 1, 1, 1, 1, 1, 1,
200
+ /* 112 p 113 q 114 r 115 s 116 t 117 u 118 v 119 w */
201
+ 1, 1, 1, 1, 1, 1, 1, 1,
202
+ /* 120 x 121 y 122 z 123 { 124 | 125 } 126 ~ 127 del */
203
+ 1, 1, 1, 1, 1, 1, 1, 0 };
168
204
 
169
205
 
170
206
  enum state
@@ -705,7 +741,7 @@ size_t http_parser_execute (http_parser *parser,
705
741
 
706
742
  case s_req_path:
707
743
  {
708
- if (USUAL(ch)) break;
744
+ if (normal_url_char[(unsigned char)ch]) break;
709
745
 
710
746
  switch (ch) {
711
747
  case ' ':
@@ -741,7 +777,7 @@ size_t http_parser_execute (http_parser *parser,
741
777
 
742
778
  case s_req_query_string_start:
743
779
  {
744
- if (USUAL(ch)) {
780
+ if (normal_url_char[(unsigned char)ch]) {
745
781
  MARK(query_string);
746
782
  state = s_req_query_string;
747
783
  break;
@@ -775,7 +811,7 @@ size_t http_parser_execute (http_parser *parser,
775
811
 
776
812
  case s_req_query_string:
777
813
  {
778
- if (USUAL(ch)) break;
814
+ if (normal_url_char[(unsigned char)ch]) break;
779
815
 
780
816
  switch (ch) {
781
817
  case '?':
@@ -810,7 +846,7 @@ size_t http_parser_execute (http_parser *parser,
810
846
 
811
847
  case s_req_fragment_start:
812
848
  {
813
- if (USUAL(ch)) {
849
+ if (normal_url_char[(unsigned char)ch]) {
814
850
  MARK(fragment);
815
851
  state = s_req_fragment;
816
852
  break;
@@ -845,7 +881,7 @@ size_t http_parser_execute (http_parser *parser,
845
881
 
846
882
  case s_req_fragment:
847
883
  {
848
- if (USUAL(ch)) break;
884
+ if (normal_url_char[(unsigned char)ch]) break;
849
885
 
850
886
  switch (ch) {
851
887
  case ' ':
@@ -1021,7 +1057,7 @@ size_t http_parser_execute (http_parser *parser,
1021
1057
 
1022
1058
  case s_header_field:
1023
1059
  {
1024
- c = lowcase[(unsigned char)ch];
1060
+ c = acceptable_header[(unsigned char)ch];
1025
1061
 
1026
1062
  if (c) {
1027
1063
  switch (header_state) {
@@ -1158,7 +1194,7 @@ size_t http_parser_execute (http_parser *parser,
1158
1194
  state = s_header_value;
1159
1195
  index = 0;
1160
1196
 
1161
- c = lowcase[(unsigned char)ch];
1197
+ c = acceptable_header[(unsigned char)ch];
1162
1198
 
1163
1199
  if (!c) {
1164
1200
  if (ch == CR) {
@@ -1221,7 +1257,7 @@ size_t http_parser_execute (http_parser *parser,
1221
1257
 
1222
1258
  case s_header_value:
1223
1259
  {
1224
- c = lowcase[(unsigned char)ch];
1260
+ c = acceptable_header[(unsigned char)ch];
1225
1261
 
1226
1262
  if (!c) {
1227
1263
  if (ch == CR) {
@@ -1428,7 +1464,7 @@ size_t http_parser_execute (http_parser *parser,
1428
1464
  {
1429
1465
  assert(parser->flags & F_CHUNKED);
1430
1466
 
1431
- c = unhex[(int)ch];
1467
+ c = unhex[(unsigned char)ch];
1432
1468
  if (c == -1) goto error;
1433
1469
  parser->content_length = c;
1434
1470
  state = s_chunk_size;
@@ -1444,7 +1480,7 @@ size_t http_parser_execute (http_parser *parser,
1444
1480
  break;
1445
1481
  }
1446
1482
 
1447
- c = unhex[(int)ch];
1483
+ c = unhex[(unsigned char)ch];
1448
1484
 
1449
1485
  if (c == -1) {
1450
1486
  if (ch == ';' || ch == ' ') {
@@ -1575,4 +1611,5 @@ http_parser_init (http_parser *parser, enum http_parser_type t)
1575
1611
  parser->nread = 0;
1576
1612
  parser->upgrade = 0;
1577
1613
  parser->flags = 0;
1614
+ parser->method = 0;
1578
1615
  }
@@ -100,15 +100,14 @@ enum http_parser_type { HTTP_REQUEST, HTTP_RESPONSE, HTTP_BOTH };
100
100
 
101
101
  struct http_parser {
102
102
  /** PRIVATE **/
103
- unsigned char type;
103
+ unsigned char type : 2;
104
+ unsigned char flags : 6;
104
105
  unsigned char state;
105
106
  unsigned char header_state;
106
107
  unsigned char index;
107
108
  char maybe_ml;
108
109
 
109
- char flags;
110
-
111
- uint64_t nread;
110
+ uint32_t nread;
112
111
  int64_t content_length;
113
112
 
114
113
  /** READ-ONLY **/
@@ -64,7 +64,8 @@ picoev_loop* picoev_create_loop(int max_timeout)
64
64
  free(loop);
65
65
  return NULL;
66
66
  }
67
-
67
+
68
+ loop->loop.now = time(NULL);
68
69
  return &loop->loop;
69
70
  }
70
71
 
@@ -1,3 +1,3 @@
1
1
  module Bossan
2
- VERSION = "0.1.4"
2
+ VERSION = "0.1.5"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bossan
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.1.5
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,8 +9,24 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-12-18 00:00:00.000000000 Z
13
- dependencies: []
12
+ date: 2013-01-27 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rack
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '1.2'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: '1.2'
14
30
  description: high performance asynchronous rack web server
15
31
  email:
16
32
  - kubo39@gmail.com
@@ -19,28 +35,18 @@ extensions:
19
35
  - ext/bossan/extconf.rb
20
36
  extra_rdoc_files: []
21
37
  files:
22
- - .gitignore
23
- - Gemfile
24
38
  - LICENSE.txt
25
- - README.md
26
- - Rakefile
27
- - bossan.gemspec
28
- - examples/config.ru
29
- - examples/hello.rb
30
- - examples/sinatra_app.rb
31
- - examples/views/index.haml
32
- - examples/views_sample.rb
33
- - ext/bossan/bossan_ext.c
34
- - ext/bossan/extconf.rb
35
- - ext/bossan/http_parser.c
39
+ - lib/bossan/version.rb
40
+ - lib/rack/handler/bossan.rb
41
+ - lib/bossan.rb
36
42
  - ext/bossan/http_parser.h
37
- - ext/bossan/picoev.h
38
43
  - ext/bossan/picoev_epoll.c
39
44
  - ext/bossan/time_cache.c
45
+ - ext/bossan/picoev.h
40
46
  - ext/bossan/time_cache.h
41
- - lib/bossan.rb
42
- - lib/bossan/version.rb
43
- - lib/rack/handler/bossan.rb
47
+ - ext/bossan/bossan_ext.c
48
+ - ext/bossan/extconf.rb
49
+ - ext/bossan/http_parser.c
44
50
  homepage: https://github.com/kubo39/bossan
45
51
  licenses: []
46
52
  post_install_message:
@@ -53,7 +59,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
53
59
  requirements:
54
60
  - - ! '>='
55
61
  - !ruby/object:Gem::Version
56
- version: '0'
62
+ version: 1.9.2
57
63
  required_rubygems_version: !ruby/object:Gem::Requirement
58
64
  none: false
59
65
  requirements:
data/.gitignore DELETED
@@ -1,19 +0,0 @@
1
- *.gem
2
- *.rbc
3
- .bundle
4
- .config
5
- .yardoc
6
- Gemfile.lock
7
- InstalledFiles
8
- _yardoc
9
- coverage
10
- doc/
11
- lib/bundler/man
12
- pkg
13
- rdoc
14
- spec/reports
15
- test/tmp
16
- test/version_tmp
17
- tmp
18
- *.o
19
- Makefile
data/Gemfile DELETED
@@ -1,4 +0,0 @@
1
- source 'https://rubygems.org'
2
-
3
- # Specify your gem's dependencies in bossan.gemspec
4
- gemspec
data/README.md DELETED
@@ -1,50 +0,0 @@
1
- # Bossan
2
-
3
- Bossan is a high performance asynchronous rack web server.
4
-
5
- ## Requirements
6
-
7
- Bossan requires Ruby 1.9.2 or later.
8
-
9
- Bossan supports Linux only.
10
-
11
- ## Installation
12
-
13
- Add this line to your application's Gemfile:
14
-
15
- gem 'bossan'
16
-
17
- And then execute:
18
-
19
- $ bundle
20
-
21
- Or install it yourself as:
22
-
23
- $ gem install bossan
24
-
25
- ## Usage
26
-
27
- simple rack app:
28
-
29
- ``` ruby
30
- require 'bossan'
31
-
32
- Bossan.run('127.0.0.1', 8000, proc {|env|
33
- [
34
- 200, # Status code
35
- { # Response headers
36
- 'Content-Type' => 'text/html',
37
- 'Content-Length' => '13',
38
- },
39
- ['hello, world!'] # Response body
40
- ]
41
- })
42
- ```
43
-
44
- ## Contributing
45
-
46
- 1. Fork it
47
- 2. Create your feature branch (`git checkout -b my-new-feature`)
48
- 3. Commit your changes (`git commit -am 'Add some feature'`)
49
- 4. Push to the branch (`git push origin my-new-feature`)
50
- 5. Create new Pull Request
data/Rakefile DELETED
@@ -1,15 +0,0 @@
1
- #!/usr/bin/env rake
2
- require "bundler/gem_tasks"
3
-
4
- task :default => [:compile, :clean]
5
-
6
- task :compile do
7
- Dir.chdir File.expand_path("../ext/bossan", __FILE__)
8
- system "ruby extconf.rb"
9
- system "make"
10
- end
11
-
12
- task :clean do
13
- Dir.chdir File.expand_path("../ext/bossan", __FILE__)
14
- system "rm -f *.o Makefile"
15
- end
@@ -1,16 +0,0 @@
1
- # -*- encoding: utf-8 -*-
2
- require File.expand_path('../lib/bossan/version', __FILE__)
3
-
4
- Gem::Specification.new do |gem|
5
- gem.name = "bossan"
6
- gem.version = Bossan::VERSION
7
- gem.authors = ["Hiroki Noda"]
8
- gem.email = ["kubo39@gmail.com"]
9
- gem.description = %q{high performance asynchronous rack web server}
10
- gem.summary = gem.description
11
- gem.homepage = "https://github.com/kubo39/bossan"
12
-
13
- gem.files = `git ls-files`.split($/)
14
- gem.extensions = ["ext/bossan/extconf.rb"]
15
- gem.require_paths = ["lib", "ext"]
16
- end
@@ -1,19 +0,0 @@
1
- require 'bossan'
2
- require 'pp'
3
-
4
- class MyApp
5
- def call env
6
- body = ['hi!']
7
- # pp env
8
- [
9
- 200, # Status code
10
- { 'Content-Type' => 'text/html',
11
- 'Content-Length' => body.join.size.to_s,
12
- }, # Reponse headers
13
- body # Body of the response
14
- ]
15
- end
16
- end
17
-
18
- # Rack::Handler::Bossan.run MyApp.new
19
- run MyApp.new
@@ -1,12 +0,0 @@
1
- require 'bossan'
2
-
3
- Bossan.run('127.0.0.1', 8000, proc {|env|
4
- [
5
- 200, # Status code
6
- { # Response headers
7
- 'Content-Type' => 'text/html',
8
- 'Content-Length' => '13',
9
- },
10
- ['hello, world!'] # Response body
11
- ]
12
- })
@@ -1,11 +0,0 @@
1
- require 'bossan'
2
- require 'sinatra/base'
3
-
4
- class App < Sinatra::Base
5
- get '/' do
6
- 'Hello world!'
7
- end
8
- end
9
-
10
- Bossan.run('127.0.0.1', 8000, App)
11
-
@@ -1,10 +0,0 @@
1
- !!!
2
- %html
3
- %head
4
- %title Hello, Bossan!
5
- %body
6
- #header
7
- %h1 Hello, Bossan!
8
- #content
9
- %p
10
- Hello, World!
@@ -1,11 +0,0 @@
1
- require 'bossan'
2
- require 'sinatra/base'
3
- require 'haml'
4
-
5
- class App < Sinatra::Base
6
- get '/' do
7
- haml :index
8
- end
9
- end
10
-
11
- Bossan.run('127.0.0.1', 8000, App)