我有以下卷曲请求 -
`curl --socks5 #{proxy} --connect-timeout 10 -H "Accept: application/json" #{url}`
我想写一个法拉第请求而不是卷曲调用。我这样做 -
faraday = Faraday.new("#{url}", ssl:{verify: false} do |f|
f.proxy "#{proxy}"
end
faraday.get
我收到了回复,但回复没有正文或标题。以下是回复 -
#<Faraday::Response:0x0056075d353ad0 @on_complete_callbacks=[], @env=#<Faraday::Env @method=:get @url=#<URI::HTTP:0x0056075d358328 URL:main_url> @request=#<Faraday::RequestOptions proxy=#<Faraday::ProxyOptions uri=#<URI::HTTP:0x0056075dce69d0 URL:proxy_url>>> @request_headers={"User-Agent"=>"Faraday v0.9.2"} @ssl=#<Faraday::SSLOptions (empty)> @response=#<Faraday::Response:0x0056075d353ad0 ...>>>
我在这里做错了什么?
答案 0 :(得分:2)
转换为法拉第的最难的问题是您需要使用SOCKS5代理。法拉第不支持SOCKS代理(有open pull-request for this)。
解决这个问题的唯一方法是使用{-3}} 来修补法拉第,这会增加对Net::HTTP
(默认法拉第网络适配器)的SOCKS代理的支持。 此过程在socksify
gem 中得到了很好的描述,我在这里主要复制粘贴一个稍微修改过的版本。
基本上您需要按照以下步骤操作:
faraday
和socksify
宝石 Monkey-patch Faraday支持SOCKS。将此代码放入Rails初始化程序中。请注意,只有在您不需要对SOCKS代理进行身份验证时,该修补程序才适用(如curl
命令所示)。如果您需要代理身份验证,请参阅要点的补丁版本的要点。补丁如下:
class Faraday::Adapter::NetHttp
def net_http_connection(env)
if proxy = env[:request][:proxy]
if proxy[:socks]
Net::HTTP::SOCKSProxy(proxy[:uri].host, proxy[:uri].port)
else
Net::HTTP::Proxy(proxy[:uri].host, proxy[:uri].port, proxy[:uri].user, proxy[:uri].password)
end
else
Net::HTTP
end.new(env[:url].host, env[:url].port)
end
end
创建请求。我注意到您可能正在尝试发出HTTPS请求,因此我考虑了这一点,以及curl
参数中的超时:
PROXY_OPTS = {
uri: URI.parse('https://proxy_url:1080'),
socks: true
}
SSL_OPTS = { verify: false }
connection = Faraday.new(url: "https://example.com",
ssl: SSL_OPTS,
request: { proxy: PROXY_OPTS }) do |faraday|
faraday.options.timeout = 10 # open/read timeout in seconds
faraday.options.open_timeout = 10 # connection open timeout in seconds
faraday.response :logger # log debug info
faraday.adapter :net_http # use the Net:HTTP adapter
faraday.headers['Accept'] = 'application/json' # your custom headers
end
response = connection.get
response.body
最后,请注意忽略对等验证(SSL选项中的verify: false
)是不安全的!您应该正确配置法拉第使用证书存储来验证对等证书。这完整记录了this gist。
答案 1 :(得分:0)
这就是我使用法拉第来获取从Microsoft Exchange API获取访问令牌的帖子请求的方法。
url = "https://login.microsoftonline.com/#{ENV['TENANT']}/oauth2/token"
conn = Faraday.new url: url do |faraday|
faraday.request :url_encoded # form-encode POST params
faraday.response :logger # log requests to STDOUT
faraday.adapter Faraday.default_adapter # make requests with Net::HTTP
end
response = conn.post do |req|
req.headers['Content-Type'] = 'application/x-www-form-urlencoded'
req.body = {
client_id: URI::encode(ENV['CLIENT_ID']),
client_secret: URI::encode(ENV['CLIENT_SECRET']),
resource: URI::encode('https://graph.microsoft.com'),
grant_type: URI::encode('client_credentials'),
}
Rails.logger.info "Body #{req.body.inspect}"
end
if response.status.to_i == 200
response_body = ActiveSupport::JSON.decode(response.body)
return response_body['access_token']
else
return false
end
希望它有所帮助。