将curl调用转换为法拉第请求

时间:2016-04-05 18:23:03

标签: ruby-on-rails ruby proxy faraday

我有以下卷曲请求 -

`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 ...>>>

我在这里做错了什么?

2 个答案:

答案 0 :(得分:2)

转换为法拉第的最难的问题是您需要使用SOCKS5代理。法拉第不支持SOCKS代理(有open pull-request for this)。

解决这个问题的唯一方法是使用{-3}} 来修补法拉第,这会增加对Net::HTTP(默认法拉第网络适配器)的SOCKS代理的支持。 此过程在socksify gem 中得到了很好的描述,我在这里主要复制粘贴一个稍微修改过的版本。

基本上您需要按照以下步骤操作:

  1. 安装faradaysocksify宝石
  2. 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
    
  3. 创建请求。我注意到您可能正在尝试发出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
    
  4. 最后,请注意忽略对等验证(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

希望它有所帮助。