* 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:
parent
ac0478b274
commit
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>
|
Fri Feb 11 17:37:50 2005 GOTOU Yuuzou <gotoyuzo@notwork.org>
|
||||||
|
|
||||||
* ext/openss/ossl_x509store.c (ossl_x509store_set_default_paths):
|
* 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
|
while true
|
||||||
redirect = catch(:open_uri_redirect) {
|
redirect = catch(:open_uri_redirect) {
|
||||||
buf = Buffer.new
|
buf = Buffer.new
|
||||||
if proxy_uri = find_proxy.call(uri)
|
uri.buffer_open(buf, find_proxy.call(uri), options)
|
||||||
proxy_uri.proxy_open(buf, uri, options)
|
|
||||||
else
|
|
||||||
uri.direct_open(buf, options)
|
|
||||||
end
|
|
||||||
nil
|
nil
|
||||||
}
|
}
|
||||||
if redirect
|
if redirect
|
||||||
@ -199,6 +195,81 @@ module OpenURI
|
|||||||
(/\A(?:http|ftp)\z/i =~ uri1.scheme && /\A(?:http|ftp)\z/i =~ uri2.scheme)
|
(/\A(?:http|ftp)\z/i =~ uri1.scheme && /\A(?:http|ftp)\z/i =~ uri2.scheme)
|
||||||
end
|
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
|
class HTTPError < StandardError
|
||||||
def initialize(message, io)
|
def initialize(message, io)
|
||||||
super(message)
|
super(message)
|
||||||
@ -515,9 +586,6 @@ module URI
|
|||||||
|
|
||||||
if proxy_uri
|
if proxy_uri
|
||||||
proxy_uri = URI.parse(proxy_uri)
|
proxy_uri = URI.parse(proxy_uri)
|
||||||
unless URI::HTTP === proxy_uri
|
|
||||||
raise "Non-HTTP proxy URI: #{proxy_uri}"
|
|
||||||
end
|
|
||||||
name = 'no_proxy'
|
name = 'no_proxy'
|
||||||
if no_proxy = ENV[name] || ENV[name.upcase]
|
if no_proxy = ENV[name] || ENV[name.upcase]
|
||||||
no_proxy.scan(/([^:,]*)(?::(\d+))?/) {|host, port|
|
no_proxy.scan(/([^:,]*)(?::(\d+))?/) {|host, port|
|
||||||
@ -536,76 +604,19 @@ module URI
|
|||||||
end
|
end
|
||||||
|
|
||||||
class HTTP
|
class HTTP
|
||||||
def direct_open(buf, options) # :nodoc:
|
def buffer_open(buf, proxy, options) # :nodoc:
|
||||||
proxy_open(buf, request_uri, options)
|
OpenURI.open_http(buf, self, proxy, 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
|
|
||||||
end
|
end
|
||||||
|
|
||||||
include OpenURI::OpenRead
|
include OpenURI::OpenRead
|
||||||
end
|
end
|
||||||
|
|
||||||
class HTTPS
|
|
||||||
def proxy_open(buf, uri, options) # :nodoc:
|
|
||||||
raise ArgumentError, "open-uri doesn't support https."
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class FTP
|
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'
|
require 'net/ftp'
|
||||||
# todo: extract user/passwd from .netrc.
|
# todo: extract user/passwd from .netrc.
|
||||||
user = 'anonymous'
|
user = 'anonymous'
|
||||||
|
Loading…
x
Reference in New Issue
Block a user