出于某种原因,在我的开发机器上,我对通过Net :: HTTP执行的HTTPS请求的响应非常非常慢.我尝试过RestClient和HTTParty,他们都有同样的问题.它似乎无处不在.我已经毫无问题地提出了数百次这些请求,但今天它们的速度令人难以忍受.
pry(main)> puts Time.now; HTTParty.get('https://api.easypost.com/v2/addresses'); puts Time.now;
2015-04-29 08:07:08 -0500
2015-04-29 08:09:39 -0500
Run Code Online (Sandbox Code Playgroud)
如您所见,响应耗时2.5分钟.而且不只是这个EasyPost API URL.我已经尝试过多次SSL请求到我知道可以连接的服务器(https : //google.com,https://weather.com等),它们都会导致相同的行为.此外,我注意到从HTTP重定向到HTTPS的请求也会发生同样的事情.现在,查看非ssl请求:
pry(main)> puts Time.now; HTTParty.get('http://lookitsatravis.com'); puts Time.now;
2015-04-29 08:12:22 -0500
2015-04-29 08:12:22 -0500
Run Code Online (Sandbox Code Playgroud)
瞬间.是什么赋予了?我猜这是Ruby和OpenSSL之间的某些配置问题.我重新安装了两个(使用Ruby 2.2.1和OpenSSL 1.0.2a),我正在使用OS X Yosemite 10.10.2来获取它的价值.重新安装了我的所有宝石,但问题仍然存在.我尝试更改我的DNS设置以防万一,但没有骰子.有没有其他我可以看到的或我可以改变的任何配置将解决这个问题?
我想使用GO net/http获取页面的内容长度?我可以在终端使用curl -i -X HEAD https://golang.org,然后检查内容长度字段.
红宝石版本:1.9.3
http://ruby-doc.org/stdlib-1.9.3/libdoc/net/http/rdoc/Net.html 文档指出“如果您希望在多个 HTTP 请求之间重用连接而不自动关闭它,您可以使用 ::new 而不是 ::start”
http://ruby-doc.org/stdlib-1.9.3/libdoc/net/http/rdoc/Net/HTTP.html#method-c-new 该文档指出“创建一个新的 Net::HTTP 对象而无需打开TCP 连接或 HTTP 会话。”
设想:
我的目标是尽可能重用 HTTP 和 TCP 连接。如果我使用 Net::HTTP.start 作为我的 HTTP 对象,并且如果两次连续调用之间存在显着延迟(> 2 分钟),则延迟后的第一次调用将失败并出现 EOFError : end of file connected。
所以,我打算用 Net::HTTP.new 交换 Net::HTTP.start
问题:
如果我使用 new 而不是 start,new 会重用连接吗?还是会在每次进行 HTTP 调用时尝试创建新的 HTTP 和 TCP 连接?
是否会因此而影响性能?在此类场景中,我们希望在大量流量中进行 HTTP 调用的最佳方法是什么?
在 ruby 中,我尝试使用自动签名证书与本地设置的 nginx 服务器建立 ssl 连接。我的代码是:
require "net/http"
require "net/https"
require "openssl"
require "uri"
require "pp"
request = Net::HTTP::Get.new("/")
response = Net::HTTP.start(
"localhost",
443,
{
:use_ssl => true,
:key => OpenSSL::PKey::RSA.new(File.read("/home/gg/crt/client.key")),
:cert => OpenSSL::X509::Certificate.new(File.read("/home/gg/crt/client.crt")),
:ca_file => "/home/gg/crt/ca.pem",
:verify_mode => OpenSSL::SSL::VERIFY_PEER,
:verify_depth => 5,
}
) do |http|
http.request(request)
end
puts response.inspect
puts response.body
Run Code Online (Sandbox Code Playgroud)
当我运行它时它返回
/home/gg/.rvm/rubies/ruby-2.2.1/lib/ruby/2.2.0/net/http.rb:923:in `connect': SSL_connect returned=1 errno=0 state=error: certificate verify failed (OpenSSL::SSL::SSLError)
from /home/gg/.rvm/rubies/ruby-2.2.1/lib/ruby/2.2.0/net/http.rb:923:in `block in connect'
from /home/gg/.rvm/rubies/ruby-2.2.1/lib/ruby/2.2.0/timeout.rb:74:in `timeout'
from /home/gg/.rvm/rubies/ruby-2.2.1/lib/ruby/2.2.0/net/http.rb:923:in `connect'
from /home/gg/.rvm/rubies/ruby-2.2.1/lib/ruby/2.2.0/net/http.rb:863:in `do_start'
from …Run Code Online (Sandbox Code Playgroud) 这个使用 Ajax 的 POST 请求完美地工作:
var token = "my_token";
function sendTextMessage(sender, text) {
$.post('https://graph.facebook.com/v2.6/me/messages?',
{ recipient: {id: sender},
message: {text:text},
access_token: token
},
function(returnedData){
console.log(returnedData);
});
};
sendTextMessage("100688998246663", "Hello");
Run Code Online (Sandbox Code Playgroud)
我需要有相同的请求,但在 Ruby 中。我尝试使用 Net:HTTP,但它不起作用,我没有收到任何错误,所以我无法调试它:
token = "my_token"
url = "https://graph.facebook.com/v2.6/me/messages?"
sender = 100688998246663
text = "Hello"
request = {
recipient: {id: sender},
message: {text: text},
access_token: token
}.to_json
uri = URI.parse(url)
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
request = Net::HTTP::Post.new(uri.request_uri)
response = http.request(request)
response.body
Run Code Online (Sandbox Code Playgroud)
我应该如何继续获取错误或我哪里出错了?
建立 HTTP 连接时会导致什么导致返回EBADF(错误的文件描述符)。
这是我的以下代码,其中建立了 HTTP 连接。虽然现在错误很少(发生得很少)但是在我将这些错误进行救援之前,我需要了解EBADF的原因是什么
def make_http_request(url, headers={})
uri = URI(url)
Net::HTTP.start(uri.host, uri.port) do |http|
req = Net::HTTP::Get.new(uri, headers)
resp = http.request(req)
if resp.code.to_i != 200
logger.error "Retrieve #{resp.code} with #{url} and #{headers}"
return false
end
return resp.body
end
rescue SocketError, Net::ReadTimeout, Errno::ECONNREFUSED => e
logger.error "make_http_request #{url} with #{headers} resulted in #{e.message} \n #{e.backtrace}"
return false
end
Run Code Online (Sandbox Code Playgroud)
我有一种感觉,connect syscall即收到了在该给定时间点无效的 FD。但还是无法理解怎么会这样。
如果它有帮助,该代码可用于使用多线程运行的应用程序。
简而言之,上述方法的定义是这样的……
module Eval
def make_http_request(url, headers={})
...
...
..
end
def request_local_endpoint(url, …Run Code Online (Sandbox Code Playgroud) Ruby-on-Rails,Net::HTTPResponse NoMethodError:未定义的方法“已关闭?” 对于零:NilClass
您好,我遇到了一个问题:我使用 RSpec 框架,我需要在我测试的方法中模拟响应。
这是该方法的示例:
def perform_request
response = DataClient.new.request(arg: 'some_arg')
# do some thing with the response
end
RSpec file:
describe '#perform_request'
let(:response) do
Net::HTTPResponse.new(1.0, 200, "OK")
end
let(:double_response) {double('DataClient', request: response)}
before do
response.body = {some_key:some_value}.to_json
allow(DataClient).to receive(:new).and_return(double_response)
end
it 'returns a response body' do
MyClass.new.perform_request
expect(response.body).to eq({some_key:some_value}.to_json)
end
end
Run Code Online (Sandbox Code Playgroud)
当我尝试调用 Net::HTTPResponse 实例的“body”方法来读取它的主体时,就会出现问题。
它抛出 NoMethodError 和消息“未定义的方法`关闭?' 对于 nil:NilClass" 我不知道。
我试图搜索任何带有问题变体的解释,例如“Net::HTTPResponse body undefined method closed?'', 'Ruby Net:: HTTPResponse body undefined methodclosed?”、“Ruby undefined method `closed?” 但找不到任何相关的答案。
事先,我不得不说除了没有任何包装器的 …
我注意到,当 http 请求超时时,Ruby (2.6.1) 会发出第二个请求。这会导致我们的端点之一出现问题,因为触发了第二个工作线程,从而占用了资源。
您可以在此处查看示例:转到https://beeceptor.com/console/timeout并运行以下代码
require "net/http"
http = Net::HTTP.new("timeout.free.beeceptor.com", 443)
http.read_timeout = 1
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
http.request(Net::HTTP::Get.new("/Time"))
Run Code Online (Sandbox Code Playgroud)
你可以看到有 2 个请求/Time,所以我想知道:
curl --max-time 1 https://timeout.free.beeceptor.com任何人都可以从 www.coupang.com 网站得到正确的回复吗?我不断向“ https://www.coupang.com/ ”提出请求,但 10 次中有 9 次出现错误。(有时它有效!令人惊讶。)
Traceback (most recent call last):
14: from lib/add_sup/test.rb:7:in `<main>'
13: from /Users/j/.rbenv/versions/2.5.3/lib/ruby/2.5.0/net/http.rb:485:in `get_response'
12: from /Users/j/.rbenv/versions/2.5.3/lib/ruby/2.5.0/net/http.rb:609:in `start'
11: from /Users/j/.rbenv/versions/2.5.3/lib/ruby/2.5.0/net/http.rb:910:in `start'
10: from /Users/j/.rbenv/versions/2.5.3/lib/ruby/2.5.0/net/http.rb:487:in `block in get_response'
9: from /Users/j/.rbenv/versions/2.5.3/lib/ruby/2.5.0/net/http.rb:1365:in `request_get'
8: from /Users/j/.rbenv/versions/2.5.3/lib/ruby/2.5.0/net/http.rb:1464:in `request'
7: from /Users/j/.rbenv/versions/2.5.3/lib/ruby/2.5.0/net/http.rb:1491:in `transport_request'
6: from /Users/j/.rbenv/versions/2.5.3/lib/ruby/2.5.0/net/http.rb:1491:in `catch'
5: from /Users/j/.rbenv/versions/2.5.3/lib/ruby/2.5.0/net/http.rb:1494:in `block in transport_request'
4: from /Users/j/.rbenv/versions/2.5.3/lib/ruby/2.5.0/net/http/response.rb:29:in `read_new'
3: from /Users/j/.rbenv/versions/2.5.3/lib/ruby/2.5.0/net/http/response.rb:40:in `read_status_line'
2: from /Users/j/.rbenv/versions/2.5.3/lib/ruby/2.5.0/net/protocol.rb:167:in `readline'
1: from /Users/j/.rbenv/versions/2.5.3/lib/ruby/2.5.0/net/protocol.rb:157:in `readuntil'
/Users/j/.rbenv/versions/2.5.3/lib/ruby/2.5.0/net/protocol.rb:181:in `rbuf_fill': Net::ReadTimeout (Net::ReadTimeout)
Run Code Online (Sandbox Code Playgroud)
我也尝试过使用 python3 …
调用 net::http 时是否可以在 ruby 中设置安全级别而不是修改 openssl 配置?
我发现 OpenSSL 有一种方法可以通过设置安全级别
OpenSSL::SSL::SSLContext#security_level
Run Code Online (Sandbox Code Playgroud)
但如何在新的 Net::Http 请求中使用它?
当我刚刚设置时
ctx = OpenSSL::SSL::SSLContext.new
ctx.security_level = 1
Run Code Online (Sandbox Code Playgroud)
它被http请求忽略