環境。
$ uname -mvrs
Darwin 10.7.0 Darwin Kernel Version 10.7.0: Sat Jan 29 15:17:16 PST 2011; root:xnu-1504.9.37~1/RELEASE_I386 i386
$ ruby -v
ruby 1.8.7 (2009-06-12 patchlevel 174) [universal-darwin10.0]
URL/URIをパースしてどんな情報になるかのサンプルコード。
$ cat ./uriparse.rb
require 'uri'
urilist = [
'http://www.nilab.info/a?b=c&d=e',
'https://www.nilab.info/a?b=c&d=e',
'ftp://ftp.nilab.info/path;type=i',
'ldap://ldap.nilab.info/dn',
'mailto:hoge@example.com?subject=daimei&cc=kabonkopi',
'file:///home/hoge/a.txt',
]
urilist.each{|str|
uri = URI.parse(str)
puts uri.inspect
puts uri.class.inspect
uri.component.each{|s|
puts "#{s}=#{uri.select(s)}"
}
puts ''
}
実行結果。
$ ruby ./uriparse.rb
#<URI::HTTP:0x1003839b0 URL:http://www.nilab.info/a?b=c&d=e>
URI::HTTP
scheme=http
userinfo=
host=www.nilab.info
port=80
path=/a
query=b=c&d=e
fragment=
#<URI::HTTPS:0x100382e48 URL:https://www.nilab.info/a?b=c&d=e>
URI::HTTPS
scheme=https
userinfo=
host=www.nilab.info
port=443
path=/a
query=b=c&d=e
fragment=
#<URI::FTP:0x100382308 URL:ftp://ftp.nilab.info/path;type=i>
URI::FTP
scheme=ftp
userinfo=
host=ftp.nilab.info
port=21
path=path
typecode=i
#<URI::LDAP:0x100381728 URL:ldap://ldap.nilab.info/dn>
URI::LDAP
scheme=ldap
host=ldap.nilab.info
port=389
dn=dn
attributes=
scope=
filter=
extensions=
#<URI::MailTo:0x100380b48 URL:mailto:hoge@example.com?subject=daimei&cc=kabonkopi>
URI::MailTo
scheme=mailto
to=hoge@example.com
headers=subjectdaimeicckabonkopi
#<URI::Generic:0x10037fe78 URL:file:/home/hoge/a.txt>
URI::Generic
scheme=file
userinfo=
host=
port=
registry=
path=/home/hoge/a.txt
opaque=
query=
fragment=
多少おかしなURIでもパースできるか(あるいはちゃんとエラー発生してくれるか)の実験サンプルコード。
URIにバックスペースとか入れてみたけど、制御文字が入っていると InvalidURIError が出るっぽい。
$ cat ./urisec.rb
require 'uri'
# back space attacks
uri_list = [
'http://www.nilab.info/a?b=c&d=e',
'http://localhost/a?b=c&d=e',
'http://127.0.0.1/a?b=c&d=e',
'file:///home/hoge/a.txt',
'http://nilab.info/\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\bfile://home/hoge/a.txt',
'http:\b\b\b\b\bfile:///home/hoge/a.txt',
'http://nilab.info/a\n',
]
# 排除するホスト(というか前方一致文字列)
$ban_list = [
'http://localhost',
'http://127.0.0.1',
]
# with secure check
def get_uri(str)
begin
$ban_list.each{|ban|
raise 'bad URI: ban list' if /^#{ban}/ =~ str
}
uri = URI.parse(str)
raise 'bad URI: ban kind' if !uri.kind_of?(URI::HTTP)
return uri
rescue
puts $!.inspect
return nil
end
end
uri_list.each{|str|
puts '--------------------------------------------------'
puts str
uri = get_uri(str)
puts uri.inspect
}
実行結果。
$ ruby ./urisec.rb
--------------------------------------------------
http://www.nilab.info/a?b=c&d=e
#<URI::HTTP:0x100382cb8 URL:http://www.nilab.info/a?b=c&d=e>
--------------------------------------------------
http://localhost/a?b=c&d=e
#<RuntimeError: bad URI: ban list>
nil
--------------------------------------------------
http://127.0.0.1/a?b=c&d=e
#<RuntimeError: bad URI: ban list>
nil
--------------------------------------------------
file:///home/hoge/a.txt
#<RuntimeError: bad URI: ban kind>
nil
--------------------------------------------------
http://nilab.info/\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\bfile://home/hoge/a.txt
#<URI::InvalidURIError: bad URI(is not URI?): http://nilab.info/\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\bfile://home/hoge/a.txt>
nil
--------------------------------------------------
http:\b\b\b\b\bfile:///home/hoge/a.txt
#<URI::InvalidURIError: bad URI(is not URI?): http:\b\b\b\b\bfile:///home/hoge/a.txt>
nil
--------------------------------------------------
http://nilab.info/a\n
#<URI::InvalidURIError: bad URI(is not URI?): http://nilab.info/a\n>
nil
Ref. Ruby 1.8.7 リファレンスマニュアル > ライブラリ一覧 > uriライブラリ (library uri)
tags: ruby
Posted by NI-Lab. (@nilab)