* lib/open-uri.rb (OpenURI.open_loop, URI::HTTP#proxy_open): use
catch/throw for redirection instead of exception. (OpenURI.open_loop, OpenURI.redirectable?): restrict redirection. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@5015 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
087a8db4d2
commit
6eaa5f2b05
@ -1,3 +1,9 @@
|
|||||||
|
Mon Nov 24 23:32:06 2003 Tanaka Akira <akr@m17n.org>
|
||||||
|
|
||||||
|
* lib/open-uri.rb (OpenURI.open_loop, URI::HTTP#proxy_open): use
|
||||||
|
catch/throw for redirection instead of exception.
|
||||||
|
(OpenURI.open_loop, OpenURI.redirectable?): restrict redirection.
|
||||||
|
|
||||||
Mon Nov 24 19:59:48 2003 Tanaka Akira <akr@m17n.org>
|
Mon Nov 24 19:59:48 2003 Tanaka Akira <akr@m17n.org>
|
||||||
|
|
||||||
* lib/open-uri.rb (URI::Generic#find_proxy): use CGI_HTTP_PROXY
|
* lib/open-uri.rb (URI::Generic#find_proxy): use CGI_HTTP_PROXY
|
||||||
|
@ -159,36 +159,44 @@ module OpenURI
|
|||||||
end
|
end
|
||||||
|
|
||||||
uri_set = {}
|
uri_set = {}
|
||||||
begin
|
buf = nil
|
||||||
buf = Buffer.new
|
while true
|
||||||
if proxy_uri = find_proxy.call(uri)
|
redirect = catch(:open_uri_redirect) {
|
||||||
proxy_uri.proxy_open(buf, uri, options)
|
buf = Buffer.new
|
||||||
|
if proxy_uri = find_proxy.call(uri)
|
||||||
|
proxy_uri.proxy_open(buf, uri, options)
|
||||||
|
else
|
||||||
|
uri.direct_open(buf, options)
|
||||||
|
end
|
||||||
|
nil
|
||||||
|
}
|
||||||
|
if redirect
|
||||||
|
if redirect.relative?
|
||||||
|
# Although it violates RFC 2616, Location: field may have relative
|
||||||
|
# URI. It is converted to absolute URI using uri.
|
||||||
|
redirect = uri + redirect
|
||||||
|
end
|
||||||
|
unless OpenURI.redirectable?(uri, redirect)
|
||||||
|
raise "redirection forbidden: #{uri} -> #{redirect}"
|
||||||
|
end
|
||||||
|
uri = redirect
|
||||||
|
raise "HTTP redirection loop: #{uri}" if uri_set.include? uri.to_s
|
||||||
|
uri_set[uri.to_s] = true
|
||||||
else
|
else
|
||||||
uri.direct_open(buf, options)
|
break
|
||||||
end
|
end
|
||||||
rescue Redirect
|
|
||||||
loc = $!.uri
|
|
||||||
if loc.relative?
|
|
||||||
# Although it violates RFC 2616, Location: field may have relative URI.
|
|
||||||
# It is converted to absolute URI using uri.
|
|
||||||
loc = uri + loc
|
|
||||||
end
|
|
||||||
uri = loc
|
|
||||||
raise "HTTP redirection loop: #{uri}" if uri_set.include? uri.to_s
|
|
||||||
uri_set[uri.to_s] = true
|
|
||||||
retry
|
|
||||||
end
|
end
|
||||||
io = buf.io
|
io = buf.io
|
||||||
io.base_uri = uri
|
io.base_uri = uri
|
||||||
io
|
io
|
||||||
end
|
end
|
||||||
|
|
||||||
class Redirect < StandardError # :nodoc:
|
def OpenURI.redirectable?(uri1, uri2) # :nodoc:
|
||||||
def initialize(uri)
|
# This test is intended to forbid a redirection from http://... to
|
||||||
super("redirection to #{uri.to_s}")
|
# file:///etc/passwd.
|
||||||
@uri = uri
|
# However this is ad hoc. It should be extensible/configurable.
|
||||||
end
|
uri1.scheme.downcase == uri2.scheme.downcase ||
|
||||||
attr_reader :uri
|
(/\A(?:http|ftp)\z/i =~ uri1.scheme && /\A(?:http|ftp)\z/i =~ uri2.scheme)
|
||||||
end
|
end
|
||||||
|
|
||||||
class HTTPError < StandardError
|
class HTTPError < StandardError
|
||||||
@ -502,7 +510,7 @@ module URI
|
|||||||
Net::HTTPFound, # 302
|
Net::HTTPFound, # 302
|
||||||
Net::HTTPSeeOther, # 303
|
Net::HTTPSeeOther, # 303
|
||||||
Net::HTTPTemporaryRedirect # 307
|
Net::HTTPTemporaryRedirect # 307
|
||||||
raise OpenURI::Redirect.new(URI.parse(resp['location']))
|
throw :open_uri_redirect, URI.parse(resp['location'])
|
||||||
else
|
else
|
||||||
raise OpenURI::HTTPError.new(io.status.join(' '), io)
|
raise OpenURI::HTTPError.new(io.status.join(' '), io)
|
||||||
end
|
end
|
||||||
|
Loading…
x
Reference in New Issue
Block a user