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.
- checksums.yaml +4 -4
- data/.travis.yml +2 -2
- data/CHANGELOG +9 -0
- data/README.md +12 -7
- data/jars/vertx-core-2.1.1.jar +0 -0
- data/java/src/jubilee/JubileeService.java +3 -3
- data/java/src/org/jruby/jubilee/Const.java +1 -1
- data/java/src/org/jruby/jubilee/JubileeVerticle.java +29 -4
- data/java/src/org/jruby/jubilee/RackApplication.java +38 -35
- data/java/src/org/jruby/jubilee/RackEnvironment.java +57 -23
- data/java/src/org/jruby/jubilee/RackEnvironmentHash.java +64 -11
- data/java/src/org/jruby/jubilee/RackInput.java +13 -10
- data/java/src/org/jruby/jubilee/RubyCallable.java +52 -0
- data/java/src/org/jruby/jubilee/RubyChannel.java +89 -0
- data/java/src/org/jruby/jubilee/RubyHttpServerResponse.java +72 -60
- data/java/src/org/jruby/jubilee/RubyNetSocket.java +169 -0
- data/java/src/org/jruby/jubilee/RubyPlatformManager.java +129 -113
- data/java/src/org/jruby/jubilee/impl/RubyIORackInput.java +9 -9
- data/java/src/org/jruby/jubilee/impl/RubyNullIO.java +1 -1
- data/java/src/org/jruby/jubilee/utils/RubyHelper.java +0 -6
- data/java/src/org/jruby/jubilee/vertx/JubileeVertx.java +12 -11
- data/jubilee.gemspec +43 -20
- data/lib/jubilee.rb +0 -1
- data/lib/jubilee/cli.rb +5 -3
- data/lib/jubilee/configuration.rb +2 -7
- data/lib/jubilee/const.rb +30 -28
- data/lib/jubilee/response.rb +40 -5
- data/lib/jubilee/server.rb +0 -3
- data/lib/jubilee/version.rb +1 -1
- data/spec/apps/rails4/basic/Gemfile +0 -2
- data/spec/apps/rails4/basic/Gemfile.lock +0 -7
- data/spec/integration/basic_rack_spec.rb +4 -3
- data/spec/integration/basic_rails4_spec.rb +4 -3
- data/spec/integration/basic_sinatra_spec.rb +4 -4
- data/spec/spec_helper.rb +1 -0
- data/test/{config → apps}/app.rb +0 -0
- data/test/apps/checker.ru +5 -10
- data/test/apps/chunked.ru +3 -0
- data/test/{config → apps}/config.ru +0 -0
- data/test/apps/content_length.ru +3 -0
- data/test/apps/hex.ru +4 -0
- data/test/apps/hijack.ru +7 -0
- data/test/apps/hijack2.ru +7 -0
- data/test/apps/huge.ru +4 -0
- data/test/apps/method_override.ru +1 -1
- data/test/apps/overwrite_check.ru +3 -2
- data/test/apps/persistent.rb +14 -0
- data/test/apps/persistent.ru +3 -0
- data/test/apps/rack_input.ru +5 -0
- data/test/apps/self_chunked.ru +6 -0
- data/test/apps/sha1.ru +2 -0
- data/test/apps/simple.ru +10 -1
- data/test/jubilee/test_cli.rb +1 -1
- data/test/jubilee/test_configuration.rb +1 -3
- data/test/jubilee/test_hijack.rb +27 -0
- data/test/jubilee/test_persistent.rb +208 -0
- data/test/jubilee/test_rack_server.rb +29 -68
- data/test/jubilee/test_server.rb +49 -15
- data/test/jubilee/test_upload.rb +13 -60
- data/test/test_helper.rb +2 -2
- metadata +19 -9
- data/java/src/org/jruby/jubilee/RubyServer.java +0 -159
- data/lib/jubilee/jubilee.jar +0 -0
- data/lib/rack/chunked.rb +0 -38
- data/test/config/app.ru +0 -3
- data/test/jubilee/test_response.rb +0 -270
data/lib/jubilee/jubilee.jar
DELETED
Binary file
|
data/lib/rack/chunked.rb
DELETED
@@ -1,38 +0,0 @@
|
|
1
|
-
# Rails use this to chunk it's streaming response body, which we don't need
|
2
|
-
module Rack
|
3
|
-
class Chunked
|
4
|
-
class Body
|
5
|
-
def initialize(body)
|
6
|
-
@body = body
|
7
|
-
end
|
8
|
-
|
9
|
-
def each
|
10
|
-
@body.each {|chunk| yield chunk}
|
11
|
-
end
|
12
|
-
|
13
|
-
def close
|
14
|
-
@body.close if @body.respond_to?(:close)
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
include Rack::Utils
|
19
|
-
|
20
|
-
def initialize(app)
|
21
|
-
@app = app
|
22
|
-
end
|
23
|
-
|
24
|
-
def call(env)
|
25
|
-
status, headers, body = @app.call(env)
|
26
|
-
headers = HeaderHash.new(headers)
|
27
|
-
|
28
|
-
unless env['HTTP_VERSION'] == 'HTTP/1.0' ||
|
29
|
-
STATUS_WITH_NO_ENTITY_BODY.include?(status) ||
|
30
|
-
headers['Content-Length'] ||
|
31
|
-
headers['Transfer-Encoding']
|
32
|
-
headers.delete('Content-Length')
|
33
|
-
headers.delete('Transfer-Encoding')
|
34
|
-
end
|
35
|
-
[status, headers, body]
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
data/test/config/app.ru
DELETED
@@ -1,270 +0,0 @@
|
|
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
|
-
@inputs = []
|
17
|
-
|
18
|
-
@simple = lambda do |env|
|
19
|
-
@inputs << env['rack.input']
|
20
|
-
status = Integer(env['HTTP_X_STATUS'] || 200)
|
21
|
-
[status, @headers, @body]
|
22
|
-
end
|
23
|
-
|
24
|
-
@host = "127.0.0.1"
|
25
|
-
@port = 8080
|
26
|
-
|
27
|
-
@server = Jubilee::Server.new @simple
|
28
|
-
@server.start
|
29
|
-
sleep 0.1
|
30
|
-
@client = TCPSocket.new @host, @port
|
31
|
-
end
|
32
|
-
|
33
|
-
def teardown
|
34
|
-
@client.close
|
35
|
-
sleep 0.1 # in case server shutdown before request is submitted
|
36
|
-
@server.stop
|
37
|
-
end
|
38
|
-
|
39
|
-
def lines(count, s=@client)
|
40
|
-
str = ""
|
41
|
-
timeout(5) do
|
42
|
-
count.times { str << s.gets }
|
43
|
-
end
|
44
|
-
str
|
45
|
-
end
|
46
|
-
|
47
|
-
def valid_response(size)
|
48
|
-
Regexp.new("HTTP/1.1 200 OK\r\nX-Header: Works\r\n(.*?\r\n)*?Content-Length: #{size}\r\nConnection: keep-alive\r\nDate(.*?)\r\n\r\n", true)
|
49
|
-
end
|
50
|
-
|
51
|
-
def test_one_with_content_length
|
52
|
-
@client << @valid_request
|
53
|
-
sz = @body[0].size.to_s
|
54
|
-
|
55
|
-
assert_match valid_response(sz), lines(7)
|
56
|
-
assert_equal "Hello", @client.read(5)
|
57
|
-
end
|
58
|
-
|
59
|
-
def test_two_back_to_back
|
60
|
-
@client << @valid_request
|
61
|
-
sz = @body[0].size.to_s
|
62
|
-
|
63
|
-
assert_match valid_response(sz), lines(7)
|
64
|
-
assert_equal "Hello", @client.read(5)
|
65
|
-
|
66
|
-
@client << @valid_request
|
67
|
-
sz = @body[0].size.to_s
|
68
|
-
|
69
|
-
assert_match valid_response(sz), lines(7)
|
70
|
-
assert_equal "Hello", @client.read(5)
|
71
|
-
end
|
72
|
-
|
73
|
-
def test_post_then_get
|
74
|
-
@client << @valid_post
|
75
|
-
sz = @body[0].size.to_s
|
76
|
-
|
77
|
-
assert_match valid_response(sz), lines(7)
|
78
|
-
assert_equal "Hello", @client.read(5)
|
79
|
-
|
80
|
-
@client << @valid_request
|
81
|
-
sz = @body[0].size.to_s
|
82
|
-
|
83
|
-
assert_match valid_response(sz), lines(7)
|
84
|
-
assert_equal "Hello", @client.read(5)
|
85
|
-
end
|
86
|
-
|
87
|
-
=begin
|
88
|
-
def test_no_body_then_get
|
89
|
-
@client << @valid_no_body
|
90
|
-
assert_match %r{HTTP/1.1 204 No Content\r\nX-Header: Works(.*?\r\n)*?Connection: keep-alive\r\n\r\n}, lines(6)
|
91
|
-
|
92
|
-
@client << @valid_request
|
93
|
-
sz = @body[0].size.to_s
|
94
|
-
|
95
|
-
assert_match %r{HTTP/1.1 200 OK\r\nX-Header: Works\r\n(.*?\r\n)*?Content-Length: #{sz}\r\nConnection: keep-alive\r\n\r\n}, lines(7)
|
96
|
-
assert_equal "Hello", @client.read(5)
|
97
|
-
end
|
98
|
-
=end
|
99
|
-
|
100
|
-
def test_chunked
|
101
|
-
@body << "Chunked"
|
102
|
-
|
103
|
-
@client << @valid_request
|
104
|
-
|
105
|
-
assert_match %r{HTTP/1.1 200 OK\r\nX-Header: Works\r\nServer(.*\r\n)*?Transfer-Encoding: chunked\r\nDate(.*?)\r\n\r\n5\r\nHello\r\n7\r\nChunked\r\n0\r\n\r\n}, lines(13)
|
106
|
-
end
|
107
|
-
|
108
|
-
def test_no_chunked_in_http10
|
109
|
-
@body << "Chunked"
|
110
|
-
|
111
|
-
@client << @http10_request
|
112
|
-
|
113
|
-
assert_match %r{HTTP/1.0 200 OK\r\nX-Header: Works(.*?\r\n)*?Connection: close\r\nDate(.*?)\r\n\r\n}, lines(6)
|
114
|
-
assert_equal "HelloChunked", @client.read
|
115
|
-
end
|
116
|
-
|
117
|
-
def test_hex
|
118
|
-
str = "This is longer and will be in hex"
|
119
|
-
@body << str
|
120
|
-
|
121
|
-
@client << @valid_request
|
122
|
-
|
123
|
-
assert_match %r{HTTP/1.1 200 OK\r\nX-Header: Works\r\n(.*?\r\n)*?Transfer-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)
|
124
|
-
|
125
|
-
end
|
126
|
-
|
127
|
-
def test_client11_close
|
128
|
-
@client << @close_request
|
129
|
-
sz = @body[0].size.to_s
|
130
|
-
|
131
|
-
assert_match %r{HTTP/1.1 200 OK\r\nX-Header: Works\r\n(.*?\r\n)*?Content-Length: #{sz}\r\nConnection: close\r\nDate(.*?)\r\n\r\n}, lines(7)
|
132
|
-
assert_equal "Hello", @client.read(5)
|
133
|
-
end
|
134
|
-
|
135
|
-
def test_client10_close
|
136
|
-
@client << @http10_request
|
137
|
-
sz = @body[0].size.to_s
|
138
|
-
|
139
|
-
assert_match %r{HTTP/1.0 200 OK\r\nX-Header: Works\r\n(.*?\r\n)*?Content-Length: #{sz}\r\nConnection: close\r\nDate(.*?)\r\n\r\n}, lines(7)
|
140
|
-
assert_equal "Hello", @client.read(5)
|
141
|
-
end
|
142
|
-
|
143
|
-
def test_one_with_keep_alive_header
|
144
|
-
@client << @keep_request
|
145
|
-
sz = @body[0].size.to_s
|
146
|
-
|
147
|
-
assert_match %r{HTTP/1.0 200 OK\r\nX-Header: Works\r\nServer(.*?\r\n)*?Content-Length: #{sz}\r\nConnection: keep-alive\r\nDate(.*?)\r\n\r\n}, lines(7)
|
148
|
-
assert_equal "Hello", @client.read(5)
|
149
|
-
end
|
150
|
-
|
151
|
-
=begin
|
152
|
-
def test_persistent_timeout
|
153
|
-
@server.persistent_timeout = 2
|
154
|
-
@client << @valid_request
|
155
|
-
sz = @body[0].size.to_s
|
156
|
-
|
157
|
-
assert_equal "HTTP/1.1 200 OK\r\nX-Header: Works\r\nContent-Length: #{sz}\r\n\r\n", lines(4)
|
158
|
-
assert_equal "Hello", @client.read(5)
|
159
|
-
|
160
|
-
sleep 3
|
161
|
-
|
162
|
-
assert_raises EOFError do
|
163
|
-
@client.read_nonblock(1)
|
164
|
-
end
|
165
|
-
end
|
166
|
-
=end
|
167
|
-
|
168
|
-
def test_app_sets_content_length
|
169
|
-
@body = ["hello", " world"]
|
170
|
-
@headers['Content-Length'] = "11"
|
171
|
-
|
172
|
-
@client << @valid_request
|
173
|
-
|
174
|
-
assert_match %r{HTTP/1.1 200 OK\r\nX-Header: Works\r\n(.*?\r\n)*?Content-Length: 11\r\nConnection: keep-alive\r\nDate(.*?)\r\n\r\n}, lines(7)
|
175
|
-
assert_equal "hello world", @client.read(11)
|
176
|
-
end
|
177
|
-
|
178
|
-
def test_allow_app_to_chunk_itself
|
179
|
-
skip "body should not be chunked before sent to jubilee"
|
180
|
-
@headers = {'Transfer-Encoding' => "chunked" }
|
181
|
-
|
182
|
-
@body = ["5\r\nhello\r\n0\r\n\r\n"]
|
183
|
-
|
184
|
-
@client << @valid_request
|
185
|
-
|
186
|
-
assert_match %r{HTTP/1.1 200 OK\r\n(.*?\r\n)*?Transfer-Encoding: chunked\r\nDate(.*?)\r\n\r\n5\r\nhello\r\n0\r\n}, lines(10)
|
187
|
-
end
|
188
|
-
|
189
|
-
|
190
|
-
def test_two_requests_in_one_chunk
|
191
|
-
|
192
|
-
req = @valid_request.to_s
|
193
|
-
req << "GET /second HTTP/1.1\r\nHost: test.com\r\nContent-Type: text/plain\r\n\r\n"
|
194
|
-
|
195
|
-
@client << req
|
196
|
-
|
197
|
-
sz = @body[0].size.to_s
|
198
|
-
|
199
|
-
assert_match %r{HTTP/1.1 200 OK\r\nX-Header: Works\r\n(.*?\r\n)*?Content-Length: #{sz}\r\nConnection: keep-alive\r\nDate(.*?)\r\n\r\n}, lines(7)
|
200
|
-
assert_equal "Hello", @client.read(5)
|
201
|
-
|
202
|
-
assert_match %r{HTTP/1.1 200 OK\r\nX-Header: Works\r\n(.*?\r\n)*?Content-Length: #{sz}\r\nConnection: keep-alive\r\nDate(.*?)\r\n\r\n}, lines(7)
|
203
|
-
assert_equal "Hello", @client.read(5)
|
204
|
-
end
|
205
|
-
|
206
|
-
def test_second_request_not_in_first_req_body
|
207
|
-
|
208
|
-
req = @valid_request.to_s
|
209
|
-
req << "GET /second HTTP/1.1\r\nHost: test.com\r\nContent-Type: text/plain\r\n\r\n"
|
210
|
-
|
211
|
-
@client << req
|
212
|
-
|
213
|
-
sz = @body[0].size.to_s
|
214
|
-
|
215
|
-
assert_match %r{HTTP/1.1 200 OK\r\nX-Header: Works\r\n(.*?\r\n)*?Content-Length: #{sz}\r\nConnection: keep-alive\r\nDate(.*?)\r\n\r\n}, lines(7)
|
216
|
-
assert_equal "Hello", @client.read(5)
|
217
|
-
|
218
|
-
assert_match %r{HTTP/1.1 200 OK\r\nX-Header: Works\r\n(.*?\r\n)*?Content-Length: #{sz}\r\nConnection: keep-alive\r\nDate(.*?)\r\n\r\n}, lines(7)
|
219
|
-
assert_equal "Hello", @client.read(5)
|
220
|
-
|
221
|
-
#assert_kind_of Jubilee::NullIO, @inputs[0]
|
222
|
-
#assert_kind_of Jubilee::NullIO, @inputs[1]
|
223
|
-
end
|
224
|
-
|
225
|
-
def test_keepalive_doesnt_starve_clients
|
226
|
-
sz = @body[0].size.to_s
|
227
|
-
|
228
|
-
@client << @valid_request
|
229
|
-
|
230
|
-
c2 = TCPSocket.new @host, @port
|
231
|
-
c2 << @valid_request
|
232
|
-
|
233
|
-
out = IO.select([c2], nil, nil, 1)
|
234
|
-
|
235
|
-
assert out, "select returned nil"
|
236
|
-
assert_equal c2, out.first.first
|
237
|
-
|
238
|
-
assert_match %r{HTTP/1.1 200 OK\r\nX-Header: Works\r\n(.*?\r\n)*?Content-Length: #{sz}\r\nConnection: keep-alive\r\nDate(.*?)\r\n\r\n}, lines(7, c2)
|
239
|
-
assert_equal "Hello", c2.read(5)
|
240
|
-
end
|
241
|
-
|
242
|
-
=begin
|
243
|
-
def test_client_shutdown_writes
|
244
|
-
bs = 15609315 * rand
|
245
|
-
sock = TCPSocket.new('127.0.0.1', @port)
|
246
|
-
sock.syswrite("PUT /hello HTTP/1.1\r\n")
|
247
|
-
sock.syswrite("Host: example.com\r\n")
|
248
|
-
sock.syswrite("Transfer-Encoding: chunked\r\n")
|
249
|
-
sock.syswrite("Trailer: X-Foo\r\n")
|
250
|
-
sock.syswrite("\r\n")
|
251
|
-
sock.syswrite("%x\r\n" % [ bs ])
|
252
|
-
sock.syswrite("F" * bs)
|
253
|
-
sock.syswrite("\r\n0\r\nX-")
|
254
|
-
"Foo: bar\r\n\r\n".each_byte do |x|
|
255
|
-
sock.syswrite x.chr
|
256
|
-
sleep 0.05
|
257
|
-
end
|
258
|
-
# we wrote the entire request before shutting down, server should
|
259
|
-
# continue to process our request and never hit EOFError on our sock
|
260
|
-
sock.shutdown(Socket::SHUT_WR)
|
261
|
-
buf = sock.read
|
262
|
-
assert_equal 'Hello', buf.split(/\r\n\r\n/).last
|
263
|
-
next_client = Net::HTTP.get(URI.parse("http://127.0.0.1:#@port/"))
|
264
|
-
assert_equal 'Hello', next_client
|
265
|
-
lines = File.readlines("test_stderr.#$$.log")
|
266
|
-
assert lines.grep(/^Unicorn::ClientShutdown: /).empty?
|
267
|
-
assert_nil sock.close
|
268
|
-
end
|
269
|
-
=end
|
270
|
-
end
|