class Reference
A relative reference, excluding any authority. The path part of an HTTP request.
Definitions
def self.parse(path = "/", parameters = nil)
Generate a reference from a path and user parameters. The path may contain a #fragment
or ?query=parameters
.
Implementation
def self.parse(path = "/", parameters = nil)
base, fragment = path.split("#", 2)
path, query = base.split("?", 2)
self.new(path, query, fragment, parameters)
end
attr_accessor :path
The path component, e.g. /foo/bar/index.html
attr_accessor :query
The un-parsed query string, e.g. 'x=10&y=20'
attr_accessor :fragment
A fragment, the part after the '#'
attr_accessor :parameters
User supplied parameters that will be appended to the query part.
def + other
Merges two references as specified by RFC2396, similar to URI.join
.
Implementation
def + other
other = self.class[other]
self.class.new(
expand_path(self.path, other.path, true),
other.query,
other.fragment,
other.parameters,
)
end
def base
Just the base path, without any query string, parameters or fragment.
Implementation
def base
self.class.new(@path, nil, nil, nil)
end
def with(path: nil, parameters: nil, fragment: @fragment, pop: false, merge: true)
Update the reference with the given path, parameters and fragment.
Implementation
def with(path: nil, parameters: nil, fragment: @fragment, pop: false, merge: true)
if @parameters
if parameters and merge
parameters = @parameters.merge(parameters)
else
parameters = @parameters
end
end
if @query and !merge
query = nil
else
query = @query
end
if path
path = expand_path(@path, path, pop)
else
path = @path
end
self.class.new(path, query, fragment, parameters)
end
def expand_path(base, relative, pop = true)
Implementation
def expand_path(base, relative, pop = true)
if relative.start_with? "/"
return relative
end
path = split(base)
# RFC2396 Section 5.2:
# 6) a) All but the last segment of the base URI's path component is
# copied to the buffer. In other words, any characters after the
# last (right-most) slash character, if any, are excluded.
path.pop if pop or path.last == ""
parts = split(relative)
# Absolute path:
if path.first == ""
expand_absolute_path(path, parts)
else
expand_relative_path(path, parts)
end
return path.join("/")
end