In message <20040128.180721.607957648.gotoyuzo@sawara.does.notwork.org>,
`GOTOU Yuuzou <gotoyuzo@notwork.org>' wrote:
> In message <20040128153311FTWK%y@hoppeta.com>,
> `"Kawaji, Shinya" <kawaji@hoppeta.com>' wrote:
> > 以下の patch は簡便のために ServerAlias は String か Regexp ということに
> > していますので、Apache の場合とは違います(Array も使えない)。
>
> かならずArrayということでいいんじゃないでしょうか。
>
> (server[:ServerAlias].nil? || server[:ServerAlias].find{|h| h === req.host })
>
> とか。StringもEnumerableなので偶然動きますけど。
10日ほど前に1.9に追加したのですが、:ServerAliasがnilの時に一
致させるのはよくなかったようなので、次のような修正を考えてみ
ました。
diff -u -p -F^[^A-Za-z0-9_+-]*\(class\|module\|def\)[^A-Za-z0-9_+-] -2 -r1.7 httpserver.rb
--- lib/webrick/httpserver.rb 7 Mar 2004 16:06:42 -0000 1.7
+++ lib/webrick/httpserver.rb 19 Mar 2004 08:26:56 -0000
@@ -136,10 +136,16 @@ def virtual_host(server)
def lookup_server(req)
- @virtual_hosts.find{|s|
+ servers = @virtual_hosts.select{|s|
(s[:Port].nil? || req.port == s[:Port]) &&
(s[:BindAddress].nil? || req.addr[3] == s[:BindAddress]) &&
((s[:ServerName].nil? || req.host == s[:ServerName]) ||
- (s[:ServerAlias].nil? || s[:ServerAlias].find{|h| h === req.host}))
+ (!s[:ServerAlias].nil? && s[:ServerAlias].find{|h| h === req.host}))
}
+ if (len = servers.length) > 1
+ args = [len, req.host, req.addr[3], req.port]
+ msg = "ambiguous virtual hosts (matches %d hosts for %s@%s:%d)" % args
+ @logger.warn(msg)
+ end
+ return servers[0]
end
で、ついでによく考えてみると(エイリアスとは関係ないのですが)、
* :BindAddressの指定ありで:Portはnil
* :BindAddressはnilで:Portの指定あり
というホストが同時に存在する場合に、どちらに一致するか曖昧な
なんですね。現状ではvirtual_hostで先に追加したほうに一致する
のですが、どちらかを優先するべきなんでしょうか。
# 簡単にテストを書いてみたので付けておきます。
--
ごとうゆうぞう
require "test/unit"
require "webrick"
module WEBrick
class TestHTTPServer < Test::Unit::TestCase
def assert_eql?(v1, v2)
assert_equal(v1.object_id, v2.object_id)
end
NullWriter = Object.new
def NullWriter.write(msg) return msg.size end
def NullWriter.<<(msg) return self end
def httpd(addr, port, host, ali)
hash = {:DoNotListen => true}
hash[:BindAddress] = addr
hash[:Port] = port
hash[:ServerName] = host
hash[:ServerAlias] = ali
WEBrick::HTTPServer.new(hash)
end
def shuffle(ary)
ary.each_index{|i|
j = rand(ary.length)
ary[i], ary[j] = ary[j], ary[i]
}
end
class Req
attr_reader :port, :host
def initialize(addr, port, host)
@addr, @port, @host = addr, port, host
end
def addr
[0,0,0,@addr]
end
end
def test_lookup_server
addr1 = "192.168.100.1"
addr2 = "192.168.100.2"
addrz = "192.168.100.254"
local = "127.0.0.1"
port1 = 80
port2 = 8080
port3 = 10080
portz = 32767
name1 = "www.example.com"
name2 = "www2.example.com"
name3 = "www3.example.com"
namea = "www.example.co.jp"
nameb = "www.example.jp"
namec = "www2.example.co.jp"
named = "www2.example.jp"
namez = "foobar.example.com"
alias1 = [namea, nameb]
alias2 = [namec, named]
stderr = $stderr
$stderr = NullWriter
host1 = httpd(nil, port1, name1, nil)
hosts = [
host2 = httpd(addr1, port1, name1, nil),
host3 = httpd(addr1, port1, name2, alias1),
host4 = httpd(addr1, port2, name1, nil),
host5 = httpd(addr1, port2, name2, alias1),
host6 = httpd(addr1, port2, name3, alias2),
host7 = httpd(addr2, nil, name1, nil),
host8 = httpd(addr2, nil, name2, alias1),
host9 = httpd(addr2, nil, name3, alias2),
host10 = httpd(local, nil, nil, nil),
host11 = httpd(nil, port3, nil, nil),
]
#shuffle(hosts)
#p hosts.collect{|h| h.object_id }
hosts.each{|h| host1.virtual_host(h) }
$stderr = stderr
# connect to addr1
assert_eql?(host2, host1.lookup_server(Req.new(addr1, port1, name1)))
assert_eql?(host3, host1.lookup_server(Req.new(addr1, port1, name2)))
assert_eql?(host3, host1.lookup_server(Req.new(addr1, port1, namea)))
assert_eql?(host3, host1.lookup_server(Req.new(addr1, port1, nameb)))
assert_eql?(nil, host1.lookup_server(Req.new(addr1, port1, namez)))
assert_eql?(host4, host1.lookup_server(Req.new(addr1, port2, name1)))
assert_eql?(host5, host1.lookup_server(Req.new(addr1, port2, name2)))
assert_eql?(host5, host1.lookup_server(Req.new(addr1, port2, namea)))
assert_eql?(host5, host1.lookup_server(Req.new(addr1, port2, nameb)))
assert_eql?(nil, host1.lookup_server(Req.new(addr1, port2, namez)))
assert_eql?(host11, host1.lookup_server(Req.new(addr1, port3, name1)))
assert_eql?(host11, host1.lookup_server(Req.new(addr1, port3, name2)))
assert_eql?(host11, host1.lookup_server(Req.new(addr1, port3, namea)))
assert_eql?(host11, host1.lookup_server(Req.new(addr1, port3, nameb)))
assert_eql?(host11, host1.lookup_server(Req.new(addr1, port3, namez)))
assert_eql?(nil, host1.lookup_server(Req.new(addr1, portz, name1)))
assert_eql?(nil, host1.lookup_server(Req.new(addr1, portz, name2)))
assert_eql?(nil, host1.lookup_server(Req.new(addr1, portz, namea)))
assert_eql?(nil, host1.lookup_server(Req.new(addr1, portz, nameb)))
assert_eql?(nil, host1.lookup_server(Req.new(addr1, portz, namez)))
# connect to addr2
assert_eql?(host7, host1.lookup_server(Req.new(addr2, port1, name1)))
assert_eql?(host8, host1.lookup_server(Req.new(addr2, port1, name2)))
assert_eql?(host8, host1.lookup_server(Req.new(addr2, port1, namea)))
assert_eql?(host8, host1.lookup_server(Req.new(addr2, port1, nameb)))
assert_eql?(nil, host1.lookup_server(Req.new(addr2, port1, namez)))
assert_eql?(host7, host1.lookup_server(Req.new(addr2, port2, name1)))
assert_eql?(host8, host1.lookup_server(Req.new(addr2, port2, name2)))
assert_eql?(host8, host1.lookup_server(Req.new(addr2, port2, namea)))
assert_eql?(host8, host1.lookup_server(Req.new(addr2, port2, nameb)))
assert_eql?(nil, host1.lookup_server(Req.new(addr2, port2, namez)))
assert_eql?(host7, host1.lookup_server(Req.new(addr2, port3, name1))) #!
assert_eql?(host8, host1.lookup_server(Req.new(addr2, port3, name2))) #!
assert_eql?(host8, host1.lookup_server(Req.new(addr2, port3, namea))) #!
assert_eql?(host8, host1.lookup_server(Req.new(addr2, port3, nameb))) #!
assert_eql?(host11, host1.lookup_server(Req.new(addr2, port3, namez)))
assert_eql?(host7, host1.lookup_server(Req.new(addr2, portz, name1)))
assert_eql?(host8, host1.lookup_server(Req.new(addr2, portz, name2)))
assert_eql?(host8, host1.lookup_server(Req.new(addr2, portz, namea)))
assert_eql?(host8, host1.lookup_server(Req.new(addr2, portz, nameb)))
assert_eql?(nil, host1.lookup_server(Req.new(addr2, portz, namez)))
# connect to addrz
assert_eql?(nil, host1.lookup_server(Req.new(addrz, port1, name1)))
assert_eql?(nil, host1.lookup_server(Req.new(addrz, port1, name2)))
assert_eql?(nil, host1.lookup_server(Req.new(addrz, port1, namea)))
assert_eql?(nil, host1.lookup_server(Req.new(addrz, port1, nameb)))
assert_eql?(nil, host1.lookup_server(Req.new(addrz, port1, namez)))
assert_eql?(nil, host1.lookup_server(Req.new(addrz, port2, name1)))
assert_eql?(nil, host1.lookup_server(Req.new(addrz, port2, name2)))
assert_eql?(nil, host1.lookup_server(Req.new(addrz, port2, namea)))
assert_eql?(nil, host1.lookup_server(Req.new(addrz, port2, nameb)))
assert_eql?(nil, host1.lookup_server(Req.new(addrz, port2, namez)))
assert_eql?(host11, host1.lookup_server(Req.new(addrz, port3, name1)))
assert_eql?(host11, host1.lookup_server(Req.new(addrz, port3, name2)))
assert_eql?(host11, host1.lookup_server(Req.new(addrz, port3, namea)))
assert_eql?(host11, host1.lookup_server(Req.new(addrz, port3, nameb)))
assert_eql?(host11, host1.lookup_server(Req.new(addrz, port3, namez)))
assert_eql?(nil, host1.lookup_server(Req.new(addrz, portz, name1)))
assert_eql?(nil, host1.lookup_server(Req.new(addrz, portz, name2)))
assert_eql?(nil, host1.lookup_server(Req.new(addrz, portz, namea)))
assert_eql?(nil, host1.lookup_server(Req.new(addrz, portz, nameb)))
assert_eql?(nil, host1.lookup_server(Req.new(addrz, portz, namez)))
# connect to localhost
assert_eql?(host10, host1.lookup_server(Req.new(local, port1, name1)))
assert_eql?(host10, host1.lookup_server(Req.new(local, port1, name2)))
assert_eql?(host10, host1.lookup_server(Req.new(local, port1, namea)))
assert_eql?(host10, host1.lookup_server(Req.new(local, port1, nameb)))
assert_eql?(host10, host1.lookup_server(Req.new(local, port1, namez)))
assert_eql?(host10, host1.lookup_server(Req.new(local, port2, name1)))
assert_eql?(host10, host1.lookup_server(Req.new(local, port2, name2)))
assert_eql?(host10, host1.lookup_server(Req.new(local, port2, namea)))
assert_eql?(host10, host1.lookup_server(Req.new(local, port2, nameb)))
assert_eql?(host10, host1.lookup_server(Req.new(local, port2, namez)))
assert_eql?(host10, host1.lookup_server(Req.new(local, port3, name1))) #!
assert_eql?(host10, host1.lookup_server(Req.new(local, port3, name2))) #!
assert_eql?(host10, host1.lookup_server(Req.new(local, port3, namea))) #!
assert_eql?(host10, host1.lookup_server(Req.new(local, port3, nameb))) #!
assert_eql?(host10, host1.lookup_server(Req.new(local, port3, namez))) #!
assert_eql?(host10, host1.lookup_server(Req.new(local, portz, name1)))
assert_eql?(host10, host1.lookup_server(Req.new(local, portz, name2)))
assert_eql?(host10, host1.lookup_server(Req.new(local, portz, namea)))
assert_eql?(host10, host1.lookup_server(Req.new(local, portz, nameb)))
assert_eql?(host10, host1.lookup_server(Req.new(local, portz, namez)))
end
end
end