2011年10月14日

[ruby-list:48467] net/https のproxy経由接続シーケンスについて

春日と申します。

Windows/MinGW で、
ruby 1.9.2p290 (2011-07-09) [i386-mingw32]
を使用しております。
----
require 'net/https'

Net::HTTP.version_1_2

http = Net::HTTP::Proxy("proxy.example.com", 8080).new('www.google.co
m', 443)

http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
http.start {|w|
response = w.get('/')
puts response.body
}
----
と言うようなコードで、proxy 経由のhttps接続を試みますと、うまく接続で
きない場合があります。

というのも、
net/http.rb のL.664辺りが、
----
if use_ssl?
begin
if proxy?
@socket.writeline sprintf('CONNECT %s:%s HTTP/%s',
@address, @port, HTTPVersion)
@socket.writeline "Host: #{@address}:#{@port}"
if proxy_user
credential = ["#{proxy_user}:#{proxy_pass}"].pack('m')
credential.delete!("\r\n")
@socket.writeline "Proxy-Authorization: Basic #{creden
tial}"
end
@socket.writeline ''
HTTPResponse.read_new(@socket).value
end
----
となっており、
@socket.writeline sprintf('CONNECT %s:%s HTTP/%s',
@address, @port, HTTPVersion)
のが実行された結果、
CONNECT ...
を含む行が、先行してtcp reassembled pduとして送信されます。
# その後、Host を含む行が、続きのパケットとして送信されます。

この先行のtcp reassembled pduパケットが、あるfirewallソフトだと黙って
廃棄されてしまい、クライアントとしてはACKを待つので、接続がタイムアウ
トしてしまいます。
# このfirewallが、この小さいtcp reassembled pduを黙って廃棄している理
由はわかりませんでした。

もちろん、このfirewallソフトを無効化すれば接続シーケンスは無事完了し
ます。

また、
@socket.writeline "Host: #{@address}:#{@port}"
をコメントアウトすると、CONNECTを含む行は、tcp reassembled pdu ではな
く、単一のパケットとして送信され、接続シーケンスは無事完了します。

net/http.rb の実装は、何となく、CONNECTとHostを1つのパケットとして送
ることを想定しているように思いますが、私が検証したように、tcp reassem
bled pdu で送信されることは想定した動作なのでしょうか?

# もしかして、openssl側の問題かも知れませんが…

-----------------------------------------
春日 玄 (KASUGA Toru)
E-mail : kasuga.toru@xxxxx

投稿者 xml-rpc : 2011年10月14日 11:30
役に立ちました?:
過去のフィードバック 平均:(0) 総合:(0) 投票回数:(0)
本記事へのTrackback: http://hoop.euqset.org/blog/mt-tb2006.cgi/106853
トラックバック
コメント
コメントする




画像の中に見える文字を入力してください。