diff --git a/lib/httpi.rb b/lib/httpi.rb index 5a96b07..4a0ad32 100644 --- a/lib/httpi.rb +++ b/lib/httpi.rb @@ -1,3 +1,4 @@ +require "uri" require "httpi/version" require "httpi/logger" require "httpi/request" @@ -159,8 +160,8 @@ def request(method, request, adapter = nil) response = adapter_class.request(method) if response && HTTPI::Response::RedirectResponseCodes.member?(response.code) && request.follow_redirect? - log("Following redirect: '#{response.headers['location']}'.") - request.url = response.headers['location'] + request.url = URI.join(request.url, response.headers['location']) + log("Following redirect: '#{request.url}'.") return request(method, request, adapter) end diff --git a/spec/httpi/httpi_spec.rb b/spec/httpi/httpi_spec.rb index cd87059..780e0e2 100644 --- a/spec/httpi/httpi_spec.rb +++ b/spec/httpi/httpi_spec.rb @@ -222,7 +222,7 @@ end describe ".request" do - let(:request) { HTTPI::Request.new('http://example.com') } + let(:request) { HTTPI::Request.new('http://example.com/foo/') } it "allows custom HTTP methods" do httpclient.any_instance.expects(:request).with(:custom) @@ -238,7 +238,33 @@ response = HTTPI::Response.new(200, {}, 'success') httpclient.any_instance.expects(:request).twice.with(:custom).returns(redirect, response) - request.expects(:url=).with(redirect_location) + request.expects(:url=).with(URI.parse(redirect_location)) + + client.request(:custom, request, :httpclient) + end + + it 'follows redirects with absolute path' do + request.follow_redirect = true + redirect_location = '/bar/foo' + + redirect = HTTPI::Response.new(302, {'location' => redirect_location}, 'Moved') + response = HTTPI::Response.new(200, {}, 'success') + + httpclient.any_instance.expects(:request).twice.with(:custom).returns(redirect, response) + request.expects(:url=).with(URI.parse('http://example.com/bar/foo')) + + client.request(:custom, request, :httpclient) + end + + it 'follows redirects with relative path' do + request.follow_redirect = true + redirect_location = 'bar/foo' + + redirect = HTTPI::Response.new(302, {'location' => redirect_location}, 'Moved') + response = HTTPI::Response.new(200, {}, 'success') + + httpclient.any_instance.expects(:request).twice.with(:custom).returns(redirect, response) + request.expects(:url=).with(URI.parse('http://example.com/foo/bar/foo')) client.request(:custom, request, :httpclient) end