在使用apache+passenger时无法使用代理

在使用gems中的httpclient的Rails应用中,当我修改了启动服务器应用后,发现Rails应用无法向代理发送请求而陷入困境,所以做了以下备忘录。

症状表现

前提

環境変数のhttp_proxyに、リクエストを流したいproxyを設定しておく

thinでrailsアプリを起動

その中でhttpclientを叩くとproxyへリクエストを流してくれる

apache+passengerでrailsアプリを起動

その中でhttpclientを叩くとproxyへリクエストを流してくれない

以下是在日志中留下的讯息

SocketError : getaddrinfo: No address associated with hostname
gems/httpclient-2.3.4.1/lib/httpclient/session.rb:803:in `initialize'
gems/httpclient-2.3.4.1/lib/httpclient/session.rb:803:in `new'
gems/httpclient-2.3.4.1/lib/httpclient/session.rb:803:in `create_socket'
gems/httpclient-2.3.4.1/lib/httpclient/session.rb:752:in `block in connect'

没有通过代理的原因。

    • 該当コード付近

gems/httpclient-2.3.4.1/lib/httpclient/session.rb:856

    def create_socket(site)
      socket = nil
      begin
        @debug_dev << "! CONNECT TO #{site.host}:#{site.port}\n" if @debug_dev
        if str = @test_loopback_http_response.shift
          socket = LoopBackSocket.new(site.host, site.port, str)
        elsif @socket_local == Site::EMPTY
          socket = TCPSocket.new(site.host, site.port)

在TCPSocket.new的地方似乎出现了错误。让我们再往前追溯一下。

    gems/httpclient-2.3.4.1/lib/httpclient/session.rb:747
    # Connect to the server
    def connect
      site = @proxy || @dest
      retry_number = 0
      begin
        timeout(@connect_timeout, ConnectTimeoutError) do
          @socket = create_socket(site)

看起来这个@proxy变成了nil,没有按照意图进行设置。
我会找到设置@proxy的位置。

    gems/httpclient-2.3.4.1/lib/httpclient.rb:1156
  def load_environment
    # http_proxy
    if getenv('REQUEST_METHOD')
      # HTTP_PROXY conflicts with the environment variable usage in CGI where
      # HTTP_* is used for HTTP header information.  Unlike open-uri, we
      # simply ignore http_proxy in CGI env and use cgi_http_proxy instead.
      self.proxy = getenv('cgi_http_proxy')
    else
      self.proxy = getenv('http_proxy')
    end
    # no_proxy
    self.no_proxy = getenv('no_proxy')
  end

在这里似乎进行设置。
在这种情况下,似乎已经变成了以下这样。

    • apache+passengerの場合

今回はgetenv(‘REQUEST_METHOD’)に’GET’が入る
cgi_http_proxyという環境変数は設定していないので、self.proxy = nilとなり、結果proxyには流れない

thinの場合

getenv(‘REQUEST_METHOD’)がnilなので、getenv(‘http_proy’)が読まれる

根据代码注释来看,似乎是为了避免冲突。
因此,我们会设定环境变量。

    /etc/httpd/conf.d/myenv.conf
  SetEnv CGI_HTTP_PROXY http://proxy.example.com:8080

我已经重新启动了Apache,并确认它已按照预期进行处理。

总结

    • railsからhttpclientをproxy経由で使いたい場合は、cgi_http_proxyを使いましょう。

 

    使おうとしているライブラリはちゃんと読めって事ですね。

在不需要的地方卡住了呢〜(=w=;
這真的是太專門了,只有自己需要的備忘錄呢…w

广告
将在 10 秒后关闭
bannerAds