スレッドを使って同時にひたすらHTTPリクエストするスクリプト……のつもりだったが、うまく動かない。
require 'net/http'
Net::HTTP.version_1_2
host = 'XXX.XXX.XXX.XXX'
port = 'XXXX'
url_prefix = '/XXXX/XXXXXXX/'
pagesfile = 'pages.txt'
alltime = 180
pages = IO.readlines(pagesfile)
threads = []
begintime = Time.now
i = 0
while i < pages.size
threads.push Thread.start {
Net::HTTP.start(host, port) {|http|
response = http.get(url_prefix + pages[i])
#puts response.code
#puts response.body
}
}
i = i + 1
sleep(alltime / pages.size)
end
threads.each { |t|
t.join
}
endtime = Time.now
print "time = ", endtime - begintime, "\n"
Debian GNU/Linux 3.1 + ruby 1.8.2 での実行結果
$ ruby -v
ruby 1.8.2 (2005-01-10) [i386-linux]
$ ruby ./attack.rb
/usr/lib/ruby/1.8/net/http.rb:1556:in `read_status_line':
wrong status line: "\211PNG" (Net::HTTPBadResponse)
from ./attack.rb:31:in `join'
from ./attack.rb:31
from ./attack.rb:30:in `each'
from ./attack.rb:30
CygwinCYGWIN_NT-5.0 1.5.10(0.116/4/2) + ruby 1.8.1 での実行結果
$ uname -a
CYGWIN_NT-5.0 1.5.10(0.116/4/2) i686 (一部略)
$ ruby ./attack.rb
/usr/lib/ruby/1.8/net/protocol.rb:83:
[BUG] Segmentation fault
ruby 1.8.1 (2003-12-25) [i386-cygwin]
Aborted (core dumped)
Windows2000(SP4) + ruby 1.8.2 での実行結果
C:\>ruby -v
ruby 1.8.2 (2005-02-01) [i386-mswin32]
C:\>ruby attack.rb
C:/ruby/lib/ruby/1.8/net/http.rb:1556:in `read_status_line':
wrong status line: "\211PNG" (Net::HTTPBadResponse)
from attack.rb:31:in `join'
from attack.rb:31
from attack.rb:30:in `each'
from attack.rb:30
コケる。スレッド数が2000件でも10件でもコケる。
アクセス先を画像PNGファイルではなくて、テキストHTMLに変更したら、
C:/ruby/lib/ruby/1.8/net/protocol.rb:197:in `sysread':
End of file reached (EOFError)
from attack.rb:33:in `join'
from attack.rb:33
from attack.rb:32:in `each'
from attack.rb:32
コケる。
例外を捕捉してみる。
i = 0
while i < pages.size
threads.push Thread.start {
Net::HTTP.start(host, port){|http|
begin
response = http.get(url_prefix + pages[i])
#puts response.code
#puts response.body
rescue => e
p e
end
}
}
i = i + 1
sleep(alltime / pages.size)
end
#<Net::HTTPBadResponse: wrong status line: "\211PNG">
Net::HTTPBadResponse ねぇ……
Net::HTTPResponse のリファレンスを見ると、Net::HTTP#get はテキストページしか取得できないようにも見える。HTTPResponse のオブジェクトを取得するだけでも、ファイルをテキストとしてパースしちゃうのか?
でも、スレッドを使わない実装を別に作って実験したらうまくいった。
スレッドかなぁ……何が悪いのかわからんけど。
参考:
tags: zlashdot Ruby Ruby
Posted by NI-Lab. (@nilab)