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
|
# frozen_string_literal: false
# = uri/http.rb
#
# Author:: Akira Yamada <akira@ruby-lang.org>
# License:: You can redistribute it and/or modify it under the same term as Ruby.
#
# See URI for general documentation
#
require_relative 'generic'
module URI
#
# The syntax of HTTP URIs is defined in RFC1738 section 3.3.
#
# Note that the Ruby URI library allows HTTP URLs containing usernames and
# passwords. This is not legal as per the RFC, but used to be
# supported in Internet Explorer 5 and 6, before the MS04-004 security
# update. See <URL:http://support.microsoft.com/kb/834489>.
#
class HTTP < Generic
# A Default port of 80 for URI::HTTP.
DEFAULT_PORT = 80
# An Array of the available components for URI::HTTP.
COMPONENT = %i[
scheme
userinfo host port
path
query
fragment
].freeze
#
# == Description
#
# Creates a new URI::HTTP object from components, with syntax checking.
#
# The components accepted are userinfo, host, port, path, query, and
# fragment.
#
# The components should be provided either as an Array, or as a Hash
# with keys formed by preceding the component names with a colon.
#
# If an Array is used, the components must be passed in the
# order <code>[userinfo, host, port, path, query, fragment]</code>.
#
# Example:
#
# uri = URI::HTTP.build(host: 'www.example.com', path: '/foo/bar')
#
# uri = URI::HTTP.build([nil, "www.example.com", nil, "/path",
# "query", 'fragment'])
#
# Currently, if passed userinfo components this method generates
# invalid HTTP URIs as per RFC 1738.
#
def self.build(args)
tmp = Util.make_components_hash(self, args)
super(tmp)
end
# Do not allow empty host names, as they are not allowed by RFC 3986.
def check_host(v)
ret = super
if ret && v.empty?
raise InvalidComponentError,
"bad component(expected host component): #{v}"
end
ret
end
#
# == Description
#
# Returns the full path for an HTTP request, as required by Net::HTTP::Get.
#
# If the URI contains a query, the full path is URI#path + '?' + URI#query.
# Otherwise, the path is simply URI#path.
#
# Example:
#
# uri = URI::HTTP.build(path: '/foo/bar', query: 'test=true')
# uri.request_uri # => "/foo/bar?test=true"
#
def request_uri
return unless @path
url = @query ? "#@path?#@query" : @path.dup
url.start_with?(?/.freeze) ? url : ?/ + url
end
#
# == Description
#
# Returns the authority for an HTTP uri, as defined in
# https://www.rfc-editor.org/rfc/rfc3986#section-3.2.
#
#
# Example:
#
# URI::HTTP.build(host: 'www.example.com', path: '/foo/bar').authority #=> "www.example.com"
# URI::HTTP.build(host: 'www.example.com', port: 8000, path: '/foo/bar').authority #=> "www.example.com:8000"
# URI::HTTP.build(host: 'www.example.com', port: 80, path: '/foo/bar').authority #=> "www.example.com"
#
def authority
if port == default_port
host
else
"#{host}:#{port}"
end
end
#
# == Description
#
# Returns the origin for an HTTP uri, as defined in
# https://www.rfc-editor.org/rfc/rfc6454.
#
#
# Example:
#
# URI::HTTP.build(host: 'www.example.com', path: '/foo/bar').origin #=> "http://www.example.com"
# URI::HTTP.build(host: 'www.example.com', port: 8000, path: '/foo/bar').origin #=> "http://www.example.com:8000"
# URI::HTTP.build(host: 'www.example.com', port: 80, path: '/foo/bar').origin #=> "http://www.example.com"
# URI::HTTPS.build(host: 'www.example.com', path: '/foo/bar').origin #=> "https://www.example.com"
#
def origin
"#{scheme}://#{authority}"
end
end
register_scheme 'HTTP', HTTP
end
|