bossan 0.3.0 → 0.4.0
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 +6 -14
- data/.travis.yml +2 -1
- data/CHANGELOG.md +16 -0
- data/README.md +5 -3
- data/examples/fork_sample.rb +1 -1
- data/examples/hello.rb +11 -11
- data/examples/uploads.rb +7 -11
- data/ext/bossan/bossan.h +33 -32
- data/ext/bossan/bossan_ext.c +1260 -679
- data/ext/bossan/buffer.c +8 -8
- data/ext/bossan/buffer.h +12 -7
- data/ext/bossan/client.h +9 -10
- data/ext/bossan/http_parser.c +1252 -677
- data/ext/bossan/http_parser.h +200 -46
- data/ext/bossan/request.c +46 -37
- data/ext/bossan/request.h +26 -15
- data/ext/bossan/time_cache.h +1 -0
- data/lib/bossan/version.rb +1 -1
- data/test/test_rack_bad_http_method.rb +75 -63
- data/test/test_rack_chunk_response.rb +76 -0
- data/test/test_rack_long_url.rb +53 -47
- data/test/test_rack_spec.rb +55 -48
- metadata +5 -5
data/ext/bossan/time_cache.h
CHANGED
data/lib/bossan/version.rb
CHANGED
@@ -1,60 +1,48 @@
|
|
1
1
|
require_relative '../lib/bossan'
|
2
|
-
require '
|
2
|
+
require 'minitest/unit'
|
3
|
+
require 'test/unit/testcase'
|
3
4
|
require 'socket'
|
4
5
|
require 'net/http'
|
5
6
|
|
6
|
-
class BadHttpMethodTest < Test::Unit::TestCase
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
8
|
+
ASSERT_RESPONSE = "Hello world!"
|
9
|
+
RESPONSE = ["Hello ", "world!"].freeze
|
10
|
+
DEFAULT_HOST = "localhost"
|
11
|
+
DEFAULT_PORT = 8000
|
12
|
+
DEFAULT_PATH = "/PATH?ket=value"
|
13
|
+
DEFAULT_VERSION = "HTTP/1.0"
|
14
|
+
DEFAULT_HEADER = {
|
15
|
+
"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",
|
16
|
+
"Accept"=> "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
|
17
|
+
"Accept-Language"=> "ja,en-us;q=0.7,en;q=0.3",
|
18
|
+
"Accept-Encoding"=> "gzip,deflate",
|
19
|
+
"Accept-Charset"=> "Shift_JIS,utf-8;q=0.7,*;q=0.7",
|
20
|
+
"Keep-Alive"=> "115",
|
21
|
+
"Connection"=> "keep-alive",
|
22
|
+
"Cache-Control"=> "max-age=0",
|
23
|
+
}
|
24
24
|
|
25
|
-
|
26
|
-
|
27
|
-
class App
|
28
|
-
def call env
|
29
|
-
body = RESPONSE
|
30
|
-
[200,
|
31
|
-
{
|
32
|
-
'Content-type'=> 'text/plain',
|
33
|
-
'Content-length'=> RESPONSE.join.size.to_s
|
34
|
-
},
|
35
|
-
body
|
36
|
-
]
|
37
|
-
end
|
38
|
-
end
|
25
|
+
ERR_400 = "HTTP/1.0 400 Bad Request"
|
39
26
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
return false
|
27
|
+
class App
|
28
|
+
def call env
|
29
|
+
body = RESPONSE
|
30
|
+
[200,
|
31
|
+
{
|
32
|
+
'Content-type'=> 'text/plain',
|
33
|
+
'Content-length'=> RESPONSE.join.size.to_s
|
34
|
+
},
|
35
|
+
body
|
36
|
+
]
|
51
37
|
end
|
38
|
+
end
|
52
39
|
|
53
|
-
|
40
|
+
class BadHttpMethodTest < Test::Unit::TestCase
|
54
41
|
|
55
42
|
def send_data method
|
56
43
|
begin
|
57
44
|
sock = TCPSocket.new DEFAULT_HOST, DEFAULT_PORT
|
45
|
+
sock.setsockopt(Socket::SOL_SOCKET,Socket::SO_REUSEADDR, true)
|
58
46
|
sock.send("#{method} #{DEFAULT_PATH} #{DEFAULT_VERSION}\r\n", 0)
|
59
47
|
sock.send("Host: #{DEFAULT_HOST}\r\n", 0)
|
60
48
|
DEFAULT_HEADER.each_pair {|k, v|
|
@@ -69,32 +57,56 @@ class BadHttpMethodTest < Test::Unit::TestCase
|
|
69
57
|
end
|
70
58
|
end
|
71
59
|
|
72
|
-
def setup
|
73
|
-
$stderr.puts RUBY_DESCRIPTION
|
74
|
-
|
75
|
-
@pid = fork do
|
76
|
-
trap(:INT) { Bossan.stop }
|
77
|
-
Bossan.listen(DEFAULT_HOST, DEFAULT_PORT)
|
78
|
-
Bossan.run(App.new)
|
79
|
-
end
|
80
|
-
Process.detach @pid
|
81
|
-
unless server_is_wake_up?
|
82
|
-
$stderr.puts "bossan won't wake up until you love it ..."
|
83
|
-
exit 1
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|
87
60
|
def test_bad_method1
|
88
61
|
response = send_data("")
|
89
|
-
assert_equal(response.split("\r\n").first
|
62
|
+
assert_equal(ERR_400, response.split("\r\n").first)
|
90
63
|
end
|
91
64
|
|
92
65
|
def test_bad_method2
|
93
66
|
response = send_data("GET" * 100)
|
94
|
-
assert_equal(response.split("\r\n").first
|
67
|
+
assert_equal(ERR_400, response.split("\r\n").first)
|
68
|
+
end
|
69
|
+
|
70
|
+
def test_bad_path
|
71
|
+
response = send_data("..")
|
72
|
+
assert_equal(ERR_400, response.split("\r\n").first)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
|
77
|
+
def server_is_wake_up? n=100
|
78
|
+
n.times {
|
79
|
+
begin
|
80
|
+
Net::HTTP.start(DEFAULT_HOST, DEFAULT_PORT)
|
81
|
+
rescue
|
82
|
+
next
|
83
|
+
end
|
84
|
+
$stderr.puts "*** running success ***"
|
85
|
+
return true
|
86
|
+
}
|
87
|
+
return false
|
88
|
+
end
|
89
|
+
|
90
|
+
|
91
|
+
begin
|
92
|
+
$stderr.puts RUBY_DESCRIPTION
|
93
|
+
|
94
|
+
pid = fork do
|
95
|
+
trap(:INT) { Bossan.stop }
|
96
|
+
Bossan.listen(DEFAULT_HOST, DEFAULT_PORT)
|
97
|
+
Bossan.run(App.new)
|
95
98
|
end
|
96
99
|
|
97
|
-
|
98
|
-
|
100
|
+
Process.detach pid
|
101
|
+
|
102
|
+
unless server_is_wake_up?
|
103
|
+
$stderr.puts "bossan won't wake up until you love it ..."
|
104
|
+
exit 1
|
99
105
|
end
|
106
|
+
|
107
|
+
err = MiniTest::Unit.new.run(ARGV)
|
108
|
+
exit false if err && err != 0
|
109
|
+
|
110
|
+
ensure
|
111
|
+
Process.kill(:INT, pid)
|
100
112
|
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
require_relative '../lib/bossan'
|
2
|
+
require 'minitest/unit'
|
3
|
+
require 'test/unit/testcase'
|
4
|
+
require 'uri'
|
5
|
+
require 'net/http'
|
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
|
+
body = RESPONSE
|
17
|
+
[200,
|
18
|
+
{'Content-type'=> 'text/plain'},
|
19
|
+
body
|
20
|
+
]
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
class RackChunkResponseTest < Test::Unit::TestCase
|
25
|
+
|
26
|
+
def test_chunk_response
|
27
|
+
response = Net::HTTP.start(DEFAULT_HOST, DEFAULT_PORT) {|http|
|
28
|
+
http.get("/")
|
29
|
+
}
|
30
|
+
|
31
|
+
headers = response.header
|
32
|
+
assert_equal("200", response.code)
|
33
|
+
assert_equal(ASSERT_RESPONSE, response.body)
|
34
|
+
assert_equal("chunked", headers["transfer-encoding"])
|
35
|
+
assert_equal("close", headers["connection"])
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
def server_is_wake_up? n=100
|
42
|
+
n.times {
|
43
|
+
begin
|
44
|
+
Net::HTTP.start(DEFAULT_HOST, DEFAULT_PORT)
|
45
|
+
rescue
|
46
|
+
next
|
47
|
+
end
|
48
|
+
$stderr.puts "*** running success ***"
|
49
|
+
return true
|
50
|
+
}
|
51
|
+
return false
|
52
|
+
end
|
53
|
+
|
54
|
+
|
55
|
+
begin
|
56
|
+
$stderr.puts RUBY_DESCRIPTION
|
57
|
+
|
58
|
+
pid = fork do
|
59
|
+
trap(:INT) { Bossan.stop }
|
60
|
+
Bossan.listen(DEFAULT_HOST, DEFAULT_PORT)
|
61
|
+
Bossan.run(App.new)
|
62
|
+
end
|
63
|
+
|
64
|
+
Process.detach pid
|
65
|
+
|
66
|
+
unless server_is_wake_up?
|
67
|
+
$stderr.puts "bossan won't wake up until you love it ..."
|
68
|
+
exit 1
|
69
|
+
end
|
70
|
+
|
71
|
+
err = MiniTest::Unit.new.run(ARGV)
|
72
|
+
exit false if err && err != 0
|
73
|
+
|
74
|
+
ensure
|
75
|
+
Process.kill(:INT, pid)
|
76
|
+
end
|
data/test/test_rack_long_url.rb
CHANGED
@@ -1,56 +1,30 @@
|
|
1
1
|
require_relative '../lib/bossan'
|
2
|
-
require '
|
2
|
+
require 'minitest/unit'
|
3
|
+
require 'test/unit/testcase'
|
3
4
|
require 'net/http'
|
4
5
|
|
5
|
-
class LongUrlTest < Test::Unit::TestCase
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
class App
|
13
|
-
def call env
|
14
|
-
body = RESPONSE
|
15
|
-
[200,
|
16
|
-
{
|
17
|
-
'Content-type'=> 'text/plain',
|
18
|
-
'Content-length'=> RESPONSE.join.size.to_s
|
19
|
-
},
|
20
|
-
body
|
21
|
-
]
|
22
|
-
end
|
23
|
-
end
|
7
|
+
ASSERT_RESPONSE = "Hello world!"
|
8
|
+
RESPONSE = ["Hello ", "world!"].freeze
|
9
|
+
DEFAULT_HOST = "localhost"
|
10
|
+
DEFAULT_PORT = 8000
|
24
11
|
|
25
|
-
def server_is_wake_up? n=100
|
26
|
-
n.times {
|
27
|
-
begin
|
28
|
-
Net::HTTP.start(DEFAULT_HOST, DEFAULT_PORT)
|
29
|
-
rescue
|
30
|
-
next
|
31
|
-
end
|
32
|
-
$stderr.puts "*** running success ***"
|
33
|
-
return true
|
34
|
-
}
|
35
|
-
return false
|
36
|
-
end
|
37
12
|
|
38
|
-
|
13
|
+
class App
|
14
|
+
def call env
|
15
|
+
body = RESPONSE
|
16
|
+
[200,
|
17
|
+
{
|
18
|
+
'Content-type'=> 'text/plain',
|
19
|
+
'Content-length'=> RESPONSE.join.size.to_s
|
20
|
+
},
|
21
|
+
body
|
22
|
+
]
|
23
|
+
end
|
24
|
+
end
|
39
25
|
|
40
|
-
def setup
|
41
|
-
$stderr.puts RUBY_DESCRIPTION
|
42
26
|
|
43
|
-
|
44
|
-
trap(:INT) { Bossan.stop }
|
45
|
-
Bossan.listen(DEFAULT_HOST, DEFAULT_PORT)
|
46
|
-
Bossan.run(App.new)
|
47
|
-
end
|
48
|
-
Process.detach @pid
|
49
|
-
unless server_is_wake_up?
|
50
|
-
$stderr.puts "bossan won't wake up until you love it ..."
|
51
|
-
exit 1
|
52
|
-
end
|
53
|
-
end
|
27
|
+
class LongUrlTest < Test::Unit::TestCase
|
54
28
|
|
55
29
|
def test_long_url1
|
56
30
|
response = Net::HTTP.start(DEFAULT_HOST, DEFAULT_PORT) {|http|
|
@@ -69,8 +43,40 @@ class LongUrlTest < Test::Unit::TestCase
|
|
69
43
|
|
70
44
|
assert_equal("400", response.code)
|
71
45
|
end
|
46
|
+
end
|
47
|
+
|
48
|
+
|
49
|
+
def server_is_wake_up? n=100
|
50
|
+
n.times {
|
51
|
+
begin
|
52
|
+
Net::HTTP.start(DEFAULT_HOST, DEFAULT_PORT)
|
53
|
+
rescue
|
54
|
+
next
|
55
|
+
end
|
56
|
+
$stderr.puts "*** running success ***"
|
57
|
+
return true
|
58
|
+
}
|
59
|
+
return false
|
60
|
+
end
|
72
61
|
|
73
|
-
|
74
|
-
|
62
|
+
|
63
|
+
begin
|
64
|
+
$stderr.puts RUBY_DESCRIPTION
|
65
|
+
|
66
|
+
pid = fork do
|
67
|
+
trap(:INT) { Bossan.stop }
|
68
|
+
Bossan.listen(DEFAULT_HOST, DEFAULT_PORT)
|
69
|
+
Bossan.run(App.new)
|
70
|
+
end
|
71
|
+
Process.detach pid
|
72
|
+
unless server_is_wake_up?
|
73
|
+
$stderr.puts "bossan won't wake up until you love it ..."
|
74
|
+
exit 1
|
75
75
|
end
|
76
|
+
|
77
|
+
err = MiniTest::Unit.new.run(ARGV)
|
78
|
+
exit false if err && err != 0
|
79
|
+
|
80
|
+
ensure
|
81
|
+
Process.kill(:INT, pid)
|
76
82
|
end
|
data/test/test_rack_spec.rb
CHANGED
@@ -1,57 +1,30 @@
|
|
1
1
|
require_relative '../lib/bossan'
|
2
|
-
require '
|
2
|
+
require 'minitest/unit'
|
3
|
+
require 'test/unit/testcase'
|
3
4
|
require 'uri'
|
4
5
|
require 'net/http'
|
5
6
|
|
6
|
-
class RackSpecTest < Test::Unit::TestCase
|
7
|
-
|
8
|
-
ASSERT_RESPONSE = "Hello world!"
|
9
|
-
RESPONSE = ["Hello ", "world!"].freeze
|
10
|
-
DEFAULT_HOST = "localhost"
|
11
|
-
DEFAULT_PORT = 8000
|
12
|
-
|
13
|
-
class App
|
14
|
-
def call env
|
15
|
-
body = RESPONSE
|
16
|
-
[200,
|
17
|
-
{
|
18
|
-
'Content-type'=> 'text/plain',
|
19
|
-
'Content-length'=> RESPONSE.join.size.to_s
|
20
|
-
},
|
21
|
-
body
|
22
|
-
]
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
def server_is_wake_up? n=100
|
27
|
-
n.times {
|
28
|
-
begin
|
29
|
-
Net::HTTP.start(DEFAULT_HOST, DEFAULT_PORT)
|
30
|
-
rescue
|
31
|
-
next
|
32
|
-
end
|
33
|
-
$stderr.puts "*** running success ***"
|
34
|
-
return true
|
35
|
-
}
|
36
|
-
return false
|
37
|
-
end
|
38
7
|
|
39
|
-
|
8
|
+
DEFAULT_HOST = "localhost"
|
9
|
+
DEFAULT_PORT = 8000
|
10
|
+
ASSERT_RESPONSE = "Hello world!"
|
11
|
+
RESPONSE = ["Hello ", "world!"].freeze
|
40
12
|
|
41
|
-
def setup
|
42
|
-
$stderr.puts RUBY_DESCRIPTION
|
43
13
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
14
|
+
class App
|
15
|
+
def call env
|
16
|
+
body = RESPONSE
|
17
|
+
[200,
|
18
|
+
{
|
19
|
+
'Content-type'=> 'text/plain',
|
20
|
+
'Content-length'=> RESPONSE.join.size.to_s
|
21
|
+
},
|
22
|
+
body
|
23
|
+
]
|
54
24
|
end
|
25
|
+
end
|
26
|
+
|
27
|
+
class RackSpecTest < Test::Unit::TestCase
|
55
28
|
|
56
29
|
def test_simple_get
|
57
30
|
response = Net::HTTP.start(DEFAULT_HOST, DEFAULT_PORT) {|http|
|
@@ -69,8 +42,42 @@ class RackSpecTest < Test::Unit::TestCase
|
|
69
42
|
assert_equal("200", response.code)
|
70
43
|
assert_equal(ASSERT_RESPONSE, response.body)
|
71
44
|
end
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
def server_is_wake_up? n=100
|
49
|
+
n.times {
|
50
|
+
begin
|
51
|
+
Net::HTTP.start(DEFAULT_HOST, DEFAULT_PORT)
|
52
|
+
rescue
|
53
|
+
next
|
54
|
+
end
|
55
|
+
$stderr.puts "*** running success ***"
|
56
|
+
return true
|
57
|
+
}
|
58
|
+
return false
|
59
|
+
end
|
60
|
+
|
72
61
|
|
73
|
-
|
74
|
-
|
62
|
+
begin
|
63
|
+
$stderr.puts RUBY_DESCRIPTION
|
64
|
+
|
65
|
+
pid = fork do
|
66
|
+
trap(:INT) { Bossan.stop }
|
67
|
+
Bossan.listen(DEFAULT_HOST, DEFAULT_PORT)
|
68
|
+
Bossan.run(App.new)
|
69
|
+
end
|
70
|
+
|
71
|
+
Process.detach pid
|
72
|
+
|
73
|
+
unless server_is_wake_up?
|
74
|
+
$stderr.puts "bossan won't wake up until you love it ..."
|
75
|
+
exit 1
|
75
76
|
end
|
77
|
+
|
78
|
+
err = MiniTest::Unit.new.run(ARGV)
|
79
|
+
exit false if err && err != 0
|
80
|
+
|
81
|
+
ensure
|
82
|
+
Process.kill(:INT, pid)
|
76
83
|
end
|