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.
- data/ext/bossan/bossan_ext.c +216 -101
- data/lib/bossan/version.rb +1 -1
- metadata +2 -2
data/ext/bossan/bossan_ext.c
CHANGED
@@ -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.
|
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
|
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
|
-
|
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
|
-
|
227
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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 \"
|
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
|
-
|
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
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
525
|
+
|
526
|
+
static int
|
490
527
|
writev_bucket(write_bucket *data)
|
491
528
|
{
|
492
|
-
|
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
|
-
|
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
|
547
|
-
VALUE object
|
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
|
-
|
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
|
-
|
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
|
-
|
731
|
+
|
732
|
+
static int
|
692
733
|
processs_write(client_t *client)
|
693
734
|
{
|
694
|
-
VALUE iterator
|
735
|
+
VALUE iterator;
|
695
736
|
VALUE v_body;
|
696
737
|
VALUE item;
|
697
738
|
char *buf;
|
698
|
-
|
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 !=
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
880
|
+
|
881
|
+
void
|
835
882
|
free_header(header *h)
|
836
883
|
{
|
837
884
|
ruby_xfree(h);
|
838
885
|
}
|
839
886
|
|
840
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
1038
|
+
header *h;
|
982
1039
|
client_t *client = get_client(p);
|
983
|
-
|
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
|
-
|
1085
|
+
header *h;
|
1028
1086
|
client_t *client = get_client(p);
|
1029
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
1250
|
+
VALUE obj, key;
|
1187
1251
|
client_t *client = get_client(p);
|
1188
1252
|
request *req = client->req;
|
1189
|
-
|
1190
|
-
|
1191
|
-
|
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
|
-
|
1394
|
+
|
1395
|
+
int
|
1329
1396
|
init_parser(client_t *cli, const char *name, const short port)
|
1330
1397
|
{
|
1331
|
-
|
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
|
-
|
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
|
-
|
1439
|
+
|
1440
|
+
int
|
1376
1441
|
parser_finish(client_t *cli)
|
1377
1442
|
{
|
1378
1443
|
return cli->complete;
|
1379
1444
|
}
|
1380
1445
|
|
1381
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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 =
|
1512
|
-
cli->http_status =
|
1513
|
-
cli->headers =
|
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 =
|
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
|
-
|
1607
|
+
|
1608
|
+
static int
|
1528
1609
|
process_rack_app(client_t *cli)
|
1529
1610
|
{
|
1530
|
-
VALUE args
|
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
|
-
|
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
|
-
|
1719
|
+
|
1720
|
+
static void
|
1635
1721
|
prepare_call_rack(client_t *client)
|
1636
1722
|
{
|
1637
|
-
VALUE input
|
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(
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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);
|
data/lib/bossan/version.rb
CHANGED
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
|
+
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-
|
12
|
+
date: 2013-02-21 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rack
|