bossan 0.1.4 → 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -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)