Protocol::HTTPSourceProtocolHTTPReference

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