jubilee 2.1.0.Alpha1-java → 2.1.0.beta-java

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.
Files changed (66) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +2 -2
  3. data/CHANGELOG +9 -0
  4. data/README.md +12 -7
  5. data/jars/vertx-core-2.1.1.jar +0 -0
  6. data/java/src/jubilee/JubileeService.java +3 -3
  7. data/java/src/org/jruby/jubilee/Const.java +1 -1
  8. data/java/src/org/jruby/jubilee/JubileeVerticle.java +29 -4
  9. data/java/src/org/jruby/jubilee/RackApplication.java +38 -35
  10. data/java/src/org/jruby/jubilee/RackEnvironment.java +57 -23
  11. data/java/src/org/jruby/jubilee/RackEnvironmentHash.java +64 -11
  12. data/java/src/org/jruby/jubilee/RackInput.java +13 -10
  13. data/java/src/org/jruby/jubilee/RubyCallable.java +52 -0
  14. data/java/src/org/jruby/jubilee/RubyChannel.java +89 -0
  15. data/java/src/org/jruby/jubilee/RubyHttpServerResponse.java +72 -60
  16. data/java/src/org/jruby/jubilee/RubyNetSocket.java +169 -0
  17. data/java/src/org/jruby/jubilee/RubyPlatformManager.java +129 -113
  18. data/java/src/org/jruby/jubilee/impl/RubyIORackInput.java +9 -9
  19. data/java/src/org/jruby/jubilee/impl/RubyNullIO.java +1 -1
  20. data/java/src/org/jruby/jubilee/utils/RubyHelper.java +0 -6
  21. data/java/src/org/jruby/jubilee/vertx/JubileeVertx.java +12 -11
  22. data/jubilee.gemspec +43 -20
  23. data/lib/jubilee.rb +0 -1
  24. data/lib/jubilee/cli.rb +5 -3
  25. data/lib/jubilee/configuration.rb +2 -7
  26. data/lib/jubilee/const.rb +30 -28
  27. data/lib/jubilee/response.rb +40 -5
  28. data/lib/jubilee/server.rb +0 -3
  29. data/lib/jubilee/version.rb +1 -1
  30. data/spec/apps/rails4/basic/Gemfile +0 -2
  31. data/spec/apps/rails4/basic/Gemfile.lock +0 -7
  32. data/spec/integration/basic_rack_spec.rb +4 -3
  33. data/spec/integration/basic_rails4_spec.rb +4 -3
  34. data/spec/integration/basic_sinatra_spec.rb +4 -4
  35. data/spec/spec_helper.rb +1 -0
  36. data/test/{config → apps}/app.rb +0 -0
  37. data/test/apps/checker.ru +5 -10
  38. data/test/apps/chunked.ru +3 -0
  39. data/test/{config → apps}/config.ru +0 -0
  40. data/test/apps/content_length.ru +3 -0
  41. data/test/apps/hex.ru +4 -0
  42. data/test/apps/hijack.ru +7 -0
  43. data/test/apps/hijack2.ru +7 -0
  44. data/test/apps/huge.ru +4 -0
  45. data/test/apps/method_override.ru +1 -1
  46. data/test/apps/overwrite_check.ru +3 -2
  47. data/test/apps/persistent.rb +14 -0
  48. data/test/apps/persistent.ru +3 -0
  49. data/test/apps/rack_input.ru +5 -0
  50. data/test/apps/self_chunked.ru +6 -0
  51. data/test/apps/sha1.ru +2 -0
  52. data/test/apps/simple.ru +10 -1
  53. data/test/jubilee/test_cli.rb +1 -1
  54. data/test/jubilee/test_configuration.rb +1 -3
  55. data/test/jubilee/test_hijack.rb +27 -0
  56. data/test/jubilee/test_persistent.rb +208 -0
  57. data/test/jubilee/test_rack_server.rb +29 -68
  58. data/test/jubilee/test_server.rb +49 -15
  59. data/test/jubilee/test_upload.rb +13 -60
  60. data/test/test_helper.rb +2 -2
  61. metadata +19 -9
  62. data/java/src/org/jruby/jubilee/RubyServer.java +0 -159
  63. data/lib/jubilee/jubilee.jar +0 -0
  64. data/lib/rack/chunked.rb +0 -38
  65. data/test/config/app.ru +0 -3
  66. data/test/jubilee/test_response.rb +0 -270
@@ -0,0 +1,5 @@
1
+ app = lambda do |env|
2
+ data = env['rack.input'].read
3
+ [200, {}, [data]]
4
+ end
5
+ run app
@@ -0,0 +1,6 @@
1
+ require_relative './persistent'
2
+ body = ["5\r\nhello\r\n", "0\r\n\r\n"]
3
+ headers= {"X-Header" => "Works", 'Transfer-Encoding' => "chunked"}
4
+
5
+ run Persistent.new(body, headers)
6
+
@@ -1,3 +1,4 @@
1
+ require 'digest'
1
2
  bs = 4096
2
3
  hdr = {'Content-Type' => 'text/plain', 'Content-Length' => '0'}
3
4
  sha1_app = lambda do |env|
@@ -31,6 +32,7 @@ sha1_app = lambda do |env|
31
32
  end
32
33
  resp[:size] = i
33
34
  resp[:expect_size] = expect_size
35
+ resp[:content_md5] = env['HTTP_X_CONTENT_MD5']
34
36
 
35
37
  [ 200, hdr.merge({'X-Resp' => resp.inspect}), [] ]
36
38
  end
@@ -1 +1,10 @@
1
- run lambda { |env| [200, { "X-Header" => "Works" }, ["Hello"]] }
1
+ require 'rack/request'
2
+ require 'json'
3
+
4
+ app = lambda do |env|
5
+ req = Rack::Request.new(env)
6
+ body = JSON.dump(req.params.merge({"QUERY_STRING" => env["QUERY_STRING"], "PATH_INFO" => env["PATH_INFO"]}))
7
+ [200, { "X-Header" => "Works" }, [body]]
8
+ end
9
+
10
+ run app
@@ -11,7 +11,7 @@ class TestJubileeCLI < MiniTest::Unit::TestCase
11
11
  def test_chdir
12
12
  cli = Jubilee::CLI.new(["--dir", "test", "app.ru"])
13
13
  cli.parse_options
14
- assert_equal "test", cli.options[:chdir]
14
+ assert_equal "test", cli.options[:root]
15
15
  end
16
16
 
17
17
  def test_eventbus_prefix
@@ -5,13 +5,11 @@ class TestConfig < MiniTest::Unit::TestCase
5
5
 
6
6
  def setup
7
7
  @tmp = Tempfile.new("jubilee_config")
8
- @dir = Dir.getwd
9
8
  end
10
9
 
11
10
  def teardown
12
11
  @tmp.close
13
12
  @tmp.unlink
14
- Dir.chdir(@dir)
15
13
  end
16
14
 
17
15
  def test_config_invalid
@@ -67,7 +65,7 @@ class TestConfig < MiniTest::Unit::TestCase
67
65
  def test_config_file_working_directory
68
66
  @tmp.syswrite(%q(working_directory "examples/chatapp"))
69
67
  options = Jubilee::Configuration.new(config_file: @tmp.path).options
70
- assert_match(/chatapp/, options[:chdir])
68
+ assert_match(/chatapp/, options[:root])
71
69
  end
72
70
 
73
71
  def test_config_file_environment
@@ -0,0 +1,27 @@
1
+ require 'test_helper'
2
+ require 'socket'
3
+
4
+ class TestJubileeServer < MiniTest::Unit::TestCase
5
+ def setup
6
+ end
7
+
8
+ def teardown
9
+ @client.close
10
+ sleep 0.1
11
+ @server.stop
12
+ end
13
+
14
+ def test_hijack_supported
15
+ skip "not valid"
16
+ @valid_post = "POST / HTTP/1.1\r\nHost: test.com\r\nContent-Type: text/plain\r\nContent-Length: 5\r\n\r\nhello"
17
+ @host, @port = "localhost", 8080
18
+
19
+ config = Jubilee::Configuration.new(rackup: File.expand_path("../../apps/hijack.ru", __FILE__), instances: 1)
20
+ @server = Jubilee::Server.new(config.options)
21
+ @server.start
22
+ @client = TCPSocket.new @host, @port
23
+
24
+ @client << @valid_post
25
+ assert @jijack
26
+ end
27
+ end
@@ -0,0 +1,208 @@
1
+ require 'test_helper'
2
+ require 'timeout'
3
+ require 'socket'
4
+ class TestResponse < MiniTest::Unit::TestCase
5
+ def setup
6
+ @valid_request = "GET / HTTP/1.1\r\nHost: test.com\r\nContent-Type: text/plain\r\n\r\n"
7
+ @close_request = "GET / HTTP/1.1\r\nHost: test.com\r\nContent-Type: text/plain\r\nConnection: Close\r\n\r\n"
8
+ @http10_request = "GET / HTTP/1.0\r\nHost: test.com\r\nContent-Type: text/plain\r\n\r\n"
9
+ @keep_request = "GET / HTTP/1.0\r\nHost: test.com\r\nContent-Type: text/plain\r\nConnection: Keep-Alive\r\n\r\n"
10
+
11
+ @valid_post = "POST / HTTP/1.1\r\nHost: test.com\r\nContent-Type: text/plain\r\nContent-Length: 5\r\n\r\nhello"
12
+ @valid_no_body = "GET / HTTP/1.1\r\nHost: test.com\r\nX-Status: 204\r\nContent-Type: text/plain\r\n\r\n"
13
+
14
+ @headers = { "X-Header" => "Works" }
15
+ @body = ["Hello"]
16
+ @sz = @body[0].size.to_s
17
+
18
+ @host = "127.0.0.1"
19
+ @port = 8080
20
+
21
+ end
22
+
23
+ def teardown
24
+ @client.close if @client
25
+ @server.stop if @server
26
+ sleep 0.1
27
+ end
28
+
29
+ def lines(count, s=@client)
30
+ str = ""
31
+ timeout(5) do
32
+ count.times { str << s.gets }
33
+ end
34
+ str
35
+ end
36
+
37
+ def valid_response(size = @sz, close = false)
38
+ conn = close ? "close" : "keep-alive"
39
+ %r{HTTP/1.1 200 OK\r\nX-Header: Works\r\nServer: Jubilee\(\d\.\d\.\d\)\r\nContent-Length: #{size}\r\nConnection: #{conn}\r\nDate: (.*?)\r\n\r\n}
40
+ end
41
+
42
+ def test_one_with_content_length
43
+ start_server
44
+ @client << @valid_request
45
+ sz = @body[0].size.to_s
46
+
47
+ assert_match valid_response(sz), lines(7)
48
+ assert_equal "Hello", @client.read(5)
49
+ end
50
+
51
+ def test_two_back_to_back
52
+ start_server
53
+ @client << @valid_request
54
+ sz = @body[0].size.to_s
55
+
56
+ assert_match valid_response(sz), lines(7)
57
+ assert_equal "Hello", @client.read(5)
58
+
59
+ @client << @valid_request
60
+ sz = @body[0].size.to_s
61
+
62
+ assert_match valid_response(sz), lines(7)
63
+ assert_equal "Hello", @client.read(5)
64
+ end
65
+
66
+ def test_post_then_get
67
+ start_server
68
+ @client << @valid_post
69
+ sz = @body[0].size.to_s
70
+
71
+ assert_match valid_response(sz), lines(7)
72
+ assert_equal "Hello", @client.read(5)
73
+
74
+ @client << @valid_request
75
+ sz = @body[0].size.to_s
76
+
77
+ assert_match valid_response(sz), lines(7)
78
+ assert_equal "Hello", @client.read(5)
79
+ end
80
+
81
+ def test_no_body_then_get
82
+ start_server
83
+ @client << @valid_no_body
84
+ assert_match %r{HTTP/1.1 204 No Content\r\nX-Header: Works\r\nConnection: keep-alive\r\n(.*?\r\n)*?\r\n}, lines(6)
85
+
86
+ @client << @valid_request
87
+ sz = @body[0].size.to_s
88
+
89
+ assert_match %r{HTTP/1.1 200 OK\r\nX-Header: Works\r\nServer: Jubilee\(\d\.\d\.\d\)\r\nContent-Length: #{sz}\r\nConnection: keep-alive\r\n(.*?\r\n)*?\r\n}, lines(7)
90
+ assert_equal "Hello", @client.read(5)
91
+ end
92
+
93
+ def test_chunked
94
+ start_server("chunked")
95
+
96
+ @client << @valid_request
97
+
98
+ assert_match %r{HTTP/1.1 200 OK\r\nX-Header: Works\r\nServer: Jubilee\(\d\.\d\.\d\)\r\nConnection: keep-alive\r\nTransfer-Encoding: chunked\r\nDate(.*?)\r\n\r\n5\r\nHello\r\n7\r\nChunked\r\n0\r\n\r\n}, lines(13)
99
+ end
100
+
101
+ def test_no_chunked_in_http10
102
+ start_server("chunked")
103
+
104
+ @client << @http10_request
105
+
106
+ assert_match %r{HTTP/1.0 200 OK\r\nX-Header: Works\r\nServer: Jubilee\(\d\.\d\.\d\)\r\nConnection: close\r\nDate: (.*?)\r\n\r\n}, lines(6)
107
+ assert_equal "HelloChunked", @client.read
108
+ end
109
+
110
+ def test_hex
111
+ start_server("hex")
112
+ str = "This is longer and will be in hex"
113
+
114
+ @client << @valid_request
115
+
116
+ assert_match %r{HTTP/1.1 200 OK\r\nX-Header: Works\r\nServer: Jubilee(.*?)\r\nConnection: keep-alive\r\nTransfer-Encoding: chunked\r\nDate: (.*?)\r\n\r\n5\r\nHello\r\n#{str.size.to_s(16)}\r\n#{str}\r\n0\r\n\r\n}, lines(13)
117
+
118
+ end
119
+
120
+ def test_client11_close
121
+ start_server
122
+ @client << @close_request
123
+ sz = @body[0].size.to_s
124
+
125
+ assert_match valid_response(sz, true), lines(7)
126
+ assert_equal "Hello", @client.read(5)
127
+ end
128
+
129
+ def test_app_sets_content_length
130
+ start_server("content_length")
131
+ @client << @valid_request
132
+
133
+ assert_match valid_response(11), lines(7)
134
+ assert_equal "hello world", @client.read(11)
135
+ end
136
+
137
+ def test_allow_app_to_chunk_itself
138
+ start_server("self_chunked")
139
+ @client << @valid_request
140
+
141
+ assert_match %r{HTTP/1.1 200 OK\r\nX-Header: Works\r\nServer: Jubilee(.*?)\r\nConnection: keep-alive\r\nTransfer-Encoding: chunked\r\nDate: (.*?)\r\n\r\n5\r\nhello\r\n0\r\n\r\n}, lines(11)
142
+ end
143
+
144
+
145
+ def test_two_requests_in_one_chunk
146
+ start_server
147
+ req = @valid_request.to_s
148
+ req << "GET /second HTTP/1.1\r\nHost: test.com\r\nContent-Type: text/plain\r\n\r\n"
149
+
150
+ @client << req
151
+
152
+ sz = @body[0].size.to_s
153
+
154
+ assert_match valid_response(sz), lines(7)
155
+ assert_equal "Hello", @client.read(5)
156
+
157
+ assert_match valid_response(sz), lines(7)
158
+ assert_equal "Hello", @client.read(5)
159
+ end
160
+
161
+ def test_second_request_not_in_first_req_body
162
+ start_server
163
+
164
+ req = @valid_request.to_s
165
+ req << "GET /second HTTP/1.1\r\nHost: test.com\r\nContent-Type: text/plain\r\n\r\n"
166
+
167
+ @client << req
168
+
169
+ sz = @body[0].size.to_s
170
+
171
+ assert_match valid_response(sz), lines(7)
172
+ assert_equal "Hello", @client.read(5)
173
+
174
+ assert_match valid_response(sz), lines(7)
175
+ assert_equal "Hello", @client.read(5)
176
+
177
+ #assert_kind_of Jubilee::IORackInput, @inputs[0]
178
+ #assert_kind_of Jubilee::IORackInput, @inputs[1]
179
+ end
180
+
181
+ def test_keepalive_doesnt_starve_clients
182
+ start_server
183
+ sz = @body[0].size.to_s
184
+
185
+ @client << @valid_request
186
+
187
+ c2 = TCPSocket.new @host, @port
188
+ c2 << @valid_request
189
+
190
+ out = IO.select([c2], nil, nil, 1)
191
+
192
+ assert out, "select returned nil"
193
+ assert_equal c2, out.first.first
194
+
195
+ assert_match valid_response(sz), lines(7, c2)
196
+ assert_equal "Hello", c2.read(5)
197
+ end
198
+
199
+ def start_server(ru='persistent')
200
+ config = Jubilee::Configuration.new(rackup: File.expand_path("../../apps/#{ru}.ru", __FILE__), instances: 1)
201
+ @server = Jubilee::Server.new(config.options)
202
+ q = Queue.new
203
+ @server.start{ q << 1 }
204
+ q.pop
205
+ sleep 0.1
206
+ @client = TCPSocket.new @host, @port
207
+ end
208
+ end
@@ -1,115 +1,76 @@
1
1
  require 'test_helper'
2
- require 'rack/lint'
3
- require 'rack/commonlogger'
2
+ require 'json'
4
3
 
5
4
  class TestRackServer < MiniTest::Unit::TestCase
6
5
  include Helpers
7
6
 
8
- def setup
9
- @valid_request = "GET / HTTP/1.1\r\nHost: test.com\r\nContent-Type: text/plain\r\n\r\n"
10
- @checker = "checker.ru"
11
- @host = "localhost"
12
- @port = 8080
13
- end
14
-
15
7
  def teardown
16
- @server.stop if @server
8
+ @server.stop
17
9
  sleep 0.1
18
10
  end
19
11
 
20
12
  def test_lint
21
- @server = Jubilee::Server.new @checker
22
-
23
- @server.start
13
+ start_server("checker")
14
+ resp = hit(['http://127.0.0.1:8080/test']).first
24
15
 
25
- hit(['http://127.0.0.1:8080/test'])
26
-
27
- if exc = @checker.exception
16
+ if exc = JSON.parse(resp.body)["exception"]
28
17
  raise exc
29
18
  end
30
19
  end
31
20
 
32
21
  def test_large_post_body
33
- @checker = ErrorChecker.new ServerLint.new(@simple)
34
- @server = Jubilee::Server.new @checker
35
-
36
- @server.start
37
- sleep 0.5
38
-
22
+ start_server("checker")
39
23
  big = "x" * (1024 * 16)
40
-
41
- Net::HTTP.post_form URI.parse('http://127.0.0.1:8080/test'),
42
- { "big" => big }
43
-
44
- if exc = @checker.exception
24
+ resp = POST('/test', { "big" => big })
25
+ if exc = JSON.parse(resp.body)["exception"]
45
26
  raise exc
46
27
  end
47
28
  end
48
29
 
49
30
  def test_path_info
50
- input = nil
51
- @server = Jubilee::Server.new(lambda { |env| input = env; @simple.call(env) })
52
- @server.start
53
-
54
- hit(['http://127.0.0.1:8080/test/a/b/c'])
55
-
56
- assert_equal "/test/a/b/c", input['PATH_INFO']
31
+ start_server("simple")
32
+ resp = hit(['http://127.0.0.1:8080/test/a/b/c']).first
33
+ assert_equal "/test/a/b/c", JSON.parse(resp.body)['PATH_INFO']
57
34
  end
58
35
 
59
36
  def test_request_method
60
- input = nil
61
- @server = Jubilee::Server.new(Rack::MethodOverride.new(lambda { |env| input = env; @simple.call(env) }))
62
- @server.start
63
-
64
- POST('/test/a/b/c', {"_method" => "delete", "user" => 1})
65
- assert_equal "DELETE", input['REQUEST_METHOD']
37
+ start_server("method_override")
38
+ resp = POST('/test/a/b/c', {"_method" => "delete", "user" => 1})
39
+ assert_equal "DELETE", resp.body
66
40
 
67
41
  # it should not memorize env
68
- POST('/test/a/b/c', {"foo" => "bar"})
69
- assert_equal "POST", input['REQUEST_METHOD']
70
-
42
+ resp = POST('/test/a/b/c', {"foo" => "bar"})
43
+ assert_equal "POST", resp.body
71
44
  end
72
45
 
73
46
  def test_query_string
74
- input = nil
75
- @server = Jubilee::Server.new(lambda { |env| input = env; @simple.call(env) })
76
- @server.start
77
- sleep 0.1
78
-
79
- hit(['http://127.0.0.1:8080/test/a/b/c?foo=bar'])
80
-
81
- assert_equal "foo=bar", input['QUERY_STRING']
47
+ start_server("simple")
48
+ resp = hit(['http://127.0.0.1:8080/test/a/b/c?foo=bar']).first
49
+ assert_equal "foo=bar", JSON.parse(resp.body)['QUERY_STRING']
82
50
  end
83
51
 
84
52
  def test_post_data
85
53
  require 'rack/request'
86
- input = nil
87
- @server = Jubilee::Server.new(lambda { |env| input = env; @simple.call(env) })
88
- @server.start
89
- sleep 0.1
90
-
54
+ start_server("simple")
91
55
  req = Net::HTTP::Post::Multipart.new("/", "foo" => "bar")
92
- Net::HTTP.start('localhost', 8080) do |http|
56
+ resp = Net::HTTP.start('localhost', 8080) do |http|
93
57
  http.request req
94
58
  end
95
59
 
96
- #Net::HTTP.post_form URI.parse('http://127.0.0.1:8080/test'), { "foo" => "bar" }
97
-
98
- request = Rack::Request.new input
99
- assert_equal "bar", request.params["foo"]
60
+ assert_equal "bar", JSON.parse(resp.body)["foo"]
100
61
  end
101
62
 
102
63
  def test_end_request_when_rack_crashes
103
- @server = Jubilee::Server.new(RackCrasher.new(@simple))
104
- @server.start
64
+ start_server("rack_crasher")
105
65
  res = hit(['http://127.0.0.1:8080/test'])
106
66
  assert_kind_of Net::HTTPServerError, res[0]
107
67
  end
108
68
 
109
- # GH_9
110
- def test_string_port_value
111
- @server = Jubilee::Server.new(@simple, {Port: "3000"})
112
- # assert_wont_raise_anything
113
- @server.start
69
+ def start_server(ru)
70
+ config = Jubilee::Configuration.new(rackup: File.expand_path("../../apps/#{ru}.ru", __FILE__), instances: 1)
71
+ @server = Jubilee::Server.new(config.options)
72
+ q = Queue.new
73
+ @server.start{ q << 1 }
74
+ q.pop
114
75
  end
115
76
  end