【问题标题】:converting a curl call to a faraday request将 curl 调用转换为法拉第请求
【发布时间】:2016-04-05 18:23:02
【问题描述】:

我有以下 curl 请求 -

`curl --socks5 #{proxy} --connect-timeout 10 -H "Accept: application/json" #{url}`

我想写一个法拉第请求而不是 curl 调用。我正在这样做 -

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

我在这里做错了什么?

【问题讨论】:

    标签: ruby-on-rails ruby proxy faraday


    【解决方案1】:

    转换到 Faraday 最困难的问题是您需要使用 SOCKS5 代理。 Faraday 不支持 SOCKS 代理(有一个open pull-request for this)。

    解决此问题的唯一方法是对 Faraday 进行猴子修补以使用 socksify gem,它将对 SOCKS 代理的支持添加到 Net::HTTP(默认的 Faraday 网络适配器)。 该过程在this gist 中有很好的描述,我主要是在此处复制粘贴稍作改动的版本。

    基本上你需要遵循以下步骤:

    1. 安装 faradaysocksify gems
    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
      

    最后,请注意忽略对等验证(SSL 选项中的verify: false)是不安全的!相反,您应该正确配置 Faraday 以使用证书存储来验证对等证书。这是完整记录的here

    【讨论】:

      【解决方案2】:

      这就是我如何使用法拉第发送请求以从 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
      

      希望对你有帮助。

      【讨论】:

      • 感谢这帮助我解决了一个不相关的问题。赞成。
      猜你喜欢
      • 2016-08-24
      • 2017-08-03
      • 1970-01-01
      • 2018-04-16
      • 2021-02-06
      • 2017-01-13
      • 1970-01-01
      • 1970-01-01
      • 2021-03-03
      相关资源
      最近更新 更多