class URI::Generic

Extension and monkeypatch of Ruby’s StdLib URI::Generic class.

Public Instance Methods

normalize() click to toggle source

(see normalize!) @return [URI::Generic] a normalized copy of ‘self`.

# File lib/rackful/uri.rb, line 28
def normalize
  r = self.dup
  r.normalize!
  r
end
normalize!() click to toggle source

Monkeypatch of [Ruby’s StdLib implementation](ruby-doc.org/stdlib/libdoc/uri/rdoc/URI/Generic.html#method-i-normalize-21). In addition to the default implementation, this implementation ensures that

  1. no unreserved characters are pct-encoded, and

  2. all non-unreserved characters are pct-encoded.

Check [RFC3986](tools.ietf.org/html/rfc3986) syntax:

abempty = *( "/" *(unreserved / pct-encoded / sub-delims / ":" / "@") )
unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
sub-delims = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "="

@return [self, nil] ‘self` if the URI was modified, or `nil` of the uri was

already in normal form.
# File lib/rackful/uri.rb, line 47
def normalize!
  #unless %r{\A(?:/(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})*)*\z}i === self.path
  #  raise TypeError, "Can’t convert String #{self.path.inspect} to Rackful::Path"
  #end
  self.uri_generic_normalize!
  path = '/' + self.segments( Encoding::BINARY ).collect do |segment|
    segment.gsub(/([^a-zA-Z0-9\-._~]+)/n) {
      '%'+$1.unpack('H2'*bytesize($1)).join('%').upcase
    }
  end.join('/')
  if path == self.path
    nil
  else
    self.path = path
    self
  end
end
relative_deprecated(base_path) click to toggle source

Turns a relative URI (starting with ‘/`) into a relative path (starting with `./` or `../`) @param base_path [Path] @return [String] a relative URI @deprecated

# File lib/rackful/uri.rb, line 121
def relative_deprecated base_path
  case self
  when base_path
    # RFC2396, Section 4.2
    return ''
  when %r{(?:\A|/)\.\.?(?:/|\z)}
    # self has abnormal absolute path,
    # like "/./", "/../", "/x/../", ...
    return self.dup
  end

  src_path = base_path.scan(%r{(?:\A|[^/]+)/})
  dst_path = self.scan(%r{(?:\A|[^/]+)/?})

  # discard same parts
  while !dst_path.empty? && dst_path.first == src_path.first
    src_path.shift
    dst_path.shift
  end

  tmp = dst_path.join

  # calculate
  if src_path.empty?
    if tmp.empty?
      return './'
    elsif dst_path.first.include?(':') # (see RFC2396 Section 5)
      return './' + tmp
    else
      return tmp
    end
  end

  return '../' * src_path.size + tmp
end
segments( encoding = Encoding::UTF_8 ) click to toggle source

@return [Array<String>] Unencoded segments

# File lib/rackful/uri.rb, line 108
def segments( encoding = Encoding::UTF_8 )
  r = self.path.split(%r{/+}).collect do |s|
    Rack::Utils.unescape( s, encoding )
  end
  r.shift
  r
end
slashify() click to toggle source

@return [Path] a copy of ‘self`, with a trailing slash.

# File lib/rackful/uri.rb, line 67
def slashify
  r = self.dup
  r.slashify!
  r
end
slashify!() click to toggle source

Adds a trailing slash to ‘self` if necessary. @return [self]

# File lib/rackful/uri.rb, line 76
def slashify!
  if '/' != self.path[-1,1]
    self.path += '/'
    self
  else
    nil
  end
end
unslashify() click to toggle source

@return [Path] a copy of ‘self` without trailing slashes.

# File lib/rackful/uri.rb, line 87
def unslashify
  r = self.dup
  r.unslashify!
  r
end
unslashify!() click to toggle source

Removes trailing slashes from ‘self`. @return [self]

# File lib/rackful/uri.rb, line 96
def unslashify!
  path = self.path.sub( %r{/+\z}, '' )
  if path == self.path
    nil
  else
    self.path = path
    self
  end
end