Ruby 规范化HTTP URI
我从Akamai的日志文件中获取URI,其中包括以下条目:Ruby 规范化HTTP URI,ruby,uri,Ruby,Uri,我从Akamai的日志文件中获取URI,其中包括以下条目: /foo/jim/jam /福/吉姆/果酱? /foo//jim/jam /foo/bar//jim/jam /foo/jim/jam?autho=&file=jam 我希望根据规则将所有这些标准化为同一条目: 如果有查询字符串,则从中剥离autho和file 如果查询字符串为空,请删除尾随的? 应删除/的目录项 应删除/../的目录项 我本以为Ruby库会涵盖这一点,但是: 它不提供任何解析查询字符串部分的机制。(这不是很难做
/foo/jim/jam
/福/吉姆/果酱?
/foo//jim/jam
/foo/bar//jim/jam
/foo/jim/jam?autho=&file=jam
我希望根据规则将所有这些标准化为同一条目:
- 如果有查询字符串,则从中剥离
和autho
file
- 如果查询字符串为空,请删除尾随的
?
- 应删除
的目录项/
- 应删除
的目录项/../
- 它不提供任何解析查询字符串部分的机制。(这不是很难做到,也不是标准。)
- 如果查询字符串为空,则不会删除尾随的
?
URI.parse('/foo?jim').tap{ |u| u.query='' }.to_s #=> "/foo?"
方法不会清除路径中的normalize
或。
def normalize(path)
result = path.dup
path.sub! /(?<=\?).+$/ do |query|
query.split('&').reject do |kv|
%w[ autho file ].include?(kv[/^[^=]+/])
end.join('&')
end
path.sub! /\?$/, ''
path.sub!(/^[^?]+/){ |path| path.gsub(%r{[^/]+/\.\.},'').gsub('/./','/') }
end
def正常化(路径)
结果=path.dup
path.sub/(?gem将为您标准化这些:
require 'addressable/uri'
# normalize relative paths
uri = Addressable::URI.parse('http://example.com/foo/bar/../jim/jam')
puts uri.normalize.to_s #=> "http://example.com/foo/jim/jam"
# removes trailing ?
uri = Addressable::URI.parse('http://example.com/foo/jim/jam?')
puts uri.normalize.to_s #=> "http://example.com/foo/jim/jam"
# leaves empty parameters alone
uri = Addressable::URI.parse('http://example.com/foo/jim/jam?jim')
puts uri.normalize.to_s #=> "http://example.com/foo/jim/jam?jim"
# remove specific query parameters
uri = Addressable::URI.parse('http://example.com/foo/jim/jam?autho=<randomstring>&file=jam')
cleaned_query = uri.query_values
cleaned_query.delete('autho')
cleaned_query.delete('file')
uri.query_values = cleaned_query
uri.normalize.to_s #=> "http://example.com/foo/jim/jam"
需要“可寻址/uri”
#规范化相对路径
uri=可寻址::uri.parse('http://example.com/foo/bar/../jim/jam')
将uri.normalize.to#u s#=>”http://example.com/foo/jim/jam"
#删除尾随?
uri=可寻址::uri.parse('http://example.com/foo/jim/jam?')
将uri.normalize.to#u s#=>”http://example.com/foo/jim/jam"
#只保留空参数
uri=可寻址::uri.parse('http://example.com/foo/jim/jam?jim')
将uri.normalize.to#u s#=>”http://example.com/foo/jim/jam?jim"
#删除特定的查询参数
uri=可寻址::uri.parse('http://example.com/foo/jim/jam?autho=&file=jam')
已清除的\u query=uri.query\u值
已清理的\u查询。删除('autho')
已清理\u查询。删除('文件')
uri.query\u values=已清理的\u查询
uri.normalize.to#u s#=>”http://example.com/foo/jim/jam"
真正重要的是,需要记住的是,URL/URI是一个协议,一个主机,一个指向资源的文件路径,然后是传递给被引用资源的选项/参数。(对于学究来说,还有其他可选的东西,但这已经足够了。)
我们可以通过使用类和方法对URL进行解析,从URL中提取路径。获得路径后,我们将根据站点的根拥有绝对路径或相对路径。处理绝对路径很容易:
require 'uri'
%w[
/foo/jim/jam
/foo/jim/jam?
/foo/./jim/jam
/foo/bar/../jim/jam
/foo/jim/jam?autho=<randomstring>&file=jam
].each do |url|
uri = URI.parse(url)
path = uri.path
puts File.absolute_path(path)
end
# >> /foo/jim/jam
# >> /foo/jim/jam
# >> /foo/jim/jam
# >> /foo/jim/jam
# >> /foo/jim/jam
require'uri'
%w[
/foo/jim/jam
/福/吉姆/果酱?
/foo//jim/jam
/foo/bar//jim/jam
/foo/jim/jam?autho=&file=jam
].每个do | url|
uri=uri.parse(url)
path=uri.path
放置文件。绝对路径(path)
结束
#>>/foo/jim/jam
#>>/foo/jim/jam
#>>/foo/jim/jam
#>>/foo/jim/jam
#>>/foo/jim/jam
因为路径是基于服务器根目录的文件路径,所以我们可以使用Ruby的方法玩游戏来规范化“.”和“..”并获得真正的绝对路径。如果有更多的,这将中断。
(父目录)而不是目录链,但您不应该在提取的路径中找到,因为这也会破坏服务器/浏览器服务/请求/接收资源的能力
当处理相对路径时,它变得更“有趣”,但文件仍然是我们的朋友,但这是一个不同的问题。这很好,但对于一个(非常小的)问题:请求/设置query\u值
会导致查询值按字母顺序排序。因此,往返“OK”通过此URL不必要地将其更改为(功能相同但不同的内容)。CGI::parse
和URI::split
可以帮助URI规范化!
可以从中受益。在2.3.0中,它只是将“”更改为“/”,并关闭方案和主机。