1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
|
require_relative "utils"
require "webrick"
require "test/unit"
class TestWEBrickCGI < Test::Unit::TestCase
CRLF = "\r\n"
def start_cgi_server(&block)
config = {
:CGIInterpreter => TestWEBrick::RubyBin,
:DocumentRoot => File.dirname(__FILE__),
:DirectoryIndex => ["webrick.cgi"],
:RequestCallback => Proc.new{|req, res|
def req.meta_vars
meta = super
meta["RUBYLIB"] = $:.join(File::PATH_SEPARATOR)
meta[RbConfig::CONFIG['LIBPATHENV']] = ENV[RbConfig::CONFIG['LIBPATHENV']] if RbConfig::CONFIG['LIBPATHENV']
return meta
end
},
}
if RUBY_PLATFORM =~ /mswin32|mingw|cygwin|bccwin32/
config[:CGIPathEnv] = ENV['PATH'] # runtime dll may not be in system dir.
end
TestWEBrick.start_httpserver(config){|server, addr, port, log|
block.call(server, addr, port, log)
}
end
def test_cgi
start_cgi_server{|server, addr, port, log|
http = Net::HTTP.new(addr, port)
req = Net::HTTP::Get.new("/webrick.cgi")
http.request(req){|res| assert_equal("/webrick.cgi", res.body, log.call)}
req = Net::HTTP::Get.new("/webrick.cgi/path/info")
http.request(req){|res| assert_equal("/path/info", res.body, log.call)}
req = Net::HTTP::Get.new("/webrick.cgi/%3F%3F%3F?foo=bar")
http.request(req){|res| assert_equal("/???", res.body, log.call)}
req = Net::HTTP::Get.new("/webrick.cgi/%A4%DB%A4%B2/%A4%DB%A4%B2")
http.request(req){|res|
assert_equal("/\xA4\xDB\xA4\xB2/\xA4\xDB\xA4\xB2", res.body, log.call)}
req = Net::HTTP::Get.new("/webrick.cgi?a=1;a=2;b=x")
http.request(req){|res| assert_equal("a=1, a=2, b=x", res.body, log.call)}
req = Net::HTTP::Get.new("/webrick.cgi?a=1&a=2&b=x")
http.request(req){|res| assert_equal("a=1, a=2, b=x", res.body, log.call)}
req = Net::HTTP::Post.new("/webrick.cgi?a=x;a=y;b=1")
req["Content-Type"] = "application/x-www-form-urlencoded"
http.request(req, "a=1;a=2;b=x"){|res|
assert_equal("a=1, a=2, b=x", res.body, log.call)}
req = Net::HTTP::Post.new("/webrick.cgi?a=x&a=y&b=1")
req["Content-Type"] = "application/x-www-form-urlencoded"
http.request(req, "a=1&a=2&b=x"){|res|
assert_equal("a=1, a=2, b=x", res.body, log.call)}
req = Net::HTTP::Get.new("/")
http.request(req){|res|
ary = res.body.lines.to_a
assert_match(%r{/$}, ary[0], log.call)
assert_match(%r{/webrick.cgi$}, ary[1], log.call)
}
req = Net::HTTP::Get.new("/webrick.cgi")
req["Cookie"] = "CUSTOMER=WILE_E_COYOTE; PART_NUMBER=ROCKET_LAUNCHER_0001"
http.request(req){|res|
assert_equal(
"CUSTOMER=WILE_E_COYOTE\nPART_NUMBER=ROCKET_LAUNCHER_0001\n",
res.body, log.call)
}
req = Net::HTTP::Get.new("/webrick.cgi")
cookie = %{$Version="1"; }
cookie << %{Customer="WILE_E_COYOTE"; $Path="/acme"; }
cookie << %{Part_Number="Rocket_Launcher_0001"; $Path="/acme"; }
cookie << %{Shipping="FedEx"; $Path="/acme"}
req["Cookie"] = cookie
http.request(req){|res|
assert_equal("Customer=WILE_E_COYOTE, Shipping=FedEx",
res["Set-Cookie"], log.call)
assert_equal("Customer=WILE_E_COYOTE\n" +
"Part_Number=Rocket_Launcher_0001\n" +
"Shipping=FedEx\n", res.body, log.call)
}
}
end
def test_bad_request
start_cgi_server{|server, addr, port, log|
sock = TCPSocket.new(addr, port)
begin
sock << "POST /webrick.cgi HTTP/1.0" << CRLF
sock << "Content-Type: application/x-www-form-urlencoded" << CRLF
sock << "Content-Length: 1024" << CRLF
sock << CRLF
sock << "a=1&a=2&b=x"
sock.close_write
assert_match(%r{\AHTTP/\d.\d 400 Bad Request}, sock.read, log.call)
ensure
sock.close
end
}
end
CtrlSeq = [0x7f, *(1..31)].pack("C*").gsub(/\s+/, '')
CtrlPat = /#{Regexp.quote(CtrlSeq)}/o
DumpPat = /#{Regexp.quote(CtrlSeq.dump[1...-1])}/o
def test_bad_uri
start_cgi_server{|server, addr, port, log|
res = TCPSocket.open(addr, port) {|sock|
sock << "GET /#{CtrlSeq}#{CRLF}#{CRLF}"
sock.close_write
sock.read
}
assert_match(%r{\AHTTP/\d.\d 400 Bad Request}, res)
s = log.call.each_line.grep(/ERROR bad URI/)[0]
assert_match(DumpPat, s)
assert_not_match(CtrlPat, s)
}
end
def test_bad_header
start_cgi_server{|server, addr, port, log|
res = TCPSocket.open(addr, port) {|sock|
sock << "GET / HTTP/1.0#{CRLF}#{CtrlSeq}#{CRLF}#{CRLF}"
sock.close_write
sock.read
}
assert_match(%r{\AHTTP/\d.\d 400 Bad Request}, res)
s = log.call.each_line.grep(/ERROR bad header/)[0]
assert_match(DumpPat, s)
assert_not_match(CtrlPat, s)
}
end
end
|