diff --git a/lib/unpoly/rails/request_echo_headers.rb b/lib/unpoly/rails/request_echo_headers.rb index 44958c2..b682469 100644 --- a/lib/unpoly/rails/request_echo_headers.rb +++ b/lib/unpoly/rails/request_echo_headers.rb @@ -18,9 +18,13 @@ def self.included(base) end private - + def set_up_request_echo_headers - response.headers['X-Up-Location'] = up.request_url_without_up_params + request_url_without_up_params = up.request_url_without_up_params + unless request_url_without_up_params == request.original_url + response.headers['X-Up-Location'] = up.request_url_without_up_params + end + response.headers['X-Up-Method'] = request.method end diff --git a/spec/unpoly/rails/controller_spec.rb b/spec/unpoly/rails/controller_spec.rb index 47dfa46..9e9591e 100644 --- a/spec/unpoly/rails/controller_spec.rb +++ b/spec/unpoly/rails/controller_spec.rb @@ -995,31 +995,28 @@ def controller_eval(headers: {}, &expression) describe 'echoing of the request location' do - it 'echoes the current path in an X-Up-Location response header' do + it 'does not echo the current path in an X-Up-Location response header to prevent the user-controlled request URL from exceeding the maximum response header size' do get '/binding_test/text' - expect(response.headers['X-Up-Location']).to end_with('/binding_test/text') + expect(response.headers['X-Up-Location']).to be_nil end - it 'echoes the current path after a redirect' do - get '/binding_test/redirect1' - expect(response).to be_redirect - follow_redirect! - expect(response.headers['X-Up-Location']).to end_with('/binding_test/redirect2') - end + describe 'when the request URL contains query params prefixed with "_up-"' do - it 'echoes the current path with query params' do - get '/binding_test/text?foo=bar' - expect(response.headers['X-Up-Location']).to end_with('/binding_test/text?foo=bar') - end + it 'removes params prefixed with "_up-"' do + get '/binding_test/text?_up_1&_up_2=y' + expect(response.headers['X-Up-Location']).to end_with('/binding_test/text') + end - it 'removes _up-* params' do - get '/binding_test/text?_up_1=x&foo=bar&_up_2=y' - expect(response.headers['X-Up-Location']).to end_with('/binding_test/text?foo=bar') - end + it 'keeps params not prefixed with "_up-"' do + get '/binding_test/text?_up_1=x&foo=bar&_up_2=y' + expect(response.headers['X-Up-Location']).to end_with('/binding_test/text?foo=bar') + end + + it 'does not mangle array params (BUGFIX)' do + get '/binding_test/text?_up_1=x&foo%5B%5D=bar&foo%5B%5D=qux&_up_location=up_location' + expect(response.headers['X-Up-Location']).to end_with('/binding_test/text?foo%5B%5D=bar&foo%5B%5D=qux') + end - it 'does not mangle array params (BUGFIX)' do - get '/binding_test/text?foo%5B%5D=bar&foo%5B%5D=qux&_up_location=up_location' - expect(response.headers['X-Up-Location']).to end_with('/binding_test/text?foo%5B%5D=bar&foo%5B%5D=qux') end end