Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Always set CONTENT_TYPE for non-GET requests #223

Merged
merged 3 commits into from
Mar 27, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion lib/rack/test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -233,14 +233,16 @@ def env_for(uri, env)
uri.query = [uri.query, build_nested_query(params)].compact.reject { |v| v == '' }.join('&')
end
elsif !env.key?(:input)
env['CONTENT_TYPE'] ||= 'application/x-www-form-urlencoded' unless params.nil?
env['CONTENT_TYPE'] ||= 'application/x-www-form-urlencoded'

if params.is_a?(Hash)
if data = build_multipart(params)
env[:input] = data
env['CONTENT_LENGTH'] ||= data.length.to_s
env['CONTENT_TYPE'] = "multipart/form-data; boundary=#{MULTIPART_BOUNDARY}"
else
# NB: We do not need to set CONTENT_LENGTH here;
# Rack::ContentLength will determine it automatically.
env[:input] = params_to_string(params)
end
else
Expand Down
111 changes: 73 additions & 38 deletions spec/rack/test_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -457,11 +457,11 @@ def close
end
end

shared_examples_for 'any #verb methods' do
shared_examples_for 'any #verb methods' do |verb|
it 'requests the URL using VERB' do
public_send(verb, '/')

check expect(last_request.env['REQUEST_METHOD']).to eq(verb.upcase)
check expect(last_request.env['REQUEST_METHOD']).to eq(verb.to_s.upcase)
expect(last_response).to be_ok
end

Expand All @@ -470,9 +470,28 @@ def close
expect(last_request.env['HTTP_USER_AGENT']).to eq('Rack::Test')
end

it 'does not set CONTENT_TYPE if params are explicitly set to nil' do
public_send(verb, '/', nil)
expect(last_request.env['CONTENT_TYPE']).to be_nil
context 'when params are not provided', unless: verb == :get do
it 'sets CONTENT_TYPE to application/x-www-form-urlencoded' do
public_send(verb, '/')
expect(last_request.env['CONTENT_TYPE']).to eq 'application/x-www-form-urlencoded'
end

it 'sets CONTENT_LENGTH to zero' do
public_send(verb, '/')
expect(last_request.env['CONTENT_LENGTH']).to eq '0'
end
end

context 'when params are explicitly set to nil', unless: verb == :get do
it 'sets CONTENT_TYPE to application/x-www-form-urlencoded' do
public_send(verb, '/', nil)
expect(last_request.env['CONTENT_TYPE']).to eq 'application/x-www-form-urlencoded'
end

it 'sets CONTENT_LENGTH to 0' do
public_send(verb, '/')
expect(last_request.env['CONTENT_LENGTH']).to eq '0'
end
end

it 'yields the response to a given block' do
Expand Down Expand Up @@ -506,10 +525,43 @@ def close
end

describe '#get' do
it_should_behave_like 'any #verb methods'
it_should_behave_like 'any #verb methods', :get

context 'when params are not provided' do
# This is not actually explicitly stated in the relevant RFCs;
# https://tools.ietf.org/html/rfc7231#section-3.1.1.5
# ...but e.g. curl do not set it for GET requests.
it 'does not set CONTENT_TYPE' do
get '/'
expect(last_request.env.key?('CONTENT_TYPE')).to eq false
end

# Quoting from https://tools.ietf.org/html/rfc7230#section-3.3.2:
#
# A user agent SHOULD NOT send a Content-Length header field when
# the request message does not contain a payload body and the
# method semantics do not anticipate such a body.
#
# _However_, something causes CONTENT_LENGTH to always be present.
# Even when we don't set it ourselves. It could be
# Rack::ContentLength that is playing tricks with us:
# https://github.com/rack/rack/blob/master/lib/rack/content_length.rb
it 'sets CONTENT_LENGTH to zero' do
get '/'
expect(last_request.env['CONTENT_LENGTH']).to eq '0'
end
end

def verb
'get'
context 'when params are explicitly set to nil' do
it 'sets CONTENT_TYPE to application/x-www-form-urlencoded' do
get '/', nil
expect(last_request.env.key?('CONTENT_TYPE')).to eq false
end

it 'sets CONTENT_LENGTH to zero' do
get '/', nil
expect(last_request.env['CONTENT_LENGTH']).to eq '0'
end
end

it 'uses the provided params hash' do
Expand Down Expand Up @@ -539,19 +591,11 @@ def verb
end

describe '#head' do
it_should_behave_like 'any #verb methods'

def verb
'head'
end
it_should_behave_like 'any #verb methods', :head
end

describe '#post' do
it_should_behave_like 'any #verb methods'

def verb
'post'
end
it_should_behave_like 'any #verb methods', :post

it 'uses the provided params hash' do
post '/', foo: 'bar'
Expand All @@ -568,6 +612,13 @@ def verb
expect(last_request.env['CONTENT_TYPE']).to eq('application/x-www-form-urlencoded')
end

# NB: This is never set in _our code_, but is added automatically
# (presumably by Rack::ContentLength)
it 'sets the CONTENT_LENGTH' do
post '/', foo: 'bar'
expect(last_request.env['CONTENT_LENGTH']).to eq('7')
end

it 'accepts a body' do
post '/', 'Lobsterlicious!'
expect(last_request.body.read).to eq('Lobsterlicious!')
Expand All @@ -582,11 +633,7 @@ def verb
end

describe '#put' do
it_should_behave_like 'any #verb methods'

def verb
'put'
end
it_should_behave_like 'any #verb methods', :put

it 'accepts a body' do
put '/', 'Lobsterlicious!'
Expand All @@ -595,11 +642,7 @@ def verb
end

describe '#patch' do
it_should_behave_like 'any #verb methods'

def verb
'patch'
end
it_should_behave_like 'any #verb methods', :patch

it 'accepts a body' do
patch '/', 'Lobsterlicious!'
Expand All @@ -608,11 +651,7 @@ def verb
end

describe '#delete' do
it_should_behave_like 'any #verb methods'

def verb
'delete'
end
it_should_behave_like 'any #verb methods', :delete

it 'uses the provided params hash' do
delete '/', foo: 'bar'
Expand All @@ -636,11 +675,7 @@ def verb
end

describe '#options' do
it_should_behave_like 'any #verb methods'

def verb
'options'
end
it_should_behave_like 'any #verb methods', :options
end

describe '#custom_request' do
Expand Down