bossan 0.1.5 → 0.1.6

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