File: uri.rb

package info (click to toggle)
ruby-http 4.4.1-6
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 704 kB
  • sloc: ruby: 5,388; makefile: 9
file content (150 lines) | stat: -rw-r--r-- 4,641 bytes parent folder | download | duplicates (3)
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