class Gem::Net::HTTP::Persistent
Persistent
为 Gem::Net::HTTP
维护持久连接
Gem::Net::HTTP::Persistent
在您希望与之通信的所有服务器上维护持久连接。对于您与之通信的每个主机:端口,都会创建一个单独的持久连接。
连接将通过连接池在线程之间共享,以提高连接的重用率。
完成后,可以通过调用 shutdown
来关闭任何剩余的 HTTP 连接。
示例
require 'bundler/vendor/net-http-persistent/lib/net/http/persistent' uri = Gem::URI 'http://example.com/awesome/web/service' http = Gem::Net::HTTP::Persistent.new # perform a GET response = http.request uri # or get = Gem::Net::HTTP::Get.new uri.request_uri response = http.request get # create a POST post_uri = uri + 'create' post = Gem::Net::HTTP::Post.new post_uri.path post.set_form_data 'some' => 'cool data' # perform the POST, the Gem::URI is always required response http.request post_uri, post
请注意,对于没有主体的 GET、HEAD 和其他请求,您应该使用 Gem::URI#request_uri 而不是 Gem::URI#path。request_uri 包含查询参数,这些参数在其他请求的主体中发送。
TLS/SSL¶ ↑
TLS 连接会根据 Gem::URI
的方案自动创建。TLS 连接会自动针对计算机的默认证书存储进行验证。您可以通过更改 verify_mode
或指定备用 cert_store 来覆盖此行为。
以下是 TLS 设置,请参阅各个方法的文档
certificate
-
此客户端的证书
ca_file
-
证书颁发机构
ca_path
-
包含证书颁发机构的目录
cert_store
-
SSL 证书存储
ciphers
-
允许的 SSL 密码列表
private_key
-
客户端的 SSL 私钥
reuse_ssl_sessions
-
为新连接重用之前打开的 SSL 会话
ssl_timeout
-
会话生命周期
ssl_version
-
要使用的特定 SSL 版本
verify_callback
-
用于服务器证书验证
verify_depth
-
证书验证的深度
verify_mode
-
应如何验证连接
verify_hostname
-
在握手期间,对服务器证书使用主机名验证
代理¶ ↑
可以通过 proxy=
设置代理,也可以在初始化时通过向 ::new
提供第二个参数来设置代理。代理可以是代理服务器的 Gem::URI
,也可以是 :ENV
,它将查阅环境变量。
有关详细信息,请参见 proxy=
和 proxy_from_env
。
标头¶ ↑
可以指定标头以用于每个请求。headers
会附加到请求中的任何标头。override_headers
会替换请求中的现有标头。
两者之间的区别可以在设置 User-Agent 时看出。使用 http.headers['User-Agent'] = 'MyUserAgent'
将发送“Ruby, MyUserAgent”,而 http.override_headers['User-Agent'] = 'MyUserAgent'
将发送“MyUserAgent”。
调优¶ ↑
隔离¶ ↑
每个 Gem::Net::HTTP::Persistent
实例都有自己的连接池。与其他实例之间没有共享(早期版本是这样的)。
空闲超时¶ ↑
如果连接在此秒数内未使用,则在下次使用时会自动重置,以避免尝试发送到已关闭的连接。默认值为 5 秒。nil 表示没有超时。通过 idle_timeout
设置。
减少此值可能有助于避免在发送非幂等请求时出现“连接重置过多”错误,而增加此值将减少往返次数。
读取超时¶ ↑
允许从套接字读取两个块之间的时间量。通过 read_timeout
设置
最大请求数¶ ↑
在打开新连接之前应发出的请求数。通常,许多支持保持活动的服务器将其调整为 100 或更少,因此第 101 个请求将因 ECONNRESET 而失败。如果未设置(默认),则此值不起作用,如果设置,则连接将在 max_requests 后的请求上重置。
打开超时¶ ↑
等待打开连接的时间量。通过 open_timeout
设置。
套接字选项¶ ↑
可以在新创建的连接上设置套接字选项。有关详细信息,请参见 socket_options
。
连接终止¶ ↑
如果您已完成使用 Gem::Net::HTTP::Persistent
实例,可以使用 shutdown
关闭当前线程中的所有连接。不建议在正常使用时使用此方法,仅当您在几分钟内不会发出其他 HTTP 请求时才应使用此方法。
如果您正在使用多个线程,请在每个线程完成发出请求时调用该线程中的 shutdown
。如果您不调用 shutdown,也没关系。当线程终止时,Ruby 会自动进行垃圾回收并关闭您的 HTTP 连接。
常量
- DEFAULT_POOL_SIZE
- VERSION
您正在使用的
Gem::Net::HTTP::Persistent
版本
属性
SSL 证书颁发机构。设置此项会将 verify_mode
设置为 VERIFY_PEER。
要用作证书颁发机构的 SSL 证书目录。设置此项会将 verify_mode
设置为 VERIFY_PEER。
此客户端的 OpenSSL::X509::Certificate
SSL 证书存储。设置此项将覆盖默认证书存储。有关详细信息,请参见 verify_mode
。
此客户端的 OpenSSL::X509::Certificate
SSL 连接允许的密码
通过 Gem::Net::HTTP#set_debug_output 将 debug_output
发送到此 IO。
切勿在生产代码中使用此方法,它会导致严重的安全漏洞。
使用 Gem::Net::HTTP#add_field 添加到每个请求的标头
将 host:port 映射到 HTTP 版本。这允许我们启用特定于版本的功能。
未使用的连接在自动关闭之前可以保持空闲的最大时间。
在 Keep-Alive 标头中发送的值。默认为 30。对于 HTTP/1.1 服务器不需要。
对于 HTTP/1.0 服务器,此方法可能无法正常工作
由于 RFC 2616 不需要此标头,因此此方法可能会在未来的版本中删除。
此客户端的 SSL 私钥
在连接被视为过期并自动关闭之前,连接上的最大请求数。
如果请求失败,则执行的重试次数。
另请参见 max_retries=
,Gem::Net::HTTP#max_retries=。
要使用的最大 SSL 版本,例如::TLS1_2
默认情况下,版本将在客户端和服务器之间自动协商。仅限 Ruby 2.5 及更高版本。
要使用的最小 SSL 版本,例如::TLS1_1
默认情况下,版本将在客户端和服务器之间自动协商。仅限 Ruby 2.5 及更高版本。
此持久连接集合的名称。
不会被代理的主机后缀列表
等待连接打开的秒数。请参见 Gem::Net::HTTP#open_timeout
使用 Gem::Net::HTTP#[]= 添加到每个请求的标头
此客户端的 SSL 私钥
将通过其代理请求的 URL
等待读取一个块的秒数。请参见 Gem::Net::HTTP#read_timeout
默认情况下,SSL 会话会被重用以避免额外的 SSL 握手。如果与 HTTPS 服务器通信时遇到问题,请将其设置为 false,例如
SSL_connect [...] read finished A: unexpected message (OpenSSL::SSL::SSLError)
用于 Socket#setsockopt 的选项数组。
默认情况下,TCP_NODELAY 选项会在套接字上设置。
要设置其他选项,请将它们追加到此数组。
http.socket_options << [Socket::SOL_SOCKET, Socket::SO_KEEPALIVE, 1]
SSL 会话生命周期。
要使用的 SSL 版本。
默认情况下,版本将在客户端和服务器之间自动协商。仅适用于 Ruby 1.9 及更高版本。自 Ruby 2.5 起已弃用。
设置 SSL 证书验证的深度。
HTTPS verify_hostname。
如果客户端将其设置为 true 并使用 SSLSocket#hostname= 启用 SNI,则在握手期间,将使用 OpenSSL::SSL.verify_certificate_identity() 自动执行对服务器证书的主机名验证。
您可以将 verify_hostname
设置为 true,以便在握手期间使用主机名验证。
注意:这适用于 Ruby > 3.0。
HTTPS 验证模式。默认为 OpenSSL::SSL::VERIFY_PEER,它会验证服务器证书。
如果没有设置 ca_file
、 ca_path
或 cert_store
,则使用默认的系统证书存储。
您可以使用 verify_mode
来覆盖任何默认值。
等待写入一个数据块的秒数。请参阅 Gem::Net::HTTP#write_timeout
公共类方法
使用此方法检测 uri
处主机的空闲超时。返回的值可用于配置 idle_timeout
。max
控制要检测的最大空闲超时。
之后
空闲超时检测是通过创建一个连接,然后在循环中执行 HEAD 请求来执行的,直到连接终止,每个循环等待额外的一秒。
注意:这可能不适用于 ruby > 1.9。
# File bundler/vendor/net-http-persistent/lib/net/http/persistent.rb, line 201 def self.detect_idle_timeout uri, max = 10 uri = Gem::URI uri unless Gem::URI::Generic === uri uri += '/' req = Gem::Net::HTTP::Head.new uri.request_uri http = new 'net-http-persistent detect_idle_timeout' http.connection_for uri do |connection| sleep_time = 0 http = connection.http loop do response = http.request req $stderr.puts "HEAD #{uri} => #{response.code}" if $DEBUG unless Gem::Net::HTTPOK === response then raise Error, "bad response code #{response.code} detecting idle timeout" end break if sleep_time >= max sleep_time += 1 $stderr.puts "sleeping #{sleep_time}" if $DEBUG sleep sleep_time end end rescue # ignore StandardErrors, we've probably found the idle timeout. ensure return sleep_time unless $! end
创建一个新的 Gem::Net::HTTP::Persistent
。
设置一个 name
用于娱乐。您的库名称应该足够好,否则它没有任何用途。
proxy
可以设置为 Gem::URI::HTTP 或 :ENV,以从环境中获取代理选项。有关详细信息,请参阅 proxy_from_env
。
为了对代理使用 Gem::URI
,如果代理需要密码,您可能需要在 Gem::URI
解析之外进行一些额外的工作。
proxy = Gem::URI 'http://proxy.example' proxy.user = 'AzureDiamond' proxy.password = 'hunter2'
设置 pool_size
以限制允许的最大连接数。默认值为允许的文件句柄数的 1/4,如果您的操作系统不支持对允许的文件句柄数的限制,则为 256。您最多只能有这么多具有活动 HTTP 事务的线程。
# File bundler/vendor/net-http-persistent/lib/net/http/persistent.rb, line 490 def initialize name: nil, proxy: nil, pool_size: DEFAULT_POOL_SIZE @name = name @debug_output = nil @proxy_uri = nil @no_proxy = [] @headers = {} @override_headers = {} @http_versions = {} @keep_alive = 30 @open_timeout = nil @read_timeout = nil @write_timeout = nil @idle_timeout = 5 @max_requests = nil @max_retries = 1 @socket_options = [] @ssl_generation = 0 # incremented when SSL session variables change @socket_options << [Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1] if Socket.const_defined? :TCP_NODELAY @pool = Gem::Net::HTTP::Persistent::Pool.new size: pool_size do |http_args| Gem::Net::HTTP::Persistent::Connection.new Gem::Net::HTTP, http_args, @ssl_generation end @certificate = nil @ca_file = nil @ca_path = nil @ciphers = nil @private_key = nil @ssl_timeout = nil @ssl_version = nil @min_version = nil @max_version = nil @verify_callback = nil @verify_depth = nil @verify_mode = nil @verify_hostname = nil @cert_store = nil @generation = 0 # incremented when proxy Gem::URI changes if HAVE_OPENSSL then @verify_mode = OpenSSL::SSL::VERIFY_PEER @reuse_ssl_sessions = OpenSSL::SSL.const_defined? :Session end self.proxy = proxy if proxy end
公共实例方法
设置 SSL 证书颁发机构文件。
# File bundler/vendor/net-http-persistent/lib/net/http/persistent.rb, line 556 def ca_file= file @ca_file = file reconnect_ssl end
设置 SSL 证书颁发机构路径。
# File bundler/vendor/net-http-persistent/lib/net/http/persistent.rb, line 565 def ca_path= path @ca_path = path reconnect_ssl end
覆盖用于验证连接的默认 SSL 证书存储。
# File bundler/vendor/net-http-persistent/lib/net/http/persistent.rb, line 575 def cert_store= store @cert_store = store reconnect_ssl end
设置此客户端的 OpenSSL::X509::Certificate
# File bundler/vendor/net-http-persistent/lib/net/http/persistent.rb, line 544 def certificate= certificate @certificate = certificate reconnect_ssl end
SSL 连接允许的密码
# File bundler/vendor/net-http-persistent/lib/net/http/persistent.rb, line 584 def ciphers= ciphers @ciphers = ciphers reconnect_ssl end
为 uri
创建一个新连接。
# File bundler/vendor/net-http-persistent/lib/net/http/persistent.rb, line 593 def connection_for uri use_ssl = uri.scheme.downcase == 'https' net_http_args = [uri.hostname, uri.port] # I'm unsure if uri.host or uri.hostname should be checked against # the proxy bypass list. if @proxy_uri and not proxy_bypass? uri.host, uri.port then net_http_args.concat @proxy_args else net_http_args.concat [nil, nil, nil, nil] end connection = @pool.checkout net_http_args http = connection.http connection.ressl @ssl_generation if connection.ssl_generation != @ssl_generation if not http.started? then ssl http if use_ssl start http elsif expired? connection then reset connection end http.keep_alive_timeout = @idle_timeout if @idle_timeout http.max_retries = @max_retries if http.respond_to?(:max_retries=) http.read_timeout = @read_timeout if @read_timeout http.write_timeout = @write_timeout if @write_timeout && http.respond_to?(:write_timeout=) return yield connection rescue Errno::ECONNREFUSED if http.proxy? address = http.proxy_address port = http.proxy_port else address = http.address port = http.port end raise Error, "connection refused: #{address}:#{port}" rescue Errno::EHOSTDOWN if http.proxy? address = http.proxy_address port = http.proxy_port else address = http.address port = http.port end raise Error, "host down: #{address}:#{port}" ensure @pool.checkin net_http_args end
CGI::escape 包装器。
# File bundler/vendor/net-http-persistent/lib/net/http/persistent.rb, line 654 def escape str CGI.escape str if str end
如果连接由于空闲超时或最大请求计数而应该被重置,则返回 true,否则返回 false。
# File bundler/vendor/net-http-persistent/lib/net/http/persistent.rb, line 670 def expired? connection return true if @max_requests && connection.requests >= @max_requests return false unless @idle_timeout return true if @idle_timeout.zero? Time.now - connection.last_use > @idle_timeout end
完成 Gem::Net::HTTP
connection
。
# File bundler/vendor/net-http-persistent/lib/net/http/persistent.rb, line 699 def finish connection connection.finish connection.http.instance_variable_set :@last_communicated, nil connection.http.instance_variable_set :@ssl_session, nil unless @reuse_ssl_sessions end
返回 uri
的 HTTP 协议版本。
# File bundler/vendor/net-http-persistent/lib/net/http/persistent.rb, line 710 def http_version uri @http_versions["#{uri.hostname}:#{uri.port}"] end
设置一个请求的最大重试次数。
默认为一次重试。
将其设置为 0 可禁用重试。
# File bundler/vendor/net-http-persistent/lib/net/http/persistent.rb, line 728 def max_retries= retries retries = retries.to_int raise ArgumentError, "max_retries must be positive" if retries < 0 @max_retries = retries reconnect end
要使用的最大 SSL 版本。
# File bundler/vendor/net-http-persistent/lib/net/http/persistent.rb, line 1063 def max_version= max_version @max_version = max_version reconnect_ssl end
要使用的最小 SSL 版本。
# File bundler/vendor/net-http-persistent/lib/net/http/persistent.rb, line 1054 def min_version= min_version @min_version = min_version reconnect_ssl end
如果字符串 uri
缺少“http://”,则添加“http://”。
# File bundler/vendor/net-http-persistent/lib/net/http/persistent.rb, line 717 def normalize_uri uri (uri =~ /^https?:/) ? uri : "http://#{uri}" end
设置此客户端的 SSL 私钥。
# File bundler/vendor/net-http-persistent/lib/net/http/persistent.rb, line 741 def private_key= key @private_key = key reconnect_ssl end
设置代理服务器。proxy
可以是代理服务器的 Gem::URI
,符号 :ENV
将从环境中读取代理,或者为 nil 以禁用代理的使用。有关从环境中设置代理的详细信息,请参阅 proxy_from_env
。
如果在发出请求后设置了代理 Gem::URI
,则下一个请求将关闭并重新打开所有连接。
no_proxy
查询参数可用于指定不应通过代理访问的主机;如果设置,它应该是一个以逗号分隔的主机名后缀列表,可以选择附加 :port
,例如 example.com,some.host:8080
。
# File bundler/vendor/net-http-persistent/lib/net/http/persistent.rb, line 764 def proxy= proxy @proxy_uri = case proxy when :ENV then proxy_from_env when Gem::URI::HTTP then proxy when nil then # ignore else raise ArgumentError, 'proxy must be :ENV or a Gem::URI::HTTP' end @no_proxy.clear if @proxy_uri then @proxy_args = [ @proxy_uri.hostname, @proxy_uri.port, unescape(@proxy_uri.user), unescape(@proxy_uri.password), ] @proxy_connection_id = [nil, *@proxy_args].join ':' if @proxy_uri.query then @no_proxy = CGI.parse(@proxy_uri.query)['no_proxy'].join(',').downcase.split(',').map { |x| x.strip }.reject { |x| x.empty? } end end reconnect reconnect_ssl end
当应该绕过主机代理时返回 true。
# File bundler/vendor/net-http-persistent/lib/net/http/persistent.rb, line 838 def proxy_bypass? host, port host = host.downcase host_port = [host, port].join ':' @no_proxy.each do |name| return true if host[-name.length, name.length] == name or host_port[-name.length, name.length] == name end false end
从 ENV 变量为 HTTP 代理服务器创建 Gem::URI
。
如果设置了 HTTP_PROXY
,将返回一个代理。
如果设置了 HTTP_PROXY_USER
或 HTTP_PROXY_PASS
,则除非 HTTP_PROXY 在 Gem::URI
中包含这两者中的任何一个,否则会为 Gem::URI
提供指示的用户和密码。
可以使用 NO_PROXY
ENV 变量指定不应通过代理访问的主机;如果设置,它应该是一个以逗号分隔的主机名后缀列表,可以选择附加 :port
,例如 example.com,some.host:8080
。当设置为 *
时,不会返回任何代理。
对于 Windows 用户,小写 ENV 变量优先于大写 ENV 变量。
# File bundler/vendor/net-http-persistent/lib/net/http/persistent.rb, line 811 def proxy_from_env env_proxy = ENV['http_proxy'] || ENV['HTTP_PROXY'] return nil if env_proxy.nil? or env_proxy.empty? uri = Gem::URI normalize_uri env_proxy env_no_proxy = ENV['no_proxy'] || ENV['NO_PROXY'] # '*' is special case for always bypass return nil if env_no_proxy == '*' if env_no_proxy then uri.query = "no_proxy=#{escape(env_no_proxy)}" end unless uri.user or uri.password then uri.user = escape ENV['http_proxy_user'] || ENV['HTTP_PROXY_USER'] uri.password = escape ENV['http_proxy_pass'] || ENV['HTTP_PROXY_PASS'] end uri end
强制重新连接所有 HTTP 连接,包括 TLS/SSL 连接。
# File bundler/vendor/net-http-persistent/lib/net/http/persistent.rb, line 854 def reconnect @generation += 1 end
强制仅重新连接 TLS/SSL 连接。
# File bundler/vendor/net-http-persistent/lib/net/http/persistent.rb, line 861 def reconnect_ssl @ssl_generation += 1 end
在 uri
上发出请求。如果 req
为 nil,则针对 uri
执行 Gem::Net::HTTP::Get。
如果传递了一个块,则 request
的行为类似于 Gem::Net::HTTP#request(响应的主体将不会被读取)。
req
必须是 Gem::Net::HTTPGenericRequest 子类(请参阅 Gem::Net::HTTP
以获取列表)。
# File bundler/vendor/net-http-persistent/lib/net/http/persistent.rb, line 893 def request uri, req = nil, &block uri = Gem::URI uri req = request_setup req || uri response = nil connection_for uri do |connection| http = connection.http begin connection.requests += 1 response = http.request req, &block if req.connection_close? or (response.http_version <= '1.0' and not response.connection_keep_alive?) or response.connection_close? then finish connection end rescue Exception # make sure to close the connection when it was interrupted finish connection raise ensure connection.last_use = Time.now end end @http_versions["#{uri.hostname}:#{uri.port}"] ||= response.http_version response end
完成然后重新启动 Gem::Net::HTTP
connection
。
# File bundler/vendor/net-http-persistent/lib/net/http/persistent.rb, line 868 def reset connection http = connection.http finish connection start http rescue Errno::ECONNREFUSED e = Error.new "connection refused: #{http.address}:#{http.port}" e.set_backtrace $@ raise e rescue Errno::EHOSTDOWN e = Error.new "host down: #{http.address}:#{http.port}" e.set_backtrace $@ raise e end
关闭所有连接。
注意:调用 shutdown 可能会很危险!
如果任何线程仍在使用连接,则可能会导致错误!当您完全完成发出请求时,请调用 shutdown
!
# File bundler/vendor/net-http-persistent/lib/net/http/persistent.rb, line 963 def shutdown @pool.shutdown { |http| http.finish } end
在 connection
上启用 SSL。
# File bundler/vendor/net-http-persistent/lib/net/http/persistent.rb, line 970 def ssl connection connection.use_ssl = true connection.ciphers = @ciphers if @ciphers connection.ssl_timeout = @ssl_timeout if @ssl_timeout connection.ssl_version = @ssl_version if @ssl_version connection.min_version = @min_version if @min_version connection.max_version = @max_version if @max_version connection.verify_depth = @verify_depth connection.verify_mode = @verify_mode connection.verify_hostname = @verify_hostname if @verify_hostname != nil && connection.respond_to?(:verify_hostname=) if OpenSSL::SSL::VERIFY_PEER == OpenSSL::SSL::VERIFY_NONE and not Object.const_defined?(:I_KNOW_THAT_OPENSSL_VERIFY_PEER_EQUALS_VERIFY_NONE_IS_WRONG) then warn <<-WARNING !!!SECURITY WARNING!!! The SSL HTTP connection to: #{connection.address}:#{connection.port} !!!MAY NOT BE VERIFIED!!! On your platform your OpenSSL implementation is broken. There is no difference between the values of VERIFY_NONE and VERIFY_PEER. This means that attempting to verify the security of SSL connections may not work. This exposes you to man-in-the-middle exploits, snooping on the contents of your connection and other dangers to the security of your data. To disable this warning define the following constant at top-level in your application: I_KNOW_THAT_OPENSSL_VERIFY_PEER_EQUALS_VERIFY_NONE_IS_WRONG = nil WARNING end connection.ca_file = @ca_file if @ca_file connection.ca_path = @ca_path if @ca_path if @ca_file or @ca_path then connection.verify_mode = OpenSSL::SSL::VERIFY_PEER connection.verify_callback = @verify_callback if @verify_callback end if @certificate and @private_key then connection.cert = @certificate connection.key = @private_key end connection.cert_store = if @cert_store then @cert_store else store = OpenSSL::X509::Store.new store.set_default_paths store end end
SSL 会话生命周期。
# File bundler/vendor/net-http-persistent/lib/net/http/persistent.rb, line 1036 def ssl_timeout= ssl_timeout @ssl_timeout = ssl_timeout reconnect_ssl end
要使用的 SSL 版本。
# File bundler/vendor/net-http-persistent/lib/net/http/persistent.rb, line 1045 def ssl_version= ssl_version @ssl_version = ssl_version reconnect_ssl end
启动 Gem::Net::HTTP
connection
。
# File bundler/vendor/net-http-persistent/lib/net/http/persistent.rb, line 681 def start http http.set_debug_output @debug_output if @debug_output http.open_timeout = @open_timeout if @open_timeout http.start socket = http.instance_variable_get :@socket if socket then # for fakeweb @socket_options.each do |option| socket.io.setsockopt(*option) end end end
CGI::unescape 包装器。
# File bundler/vendor/net-http-persistent/lib/net/http/persistent.rb, line 661 def unescape str CGI.unescape str if str end
SSL 验证回调。
# File bundler/vendor/net-http-persistent/lib/net/http/persistent.rb, line 1103 def verify_callback= callback @verify_callback = callback reconnect_ssl end
设置 SSL 证书验证的深度。
# File bundler/vendor/net-http-persistent/lib/net/http/persistent.rb, line 1072 def verify_depth= verify_depth @verify_depth = verify_depth reconnect_ssl end
设置 HTTPS verify_hostname。
# File bundler/vendor/net-http-persistent/lib/net/http/persistent.rb, line 1094 def verify_hostname= verify_hostname @verify_hostname = verify_hostname reconnect_ssl end
设置 HTTPS 验证模式。默认为 OpenSSL::SSL::VERIFY_PEER。
将此项设置为 VERIFY_NONE 是一个非常糟糕的主意,绝对不应该使用。请安全地传输正确的证书并更新默认证书存储,或者设置 ca 文件来代替。
# File bundler/vendor/net-http-persistent/lib/net/http/persistent.rb, line 1085 def verify_mode= verify_mode @verify_mode = verify_mode reconnect_ssl end