在使用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