bossan 0.1.5 → 0.1.6

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.
@@ -61,7 +61,7 @@
61
61
 
62
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>")
63
63
 
64
- #define SERVER "bossan/0.1.5"
64
+ #define SERVER "bossan/0.1.6"
65
65
 
66
66
  VALUE server; // Bossan
67
67
 
@@ -99,6 +99,7 @@ static VALUE http_connection;
99
99
  static VALUE empty_string;
100
100
 
101
101
  static VALUE http_user_agent;
102
+ static VALUE http_referer;
102
103
 
103
104
  static VALUE i_keys;
104
105
  static VALUE i_call;
@@ -107,7 +108,7 @@ static VALUE i_key;
107
108
  static VALUE i_each;
108
109
  static VALUE i_close;
109
110
 
110
- static char *server_name = "127.0.0.1";
111
+ static const char *server_name = "127.0.0.1";
111
112
  static short server_port = 8000;
112
113
 
113
114
  static int listen_sock; // listen socket
@@ -116,7 +117,7 @@ static char *unix_sock_name = NULL;
116
117
 
117
118
  static int loop_done; // main loop flag
118
119
  static picoev_loop* main_loop; //main loop
119
- static VALUE rack_app = NULL; //rack app
120
+ static VALUE rack_app; //rack app
120
121
 
121
122
  static char *log_path = NULL; //access log path
122
123
  static int log_fd = -1; //access log
@@ -207,7 +208,8 @@ typedef struct {
207
208
  uint32_t total_size;
208
209
  } write_bucket;
209
210
 
210
- buffer *
211
+
212
+ buffer *
211
213
  new_buffer(size_t buf_size, size_t limit)
212
214
  {
213
215
  buffer *buf;
@@ -223,8 +225,10 @@ new_buffer(size_t buf_size, size_t limit)
223
225
  return buf;
224
226
  }
225
227
 
226
- buffer_result
227
- write2buf(buffer *buf, const char *c, size_t l) {
228
+
229
+ buffer_result
230
+ write2buf(buffer *buf, const char *c, size_t l)
231
+ {
228
232
  size_t newl;
229
233
  char *newbuf;
230
234
  buffer_result ret = WRITE_OK;
@@ -250,14 +254,16 @@ write2buf(buffer *buf, const char *c, size_t l) {
250
254
  return ret;
251
255
  }
252
256
 
253
- void
257
+
258
+ void
254
259
  free_buffer(buffer *buf)
255
260
  {
256
261
  ruby_xfree(buf->buf);
257
262
  ruby_xfree(buf);
258
263
  }
259
264
 
260
- VALUE
265
+
266
+ VALUE
261
267
  getRbString(buffer *buf)
262
268
  {
263
269
  VALUE o;
@@ -266,20 +272,23 @@ getRbString(buffer *buf)
266
272
  return o;
267
273
  }
268
274
 
269
- char *
275
+
276
+ char *
270
277
  getString(buffer *buf)
271
278
  {
272
279
  buf->buf[buf->len] = '\0';
273
280
  return buf->buf;
274
281
  }
275
282
 
283
+
276
284
  int
277
285
  open_log_file(const char *path)
278
286
  {
279
287
  return open(path, O_CREAT|O_APPEND|O_WRONLY, 0744);
280
288
  }
281
289
 
282
- static int
290
+
291
+ static int
283
292
  write_log(const char *new_path, int fd, const char *data, size_t len)
284
293
  {
285
294
  int openfd;
@@ -306,45 +315,54 @@ write_log(const char *new_path, int fd, const char *data, size_t len)
306
315
  return fd;
307
316
  }
308
317
 
318
+
309
319
  int
310
320
  write_access_log(client_t *cli, int log_fd, const char *log_path)
311
321
  {
312
- char buf[1024];
322
+ char buf[1024*4];
313
323
  if(log_fd > 0){
314
324
  VALUE obj;
315
- char *method, *path, *version, *ua;
325
+ char *method, *path, *version, *ua, *referer;
316
326
 
317
327
  obj = rb_hash_aref(cli->environ, request_method);
318
- if(obj){
328
+ if(obj != Qnil){
319
329
  method = StringValuePtr(obj);
320
330
  }else{
321
331
  method = "-";
322
332
  }
323
333
 
324
334
  obj = rb_hash_aref(cli->environ, path_info);
325
- if(obj){
335
+ if(obj != Qnil){
326
336
  path = StringValuePtr(obj);
327
337
  }else{
328
338
  path = "-";
329
339
  }
330
340
 
331
341
  obj = rb_hash_aref(cli->environ, server_protocol);
332
- if(obj){
342
+ if(obj != Qnil){
333
343
  version = StringValuePtr(obj);
334
344
  }else{
335
345
  version = "-";
336
346
  }
337
347
 
338
348
  obj = rb_hash_aref(cli->environ, http_user_agent);
339
- if(obj){
349
+ if(obj != Qnil){
340
350
  ua = StringValuePtr(obj);
341
351
  }else{
342
352
  ua = "-";
343
353
  }
354
+
355
+ obj = rb_hash_aref(cli->environ, http_referer);
356
+ if(obj != Qnil){
357
+ referer = StringValuePtr(obj);
358
+ }else{
359
+ referer = "-";
360
+ }
361
+
344
362
  //update
345
363
  cache_time_update();
346
364
 
347
- sprintf(buf, "%s - - [%s] \"%s %s %s\" %d %d \"-\" \"%s\"\n",
365
+ sprintf(buf, "%s - - [%s] \"%s %s %s\" %d %d \"%s\" \"%s\"\n",
348
366
  cli->remote_addr,
349
367
  http_log_time,
350
368
  method,
@@ -352,13 +370,15 @@ write_access_log(client_t *cli, int log_fd, const char *log_path)
352
370
  version,
353
371
  cli->status_code,
354
372
  cli->write_bytes,
373
+ referer,
355
374
  ua);
356
375
  return write_log(log_path, log_fd, buf, strlen(buf));
357
376
  }
358
377
  return 0;
359
378
  }
360
379
 
361
- static int
380
+
381
+ static int
362
382
  blocking_write(client_t *client, char *data, size_t len)
363
383
  {
364
384
  size_t r = 0, send_len = len;
@@ -373,19 +393,26 @@ blocking_write(client_t *client, char *data, size_t len)
373
393
  break;
374
394
  case -1:
375
395
  if (errno == EAGAIN || errno == EWOULDBLOCK) { /* try again later */
376
- //printf("EAGAIN \n");
377
396
  usleep(500); //TODO try again later
378
397
  break;
379
398
  }else{
380
399
  // fatal error
381
400
  //close
382
- rb_raise(rb_eException, "fatal error");
383
-
384
- // TODO:
385
- // raise exception from errno
386
- /* rb_raise(rb_eIOError); */
387
- /* write_error_log(__FILE__, __LINE__); */
388
- client->keep_alive = 0;
401
+
402
+ if(errno == EPIPE){
403
+ // Connection reset by peer
404
+ client->keep_alive = 0;
405
+ client->status_code = 500;
406
+ client->header_done = 1;
407
+ client->response_closed = 1;
408
+
409
+ }else{
410
+ // TODO:
411
+ // raise exception from errno
412
+
413
+ /* write_error_log(__FILE__, __LINE__); */
414
+ client->keep_alive = 0;
415
+ }
389
416
  return -1;
390
417
  }
391
418
  default:
@@ -397,6 +424,7 @@ blocking_write(client_t *client, char *data, size_t len)
397
424
  return 1;
398
425
  }
399
426
 
427
+
400
428
  void
401
429
  send_error_page(client_t *client)
402
430
  {
@@ -425,9 +453,12 @@ send_error_page(client_t *client)
425
453
  break;
426
454
  }
427
455
  client->keep_alive = 0;
456
+ client->header_done = 1;
457
+ client->response_closed = 1;
428
458
  }
429
459
 
430
- static void
460
+
461
+ static void
431
462
  extent_sndbuf(client_t *client)
432
463
  {
433
464
  int bufsize = 1024 * 1024 * 2, r;
@@ -435,7 +466,8 @@ extent_sndbuf(client_t *client)
435
466
  assert(r == 0);
436
467
  }
437
468
 
438
- static void
469
+
470
+ static void
439
471
  enable_cork(client_t *client)
440
472
  {
441
473
  int on = 1, r;
@@ -447,7 +479,8 @@ enable_cork(client_t *client)
447
479
  assert(r == 0);
448
480
  }
449
481
 
450
- static write_bucket *
482
+
483
+ static write_bucket *
451
484
  new_write_bucket(int fd, int cnt)
452
485
  {
453
486
  write_bucket *bucket;
@@ -460,14 +493,16 @@ new_write_bucket(int fd, int cnt)
460
493
  return bucket;
461
494
  }
462
495
 
463
- static void
496
+
497
+ static void
464
498
  free_write_bucket(write_bucket *bucket)
465
499
  {
466
500
  ruby_xfree(bucket->iov);
467
501
  ruby_xfree(bucket);
468
502
  }
469
503
 
470
- static void
504
+
505
+ static void
471
506
  set2bucket(write_bucket *bucket, char *buf, size_t len)
472
507
  {
473
508
  bucket->iov[bucket->iov_cnt].iov_base = buf;
@@ -477,7 +512,8 @@ set2bucket(write_bucket *bucket, char *buf, size_t len)
477
512
  bucket->total_size += len;
478
513
  }
479
514
 
480
- static void
515
+
516
+ static void
481
517
  add_header(write_bucket *bucket, char *key, size_t keylen, char *val, size_t vallen)
482
518
  {
483
519
  set2bucket(bucket, key, keylen);
@@ -486,10 +522,11 @@ add_header(write_bucket *bucket, char *key, size_t keylen, char *val, size_t val
486
522
  set2bucket(bucket, CRLF, 2);
487
523
  }
488
524
 
489
- static int
525
+
526
+ static int
490
527
  writev_bucket(write_bucket *data)
491
528
  {
492
- size_t w;
529
+ ssize_t w;
493
530
  int i = 0;
494
531
  w = writev(data->fd, data->iov, data->iov_cnt);
495
532
  if(w == -1){
@@ -499,7 +536,6 @@ writev_bucket(write_bucket *data)
499
536
  return 0;
500
537
  }else{
501
538
  //ERROR
502
- rb_raise(rb_eException, "fatal error");
503
539
 
504
540
  // TODO:
505
541
  // raise exception from errno
@@ -534,7 +570,8 @@ writev_bucket(write_bucket *data)
534
570
  return 1;
535
571
  }
536
572
 
537
- static int
573
+
574
+ static int
538
575
  write_headers(client_t *client)
539
576
  {
540
577
  if(client->header_done){
@@ -543,8 +580,8 @@ write_headers(client_t *client)
543
580
  write_bucket *bucket;
544
581
  uint32_t i = 0, hlen = 0;
545
582
 
546
- VALUE arr = NULL;
547
- VALUE object = NULL;
583
+ VALUE arr;
584
+ VALUE object;
548
585
  char *name = NULL;
549
586
  ssize_t namelen;
550
587
  char *value = NULL;
@@ -651,7 +688,8 @@ write_headers(client_t *client)
651
688
  return -1;
652
689
  }
653
690
 
654
- /* static int */
691
+
692
+ /* static int */
655
693
  /* write_sendfile(int out_fd, int in_fd, size_t count) */
656
694
  /* { */
657
695
  /* int size = (int)count; */
@@ -670,7 +708,8 @@ write_headers(client_t *client)
670
708
  /* return sendfile(out_fd, in_fd, NULL, count); */
671
709
  /* } */
672
710
 
673
- static void
711
+
712
+ static void
674
713
  close_response(client_t *client)
675
714
  {
676
715
  //send all response
@@ -678,6 +717,7 @@ close_response(client_t *client)
678
717
  client->response_closed = 1;
679
718
  }
680
719
 
720
+
681
721
  static VALUE
682
722
  collect_body(VALUE i, VALUE str, int argc, VALUE *argv)
683
723
  {
@@ -688,21 +728,22 @@ collect_body(VALUE i, VALUE str, int argc, VALUE *argv)
688
728
  return Qnil;
689
729
  }
690
730
 
691
- static int
731
+
732
+ static int
692
733
  processs_write(client_t *client)
693
734
  {
694
- VALUE iterator = NULL;
735
+ VALUE iterator;
695
736
  VALUE v_body;
696
737
  VALUE item;
697
738
  char *buf;
698
- ssize_t buflen;
739
+ size_t buflen;
699
740
  write_bucket *bucket;
700
741
  int ret;
701
742
 
702
743
  // body
703
744
  iterator = client->response_iter;
704
745
 
705
- if(iterator != NULL){
746
+ if(iterator != Qnil){
706
747
  if (TYPE(iterator) != T_ARRAY || RARRAY_LEN(iterator) != 3){
707
748
  return -1;
708
749
  }
@@ -742,7 +783,8 @@ processs_write(client_t *client)
742
783
  return 1;
743
784
  }
744
785
 
745
- int
786
+
787
+ int
746
788
  process_body(client_t *client)
747
789
  {
748
790
  int ret;
@@ -765,7 +807,8 @@ process_body(client_t *client)
765
807
  return ret;
766
808
  }
767
809
 
768
- static int
810
+
811
+ static int
769
812
  start_response_write(client_t *client)
770
813
  {
771
814
  VALUE iterator;
@@ -794,7 +837,8 @@ start_response_write(client_t *client)
794
837
  return write_headers(client);
795
838
  }
796
839
 
797
- int
840
+
841
+ int
798
842
  response_start(client_t *client)
799
843
  {
800
844
  int ret;
@@ -813,7 +857,8 @@ response_start(client_t *client)
813
857
  return ret;
814
858
  }
815
859
 
816
- request *
860
+
861
+ request *
817
862
  new_request(void)
818
863
  {
819
864
  request *req = (request *)ruby_xmalloc(sizeof(request));
@@ -821,7 +866,8 @@ new_request(void)
821
866
  return req;
822
867
  }
823
868
 
824
- header *
869
+
870
+ header *
825
871
  new_header(size_t fsize, size_t flimit, size_t vsize, size_t vlimit)
826
872
  {
827
873
  header *h;
@@ -831,13 +877,15 @@ new_header(size_t fsize, size_t flimit, size_t vsize, size_t vlimit)
831
877
  return h;
832
878
  }
833
879
 
834
- void
880
+
881
+ void
835
882
  free_header(header *h)
836
883
  {
837
884
  ruby_xfree(h);
838
885
  }
839
886
 
840
- void
887
+
888
+ void
841
889
  free_request(request *req)
842
890
  {
843
891
  uint32_t i;
@@ -870,7 +918,8 @@ free_request(request *req)
870
918
  ruby_xfree(req);
871
919
  }
872
920
 
873
- static void
921
+
922
+ static void
874
923
  key_upper(char *s, const char *key, size_t len)
875
924
  {
876
925
  int i = 0;
@@ -889,7 +938,8 @@ key_upper(char *s, const char *key, size_t len)
889
938
  }
890
939
  }
891
940
 
892
- static int
941
+
942
+ static int
893
943
  write_body2file(client_t *client, const char *buffer, size_t buffer_len)
894
944
  {
895
945
  FILE *tmp = (FILE *)client->body;
@@ -901,10 +951,11 @@ write_body2file(client_t *client, const char *buffer, size_t buffer_len)
901
951
  return client->body_readed;
902
952
  }
903
953
 
904
- static int
954
+
955
+ static int
905
956
  write_body2mem(client_t *client, const char *buffer, size_t buffer_len)
906
957
  {
907
- printf("body2mem called\n");
958
+ /* printf("body2mem called\n"); */
908
959
  VALUE obj = (VALUE)client->body;
909
960
  rb_str_concat(obj, rb_str_new(buffer, buffer_len));
910
961
  client->body_readed += buffer_len;
@@ -914,18 +965,21 @@ write_body2mem(client_t *client, const char *buffer, size_t buffer_len)
914
965
  return client->body_readed;
915
966
  }
916
967
 
917
- static int
968
+
969
+ static int
918
970
  write_body(client_t *cli, const char *buffer, size_t buffer_len)
919
971
  {
920
972
  return write_body2mem(cli, buffer, buffer_len);
921
973
  }
922
974
 
975
+
923
976
  typedef enum{
924
977
  CONTENT_TYPE,
925
978
  CONTENT_LENGTH,
926
979
  OTHER
927
980
  } rack_header_type;
928
981
 
982
+
929
983
  static rack_header_type
930
984
  check_header_type(const char *buf)
931
985
  {
@@ -962,25 +1016,28 @@ check_header_type(const char *buf)
962
1016
  return OTHER;
963
1017
  }
964
1018
 
965
- static client_t *
1019
+
1020
+ static client_t *
966
1021
  get_client(http_parser *p)
967
1022
  {
968
1023
  return (client_t *)p->data;
969
1024
  }
970
1025
 
1026
+
971
1027
  int
972
1028
  message_begin_cb(http_parser *p)
973
1029
  {
974
1030
  return 0;
975
1031
  }
976
1032
 
1033
+
977
1034
  int
978
1035
  header_field_cb (http_parser *p, const char *buf, size_t len, char partial)
979
1036
  {
980
1037
  uint32_t i;
981
- register header *h;
1038
+ header *h;
982
1039
  client_t *client = get_client(p);
983
- register request *req = client->req;
1040
+ request *req = client->req;
984
1041
  char temp[len];
985
1042
 
986
1043
  buffer_result ret = MEMORY_ERROR;
@@ -1020,13 +1077,14 @@ header_field_cb (http_parser *p, const char *buf, size_t len, char partial)
1020
1077
  return 0;
1021
1078
  }
1022
1079
 
1080
+
1023
1081
  int
1024
1082
  header_value_cb (http_parser *p, const char *buf, size_t len, char partial)
1025
1083
  {
1026
1084
  uint32_t i;
1027
- register header *h;
1085
+ header *h;
1028
1086
  client_t *client = get_client(p);
1029
- register request *req = client->req;
1087
+ request *req = client->req;
1030
1088
 
1031
1089
  buffer_result ret = MEMORY_ERROR;
1032
1090
  i = req->num_headers;
@@ -1049,11 +1107,12 @@ header_value_cb (http_parser *p, const char *buf, size_t len, char partial)
1049
1107
  return 0;
1050
1108
  }
1051
1109
 
1110
+
1052
1111
  int
1053
1112
  request_path_cb (http_parser *p, const char *buf, size_t len, char partial)
1054
1113
  {
1055
1114
  client_t *client = get_client(p);
1056
- register request *req = client->req;
1115
+ request *req = client->req;
1057
1116
  buffer_result ret = MEMORY_ERROR;
1058
1117
 
1059
1118
  if(req->path){
@@ -1075,6 +1134,7 @@ request_path_cb (http_parser *p, const char *buf, size_t len, char partial)
1075
1134
  return 0;
1076
1135
  }
1077
1136
 
1137
+
1078
1138
  int
1079
1139
  request_uri_cb (http_parser *p, const char *buf, size_t len, char partial)
1080
1140
  {
@@ -1101,11 +1161,12 @@ request_uri_cb (http_parser *p, const char *buf, size_t len, char partial)
1101
1161
  return 0;
1102
1162
  }
1103
1163
 
1164
+
1104
1165
  int
1105
1166
  query_string_cb (http_parser *p, const char *buf, size_t len, char partial)
1106
1167
  {
1107
1168
  client_t *client = get_client(p);
1108
- register request *req = client->req;
1169
+ request *req = client->req;
1109
1170
  buffer_result ret = MEMORY_ERROR;
1110
1171
 
1111
1172
  if(req->query_string){
@@ -1127,6 +1188,7 @@ query_string_cb (http_parser *p, const char *buf, size_t len, char partial)
1127
1188
  return 0;
1128
1189
  }
1129
1190
 
1191
+
1130
1192
  int
1131
1193
  fragment_cb (http_parser *p, const char *buf, size_t len, char partial)
1132
1194
  {
@@ -1153,6 +1215,7 @@ fragment_cb (http_parser *p, const char *buf, size_t len, char partial)
1153
1215
  return 0;
1154
1216
  }
1155
1217
 
1218
+
1156
1219
  int
1157
1220
  body_cb (http_parser *p, const char *buf, size_t len, char partial)
1158
1221
  {
@@ -1180,15 +1243,16 @@ body_cb (http_parser *p, const char *buf, size_t len, char partial)
1180
1243
  return 0;
1181
1244
  }
1182
1245
 
1246
+
1183
1247
  int
1184
1248
  headers_complete_cb(http_parser *p)
1185
1249
  {
1186
- register VALUE obj, key;
1250
+ VALUE obj, key;
1187
1251
  client_t *client = get_client(p);
1188
1252
  request *req = client->req;
1189
- register VALUE env = client->environ;
1190
- register uint32_t i = 0;
1191
- register header *h;
1253
+ VALUE env = client->environ;
1254
+ uint32_t i = 0;
1255
+ header *h;
1192
1256
 
1193
1257
  if(max_content_length < p->content_length){
1194
1258
  client->bad_request_code = 413;
@@ -1304,6 +1368,7 @@ headers_complete_cb(http_parser *p)
1304
1368
  return 0;
1305
1369
  }
1306
1370
 
1371
+
1307
1372
  int
1308
1373
  message_complete_cb (http_parser *p)
1309
1374
  {
@@ -1312,6 +1377,7 @@ message_complete_cb (http_parser *p)
1312
1377
  return 0;
1313
1378
  }
1314
1379
 
1380
+
1315
1381
  static http_parser_settings settings =
1316
1382
  {.on_message_begin = message_begin_cb
1317
1383
  ,.on_header_field = header_field_cb
@@ -1325,20 +1391,18 @@ static http_parser_settings settings =
1325
1391
  ,.on_message_complete = message_complete_cb
1326
1392
  };
1327
1393
 
1328
- int
1394
+
1395
+ int
1329
1396
  init_parser(client_t *cli, const char *name, const short port)
1330
1397
  {
1331
- register VALUE object;
1398
+ VALUE object;
1399
+ char r_port[7];
1332
1400
 
1333
1401
  cli->http = (http_parser*)ruby_xmalloc(sizeof(http_parser));
1334
1402
  memset(cli->http, 0, sizeof(http_parser));
1335
1403
 
1336
1404
  cli->environ = rb_hash_new();
1337
1405
 
1338
- if (cli->environ == NULL) {
1339
- return -1;
1340
- }
1341
-
1342
1406
  rb_hash_aset(cli->environ, version_key, version_val);
1343
1407
  rb_hash_aset(cli->environ, scheme_key, scheme_val);
1344
1408
  rb_hash_aset(cli->environ, errors_key, errors_val);
@@ -1355,7 +1419,6 @@ init_parser(client_t *cli, const char *name, const short port)
1355
1419
  object = rb_str_new2(cli->remote_addr);
1356
1420
  rb_hash_aset(cli->environ, rb_remote_addr, object);
1357
1421
 
1358
- char r_port[6];
1359
1422
  sprintf(r_port, "%d", cli->remote_port);
1360
1423
  object = rb_str_new2(r_port);
1361
1424
  rb_hash_aset(cli->environ, rb_remote_port, object);
@@ -1366,21 +1429,26 @@ init_parser(client_t *cli, const char *name, const short port)
1366
1429
  return 0;
1367
1430
  }
1368
1431
 
1369
- size_t
1432
+
1433
+ size_t
1370
1434
  execute_parse(client_t *cli, const char *data, size_t len)
1371
1435
  {
1372
1436
  return http_parser_execute(cli->http, &settings, data, len);
1373
1437
  }
1374
1438
 
1375
- int
1439
+
1440
+ int
1376
1441
  parser_finish(client_t *cli)
1377
1442
  {
1378
1443
  return cli->complete;
1379
1444
  }
1380
1445
 
1381
- void
1446
+
1447
+ void
1382
1448
  setup_static_env(char *name, int port)
1383
1449
  {
1450
+ char vport[7];
1451
+
1384
1452
  version_val = rb_obj_freeze(rb_ary_new3(2, INT2FIX(1), INT2FIX(1)));
1385
1453
  version_key = rb_obj_freeze(rb_str_new2("rack.version"));
1386
1454
 
@@ -1405,7 +1473,6 @@ setup_static_env(char *name, int port)
1405
1473
  server_name_val = rb_obj_freeze(rb_str_new2(name));
1406
1474
  server_name_key = rb_obj_freeze(rb_str_new2("SERVER_NAME"));
1407
1475
 
1408
- char vport[6];
1409
1476
  sprintf(vport, "%d", port);
1410
1477
  server_port_val = rb_obj_freeze(rb_str_new2(vport));
1411
1478
  server_port_key = rb_obj_freeze(rb_str_new2("SERVER_PORT"));
@@ -1422,9 +1489,11 @@ setup_static_env(char *name, int port)
1422
1489
  http_connection = rb_obj_freeze(rb_str_new2("HTTP_CONNECTION"));
1423
1490
 
1424
1491
  http_user_agent = rb_obj_freeze(rb_str_new2("HTTP_USER_AGENT"));
1492
+ http_referer = rb_obj_freeze(rb_str_new2("HTTP_REFERER"));
1425
1493
  }
1426
1494
 
1427
- static int
1495
+
1496
+ static int
1428
1497
  setsig(int sig, void* handler)
1429
1498
  {
1430
1499
  struct sigaction context, ocontext;
@@ -1434,7 +1503,8 @@ setsig(int sig, void* handler)
1434
1503
  return sigaction(sig, &context, &ocontext);
1435
1504
  }
1436
1505
 
1437
- static void
1506
+
1507
+ static void
1438
1508
  setup_sock(int fd)
1439
1509
  {
1440
1510
  int on = 1, r;
@@ -1444,7 +1514,8 @@ setup_sock(int fd)
1444
1514
  assert(r == 0);
1445
1515
  }
1446
1516
 
1447
- static void
1517
+
1518
+ static void
1448
1519
  disable_cork(client_t *client)
1449
1520
  {
1450
1521
  int off = 0;
@@ -1459,7 +1530,8 @@ disable_cork(client_t *client)
1459
1530
  assert(r == 0);
1460
1531
  }
1461
1532
 
1462
- static client_t *
1533
+
1534
+ static client_t *
1463
1535
  new_client_t(int client_fd, struct sockaddr_in client_addr){
1464
1536
  client_t *client;
1465
1537
 
@@ -1478,7 +1550,8 @@ new_client_t(int client_fd, struct sockaddr_in client_addr){
1478
1550
  return client;
1479
1551
  }
1480
1552
 
1481
- static void
1553
+
1554
+ static void
1482
1555
  clean_cli(client_t *client)
1483
1556
  {
1484
1557
  write_access_log(client, log_fd, log_path);
@@ -1486,6 +1559,12 @@ clean_cli(client_t *client)
1486
1559
  free_request(client->req);
1487
1560
  client->req = NULL;
1488
1561
  }
1562
+ #ifdef DEBUG
1563
+ printf("close environ %p \n", client->environ);
1564
+ #endif
1565
+
1566
+ // force clear
1567
+ client->environ = rb_hash_new();
1489
1568
 
1490
1569
  if(client->http != NULL){
1491
1570
  ruby_xfree(client->http);
@@ -1493,7 +1572,8 @@ clean_cli(client_t *client)
1493
1572
  }
1494
1573
  }
1495
1574
 
1496
- static void
1575
+
1576
+ static void
1497
1577
  close_conn(client_t *cli, picoev_loop* loop)
1498
1578
  {
1499
1579
  if(!cli->keep_alive){
@@ -1508,13 +1588,13 @@ close_conn(client_t *cli, picoev_loop* loop)
1508
1588
  clean_cli(cli);
1509
1589
  disable_cork(cli);
1510
1590
  cli->keep_alive = 1;
1511
- cli->environ = NULL;
1512
- cli->http_status = NULL;
1513
- cli->headers = NULL;
1591
+ cli->environ = Qnil;
1592
+ cli->http_status = Qnil;
1593
+ cli->headers = Qnil;
1514
1594
  cli->header_done = 0;
1515
1595
  cli->body_type = BODY_TYPE_NONE;
1516
1596
  cli->status_code = 0;
1517
- cli->response = NULL;
1597
+ cli->response = Qnil;
1518
1598
  cli->content_length_set = 0;
1519
1599
  cli->content_length = 0;
1520
1600
  cli->write_bytes = 0;
@@ -1524,10 +1604,11 @@ close_conn(client_t *cli, picoev_loop* loop)
1524
1604
  }
1525
1605
  }
1526
1606
 
1527
- static int
1607
+
1608
+ static int
1528
1609
  process_rack_app(client_t *cli)
1529
1610
  {
1530
- VALUE args = NULL;
1611
+ VALUE args;
1531
1612
  char *status;
1532
1613
 
1533
1614
  args = cli->environ;
@@ -1567,6 +1648,7 @@ process_rack_app(client_t *cli)
1567
1648
  return 1;
1568
1649
  }
1569
1650
 
1651
+
1570
1652
  static void
1571
1653
  w_callback(picoev_loop* loop, int fd, int events, void* cb_arg)
1572
1654
  {
@@ -1596,7 +1678,8 @@ w_callback(picoev_loop* loop, int fd, int events, void* cb_arg)
1596
1678
  }
1597
1679
  }
1598
1680
 
1599
- static void
1681
+
1682
+ static void
1600
1683
  call_rack_app(client_t *client, picoev_loop* loop)
1601
1684
  {
1602
1685
  int ret;
@@ -1623,6 +1706,8 @@ call_rack_app(client_t *client, picoev_loop* loop)
1623
1706
  #ifdef DEBUG
1624
1707
  printf("set write callback %d \n", ret);
1625
1708
  #endif
1709
+ //clear event
1710
+ picoev_del(loop, client->fd);
1626
1711
  picoev_add(loop, client->fd, PICOEV_WRITE, WRITE_TIMEOUT_SECS, w_callback, (void *)client);
1627
1712
  return;
1628
1713
  default:
@@ -1631,21 +1716,22 @@ call_rack_app(client_t *client, picoev_loop* loop)
1631
1716
  }
1632
1717
  }
1633
1718
 
1634
- static void
1719
+
1720
+ static void
1635
1721
  prepare_call_rack(client_t *client)
1636
1722
  {
1637
- VALUE input = NULL, object = NULL, c = NULL;
1723
+ VALUE input, object, c;
1638
1724
  char *val;
1639
1725
 
1640
1726
  object = rb_str_new2("");
1641
1727
  input = rb_funcall(StringIO, i_new, 1, object);
1642
- rb_hash_aset((VALUE)client->environ, rack_input, input);
1728
+ rb_hash_aset(client->environ, rack_input, input);
1643
1729
  client->body = object;
1644
1730
 
1645
1731
  if(is_keep_alive){
1646
1732
  //support keep-alive
1647
1733
  c = rb_hash_aref(client->environ, http_connection);
1648
- if(c){
1734
+ if(c != Qnil){
1649
1735
  val = StringValuePtr(c);
1650
1736
  if(!strcasecmp(val, "keep-alive")){
1651
1737
  client->keep_alive = 1;
@@ -1658,6 +1744,7 @@ prepare_call_rack(client_t *client)
1658
1744
  }
1659
1745
  }
1660
1746
 
1747
+
1661
1748
  static void
1662
1749
  r_callback(picoev_loop* loop, int fd, int events, void* cb_arg)
1663
1750
  {
@@ -1741,6 +1828,7 @@ r_callback(picoev_loop* loop, int fd, int events, void* cb_arg)
1741
1828
  }
1742
1829
  }
1743
1830
 
1831
+
1744
1832
  static void
1745
1833
  accept_callback(picoev_loop* loop, int fd, int events, void* cb_arg)
1746
1834
  {
@@ -1753,8 +1841,11 @@ accept_callback(picoev_loop* loop, int fd, int events, void* cb_arg)
1753
1841
  return;
1754
1842
  }else if ((events & PICOEV_READ) != 0) {
1755
1843
  socklen_t client_len = sizeof(client_addr);
1756
- //client_fd = accept4(fd, (struct sockaddr *)&client_addr, &client_len, SOCK_NONBLOCK | SOCK_CLOEXEC);
1844
+ #ifdef linux
1845
+ client_fd = accept4(fd, (struct sockaddr *)&client_addr, &client_len, SOCK_NONBLOCK | SOCK_CLOEXEC);
1846
+ #else
1757
1847
  client_fd = accept(fd, (struct sockaddr *)&client_addr, &client_len);
1848
+ #endif
1758
1849
  if (client_fd != -1) {
1759
1850
  #ifdef DEBUG
1760
1851
  printf("accept fd %d \n", client_fd);
@@ -1781,7 +1872,8 @@ accept_callback(picoev_loop* loop, int fd, int events, void* cb_arg)
1781
1872
  }
1782
1873
  }
1783
1874
 
1784
- static void
1875
+
1876
+ static void
1785
1877
  setup_server_env(void)
1786
1878
  {
1787
1879
  setup_sock(listen_sock);
@@ -1790,7 +1882,8 @@ setup_server_env(void)
1790
1882
  setup_static_env(server_name, server_port);
1791
1883
  }
1792
1884
 
1793
- static int
1885
+
1886
+ static int
1794
1887
  inet_listen(void)
1795
1888
  {
1796
1889
  struct addrinfo hints, *servinfo, *p;
@@ -1859,7 +1952,8 @@ inet_listen(void)
1859
1952
  return 1;
1860
1953
  }
1861
1954
 
1862
- static int
1955
+
1956
+ static int
1863
1957
  check_unix_sockpath(char *sock_name)
1864
1958
  {
1865
1959
  if(!access(sock_name, F_OK)){
@@ -1870,7 +1964,8 @@ check_unix_sockpath(char *sock_name)
1870
1964
  return 1;
1871
1965
  }
1872
1966
 
1873
- static int
1967
+
1968
+ static int
1874
1969
  unix_listen(char *sock_name)
1875
1970
  {
1876
1971
  int flag = 1;
@@ -1914,6 +2009,7 @@ unix_listen(char *sock_name)
1914
2009
  return 1;
1915
2010
  }
1916
2011
 
2012
+
1917
2013
  static void
1918
2014
  sigint_cb(int signum)
1919
2015
  {
@@ -1921,11 +2017,13 @@ sigint_cb(int signum)
1921
2017
  /* rb_interrupt(); */
1922
2018
  }
1923
2019
 
2020
+
1924
2021
  static void
1925
2022
  sigpipe_cb(int signum)
1926
2023
  {
1927
2024
  }
1928
2025
 
2026
+
1929
2027
  static VALUE
1930
2028
  bossan_stop(VALUE self)
1931
2029
  {
@@ -1933,6 +2031,7 @@ bossan_stop(VALUE self)
1933
2031
  return Qnil;
1934
2032
  }
1935
2033
 
2034
+
1936
2035
  static VALUE
1937
2036
  bossan_access_log(VALUE self, VALUE args)
1938
2037
  {
@@ -1941,6 +2040,17 @@ bossan_access_log(VALUE self, VALUE args)
1941
2040
  if(log_fd > 0){
1942
2041
  close(log_fd);
1943
2042
  }
2043
+
2044
+ if(!strcasecmp(log_path, "stdout")){
2045
+ log_fd = 1;
2046
+ return Qnil;
2047
+ }
2048
+
2049
+ if(!strcasecmp(log_path, "stderr")){
2050
+ log_fd = 2;
2051
+ return Qnil;
2052
+ }
2053
+
1944
2054
  log_fd = open_log_file(log_path);
1945
2055
 
1946
2056
  if(log_fd < 0){
@@ -1949,6 +2059,7 @@ bossan_access_log(VALUE self, VALUE args)
1949
2059
  return Qnil;
1950
2060
  }
1951
2061
 
2062
+
1952
2063
  static VALUE
1953
2064
  bossan_run_loop(int argc, VALUE *argv, VALUE self)
1954
2065
  {
@@ -1978,7 +2089,7 @@ bossan_run_loop(int argc, VALUE *argv, VALUE self)
1978
2089
  rack_app = args3;
1979
2090
  } else {
1980
2091
  Check_Type(args1, T_STRING);
1981
- ret = unix_listen(args1);
2092
+ ret = unix_listen(StringValuePtr(args1));
1982
2093
  rack_app = args2;
1983
2094
  }
1984
2095
 
@@ -2014,6 +2125,7 @@ bossan_run_loop(int argc, VALUE *argv, VALUE self)
2014
2125
  return Qnil;
2015
2126
  }
2016
2127
 
2128
+
2017
2129
  VALUE
2018
2130
  bossan_set_max_content_length(VALUE self, VALUE args)
2019
2131
  {
@@ -2021,12 +2133,14 @@ bossan_set_max_content_length(VALUE self, VALUE args)
2021
2133
  return Qnil;
2022
2134
  }
2023
2135
 
2136
+
2024
2137
  VALUE
2025
2138
  bossan_get_max_content_length(VALUE self)
2026
2139
  {
2027
2140
  return INT2NUM(max_content_length);
2028
2141
  }
2029
2142
 
2143
+
2030
2144
  void
2031
2145
  Init_bossan_ext(void)
2032
2146
  {
@@ -2062,6 +2176,7 @@ Init_bossan_ext(void)
2062
2176
  rb_gc_register_address(&http_connection);
2063
2177
 
2064
2178
  rb_gc_register_address(&http_user_agent);
2179
+ rb_gc_register_address(&http_referer);
2065
2180
 
2066
2181
  empty_string = rb_obj_freeze(rb_str_new2(""));
2067
2182
  rb_gc_register_address(&empty_string);
@@ -1,3 +1,3 @@
1
1
  module Bossan
2
- VERSION = "0.1.5"
2
+ VERSION = "0.1.6"
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.5
4
+ version: 0.1.6
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-01-27 00:00:00.000000000 Z
12
+ date: 2013-02-21 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rack