bossan 0.4.3 → 0.4.4
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +8 -0
- data/Rakefile +5 -2
- data/ext/bossan/bossan_ext.c +82 -60
- data/ext/bossan/client.h +2 -0
- data/lib/bossan/version.rb +1 -1
- data/lib/rack/handler/bossan.rb +1 -1
- data/test/bossan_test.rb +93 -0
- data/test/driver.rb +8 -0
- data/test/test_rack_chunk_response.rb +17 -49
- data/test/test_rack_each_response.rb +38 -0
- data/test/test_rack_env_big_message_body.rb +18 -32
- data/test/test_rack_env_simple_get.rb +30 -49
- data/test/test_rack_env_simple_query.rb +26 -44
- data/test/test_rack_err_spec.rb +17 -43
- data/test/test_rack_evil.rb +90 -88
- data/test/test_rack_handler.rb +69 -0
- data/test/test_rack_spec.rb +22 -49
- metadata +6 -3
- data/examples/inifinity.rb +0 -17
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1f63887612e549dc1e027b914db6cbc429fa2ff8
|
4
|
+
data.tar.gz: ee4fd5453fc575eb810518206f448f295c46045c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f8ed1e66372a702c38443a2496f7ae620b915ae98480912dbba4fbaca4cb6c10852b430bd26705783dad1e9b7a0fc333b94c5a02ad3bc356e23730dee29ec6f0
|
7
|
+
data.tar.gz: e7eef7ca48ed92bacc789ccbf6b260b65dad39f381532160c2ffd9bbadf2928001c2a48003ab5c74b01d7e8d8d996aa6e5ab7e60c71dce9e456832a0bd020f50
|
data/CHANGELOG.md
CHANGED
data/Rakefile
CHANGED
@@ -5,18 +5,21 @@ require "rbconfig"
|
|
5
5
|
task :default => [:compile, :clean, :test]
|
6
6
|
|
7
7
|
task :compile do
|
8
|
+
pwd = Dir.pwd
|
8
9
|
Dir.chdir File.expand_path("../ext/bossan", __FILE__)
|
9
10
|
sh "ruby extconf.rb"
|
10
11
|
sh "make"
|
11
12
|
sh "mv bossan_ext.#{RbConfig::CONFIG['DLEXT']} ../../lib/bossan/"
|
13
|
+
Dir.chdir pwd
|
12
14
|
end
|
13
15
|
|
14
16
|
task :clean do
|
17
|
+
pwd = Dir.pwd
|
15
18
|
Dir.chdir File.expand_path("../ext/bossan", __FILE__)
|
16
19
|
sh "rm -f *.o Makefile mkmf.log"
|
20
|
+
Dir.chdir pwd
|
17
21
|
end
|
18
22
|
|
19
23
|
task :test do
|
20
|
-
|
21
|
-
sh "ruby test_rack_spec.rb"
|
24
|
+
sh "ruby test/driver.rb"
|
22
25
|
end
|
data/ext/bossan/bossan_ext.c
CHANGED
@@ -23,7 +23,7 @@
|
|
23
23
|
#define CRLF "\r\n"
|
24
24
|
#define DELIM ": "
|
25
25
|
|
26
|
-
#define SERVER "bossan/0.4.
|
26
|
+
#define SERVER "bossan/0.4.4"
|
27
27
|
|
28
28
|
#define H_MSG_500 "HTTP/1.0 500 Internal Server Error\r\nContent-Type: text/html\r\nServer: " SERVER "\r\n\r\n"
|
29
29
|
|
@@ -133,6 +133,7 @@ static ID i_write;
|
|
133
133
|
static ID i_seek;
|
134
134
|
static ID i_toa;
|
135
135
|
static ID i_next;
|
136
|
+
static ID i_join;
|
136
137
|
|
137
138
|
static VALUE default_path_string;
|
138
139
|
|
@@ -741,50 +742,52 @@ processs_write(client_t *client)
|
|
741
742
|
DEBUG("process_write start");
|
742
743
|
iterator = client->response_iter;
|
743
744
|
|
744
|
-
|
745
|
+
if (client->response_body_type != T_ARRAY) {
|
746
|
+
while ( (item = rb_rescue(rb_body_iterator, iterator, ret_qnil, NULL)) != Qnil ) {
|
745
747
|
|
746
|
-
|
747
|
-
|
748
|
+
buf = StringValuePtr(item);
|
749
|
+
buflen = RSTRING_LEN(item);
|
748
750
|
|
749
|
-
|
750
|
-
|
751
|
-
|
752
|
-
|
753
|
-
|
754
|
-
|
755
|
-
|
756
|
-
|
751
|
+
//write
|
752
|
+
if(client->chunked_response){
|
753
|
+
bucket = new_write_bucket(client->fd, 4);
|
754
|
+
if(bucket == NULL){
|
755
|
+
return STATUS_ERROR;
|
756
|
+
}
|
757
|
+
char *lendata = NULL;
|
758
|
+
ssize_t len = 0;
|
757
759
|
|
758
|
-
|
759
|
-
|
760
|
-
|
761
|
-
|
760
|
+
VALUE chunk_data = get_chunk_data(buflen);
|
761
|
+
//TODO CHECK ERROR
|
762
|
+
lendata = StringValuePtr(chunk_data);
|
763
|
+
len = RSTRING_LEN(chunk_data);
|
762
764
|
|
763
|
-
|
764
|
-
|
765
|
-
|
766
|
-
|
767
|
-
|
768
|
-
|
765
|
+
set_chunked_data(bucket, lendata, len, buf, buflen);
|
766
|
+
bucket->chunk_data = chunk_data;
|
767
|
+
} else {
|
768
|
+
bucket = new_write_bucket(client->fd, 1);
|
769
|
+
if(bucket == NULL){
|
770
|
+
return STATUS_ERROR;
|
771
|
+
}
|
772
|
+
set2bucket(bucket, buf, buflen);
|
769
773
|
}
|
770
|
-
|
771
|
-
}
|
772
|
-
bucket->temp1 = item;
|
774
|
+
bucket->temp1 = item;
|
773
775
|
|
774
|
-
|
775
|
-
|
776
|
-
|
777
|
-
|
778
|
-
|
776
|
+
ret = writev_bucket(bucket);
|
777
|
+
if(ret != STATUS_OK){
|
778
|
+
client->bucket = bucket;
|
779
|
+
return ret;
|
780
|
+
}
|
779
781
|
|
780
|
-
|
781
|
-
|
782
|
-
|
783
|
-
|
784
|
-
|
785
|
-
|
786
|
-
|
787
|
-
|
782
|
+
free_write_bucket(bucket);
|
783
|
+
//mark
|
784
|
+
client->write_bytes += buflen;
|
785
|
+
//check write_bytes/content_length
|
786
|
+
if(client->content_length_set){
|
787
|
+
if(client->content_length <= client->write_bytes){
|
788
|
+
// all done
|
789
|
+
break;
|
790
|
+
}
|
788
791
|
}
|
789
792
|
}
|
790
793
|
}
|
@@ -838,14 +841,20 @@ start_response_write(client_t *client)
|
|
838
841
|
VALUE item;
|
839
842
|
char *buf = NULL;
|
840
843
|
ssize_t buflen = NULL;
|
841
|
-
|
842
|
-
item = rb_rescue(rb_body_iterator, client->response_iter, ret_qnil, NULL);
|
843
|
-
DEBUG("client %p :fd %d", client, client->fd);
|
844
844
|
|
845
|
-
if (
|
846
|
-
|
845
|
+
if (client->response_body_type == T_ARRAY) {
|
846
|
+
item = client->response_iter;
|
847
847
|
buf = StringValuePtr(item);
|
848
848
|
buflen = RSTRING_LEN(item);
|
849
|
+
} else {
|
850
|
+
item = rb_rescue(rb_body_iterator, client->response_iter, ret_qnil, NULL);
|
851
|
+
DEBUG("client %p :fd %d", client, client->fd);
|
852
|
+
|
853
|
+
if (item != Qnil) {
|
854
|
+
//write string only
|
855
|
+
buf = StringValuePtr(item);
|
856
|
+
buflen = RSTRING_LEN(item);
|
857
|
+
}
|
849
858
|
}
|
850
859
|
|
851
860
|
/* DEBUG("status_code %d body:%.*s", client->status_code, (int)buflen, buf); */
|
@@ -980,17 +989,25 @@ hex2int(int i)
|
|
980
989
|
|
981
990
|
|
982
991
|
static int
|
983
|
-
urldecode(char *buf
|
992
|
+
urldecode(char *buf)
|
984
993
|
{
|
985
|
-
int
|
986
|
-
char *s0, *t;
|
994
|
+
int len;
|
995
|
+
char c, c1, *s0, *t;
|
996
|
+
|
987
997
|
t = s0 = buf;
|
988
|
-
|
998
|
+
len = strlen(buf);
|
999
|
+
while(len > 0){
|
989
1000
|
c = *buf++;
|
990
1001
|
if(c == '%' && len > 2){
|
991
1002
|
c = *buf++;
|
1003
|
+
if (!isxdigit(c)) {
|
1004
|
+
return -1;
|
1005
|
+
}
|
992
1006
|
c1 = c;
|
993
1007
|
c = *buf++;
|
1008
|
+
if (!isxdigit(c)) {
|
1009
|
+
return -1;
|
1010
|
+
}
|
994
1011
|
c = hex2int(c1) * 16 + hex2int(c);
|
995
1012
|
len -= 2;
|
996
1013
|
}
|
@@ -1095,7 +1112,9 @@ set_path(VALUE env, char *buf, int len)
|
|
1095
1112
|
len--;
|
1096
1113
|
}
|
1097
1114
|
slen = t - s0;
|
1098
|
-
|
1115
|
+
if (urldecode(s0) == -1) {
|
1116
|
+
return -1;
|
1117
|
+
}
|
1099
1118
|
|
1100
1119
|
obj = rb_str_new(s0, slen);
|
1101
1120
|
|
@@ -1195,6 +1214,7 @@ header_field_cb(http_parser *p, const char *buf, size_t len)
|
|
1195
1214
|
}
|
1196
1215
|
|
1197
1216
|
req->field = obj;
|
1217
|
+
rb_gc_register_address(&req->field);
|
1198
1218
|
req->last_header_element = FIELD;
|
1199
1219
|
return 0;
|
1200
1220
|
}
|
@@ -1221,6 +1241,7 @@ header_value_cb(http_parser *p, const char *buf, size_t len)
|
|
1221
1241
|
return -1;
|
1222
1242
|
}
|
1223
1243
|
req->value = obj;
|
1244
|
+
rb_gc_register_address(&req->value);
|
1224
1245
|
req->last_header_element = VAL;
|
1225
1246
|
return 0;
|
1226
1247
|
}
|
@@ -1335,7 +1356,6 @@ headers_complete_cb(http_parser *p)
|
|
1335
1356
|
//Last header
|
1336
1357
|
if(likely(req->field && req->value)){
|
1337
1358
|
rb_hash_aset(env, req->field, req->value);
|
1338
|
-
|
1339
1359
|
req->field = NULL;
|
1340
1360
|
req->value = NULL;
|
1341
1361
|
}
|
@@ -1832,7 +1852,14 @@ process_rack_app(client_t *cli)
|
|
1832
1852
|
|
1833
1853
|
cli->status_code = NUM2INT(status_code);
|
1834
1854
|
cli->headers = headers;
|
1835
|
-
|
1855
|
+
|
1856
|
+
if (TYPE(response_body) == T_ARRAY) {
|
1857
|
+
cli->response_body_type = T_ARRAY;
|
1858
|
+
cli->response_iter = rb_ary_join(response_body, rb_str_new2(""));
|
1859
|
+
} else {
|
1860
|
+
cli->response_body_type = 0; // TODO: fix
|
1861
|
+
cli->response_iter = rb_funcall(response_body, i_toenum, 0);
|
1862
|
+
}
|
1836
1863
|
|
1837
1864
|
rb_gc_register_address(&cli->headers);
|
1838
1865
|
rb_gc_register_address(&cli->response_iter);
|
@@ -1849,7 +1876,7 @@ process_rack_app(client_t *cli)
|
|
1849
1876
|
char* reason_phrase;
|
1850
1877
|
reason_phrase = get_reason_phrase(cli->status_code);
|
1851
1878
|
|
1852
|
-
char buff[
|
1879
|
+
char buff[64];
|
1853
1880
|
sprintf(buff, "HTTP/1.%d %d %s\r\n", cli->http_parser->http_minor, cli->status_code, reason_phrase);
|
1854
1881
|
cli->http_status = rb_str_new(buff, strlen(buff));
|
1855
1882
|
rb_gc_register_address(&cli->http_status);
|
@@ -2462,6 +2489,9 @@ bossan_run_loop(VALUE self, VALUE args)
|
|
2462
2489
|
if(unix_sock_name){
|
2463
2490
|
unlink(unix_sock_name);
|
2464
2491
|
}
|
2492
|
+
if(listen_sock){
|
2493
|
+
close(listen_sock);
|
2494
|
+
}
|
2465
2495
|
printf("Bye.\n");
|
2466
2496
|
return Qnil;
|
2467
2497
|
}
|
@@ -2621,15 +2651,6 @@ Init_bossan_ext(void)
|
|
2621
2651
|
empty_string = rb_obj_freeze(rb_str_new2(""));
|
2622
2652
|
rb_gc_register_address(&empty_string);
|
2623
2653
|
|
2624
|
-
rb_gc_register_address(&i_keys);
|
2625
|
-
rb_gc_register_address(&i_call);
|
2626
|
-
rb_gc_register_address(&i_new);
|
2627
|
-
rb_gc_register_address(&i_each);
|
2628
|
-
rb_gc_register_address(&i_toenum);
|
2629
|
-
rb_gc_register_address(&i_close);
|
2630
|
-
rb_gc_register_address(&i_write);
|
2631
|
-
rb_gc_register_address(&i_seek);
|
2632
|
-
|
2633
2654
|
rb_gc_register_address(&rack_app); //rack app
|
2634
2655
|
|
2635
2656
|
i_new = rb_intern("new");
|
@@ -2642,6 +2663,7 @@ Init_bossan_ext(void)
|
|
2642
2663
|
i_seek = rb_intern("seek");
|
2643
2664
|
i_toa = rb_intern("to_a");
|
2644
2665
|
i_next = rb_intern("next");
|
2666
|
+
i_join = rb_intern("join");
|
2645
2667
|
|
2646
2668
|
server = rb_define_module("Bossan");
|
2647
2669
|
rb_gc_register_address(&server);
|
data/ext/bossan/client.h
CHANGED
data/lib/bossan/version.rb
CHANGED
data/lib/rack/handler/bossan.rb
CHANGED
@@ -15,7 +15,7 @@ module Rack
|
|
15
15
|
options = DEFAULT_OPTIONS.merge(options)
|
16
16
|
puts "* Listening on tcp://#{options[:Host]}:#{options[:Port]}"
|
17
17
|
|
18
|
-
::Bossan.listen(options[:Host], options[:Port])
|
18
|
+
::Bossan.listen(options[:Host], options[:Port].to_i)
|
19
19
|
::Bossan.run(app)
|
20
20
|
end
|
21
21
|
|
data/test/bossan_test.rb
ADDED
@@ -0,0 +1,93 @@
|
|
1
|
+
require_relative '../lib/bossan'
|
2
|
+
require 'minitest/unit'
|
3
|
+
require 'test/unit/testcase'
|
4
|
+
require 'net/http'
|
5
|
+
require 'tempfile'
|
6
|
+
|
7
|
+
module Bossan::Test
|
8
|
+
class TestCase < Test::Unit::TestCase
|
9
|
+
def setup
|
10
|
+
super
|
11
|
+
check_app
|
12
|
+
start_server
|
13
|
+
end
|
14
|
+
|
15
|
+
def teardown
|
16
|
+
super
|
17
|
+
stop_server
|
18
|
+
check_output_log
|
19
|
+
end
|
20
|
+
|
21
|
+
def host
|
22
|
+
"localhost"
|
23
|
+
end
|
24
|
+
|
25
|
+
def port
|
26
|
+
8000
|
27
|
+
end
|
28
|
+
|
29
|
+
def app
|
30
|
+
raise("app must override")
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
def check_app
|
35
|
+
app
|
36
|
+
end
|
37
|
+
|
38
|
+
def check_output_log
|
39
|
+
@mocked_stdout.rewind
|
40
|
+
server_stdout_log = @mocked_stdout.read
|
41
|
+
server_stdout_log.sub!("Bye.\n", "")
|
42
|
+
unless server_stdout_log.empty?
|
43
|
+
puts "! Something wrong on server. stdout:"
|
44
|
+
puts server_stdout_log
|
45
|
+
end
|
46
|
+
|
47
|
+
@mocked_stderr.rewind
|
48
|
+
server_stderr_log = @mocked_stderr.read
|
49
|
+
unless server_stderr_log.empty?
|
50
|
+
puts "! Something wrong on server. stderr:"
|
51
|
+
print server_stderr_log
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def start_server
|
56
|
+
@mocked_stdout = Tempfile.new("bossan.out")
|
57
|
+
@mocked_stderr = Tempfile.new("bossan.err")
|
58
|
+
|
59
|
+
@pid = fork do
|
60
|
+
STDOUT.reopen(@mocked_stdout)
|
61
|
+
STDERR.reopen(@mocked_stderr)
|
62
|
+
trap(:INT) { Bossan.stop }
|
63
|
+
Bossan.listen(host, port)
|
64
|
+
Bossan.run(app)
|
65
|
+
@mocked_stdout.close
|
66
|
+
@mocked_stderr.close
|
67
|
+
end
|
68
|
+
|
69
|
+
Process.detach @pid
|
70
|
+
|
71
|
+
unless server_is_wake_up?
|
72
|
+
$stderr.puts "bossan won't wake up until you love it ..."
|
73
|
+
exit 1
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def stop_server
|
78
|
+
Process.kill(:INT, @pid)
|
79
|
+
end
|
80
|
+
|
81
|
+
def server_is_wake_up? n=100
|
82
|
+
n.times {
|
83
|
+
begin
|
84
|
+
Net::HTTP.start(host, port)
|
85
|
+
rescue
|
86
|
+
next
|
87
|
+
end
|
88
|
+
return true
|
89
|
+
}
|
90
|
+
return false
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
data/test/driver.rb
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
require './test/test_rack_spec'
|
2
|
+
require './test/test_rack_err_spec'
|
3
|
+
require './test/test_rack_evil'
|
4
|
+
require './test/test_rack_chunk_response'
|
5
|
+
require './test/test_rack_env_big_message_body'
|
6
|
+
require './test/test_rack_env_simple_get'
|
7
|
+
require './test/test_rack_env_simple_query'
|
8
|
+
require './test/test_rack_each_response'
|
@@ -1,62 +1,30 @@
|
|
1
|
-
require_relative '
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
class App
|
15
|
-
def call env
|
16
|
-
body = RESPONSE
|
17
|
-
[200,
|
18
|
-
{'Content-type'=> 'text/plain'},
|
19
|
-
body
|
20
|
-
]
|
1
|
+
require_relative './bossan_test'
|
2
|
+
require 'minitest/autorun'
|
3
|
+
|
4
|
+
class RackChunkResponseTest < Bossan::Test::TestCase
|
5
|
+
class App
|
6
|
+
def call env
|
7
|
+
body = ["Hello ", "World!"]
|
8
|
+
[200,
|
9
|
+
{'Content-type'=> 'text/plain'},
|
10
|
+
body
|
11
|
+
]
|
12
|
+
end
|
21
13
|
end
|
22
|
-
end
|
23
14
|
|
24
|
-
|
15
|
+
def app
|
16
|
+
App.new
|
17
|
+
end
|
25
18
|
|
26
19
|
def test_chunk_response
|
27
|
-
response = Net::HTTP.start(
|
20
|
+
response = Net::HTTP.start(host(), port()) {|http|
|
28
21
|
http.get("/")
|
29
22
|
}
|
30
23
|
|
31
24
|
headers = response.header
|
32
25
|
assert_equal("200", response.code)
|
33
|
-
assert_equal(
|
26
|
+
assert_equal("Hello World!", response.body)
|
34
27
|
assert_equal("chunked", headers["transfer-encoding"])
|
35
28
|
assert_equal("close", headers["connection"])
|
36
29
|
end
|
37
|
-
|
38
|
-
end
|
39
|
-
|
40
|
-
|
41
|
-
begin
|
42
|
-
$stderr.puts RUBY_DESCRIPTION
|
43
|
-
|
44
|
-
pid = fork do
|
45
|
-
trap(:INT) { Bossan.stop }
|
46
|
-
Bossan.listen(DEFAULT_HOST, DEFAULT_PORT)
|
47
|
-
Bossan.run(App.new)
|
48
|
-
end
|
49
|
-
|
50
|
-
Process.detach pid
|
51
|
-
|
52
|
-
unless server_is_wake_up?
|
53
|
-
$stderr.puts "bossan won't wake up until you love it ..."
|
54
|
-
exit 1
|
55
|
-
end
|
56
|
-
|
57
|
-
err = MiniTest::Unit.new.run(ARGV)
|
58
|
-
exit false if err && err != 0
|
59
|
-
|
60
|
-
ensure
|
61
|
-
Process.kill(:INT, pid)
|
62
30
|
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require_relative './bossan_test'
|
2
|
+
require 'minitest/autorun'
|
3
|
+
require 'uri'
|
4
|
+
|
5
|
+
class RackEachResponseTest < Bossan::Test::TestCase
|
6
|
+
class EachResponse
|
7
|
+
def each
|
8
|
+
yield "Hello"
|
9
|
+
yield " "
|
10
|
+
yield "World!"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class App
|
15
|
+
def call env
|
16
|
+
body = EachResponse.new
|
17
|
+
[200,
|
18
|
+
{
|
19
|
+
'Content-type'=> 'text/plain',
|
20
|
+
'Content-length'=> "Hello World".size.to_s
|
21
|
+
},
|
22
|
+
body
|
23
|
+
]
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def app
|
28
|
+
App.new
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_each_response
|
32
|
+
response = Net::HTTP.start(host(), port()) {|http|
|
33
|
+
http.get("/")
|
34
|
+
}
|
35
|
+
assert_equal("200", response.code)
|
36
|
+
assert_equal("Hello World", response.body)
|
37
|
+
end
|
38
|
+
end
|
@@ -1,45 +1,31 @@
|
|
1
|
-
|
1
|
+
require_relative './bossan_test'
|
2
2
|
require "uri"
|
3
|
-
require '
|
4
|
-
require_relative '../lib/bossan'
|
3
|
+
require 'minitest/autorun'
|
5
4
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
5
|
+
class RackEnvBigMessageBodyTest < Bossan::Test::TestCase
|
6
|
+
def app
|
7
|
+
proc {|env|
|
8
|
+
@env = env.dup
|
9
|
+
body = @env["rack.input"].class.to_s
|
10
|
+
[200,
|
11
|
+
{
|
12
|
+
'Content-type'=> 'text/plain',
|
13
|
+
'Content-length'=> body.size.to_s
|
14
|
+
},
|
15
|
+
[ body ]
|
16
|
+
]
|
17
|
+
}
|
18
|
+
end
|
12
19
|
|
13
20
|
def test_query_app
|
14
|
-
|
15
|
-
trap(:INT) { Bossan.stop }
|
16
|
-
Bossan.listen(DEFAULT_HOST, DEFAULT_PORT)
|
17
|
-
Bossan.run(proc {|env|
|
18
|
-
@env = env.dup
|
19
|
-
assert_equal(IO, @env["rack.input"].class)
|
20
|
-
body = RESPONSE
|
21
|
-
[200,
|
22
|
-
{
|
23
|
-
'Content-type'=> 'text/plain',
|
24
|
-
'Content-length'=> RESPONSE.join.size.to_s
|
25
|
-
},
|
26
|
-
body
|
27
|
-
]
|
28
|
-
})
|
29
|
-
end
|
30
|
-
Process.detach pid
|
31
|
-
sleep 2
|
32
|
-
|
33
|
-
uri = URI.parse("http://0.0.0.0:8000/")
|
21
|
+
uri = URI.parse("http://#{host()}:#{port()}/")
|
34
22
|
Net::HTTP.start(uri.host, uri.port){|http|
|
35
23
|
header = {
|
36
24
|
"user-agent" => "Ruby/#{RUBY_VERSION} MyHttpClient"
|
37
25
|
}
|
38
26
|
body = "A" * 1024 * 513 # 513K
|
39
27
|
response = http.post(uri.path, body, header)
|
28
|
+
assert_equal("IO", response.body)
|
40
29
|
}
|
41
|
-
ensure
|
42
|
-
Process.kill(:INT, pid)
|
43
30
|
end
|
44
|
-
|
45
31
|
end
|
@@ -1,59 +1,40 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
|
-
|
3
|
-
require 'pp'
|
2
|
+
require_relative './bossan_test'
|
4
3
|
require 'net/http'
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
class RackEnvSimpleGetTest < Test::
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
4
|
+
require 'json'
|
5
|
+
require 'minitest/autorun'
|
6
|
+
|
7
|
+
class RackEnvSimpleGetTest < Bossan::Test::TestCase
|
8
|
+
def app
|
9
|
+
proc {|env|
|
10
|
+
@env = env.dup
|
11
|
+
# I have no idea how to check this two values..
|
12
|
+
@env.delete "rack.input"
|
13
|
+
@env.delete "rack.errors"
|
14
|
+
body = [JSON.dump(@env)]
|
15
|
+
[200,
|
16
|
+
{
|
17
|
+
'Content-type'=> 'application/json',
|
18
|
+
'Content-length'=> body.join.size.to_s
|
19
|
+
},
|
20
|
+
body
|
21
|
+
]
|
22
|
+
}
|
23
|
+
end
|
13
24
|
|
14
25
|
def test_simple_app
|
15
|
-
|
16
|
-
pid = fork do
|
17
|
-
r.close
|
18
|
-
trap(:INT) { Bossan.stop }
|
19
|
-
Bossan.listen(DEFAULT_HOST, DEFAULT_PORT)
|
20
|
-
Bossan.run(proc {|env|
|
21
|
-
@env = env.dup
|
22
|
-
# I have no idea how to check this two values..
|
23
|
-
@env.delete "rack.input"
|
24
|
-
@env.delete "rack.errors"
|
25
|
-
w.write Marshal.dump(@env)
|
26
|
-
w.close
|
27
|
-
body = RESPONSE
|
28
|
-
[200,
|
29
|
-
{
|
30
|
-
'Content-type'=> 'text/plain',
|
31
|
-
'Content-length'=> RESPONSE.join.size.to_s
|
32
|
-
},
|
33
|
-
body
|
34
|
-
]
|
35
|
-
})
|
36
|
-
end
|
37
|
-
Process.detach pid
|
38
|
-
sleep 2
|
39
|
-
|
40
|
-
Net::HTTP.start(DEFAULT_HOST, DEFAULT_PORT){|http|
|
26
|
+
response = Net::HTTP.start(host(), port()){|http|
|
41
27
|
http.get("/")
|
42
28
|
}
|
43
29
|
|
44
|
-
|
45
|
-
env = Marshal.load(r.read)
|
46
|
-
r.close
|
30
|
+
env = JSON.parse(response.body)
|
47
31
|
|
48
|
-
assert_equal(env["PATH_INFO"]
|
49
|
-
assert_equal(env["SCRIPT_NAME"]
|
50
|
-
assert_equal(env["QUERY_STRING"]
|
51
|
-
assert_equal(env["REQUEST_METHOD"]
|
52
|
-
assert_equal(env["SERVER_NAME"]
|
53
|
-
assert_equal(env["SERVER_PORT"]
|
54
|
-
assert_not_equal(env["HTTP_USER_AGENT"]
|
55
|
-
ensure
|
56
|
-
Process.kill(:INT, pid)
|
32
|
+
assert_equal("/", env["PATH_INFO"])
|
33
|
+
assert_equal("", env["SCRIPT_NAME"])
|
34
|
+
assert_equal("", env["QUERY_STRING"])
|
35
|
+
assert_equal("GET", env["REQUEST_METHOD"])
|
36
|
+
assert_equal("localhost", env["SERVER_NAME"])
|
37
|
+
assert_equal("8000", env["SERVER_PORT"])
|
38
|
+
assert_not_equal("", env["HTTP_USER_AGENT"])
|
57
39
|
end
|
58
|
-
|
59
40
|
end
|
@@ -1,54 +1,36 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
|
-
|
3
|
-
require 'pp'
|
2
|
+
require_relative './bossan_test'
|
4
3
|
require 'net/http'
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
class RackEnvSimpleQueryTest < Test::
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
4
|
+
require 'json'
|
5
|
+
require 'minitest/autorun'
|
6
|
+
|
7
|
+
class RackEnvSimpleQueryTest < Bossan::Test::TestCase
|
8
|
+
def app
|
9
|
+
proc {|env|
|
10
|
+
@env = env.dup
|
11
|
+
# I have no idea how to check this two values..
|
12
|
+
@env.delete "rack.input"
|
13
|
+
@env.delete "rack.errors"
|
14
|
+
|
15
|
+
body = [JSON.dump(@env)]
|
16
|
+
[200,
|
17
|
+
{
|
18
|
+
'Content-type'=> 'application/json',
|
19
|
+
'Content-length'=> body.join.size.to_s
|
20
|
+
},
|
21
|
+
body
|
22
|
+
]
|
23
|
+
}
|
24
|
+
end
|
13
25
|
|
14
26
|
def test_query_app
|
15
|
-
|
16
|
-
pid = fork do
|
17
|
-
r.close
|
18
|
-
trap(:INT) { Bossan.stop }
|
19
|
-
Bossan.listen(DEFAULT_HOST, DEFAULT_PORT)
|
20
|
-
Bossan.run(proc {|env|
|
21
|
-
@env = env.dup
|
22
|
-
# I have no idea how to check this two values..
|
23
|
-
@env.delete "rack.input"
|
24
|
-
@env.delete "rack.errors"
|
25
|
-
w.write Marshal.dump(@env)
|
26
|
-
w.close
|
27
|
-
body = RESPONSE
|
28
|
-
[200,
|
29
|
-
{
|
30
|
-
'Content-type'=> 'text/plain',
|
31
|
-
'Content-length'=> RESPONSE.join.size.to_s
|
32
|
-
},
|
33
|
-
body
|
34
|
-
]
|
35
|
-
})
|
36
|
-
end
|
37
|
-
Process.detach pid
|
38
|
-
sleep 2
|
39
|
-
|
40
|
-
Net::HTTP.start(DEFAULT_HOST, DEFAULT_PORT){|http|
|
27
|
+
response = Net::HTTP.start(host(), port()){|http|
|
41
28
|
http.get("/ABC/DEF?a=1234&bbbb=ccc")
|
42
29
|
}
|
43
30
|
|
44
|
-
|
45
|
-
env = Marshal.load(r.read)
|
46
|
-
r.close
|
31
|
+
env = JSON.parse(response.body)
|
47
32
|
|
48
|
-
assert_equal(env["PATH_INFO"]
|
49
|
-
assert_equal(
|
50
|
-
ensure
|
51
|
-
Process.kill(:INT, pid)
|
33
|
+
assert_equal("/ABC/DEF", env["PATH_INFO"])
|
34
|
+
assert_equal("a=1234&bbbb=ccc", env["QUERY_STRING"])
|
52
35
|
end
|
53
|
-
|
54
36
|
end
|
data/test/test_rack_err_spec.rb
CHANGED
@@ -1,57 +1,31 @@
|
|
1
|
-
require_relative '
|
2
|
-
|
3
|
-
require 'minitest/unit'
|
4
|
-
require 'test/unit/testcase'
|
1
|
+
require_relative './bossan_test'
|
2
|
+
require 'minitest/autorun'
|
5
3
|
|
6
|
-
|
7
|
-
DEFAULT_HOST = "localhost"
|
8
|
-
DEFAULT_PORT = 8000
|
9
4
|
ASSERT_RESPONSE = "Hello world!"
|
10
5
|
RESPONSE = ["Hello ", "world!"].freeze
|
11
6
|
|
12
|
-
|
13
|
-
class ErrApp
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
7
|
+
class RackErrSpecTest < Bossan::Test::TestCase
|
8
|
+
class ErrApp
|
9
|
+
def call env
|
10
|
+
body = RESPONSE
|
11
|
+
[500,
|
12
|
+
{
|
13
|
+
'Content-type'=> 'text/html',
|
14
|
+
},
|
15
|
+
RESPONSE
|
16
|
+
]
|
17
|
+
end
|
22
18
|
end
|
23
|
-
end
|
24
19
|
|
20
|
+
def app
|
21
|
+
ErrApp.new
|
22
|
+
end
|
25
23
|
|
26
|
-
class RackErrSpecTest < Test::Unit::TestCase
|
27
24
|
def test_error
|
28
|
-
response = Net::HTTP.start(
|
25
|
+
response = Net::HTTP.start(host(), port()) {|http|
|
29
26
|
http.get("/")
|
30
27
|
}
|
31
28
|
assert_equal("500", response.code)
|
32
29
|
assert_equal(ASSERT_RESPONSE, response.body)
|
33
30
|
end
|
34
31
|
end
|
35
|
-
|
36
|
-
|
37
|
-
begin
|
38
|
-
$stderr.puts RUBY_DESCRIPTION
|
39
|
-
pid = fork do
|
40
|
-
trap(:INT) { Bossan.stop }
|
41
|
-
Bossan.listen(DEFAULT_HOST, DEFAULT_PORT)
|
42
|
-
Bossan.run(ErrApp.new)
|
43
|
-
end
|
44
|
-
|
45
|
-
Process.detach pid
|
46
|
-
|
47
|
-
unless server_is_wake_up?
|
48
|
-
$stderr.puts "bossan won't wake up until you love it ..."
|
49
|
-
exit 1
|
50
|
-
end
|
51
|
-
|
52
|
-
err = MiniTest::Unit.new.run(ARGV)
|
53
|
-
exit false if err && err != 0
|
54
|
-
|
55
|
-
ensure
|
56
|
-
Process.kill(:INT, pid)
|
57
|
-
end
|
data/test/test_rack_evil.rb
CHANGED
@@ -1,81 +1,108 @@
|
|
1
|
-
require_relative '
|
2
|
-
require_relative './util'
|
3
|
-
require 'minitest/unit'
|
4
|
-
require 'test/unit/testcase'
|
1
|
+
require_relative './bossan_test'
|
5
2
|
require 'socket'
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
]
|
3
|
+
require 'minitest/autorun'
|
4
|
+
|
5
|
+
class BadHttpMethodTest < Bossan::Test::TestCase
|
6
|
+
ASSERT_RESPONSE = "Hello world!"
|
7
|
+
RESPONSE = ["Hello ", "world!"].freeze
|
8
|
+
DEFAULT_PATH = "/PATH?ket=value"
|
9
|
+
DEFAULT_VERSION = "HTTP/1.0"
|
10
|
+
DEFAULT_HEADER = {
|
11
|
+
"User-Agent"=> "Mozilla/5.0 (X11; U; Linux i686; ja; rv:1.9.2.7) Gecko/20100715 Ubuntu/10.04 (lucid) Firefox/3.6.7",
|
12
|
+
"Accept"=> "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
|
13
|
+
"Accept-Language"=> "ja,en-us;q=0.7,en;q=0.3",
|
14
|
+
"Accept-Encoding"=> "gzip,deflate",
|
15
|
+
"Accept-Charset"=> "Shift_JIS,utf-8;q=0.7,*;q=0.7",
|
16
|
+
"Keep-Alive"=> "115",
|
17
|
+
"Connection"=> "keep-alive",
|
18
|
+
"Cache-Control"=> "max-age=0",
|
19
|
+
}
|
20
|
+
ERR_400 = "HTTP/1.0 400 Bad Request"
|
21
|
+
|
22
|
+
class App
|
23
|
+
def call env
|
24
|
+
body = RESPONSE
|
25
|
+
[200,
|
26
|
+
{
|
27
|
+
'Content-type'=> 'text/plain',
|
28
|
+
'Content-length'=> RESPONSE.join.size.to_s
|
29
|
+
},
|
30
|
+
body
|
31
|
+
]
|
32
|
+
end
|
37
33
|
end
|
38
|
-
end
|
39
|
-
|
40
|
-
|
41
|
-
def send_data method
|
42
|
-
begin
|
43
|
-
sock = TCPSocket.new DEFAULT_HOST, DEFAULT_PORT
|
44
|
-
sock.setsockopt(Socket::SOL_SOCKET,Socket::SO_REUSEADDR, true)
|
45
|
-
sock.send("#{method} #{DEFAULT_PATH} #{DEFAULT_VERSION}\r\n", 0)
|
46
|
-
sock.send("Host: #{DEFAULT_HOST}\r\n", 0)
|
47
|
-
DEFAULT_HEADER.each_pair {|k, v|
|
48
|
-
sock.send("#{k}: #{v}\r\n", 0)
|
49
|
-
}
|
50
|
-
sock.send("\r\n", 0)
|
51
34
|
|
52
|
-
|
53
|
-
|
54
|
-
rescue
|
55
|
-
raise
|
35
|
+
def app
|
36
|
+
App.new
|
56
37
|
end
|
57
|
-
end
|
58
38
|
|
59
|
-
|
60
|
-
|
39
|
+
def send_data method
|
40
|
+
begin
|
41
|
+
sock = TCPSocket.new(host(), port())
|
42
|
+
sock.setsockopt(Socket::SOL_SOCKET,Socket::SO_REUSEADDR, true)
|
43
|
+
sock.send("#{method} #{DEFAULT_PATH} #{DEFAULT_VERSION}\r\n", 0)
|
44
|
+
sock.send("Host: #{host()}\r\n", 0)
|
45
|
+
DEFAULT_HEADER.each_pair {|k, v|
|
46
|
+
sock.send("#{k}: #{v}\r\n", 0)
|
47
|
+
}
|
48
|
+
sock.send("\r\n", 0)
|
49
|
+
|
50
|
+
data = sock.recv(1024 * 2)
|
51
|
+
return data
|
52
|
+
rescue
|
53
|
+
raise
|
54
|
+
end
|
55
|
+
end
|
61
56
|
|
62
57
|
def test_bad_method1
|
63
|
-
|
64
|
-
|
58
|
+
begin
|
59
|
+
response = send_data("")
|
60
|
+
assert_equal(ERR_400, response.split("\r\n").first)
|
61
|
+
rescue Errno::EPIPE => e
|
62
|
+
assert(true)
|
63
|
+
rescue Errno::ECONNRESET => e
|
64
|
+
assert(true)
|
65
|
+
rescue
|
66
|
+
assert(false)
|
67
|
+
end
|
65
68
|
end
|
66
69
|
|
67
70
|
def test_bad_method2
|
68
|
-
|
69
|
-
|
71
|
+
begin
|
72
|
+
response = send_data("GET" * 100)
|
73
|
+
assert_equal(ERR_400, response.split("\r\n").first)
|
74
|
+
rescue Errno::EPIPE => e
|
75
|
+
assert(true)
|
76
|
+
rescue Errno::ECONNRESET => e
|
77
|
+
assert(true)
|
78
|
+
rescue
|
79
|
+
assert(false)
|
80
|
+
end
|
70
81
|
end
|
71
82
|
|
72
83
|
def test_bad_path
|
73
|
-
|
74
|
-
|
84
|
+
begin
|
85
|
+
response = send_data("..")
|
86
|
+
assert_equal(ERR_400, response.split("\r\n").first)
|
87
|
+
rescue Errno::EPIPE => e
|
88
|
+
assert(true)
|
89
|
+
rescue Errno::ECONNRESET => e
|
90
|
+
assert(true)
|
91
|
+
rescue
|
92
|
+
assert(false)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def test_invalid_encoded_url
|
97
|
+
response = Net::HTTP.start(host(), port()) {|http|
|
98
|
+
query = "?q=%XY"
|
99
|
+
http.get("/#{query}")
|
100
|
+
}
|
101
|
+
assert_equal("400", response.code)
|
75
102
|
end
|
76
103
|
|
77
104
|
def test_long_url1
|
78
|
-
response = Net::HTTP.start(
|
105
|
+
response = Net::HTTP.start(host(), port()) {|http|
|
79
106
|
query = "A" * 4095
|
80
107
|
http.get("/#{query}")
|
81
108
|
}
|
@@ -83,35 +110,10 @@ class BadHttpMethodTest < Test::Unit::TestCase
|
|
83
110
|
end
|
84
111
|
|
85
112
|
def test_long_url2
|
86
|
-
response = Net::HTTP.start(
|
113
|
+
response = Net::HTTP.start(host(), port()) {|http|
|
87
114
|
query = "A" * 4096
|
88
115
|
http.get("/#{query}")
|
89
116
|
}
|
90
117
|
assert_equal("400", response.code)
|
91
118
|
end
|
92
|
-
|
93
|
-
end
|
94
|
-
|
95
|
-
|
96
|
-
begin
|
97
|
-
$stderr.puts RUBY_DESCRIPTION
|
98
|
-
|
99
|
-
pid = fork do
|
100
|
-
trap(:INT) { Bossan.stop }
|
101
|
-
Bossan.listen(DEFAULT_HOST, DEFAULT_PORT)
|
102
|
-
Bossan.run(App.new)
|
103
|
-
end
|
104
|
-
|
105
|
-
Process.detach pid
|
106
|
-
|
107
|
-
unless server_is_wake_up?
|
108
|
-
$stderr.puts "bossan won't wake up until you love it ..."
|
109
|
-
exit 1
|
110
|
-
end
|
111
|
-
|
112
|
-
err = MiniTest::Unit.new.run(ARGV)
|
113
|
-
exit false if err && err != 0
|
114
|
-
|
115
|
-
ensure
|
116
|
-
Process.kill(:INT, pid)
|
117
119
|
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require_relative '../lib/rack/handler/bossan'
|
2
|
+
require_relative './util'
|
3
|
+
require 'minitest/unit'
|
4
|
+
require 'test/unit/testcase'
|
5
|
+
require 'uri'
|
6
|
+
|
7
|
+
|
8
|
+
DEFAULT_HOST = "localhost"
|
9
|
+
DEFAULT_PORT = "8000"
|
10
|
+
ASSERT_RESPONSE = "Hello world!"
|
11
|
+
RESPONSE = ["Hello ", "world!"].freeze
|
12
|
+
|
13
|
+
|
14
|
+
class App
|
15
|
+
def call env
|
16
|
+
# p env
|
17
|
+
body = RESPONSE
|
18
|
+
[200,
|
19
|
+
{
|
20
|
+
'Content-type'=> 'text/plain',
|
21
|
+
'Content-length'=> RESPONSE.join.size.to_s
|
22
|
+
},
|
23
|
+
body
|
24
|
+
]
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
class RackSpecTest < Test::Unit::TestCase
|
30
|
+
|
31
|
+
def test_get
|
32
|
+
response = Net::HTTP.start(DEFAULT_HOST, DEFAULT_PORT) {|http|
|
33
|
+
http.get("/")
|
34
|
+
}
|
35
|
+
assert_equal("200", response.code)
|
36
|
+
assert_equal(ASSERT_RESPONSE, response.body)
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_post
|
40
|
+
response = Net::HTTP.post_form(URI.parse("http://#{DEFAULT_HOST}:#{DEFAULT_PORT}/"),
|
41
|
+
{'key1'=> 'value1', 'key2'=> 'value2'})
|
42
|
+
assert_equal("200", response.code)
|
43
|
+
assert_equal(ASSERT_RESPONSE, response.body)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
begin
|
49
|
+
$stderr.puts RUBY_DESCRIPTION
|
50
|
+
pid = fork do
|
51
|
+
trap(:INT) { Rack::Handler::Bossan.stop }
|
52
|
+
Rack::Handler::Bossan.run(App.new, {
|
53
|
+
:Host => DEFAULT_HOST, :Port => DEFAULT_PORT
|
54
|
+
})
|
55
|
+
end
|
56
|
+
|
57
|
+
Process.detach pid
|
58
|
+
|
59
|
+
unless server_is_wake_up?
|
60
|
+
$stderr.puts "bossan won't wake up until you love it ..."
|
61
|
+
exit 1
|
62
|
+
end
|
63
|
+
|
64
|
+
err = MiniTest::Unit.new.run(ARGV)
|
65
|
+
exit false if err && err != 0
|
66
|
+
|
67
|
+
ensure
|
68
|
+
Process.kill(:INT, pid)
|
69
|
+
end
|
data/test/test_rack_spec.rb
CHANGED
@@ -1,35 +1,30 @@
|
|
1
|
-
require_relative '
|
2
|
-
|
3
|
-
require 'minitest/unit'
|
4
|
-
require 'test/unit/testcase'
|
1
|
+
require_relative './bossan_test'
|
2
|
+
require 'minitest/autorun'
|
5
3
|
require 'uri'
|
6
4
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
},
|
23
|
-
body
|
24
|
-
]
|
5
|
+
class RackSpecTest < Bossan::Test::TestCase
|
6
|
+
ASSERT_RESPONSE = "Hello world!"
|
7
|
+
RESPONSE = ["Hello ", "world!"].freeze
|
8
|
+
|
9
|
+
class App
|
10
|
+
def call env
|
11
|
+
body = RESPONSE
|
12
|
+
[200,
|
13
|
+
{
|
14
|
+
'Content-type'=> 'text/plain',
|
15
|
+
'Content-length'=> RESPONSE.join.size.to_s
|
16
|
+
},
|
17
|
+
body
|
18
|
+
]
|
19
|
+
end
|
25
20
|
end
|
26
|
-
end
|
27
21
|
|
28
|
-
|
29
|
-
|
22
|
+
def app
|
23
|
+
App.new
|
24
|
+
end
|
30
25
|
|
31
26
|
def test_get
|
32
|
-
response = Net::HTTP.start(
|
27
|
+
response = Net::HTTP.start(host(), port()) {|http|
|
33
28
|
http.get("/")
|
34
29
|
}
|
35
30
|
assert_equal("200", response.code)
|
@@ -37,32 +32,10 @@ class RackSpecTest < Test::Unit::TestCase
|
|
37
32
|
end
|
38
33
|
|
39
34
|
def test_post
|
40
|
-
response = Net::HTTP.post_form(URI.parse("http://#{
|
35
|
+
response = Net::HTTP.post_form(URI.parse("http://#{host()}:#{port()}/"),
|
41
36
|
{'key1'=> 'value1', 'key2'=> 'value2'})
|
42
37
|
assert_equal("200", response.code)
|
43
38
|
assert_equal(ASSERT_RESPONSE, response.body)
|
44
39
|
end
|
45
40
|
end
|
46
41
|
|
47
|
-
|
48
|
-
begin
|
49
|
-
$stderr.puts RUBY_DESCRIPTION
|
50
|
-
pid = fork do
|
51
|
-
trap(:INT) { Bossan.stop }
|
52
|
-
Bossan.listen(DEFAULT_HOST, DEFAULT_PORT)
|
53
|
-
Bossan.run(App.new)
|
54
|
-
end
|
55
|
-
|
56
|
-
Process.detach pid
|
57
|
-
|
58
|
-
unless server_is_wake_up?
|
59
|
-
$stderr.puts "bossan won't wake up until you love it ..."
|
60
|
-
exit 1
|
61
|
-
end
|
62
|
-
|
63
|
-
err = MiniTest::Unit.new.run(ARGV)
|
64
|
-
exit false if err && err != 0
|
65
|
-
|
66
|
-
ensure
|
67
|
-
Process.kill(:INT, pid)
|
68
|
-
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bossan
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Hiroki Noda
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-
|
11
|
+
date: 2013-08-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rack
|
@@ -49,7 +49,6 @@ files:
|
|
49
49
|
- examples/config.ru
|
50
50
|
- examples/fork_sample.rb
|
51
51
|
- examples/hello.rb
|
52
|
-
- examples/inifinity.rb
|
53
52
|
- examples/sinatra_app.rb
|
54
53
|
- examples/views/index.haml
|
55
54
|
- examples/views_sample.rb
|
@@ -71,12 +70,16 @@ files:
|
|
71
70
|
- lib/bossan.rb
|
72
71
|
- lib/bossan/version.rb
|
73
72
|
- lib/rack/handler/bossan.rb
|
73
|
+
- test/bossan_test.rb
|
74
|
+
- test/driver.rb
|
74
75
|
- test/test_rack_chunk_response.rb
|
76
|
+
- test/test_rack_each_response.rb
|
75
77
|
- test/test_rack_env_big_message_body.rb
|
76
78
|
- test/test_rack_env_simple_get.rb
|
77
79
|
- test/test_rack_env_simple_query.rb
|
78
80
|
- test/test_rack_err_spec.rb
|
79
81
|
- test/test_rack_evil.rb
|
82
|
+
- test/test_rack_handler.rb
|
80
83
|
- test/test_rack_spec.rb
|
81
84
|
- test/util.rb
|
82
85
|
homepage: https://github.com/kubo39/bossan
|
data/examples/inifinity.rb
DELETED
@@ -1,17 +0,0 @@
|
|
1
|
-
require_relative '../lib/bossan'
|
2
|
-
|
3
|
-
|
4
|
-
app = lambda do |env|
|
5
|
-
body = (1..Float::INFINITY).lazy.map(&:to_s)
|
6
|
-
[
|
7
|
-
200, # Status code
|
8
|
-
{ # Response headers
|
9
|
-
'Content-Type' => 'text/html',
|
10
|
-
},
|
11
|
-
body # Response body
|
12
|
-
]
|
13
|
-
end
|
14
|
-
|
15
|
-
Bossan.set_keepalive(10)
|
16
|
-
Bossan.listen('127.0.0.1', 8000)
|
17
|
-
Bossan.run(app)
|