Furlでhttpsリクエストがtimeoutになる場合がある件

皆様に教えていただいています。ありがとうございます ><
4
Kazuho Oku @kazuho

@sugyan read() は複数回呼ばないと切断 (SSLの場合は切断パケット) が検知できない。でも read_timeout は read() と select() を交互に呼び出す

2011-08-23 10:56:59
Kazuho Oku @kazuho

@sugyan 結果、切断パケットが受信済だけど read() はその前のパケットのデータを返した場合、次のread_timeoutはソケットに何もデータが待機してないのでブロックする

2011-08-23 10:57:38
Kazuho Oku @kazuho

O_NONBLOCK セットしてるし、現状の select => read を read => select => read にするのが無難かな。https の場合のみそうするか、http の場合もそうすべきかは要検討だけど

2011-08-23 10:59:00
Kazuho Oku @kazuho

from performance perspective

2011-08-23 10:59:06
すぎゃーん💯 @sugyan

ぬぉ…このへんの知識が無さ過ぎる orz

2011-08-23 10:59:30
すぎゃーん💯 @sugyan

@kazuho なんとなく分かったような分からないような… ありがとうございます!! ><

2011-08-23 10:59:54
Kazuho Oku @kazuho

そのへん推奨されるやり方は IO::Socket::SSL の perldoc とかに書いてあるのかなー

2011-08-23 11:01:32
Kazuho Oku @kazuho

SSLの場合、ソケットをselectしてデータがあるからと言って、そのデータをSSLが読んだところで平文化されたデータが返ってくるとは限らないし、その逆もまた然りなので注意が必要

2011-08-23 11:03:36
FUJI Goro @__gfx__

なんでSSLのときだけ問題になるのかよくわかってない。

2011-08-23 11:06:49
Kazuho Oku @kazuho

read_timeout の sysread() 呼び出しの際に IO::Socket::SSL が SSL の data packet と close_notify を受け取って、前者の復号化されたデータを返す。次に read_timeout を呼ぶけど、何も起こらない

2011-08-23 11:11:21
Kazuho Oku @kazuho

本来は、select せずにもう1回 sysread 経由で close_notify を受け取って SSL の切断処理を行う必要がある。ok?

2011-08-23 11:11:54
Kazuho Oku @kazuho

ってことだと思います多分

2011-08-23 11:12:12
Kazuho Oku @kazuho

まあこういうケースでは read => select => read がベストプラクティスだとじっちゃんが言ってた気がする

2011-08-23 11:14:44
FUJI Goro @__gfx__

なんとなくわかった希ガス。

2011-08-23 11:15:07
すぎゃーん💯 @sugyan

原因が分かったぽい としても僕が直せるモノじゃなさそうなのでどなたかが直して下さるのを待つしかなさそう... orz

2011-08-23 11:15:25
FUJI Goro @__gfx__

ここまで答えを貰えば直せる希ガス!

2011-08-23 11:16:03
mattn @mattn_jp

read_timeoutのwhileの中にdo_select持っていけば解決するはず

2011-08-23 11:19:09
FUJI Goro @__gfx__

とりあえずFurlのSSLはこれで通るようになる。make testも通る。 http://t.co/NmNn5a5

2011-08-23 11:28:30
FUJI Goro @__gfx__

kazuho案をそのままコードに落としただけですけど///

2011-08-23 11:30:01
FUJI Goro @__gfx__

mattn案は動きませんでしたw

2011-08-23 11:30:36
FUJI Goro @__gfx__

@kazuho え!いやあとでdo_selectはしてますよ?

2011-08-23 11:32:05