* lib/webrick/httprequest.rb: supprt X-Forwarded-* header fields.
WEBrick::HTTPRequest#{host,port,request_uri} is derived having regards to X-Forwarded-Proto and X-Forwarded-Host. * lib/webrick/httprequest.rb (WEBrick::HTTPRequest#server_name?): new method. (WEBrick::HTTPRequest#remote_ip?): new method. (WEBrick::HTTPRequest#ssl?): new method. * string.c (rb_enc_cr_str_buf_cat): fix self appending. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@14968 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
53ac21c325
commit
b04f5e661f
11
ChangeLog
11
ChangeLog
@ -1,3 +1,14 @@
|
|||||||
|
Wed Jan 9 20:35:42 2008 GOTOU Yuuzou <gotoyuzo@notwork.org>
|
||||||
|
|
||||||
|
* lib/webrick/httprequest.rb: supprt X-Forwarded-* header fields.
|
||||||
|
WEBrick::HTTPRequest#{host,port,request_uri} is derived having
|
||||||
|
regards to X-Forwarded-Proto and X-Forwarded-Host.
|
||||||
|
|
||||||
|
* lib/webrick/httprequest.rb
|
||||||
|
(WEBrick::HTTPRequest#server_name?): new method.
|
||||||
|
(WEBrick::HTTPRequest#remote_ip?): new method.
|
||||||
|
(WEBrick::HTTPRequest#ssl?): new method.
|
||||||
|
|
||||||
Wed Jan 9 18:24:39 2008 WATANABE Hirofumi <eban@ruby-lang.org>
|
Wed Jan 9 18:24:39 2008 WATANABE Hirofumi <eban@ruby-lang.org>
|
||||||
|
|
||||||
* golf_prelude.rb (Array#to_s): alias to join.
|
* golf_prelude.rb (Array#to_s): alias to join.
|
||||||
|
@ -69,6 +69,9 @@ module WEBrick
|
|||||||
|
|
||||||
@remaining_size = nil
|
@remaining_size = nil
|
||||||
@socket = nil
|
@socket = nil
|
||||||
|
|
||||||
|
@forwarded_proto = @forwarded_host = @forwarded_port =
|
||||||
|
@forwarded_server = @forwarded_for = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
def parse(socket=nil)
|
def parse(socket=nil)
|
||||||
@ -95,6 +98,7 @@ module WEBrick
|
|||||||
return if @unparsed_uri == "*"
|
return if @unparsed_uri == "*"
|
||||||
|
|
||||||
begin
|
begin
|
||||||
|
setup_forwarded_info
|
||||||
@request_uri = parse_uri(@unparsed_uri)
|
@request_uri = parse_uri(@unparsed_uri)
|
||||||
@path = HTTPUtils::unescape(@request_uri.path)
|
@path = HTTPUtils::unescape(@request_uri.path)
|
||||||
@path = HTTPUtils::normalize_path(@path)
|
@path = HTTPUtils::normalize_path(@path)
|
||||||
@ -153,6 +157,26 @@ module WEBrick
|
|||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def host
|
||||||
|
return @forwarded_host || @host
|
||||||
|
end
|
||||||
|
|
||||||
|
def port
|
||||||
|
return @forwarded_port || @port
|
||||||
|
end
|
||||||
|
|
||||||
|
def server_name
|
||||||
|
return @forwarded_server || @config[:ServerName]
|
||||||
|
end
|
||||||
|
|
||||||
|
def remote_ip
|
||||||
|
return self["client-ip"] || @forwarded_for || @peeraddr[3]
|
||||||
|
end
|
||||||
|
|
||||||
|
def ssl?
|
||||||
|
return @request_uri.scheme == "https"
|
||||||
|
end
|
||||||
|
|
||||||
def keep_alive?
|
def keep_alive?
|
||||||
@keep_alive
|
@keep_alive
|
||||||
end
|
end
|
||||||
@ -255,7 +279,9 @@ module WEBrick
|
|||||||
end
|
end
|
||||||
uri = URI::parse(str)
|
uri = URI::parse(str)
|
||||||
return uri if uri.absolute?
|
return uri if uri.absolute?
|
||||||
if self["host"]
|
if @forwarded_host
|
||||||
|
host, port = @forwarded_host, @forwarded_port
|
||||||
|
elsif self["host"]
|
||||||
pattern = /\A(#{URI::REGEXP::PATTERN::HOST})(?::(\d+))?\z/n
|
pattern = /\A(#{URI::REGEXP::PATTERN::HOST})(?::(\d+))?\z/n
|
||||||
host, port = *self['host'].scan(pattern)[0]
|
host, port = *self['host'].scan(pattern)[0]
|
||||||
elsif @addr.size > 0
|
elsif @addr.size > 0
|
||||||
@ -263,7 +289,7 @@ module WEBrick
|
|||||||
else
|
else
|
||||||
host, port = @config[:ServerName], @config[:Port]
|
host, port = @config[:ServerName], @config[:Port]
|
||||||
end
|
end
|
||||||
uri.scheme = scheme
|
uri.scheme = @forwarded_proto || scheme
|
||||||
uri.host = host
|
uri.host = host
|
||||||
uri.port = port ? port.to_i : nil
|
uri.port = port ? port.to_i : nil
|
||||||
return URI::parse(uri.to_s)
|
return URI::parse(uri.to_s)
|
||||||
@ -356,5 +382,25 @@ module WEBrick
|
|||||||
raise HTTPStatus::BadRequest, ex.message
|
raise HTTPStatus::BadRequest, ex.message
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
PrivateNetworkRegexp = /
|
||||||
|
^unknown$|
|
||||||
|
^((::ffff:)?127.0.0.1|::1)$|
|
||||||
|
^(::ffff:)?(10|172\.(1[6-9]|2[0-9]|3[01])|192\.168)\.
|
||||||
|
/ixo
|
||||||
|
|
||||||
|
def setup_forwarded_info
|
||||||
|
@forwarded_server = self["x-forwarded-server"]
|
||||||
|
@forwarded_proto = self["x-forwarded-proto"]
|
||||||
|
if host_port = self["x-forwarded-host"]
|
||||||
|
@forwarded_host, tmp = host_port.split(":", 2)
|
||||||
|
@forwarded_port = (tmp || (@forwarded_proto == "https" ? 443 : 80)).to_i
|
||||||
|
end
|
||||||
|
if addrs = self["x-forwarded-for"]
|
||||||
|
addrs = addrs.split(",").collect(&:strip)
|
||||||
|
addrs.reject!{|ip| PrivateNetworkRegexp =~ ip }
|
||||||
|
@forwarded_for = addrs.first
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -79,6 +79,7 @@ class TestWEBrickHTTPRequest < Test::Unit::TestCase
|
|||||||
Accept-Language: ja
|
Accept-Language: ja
|
||||||
Content-Type: text/plain
|
Content-Type: text/plain
|
||||||
Content-Length: 7
|
Content-Length: 7
|
||||||
|
X-Empty-Header:
|
||||||
|
|
||||||
foobar
|
foobar
|
||||||
_end_of_message_
|
_end_of_message_
|
||||||
@ -97,6 +98,8 @@ class TestWEBrickHTTPRequest < Test::Unit::TestCase
|
|||||||
assert_equal(7, req.content_length)
|
assert_equal(7, req.content_length)
|
||||||
assert_equal("text/plain", req.content_type)
|
assert_equal("text/plain", req.content_type)
|
||||||
assert_equal("foobar\n", req.body)
|
assert_equal("foobar\n", req.body)
|
||||||
|
assert_equal("", req["x-empty-header"])
|
||||||
|
assert_equal(nil, req["x-no-header"])
|
||||||
assert(req.query.empty?)
|
assert(req.query.empty?)
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -238,6 +241,70 @@ class TestWEBrickHTTPRequest < Test::Unit::TestCase
|
|||||||
assert_equal(File.read(__FILE__), req.body)
|
assert_equal(File.read(__FILE__), req.body)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_forwarded
|
||||||
|
msg = <<-_end_of_message_
|
||||||
|
GET /foo HTTP/1.1
|
||||||
|
Host: localhost:10080
|
||||||
|
User-Agent: w3m/0.5.2
|
||||||
|
X-Forwarded-For: 123.123.123.123
|
||||||
|
X-Forwarded-Host: forward.example.com
|
||||||
|
X-Forwarded-Server: server.example.com
|
||||||
|
Connection: Keep-Alive
|
||||||
|
|
||||||
|
_end_of_message_
|
||||||
|
msg.gsub!(/^ {6}/, "")
|
||||||
|
req = WEBrick::HTTPRequest.new(WEBrick::Config::HTTP)
|
||||||
|
req.parse(StringIO.new(msg))
|
||||||
|
assert_equal("server.example.com", req.server_name)
|
||||||
|
assert_equal("http://forward.example.com/foo", req.request_uri.to_s)
|
||||||
|
assert_equal("forward.example.com", req.host)
|
||||||
|
assert_equal(80, req.port)
|
||||||
|
assert_equal("123.123.123.123", req.remote_ip)
|
||||||
|
assert(!req.ssl?)
|
||||||
|
|
||||||
|
msg = <<-_end_of_message_
|
||||||
|
GET /foo HTTP/1.1
|
||||||
|
Host: localhost:10080
|
||||||
|
User-Agent: w3m/0.5.2
|
||||||
|
X-Forwarded-For: 192.168.1.10, 172.16.1.1, 123.123.123.123
|
||||||
|
X-Forwarded-Host: forward.example.com:8080
|
||||||
|
X-Forwarded-Server: server.example.com
|
||||||
|
Connection: Keep-Alive
|
||||||
|
|
||||||
|
_end_of_message_
|
||||||
|
msg.gsub!(/^ {6}/, "")
|
||||||
|
req = WEBrick::HTTPRequest.new(WEBrick::Config::HTTP)
|
||||||
|
req.parse(StringIO.new(msg))
|
||||||
|
assert_equal("server.example.com", req.server_name)
|
||||||
|
assert_equal("http://forward.example.com:8080/foo", req.request_uri.to_s)
|
||||||
|
assert_equal("forward.example.com", req.host)
|
||||||
|
assert_equal(8080, req.port)
|
||||||
|
assert_equal("123.123.123.123", req.remote_ip)
|
||||||
|
assert(!req.ssl?)
|
||||||
|
|
||||||
|
msg = <<-_end_of_message_
|
||||||
|
GET /foo HTTP/1.1
|
||||||
|
Host: localhost:10080
|
||||||
|
Client-IP: 234.234.234.234
|
||||||
|
X-Forwarded-Proto: https
|
||||||
|
X-Forwarded-For: 192.168.1.10, 10.0.0.1, 123.123.123.123
|
||||||
|
X-Forwarded-Host: forward.example.com
|
||||||
|
X-Forwarded-Server: server.example.com
|
||||||
|
X-Requested-With: XMLHttpRequest
|
||||||
|
Connection: Keep-Alive
|
||||||
|
|
||||||
|
_end_of_message_
|
||||||
|
msg.gsub!(/^ {6}/, "")
|
||||||
|
req = WEBrick::HTTPRequest.new(WEBrick::Config::HTTP)
|
||||||
|
req.parse(StringIO.new(msg))
|
||||||
|
assert_equal("server.example.com", req.server_name)
|
||||||
|
assert_equal("https://forward.example.com/foo", req.request_uri.to_s)
|
||||||
|
assert_equal("forward.example.com", req.host)
|
||||||
|
assert_equal(443, req.port)
|
||||||
|
assert_equal("234.234.234.234", req.remote_ip)
|
||||||
|
assert(req.ssl?)
|
||||||
|
end
|
||||||
|
|
||||||
def test_bad_messages
|
def test_bad_messages
|
||||||
param = "foo=1;foo=2;foo=3;bar=x"
|
param = "foo=1;foo=2;foo=3;bar=x"
|
||||||
msg = <<-_end_of_message_
|
msg = <<-_end_of_message_
|
||||||
|
Loading…
x
Reference in New Issue
Block a user