Skip to content

Commit de6b618

Browse files
authored
Rack 3 no longer required environments (#437)
* when using Rack 3, don't add no longer required environments (rack.multithread/rack.multiprocess/rack.run_once/rack.version)
1 parent dbf793a commit de6b618

File tree

3 files changed

+67
-25
lines changed

3 files changed

+67
-25
lines changed

lib/thin/env.rb

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
2+
module Thin
3+
module Env
4+
def self.with_defaults(env)
5+
if ::Rack.release >= "3"
6+
rack_env_class = Rack3
7+
else
8+
rack_env_class = Rack2
9+
end
10+
11+
rack_env_class.env.merge(env)
12+
end
13+
end
14+
15+
private
16+
17+
class Rack2
18+
def self.env
19+
{
20+
::Thin::Request::RACK_VERSION => ::Thin::VERSION::RACK,
21+
::Thin::Request::RACK_MULTITHREAD => false,
22+
::Thin::Request::RACK_MULTIPROCESS => false,
23+
::Thin::Request::RACK_RUN_ONCE => false
24+
}
25+
end
26+
end
27+
28+
class Rack3
29+
def self.env
30+
{}
31+
end
32+
end
33+
end

lib/thin/request.rb

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
require 'tempfile'
2+
require_relative './env'
23

34
module Thin
45
# Raised when an incoming request is not valid
@@ -55,20 +56,14 @@ def initialize
5556
@data = String.new
5657
@nparsed = 0
5758
@body = StringIO.new(INITIAL_BODY.dup)
58-
@env = {
59+
@env = Env.with_defaults({
5960
SERVER_SOFTWARE => SERVER,
6061
SERVER_NAME => LOCALHOST,
6162

6263
# Rack stuff
6364
RACK_INPUT => @body,
64-
65-
RACK_VERSION => VERSION::RACK,
6665
RACK_ERRORS => STDERR,
67-
68-
RACK_MULTITHREAD => false,
69-
RACK_MULTIPROCESS => false,
70-
RACK_RUN_ONCE => false
71-
}
66+
})
7267
end
7368

7469
# Parse a chunk of data into the request environment

spec/request/parser_spec.rb

Lines changed: 31 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -19,48 +19,48 @@
1919
expect(request.env["rack.url_scheme"]).to eq('http')
2020
expect(request.env['FRAGMENT'].to_s).to be_empty
2121
expect(request.env['QUERY_STRING'].to_s).to be_empty
22-
22+
2323
expect(request).to validate_with_lint
2424
end
25-
25+
2626
it 'should upcase headers' do
2727
request = R("GET / HTTP/1.1\r\nX-Invisible: yo\r\n\r\n")
2828
expect(request.env['HTTP_X_INVISIBLE']).to eq('yo')
2929
end
30-
30+
3131
it 'should not prepend HTTP_ to Content-Type and Content-Length' do
3232
request = R("POST / HTTP/1.1\r\nHost: localhost\r\nContent-Type: text/html\r\nContent-Length: 2\r\n\r\naa")
3333
expect(request.env.keys).not_to include('HTTP_CONTENT_TYPE', 'HTTP_CONTENT_LENGTH')
3434
expect(request.env.keys).to include('CONTENT_TYPE', 'CONTENT_LENGTH')
35-
35+
3636
expect(request).to validate_with_lint
3737
end
38-
38+
3939
it 'should raise error on invalid request line' do
4040
expect { R("GET / SsUTF/1.1") }.to raise_error(InvalidRequest)
4141
expect { R("GET / HTTP/1.1yousmelllikecheeze") }.to raise_error(InvalidRequest)
4242
end
43-
43+
4444
it 'should support fragment in uri' do
4545
request = R("GET /forums/1/topics/2375?page=1#posts-17408 HTTP/1.1\r\nHost: localhost\r\n\r\n")
4646

4747
expect(request.env['REQUEST_URI']).to eq('/forums/1/topics/2375?page=1')
4848
expect(request.env['PATH_INFO']).to eq('/forums/1/topics/2375')
4949
expect(request.env['QUERY_STRING']).to eq('page=1')
5050
expect(request.env['FRAGMENT']).to eq('posts-17408')
51-
51+
5252
expect(request).to validate_with_lint
5353
end
54-
54+
5555
it 'should parse path with query string' do
5656
request = R("GET /index.html?234235 HTTP/1.1\r\nHost: localhost\r\n\r\n")
5757
expect(request.env['REQUEST_PATH']).to eq('/index.html')
5858
expect(request.env['QUERY_STRING']).to eq('234235')
5959
expect(request.env['FRAGMENT']).to be_nil
60-
60+
6161
expect(request).to validate_with_lint
6262
end
63-
63+
6464
it 'should parse headers from GET request' do
6565
request = R(<<-EOS, true)
6666
GET / HTTP/1.1
@@ -151,7 +151,7 @@
151151

152152
expect(request).to validate_with_lint
153153
end
154-
154+
155155
it 'should parse even with stupid Content-Length' do
156156
body = <<-EOS.chomp
157157
POST / HTTP/1.1
@@ -165,7 +165,7 @@
165165
request.body.rewind
166166
expect(request.body.read).to eq('aye')
167167
end
168-
168+
169169
it "should parse ie6 urls" do
170170
%w(/some/random/path"
171171
/some/random/path>
@@ -184,14 +184,14 @@
184184
expect(parser).not_to be_error
185185
end
186186
end
187-
187+
188188
it "should parse absolute request URI" do
189189
request = R(<<-EOS, true)
190190
GET http://localhost:3000/hi?qs#f HTTP/1.1
191191
Host: localhost:3000
192192
193193
EOS
194-
194+
195195
expect(request.env['PATH_INFO']).to eq('/hi')
196196
expect(request.env['REQUEST_PATH']).to eq('/hi')
197197
expect(request.env['REQUEST_URI']).to eq('/hi?qs')
@@ -236,7 +236,7 @@
236236
expect(req).to have_key('HTTP_HOS_T')
237237
}
238238
end
239-
239+
240240
it "should parse PATH_INFO with semicolon" do
241241
qs = "QUERY_STRING"
242242
pi = "PATH_INFO"
@@ -257,14 +257,14 @@
257257
expect(env["REQUEST_URI"]).to eq(uri)
258258

259259
next if uri == "*"
260-
260+
261261
# Validate w/ Ruby's URI.parse
262262
uri = URI.parse("http://example.com#{uri}")
263263
expect(env[qs]).to eq(uri.query.to_s)
264264
expect(env[pi]).to eq(uri.path)
265265
end
266266
end
267-
267+
268268
it "should parse IE7 badly encoded URL" do
269269
body = <<-EOS.chomp
270270
GET /H%uFFFDhnchenbrustfilet HTTP/1.1
@@ -275,4 +275,18 @@
275275

276276
expect(request.env['REQUEST_URI']).to eq("/H%uFFFDhnchenbrustfilet")
277277
end
278+
279+
describe "with Rack < 3", unless: ::Rack.release >= "3" do
280+
it "should add required env" do
281+
request = R("GET / HTTP/1.1\r\nHost: localhost\r\n\r\n")
282+
expect(request.env).to include("rack.version", "rack.multithread", "rack.multiprocess", "rack.run_once")
283+
end
284+
end
285+
286+
describe "with Rack >= 3", if: ::Rack.release >= "3" do
287+
it "should not add not required env" do
288+
request = R("GET / HTTP/1.1\r\nHost: localhost\r\n\r\n")
289+
expect(request.env).not_to include("rack.version", "rack.multithread", "rack.multiprocess", "rack.run_once")
290+
end
291+
end
278292
end

0 commit comments

Comments
 (0)