1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150
|
# frozen_string_literal: true
require "addressable/uri"
module HTTP
class URI
extend Forwardable
def_delegators :@uri, :scheme, :normalized_scheme, :scheme=
def_delegators :@uri, :user, :normalized_user, :user=
def_delegators :@uri, :password, :normalized_password, :password=
def_delegators :@uri, :host, :normalized_host, :host=
def_delegators :@uri, :authority, :normalized_authority, :authority=
def_delegators :@uri, :origin, :origin=
def_delegators :@uri, :normalized_port, :port=
def_delegators :@uri, :path, :normalized_path, :path=
def_delegators :@uri, :query, :normalized_query, :query=
def_delegators :@uri, :query_values, :query_values=
def_delegators :@uri, :request_uri, :request_uri=
def_delegators :@uri, :fragment, :normalized_fragment, :fragment=
def_delegators :@uri, :omit, :join, :normalize
# @private
HTTP_SCHEME = "http"
# @private
HTTPS_SCHEME = "https"
# @private
NORMALIZER = lambda do |uri|
uri = HTTP::URI.parse uri
HTTP::URI.new(
:scheme => uri.normalized_scheme,
:authority => uri.normalized_authority,
:path => uri.normalized_path,
:query => uri.query,
:fragment => uri.normalized_fragment
)
end
# Parse the given URI string, returning an HTTP::URI object
#
# @param [HTTP::URI, String, #to_str] uri to parse
#
# @return [HTTP::URI] new URI instance
def self.parse(uri)
return uri if uri.is_a?(self)
new(Addressable::URI.parse(uri))
end
# Encodes key/value pairs as application/x-www-form-urlencoded
#
# @param [#to_hash, #to_ary] form_values to encode
# @param [TrueClass, FalseClass] sort should key/value pairs be sorted first?
#
# @return [String] encoded value
def self.form_encode(form_values, sort = false)
Addressable::URI.form_encode(form_values, sort)
end
# Creates an HTTP::URI instance from the given options
#
# @param [Hash, Addressable::URI] options_or_uri
#
# @option options_or_uri [String, #to_str] :scheme URI scheme
# @option options_or_uri [String, #to_str] :user for basic authentication
# @option options_or_uri [String, #to_str] :password for basic authentication
# @option options_or_uri [String, #to_str] :host name component
# @option options_or_uri [String, #to_str] :port network port to connect to
# @option options_or_uri [String, #to_str] :path component to request
# @option options_or_uri [String, #to_str] :query component distinct from path
# @option options_or_uri [String, #to_str] :fragment component at the end of the URI
#
# @return [HTTP::URI] new URI instance
def initialize(options_or_uri = {})
case options_or_uri
when Hash
@uri = Addressable::URI.new(options_or_uri)
when Addressable::URI
@uri = options_or_uri
else
raise TypeError, "expected Hash for options, got #{options_or_uri.class}"
end
end
# Are these URI objects equal? Normalizes both URIs prior to comparison
#
# @param [Object] other URI to compare this one with
#
# @return [TrueClass, FalseClass] are the URIs equivalent (after normalization)?
def ==(other)
other.is_a?(URI) && normalize.to_s == other.normalize.to_s
end
# Are these URI objects equal? Does NOT normalizes both URIs prior to comparison
#
# @param [Object] other URI to compare this one with
#
# @return [TrueClass, FalseClass] are the URIs equivalent?
def eql?(other)
other.is_a?(URI) && to_s == other.to_s
end
# Hash value based off the normalized form of a URI
#
# @return [Integer] A hash of the URI
def hash
@hash ||= to_s.hash * -1
end
# Port number, either as specified or the default if unspecified
#
# @return [Integer] port number
def port
@uri.port || @uri.default_port
end
# @return [True] if URI is HTTP
# @return [False] otherwise
def http?
HTTP_SCHEME == scheme
end
# @return [True] if URI is HTTPS
# @return [False] otherwise
def https?
HTTPS_SCHEME == scheme
end
# @return [Object] duplicated URI
def dup
self.class.new @uri.dup
end
# Convert an HTTP::URI to a String
#
# @return [String] URI serialized as a String
def to_s
@uri.to_s
end
alias to_str to_s
# @return [String] human-readable representation of URI
def inspect
format("#<%s:0x%014x URI:%s>", self.class.name, object_id << 1, to_s)
end
end
end
|