Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Handle '303 See Other' properly

RFC2616 says it should be redirected with GET.
  • Loading branch information...
commit b63d0b9815efd3cbad540e2b2c1daabca5def798 1 parent 80a7918
@nahi authored
View
7 lib/httpclient.rb
@@ -945,7 +945,7 @@ def follow_redirect(method, uri, query, body, header, &block)
uri = urify(uri)
if block
filtered_block = proc { |r, str|
- block.call(str) if HTTP::Status.successful?(r.status)
+ block.call(str) if r.ok?
}
end
if HTTP::Message.file?(body)
@@ -955,7 +955,8 @@ def follow_redirect(method, uri, query, body, header, &block)
while retry_number < @follow_redirect_count
body.pos = pos if pos
res = do_request(method, uri, query, body, header, &filtered_block)
- if HTTP::Status.redirect?(res.status)
+ if res.redirect?
+ method = :get if res.see_other? # See RFC2616 10.3.4
uri = urify(@redirect_uri_callback.call(uri, res))
retry_number += 1
else
@@ -966,7 +967,7 @@ def follow_redirect(method, uri, query, body, header, &block)
end
def success_content(res)
- if HTTP::Status.successful?(res.status)
+ if res.ok?
return res.content
else
raise BadResponseError.new("unexpected response: #{res.header.inspect}", res)
View
10 lib/httpclient/http.rb
@@ -1032,7 +1032,15 @@ def cookies
def ok?
HTTP::Status.successful?(status)
end
- end
+ def redirect?
+ HTTP::Status.redirect?(status)
+ end
+
+ # SEE_OTHER is a redirect, but it should sent as GET
+ def see_other?
+ status == HTTP::Status::SEE_OTHER
+ end
+ end
end
View
16 test/test_httpclient.rb
@@ -479,6 +479,10 @@ def test_redirect_non_https
end
end
+ def test_redirect_see_other
+ assert_equal('hello', @client.post_content(serverurl + 'redirect_see_other'))
+ end
+
def test_redirect_relative
@client.test_loopback_http_response << "HTTP/1.0 302 OK\nLocation: hello\n\n"
silent do
@@ -1575,8 +1579,8 @@ def setup_server
@serverport = @server.config[:Port]
[
:hello, :sleep, :servlet_redirect, :redirect1, :redirect2, :redirect3,
- :redirect_self, :relative_redirect, :chunked, :largebody, :status,
- :compressed, :charset, :continue
+ :redirect_self, :relative_redirect, :redirect_see_other, :chunked,
+ :largebody, :status, :compressed, :charset, :continue
].each do |sym|
@server.mount(
"/#{sym}",
@@ -1631,6 +1635,14 @@ def do_relative_redirect(req, res)
res.set_redirect(WEBrick::HTTPStatus::Found, "hello")
end
+ def do_redirect_see_other(req, res)
+ if req.request_method == 'POST'
+ res.set_redirect(WEBrick::HTTPStatus::SeeOther, serverurl + "redirect_see_other") # self
+ else
+ res.body = 'hello'
+ end
+ end
+
def do_chunked(req, res)
res.chunked = true
piper, pipew = IO.pipe
Please sign in to comment.
Something went wrong with that request. Please try again.