зеркало из https://github.com/github/ruby.git
* lib/open-uri.rb: support https if the platform provides CA
certificates. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@7947 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
Родитель
ac0478b274
Коммит
c34e899e4f
|
@ -1,3 +1,8 @@
|
|||
Sat Feb 12 13:54:03 2005 Tanaka Akira <akr@m17n.org>
|
||||
|
||||
* lib/open-uri.rb: support https if the platform provides CA
|
||||
certificates.
|
||||
|
||||
Fri Feb 11 17:37:50 2005 GOTOU Yuuzou <gotoyuzo@notwork.org>
|
||||
|
||||
* ext/openss/ossl_x509store.c (ossl_x509store_set_default_paths):
|
||||
|
|
155
lib/open-uri.rb
155
lib/open-uri.rb
|
@ -163,11 +163,7 @@ module OpenURI
|
|||
while true
|
||||
redirect = catch(:open_uri_redirect) {
|
||||
buf = Buffer.new
|
||||
if proxy_uri = find_proxy.call(uri)
|
||||
proxy_uri.proxy_open(buf, uri, options)
|
||||
else
|
||||
uri.direct_open(buf, options)
|
||||
end
|
||||
uri.buffer_open(buf, find_proxy.call(uri), options)
|
||||
nil
|
||||
}
|
||||
if redirect
|
||||
|
@ -199,6 +195,81 @@ module OpenURI
|
|||
(/\A(?:http|ftp)\z/i =~ uri1.scheme && /\A(?:http|ftp)\z/i =~ uri2.scheme)
|
||||
end
|
||||
|
||||
def OpenURI.open_http(buf, target, proxy, options) # :nodoc:
|
||||
if proxy
|
||||
raise "Non-HTTP proxy URI: #{proxy}" if proxy.class != URI::HTTP
|
||||
end
|
||||
|
||||
require 'net/http'
|
||||
klass = Net::HTTP
|
||||
if URI::HTTP === target
|
||||
# HTTP or HTTPS
|
||||
if proxy
|
||||
klass = Net::HTTP::Proxy(proxy.host, proxy.port)
|
||||
end
|
||||
target_host = target.host
|
||||
target_port = target.port
|
||||
request_uri = target.request_uri
|
||||
else
|
||||
# FTP over HTTP proxy
|
||||
target_host = proxy.host
|
||||
target_port = proxy.port
|
||||
request_uri = target.to_s
|
||||
end
|
||||
|
||||
http = klass.new(target_host, target_port)
|
||||
if target.class == URI::HTTPS
|
||||
require 'net/https'
|
||||
http.use_ssl = true
|
||||
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
||||
store = OpenSSL::X509::Store.new
|
||||
store.set_default_paths
|
||||
http.cert_store = store
|
||||
end
|
||||
|
||||
header = {}
|
||||
options.each {|k, v| header[k] = v if String === k }
|
||||
|
||||
resp = nil
|
||||
http.start {
|
||||
req = Net::HTTP::Get.new(request_uri, header)
|
||||
if options.include? :http_basic_authentication
|
||||
user, pass = options[:http_basic_authentication]
|
||||
req.basic_auth user, pass
|
||||
end
|
||||
http.request(req) {|response|
|
||||
resp = response
|
||||
if options[:content_length_proc] && Net::HTTPSuccess === resp
|
||||
if resp.key?('Content-Length')
|
||||
options[:content_length_proc].call(resp['Content-Length'].to_i)
|
||||
else
|
||||
options[:content_length_proc].call(nil)
|
||||
end
|
||||
end
|
||||
resp.read_body {|str|
|
||||
buf << str
|
||||
if options[:progress_proc] && Net::HTTPSuccess === resp
|
||||
options[:progress_proc].call(buf.size)
|
||||
end
|
||||
}
|
||||
}
|
||||
}
|
||||
io = buf.io
|
||||
io.rewind
|
||||
io.status = [resp.code, resp.message]
|
||||
resp.each {|name,value| buf.io.meta_add_field name, value }
|
||||
case resp
|
||||
when Net::HTTPSuccess
|
||||
when Net::HTTPMovedPermanently, # 301
|
||||
Net::HTTPFound, # 302
|
||||
Net::HTTPSeeOther, # 303
|
||||
Net::HTTPTemporaryRedirect # 307
|
||||
throw :open_uri_redirect, URI.parse(resp['location'])
|
||||
else
|
||||
raise OpenURI::HTTPError.new(io.status.join(' '), io)
|
||||
end
|
||||
end
|
||||
|
||||
class HTTPError < StandardError
|
||||
def initialize(message, io)
|
||||
super(message)
|
||||
|
@ -515,9 +586,6 @@ module URI
|
|||
|
||||
if proxy_uri
|
||||
proxy_uri = URI.parse(proxy_uri)
|
||||
unless URI::HTTP === proxy_uri
|
||||
raise "Non-HTTP proxy URI: #{proxy_uri}"
|
||||
end
|
||||
name = 'no_proxy'
|
||||
if no_proxy = ENV[name] || ENV[name.upcase]
|
||||
no_proxy.scan(/([^:,]*)(?::(\d+))?/) {|host, port|
|
||||
|
@ -536,76 +604,19 @@ module URI
|
|||
end
|
||||
|
||||
class HTTP
|
||||
def direct_open(buf, options) # :nodoc:
|
||||
proxy_open(buf, request_uri, options)
|
||||
end
|
||||
|
||||
def proxy_open(buf, uri, options) # :nodoc:
|
||||
header = {}
|
||||
options.each {|k, v| header[k] = v if String === k }
|
||||
|
||||
if uri.respond_to? :host
|
||||
# According to RFC2616 14.23, Host: request-header field should be
|
||||
# the origin server.
|
||||
# But net/http wrongly set a proxy server if an absolute URI is
|
||||
# specified as a request URI.
|
||||
# So open-uri override it here explicitly.
|
||||
header['host'] = uri.host
|
||||
header['host'] += ":#{uri.port}" if uri.port
|
||||
end
|
||||
|
||||
require 'net/http'
|
||||
resp = nil
|
||||
req = Net::HTTP::Get.new(uri.to_s, header)
|
||||
if options.include? :http_basic_authentication
|
||||
user, pass = options[:http_basic_authentication]
|
||||
req.basic_auth user, pass
|
||||
end
|
||||
Net::HTTP.start(self.host, self.port) {|http|
|
||||
http.request(req) {|response|
|
||||
resp = response
|
||||
if options[:content_length_proc] && Net::HTTPSuccess === resp
|
||||
if resp.key?('Content-Length')
|
||||
options[:content_length_proc].call(resp['Content-Length'].to_i)
|
||||
else
|
||||
options[:content_length_proc].call(nil)
|
||||
end
|
||||
end
|
||||
resp.read_body {|str|
|
||||
buf << str
|
||||
if options[:progress_proc] && Net::HTTPSuccess === resp
|
||||
options[:progress_proc].call(buf.size)
|
||||
end
|
||||
}
|
||||
}
|
||||
}
|
||||
io = buf.io
|
||||
io.rewind
|
||||
io.status = [resp.code, resp.message]
|
||||
resp.each {|name,value| buf.io.meta_add_field name, value }
|
||||
case resp
|
||||
when Net::HTTPSuccess
|
||||
when Net::HTTPMovedPermanently, # 301
|
||||
Net::HTTPFound, # 302
|
||||
Net::HTTPSeeOther, # 303
|
||||
Net::HTTPTemporaryRedirect # 307
|
||||
throw :open_uri_redirect, URI.parse(resp['location'])
|
||||
else
|
||||
raise OpenURI::HTTPError.new(io.status.join(' '), io)
|
||||
end
|
||||
def buffer_open(buf, proxy, options) # :nodoc:
|
||||
OpenURI.open_http(buf, self, proxy, options)
|
||||
end
|
||||
|
||||
include OpenURI::OpenRead
|
||||
end
|
||||
|
||||
class HTTPS
|
||||
def proxy_open(buf, uri, options) # :nodoc:
|
||||
raise ArgumentError, "open-uri doesn't support https."
|
||||
end
|
||||
end
|
||||
|
||||
class FTP
|
||||
def direct_open(buf, options) # :nodoc:
|
||||
def buffer_open(buf, proxy, options) # :nodoc:
|
||||
if proxy
|
||||
OpenURI.open_http(buf, self, proxy, options)
|
||||
return
|
||||
end
|
||||
require 'net/ftp'
|
||||
# todo: extract user/passwd from .netrc.
|
||||
user = 'anonymous'
|
||||
|
|
Загрузка…
Ссылка в новой задаче