uri 0.12.4 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of uri might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/.github/workflows/gh-pages.yml +46 -0
- data/.github/workflows/test.yml +8 -7
- data/.gitignore +1 -0
- data/README.md +1 -0
- data/Rakefile +6 -5
- data/lib/uri/common.rb +256 -134
- data/lib/uri/generic.rb +9 -7
- data/lib/uri/rfc3986_parser.rb +95 -31
- data/lib/uri/version.rb +1 -1
- data/rakelib/sync_tool.rake +17 -0
- data/uri.gemspec +13 -5
- metadata +9 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8f4eaea3d45b9a860a4a1765dfa211d195929e01ea90e2ff25405fea90948098
|
4
|
+
data.tar.gz: 5f962ae3a2b0c56f589df823edf89560420d8c2dced50ac7332e5a6322a772bc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8fb0be9745374a552f34d58d834e206adabc9a81bfc15bc7179c4143b639f0f62dd73ab46637023147e10be72b61ffdb2b18ac32a697d185244026a51560dc54
|
7
|
+
data.tar.gz: 6961a3339bfa178cd339a14828cbb4be6d79249fc1d262da0ea7d68095435efe801ef71642866ab0de2e7a5edc759a168e8b54a006f038e446d755c9781dbf49
|
@@ -0,0 +1,46 @@
|
|
1
|
+
name: Deploy RDoc site to Pages
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
branches: [ 'master' ]
|
6
|
+
workflow_dispatch:
|
7
|
+
|
8
|
+
permissions:
|
9
|
+
contents: read
|
10
|
+
pages: write
|
11
|
+
id-token: write
|
12
|
+
|
13
|
+
concurrency:
|
14
|
+
group: "pages"
|
15
|
+
cancel-in-progress: true
|
16
|
+
|
17
|
+
jobs:
|
18
|
+
build:
|
19
|
+
runs-on: ubuntu-latest
|
20
|
+
steps:
|
21
|
+
- name: Checkout
|
22
|
+
uses: actions/checkout@v4
|
23
|
+
- name: Setup Ruby
|
24
|
+
uses: ruby/setup-ruby@250fcd6a742febb1123a77a841497ccaa8b9e939 # v1.152.0
|
25
|
+
with:
|
26
|
+
ruby-version: '3.2'
|
27
|
+
bundler-cache: true
|
28
|
+
- name: Setup Pages
|
29
|
+
id: pages
|
30
|
+
uses: actions/configure-pages@v3
|
31
|
+
- name: Build with RDoc
|
32
|
+
# Outputs to the './_site' directory by default
|
33
|
+
run: bundle exec rake rdoc
|
34
|
+
- name: Upload artifact
|
35
|
+
uses: actions/upload-pages-artifact@v2
|
36
|
+
|
37
|
+
deploy:
|
38
|
+
environment:
|
39
|
+
name: github-pages
|
40
|
+
url: ${{ steps.deployment.outputs.page_url }}
|
41
|
+
runs-on: ubuntu-latest
|
42
|
+
needs: build
|
43
|
+
steps:
|
44
|
+
- name: Deploy to GitHub Pages
|
45
|
+
id: deployment
|
46
|
+
uses: actions/deploy-pages@v2
|
data/.github/workflows/test.yml
CHANGED
@@ -3,20 +3,21 @@ name: CI
|
|
3
3
|
on: [push, pull_request]
|
4
4
|
|
5
5
|
jobs:
|
6
|
+
ruby-versions:
|
7
|
+
uses: ruby/actions/.github/workflows/ruby_versions.yml@master
|
8
|
+
with:
|
9
|
+
min_version: 2.5
|
10
|
+
|
6
11
|
build:
|
12
|
+
needs: ruby-versions
|
7
13
|
name: build (${{ matrix.ruby }} / ${{ matrix.os }})
|
8
14
|
strategy:
|
9
15
|
matrix:
|
10
|
-
ruby:
|
16
|
+
ruby: ${{ fromJson(needs.ruby-versions.outputs.versions) }}
|
11
17
|
os: [ ubuntu-latest, macos-latest ]
|
12
|
-
exclude:
|
13
|
-
- ruby: 2.4
|
14
|
-
os: macos-latest
|
15
|
-
- ruby: 2.5
|
16
|
-
os: macos-latest
|
17
18
|
runs-on: ${{ matrix.os }}
|
18
19
|
steps:
|
19
|
-
- uses: actions/checkout@
|
20
|
+
- uses: actions/checkout@v4
|
20
21
|
- name: Set up Ruby
|
21
22
|
uses: ruby/setup-ruby@v1
|
22
23
|
with:
|
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# URI
|
2
2
|
|
3
3
|
[](https://github.com/ruby/uri/actions/workflows/test.yml)
|
4
|
+
[](https://ruby.github.io/uri/)
|
4
5
|
|
5
6
|
URI is a module providing classes to handle Uniform Resource Identifiers [RFC2396](http://tools.ietf.org/html/rfc2396).
|
6
7
|
|
data/Rakefile
CHANGED
@@ -7,11 +7,12 @@ Rake::TestTask.new(:test) do |t|
|
|
7
7
|
t.test_files = FileList["test/**/test_*.rb"]
|
8
8
|
end
|
9
9
|
|
10
|
-
task
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
10
|
+
require "rdoc/task"
|
11
|
+
RDoc::Task.new do |doc|
|
12
|
+
doc.main = "README.md"
|
13
|
+
doc.title = "URI - handle Uniform Resource Identifiers"
|
14
|
+
doc.rdoc_files = FileList.new %w[lib README.md LICENSE.txt]
|
15
|
+
doc.rdoc_dir = "_site" # for github pages
|
15
16
|
end
|
16
17
|
|
17
18
|
task :default => :test
|
data/lib/uri/common.rb
CHANGED
@@ -19,8 +19,6 @@ module URI
|
|
19
19
|
Parser = RFC2396_Parser
|
20
20
|
RFC3986_PARSER = RFC3986_Parser.new
|
21
21
|
Ractor.make_shareable(RFC3986_PARSER) if defined?(Ractor)
|
22
|
-
RFC2396_PARSER = RFC2396_Parser.new
|
23
|
-
Ractor.make_shareable(RFC2396_PARSER) if defined?(Ractor)
|
24
22
|
|
25
23
|
# URI::Parser.new
|
26
24
|
DEFAULT_PARSER = Parser.new
|
@@ -70,16 +68,32 @@ module URI
|
|
70
68
|
end
|
71
69
|
private_constant :Schemes
|
72
70
|
|
71
|
+
# Registers the given +klass+ as the class to be instantiated
|
72
|
+
# when parsing a \URI with the given +scheme+:
|
73
73
|
#
|
74
|
-
#
|
75
|
-
#
|
76
|
-
# can be registered (no -/+/. allowed).
|
74
|
+
# URI.register_scheme('MS_SEARCH', URI::Generic) # => URI::Generic
|
75
|
+
# URI.scheme_list['MS_SEARCH'] # => URI::Generic
|
77
76
|
#
|
77
|
+
# Note that after calling String#upcase on +scheme+, it must be a valid
|
78
|
+
# constant name.
|
78
79
|
def self.register_scheme(scheme, klass)
|
79
80
|
Schemes.const_set(scheme.to_s.upcase, klass)
|
80
81
|
end
|
81
82
|
|
82
|
-
# Returns a
|
83
|
+
# Returns a hash of the defined schemes:
|
84
|
+
#
|
85
|
+
# URI.scheme_list
|
86
|
+
# # =>
|
87
|
+
# {"MAILTO"=>URI::MailTo,
|
88
|
+
# "LDAPS"=>URI::LDAPS,
|
89
|
+
# "WS"=>URI::WS,
|
90
|
+
# "HTTP"=>URI::HTTP,
|
91
|
+
# "HTTPS"=>URI::HTTPS,
|
92
|
+
# "LDAP"=>URI::LDAP,
|
93
|
+
# "FILE"=>URI::File,
|
94
|
+
# "FTP"=>URI::FTP}
|
95
|
+
#
|
96
|
+
# Related: URI.register_scheme.
|
83
97
|
def self.scheme_list
|
84
98
|
Schemes.constants.map { |name|
|
85
99
|
[name.to_s.upcase, Schemes.const_get(name)]
|
@@ -90,9 +104,21 @@ module URI
|
|
90
104
|
private_constant :INITIAL_SCHEMES
|
91
105
|
Ractor.make_shareable(INITIAL_SCHEMES) if defined?(Ractor)
|
92
106
|
|
107
|
+
# Returns a new object constructed from the given +scheme+, +arguments+,
|
108
|
+
# and +default+:
|
109
|
+
#
|
110
|
+
# - The new object is an instance of <tt>URI.scheme_list[scheme.upcase]</tt>.
|
111
|
+
# - The object is initialized by calling the class initializer
|
112
|
+
# using +scheme+ and +arguments+.
|
113
|
+
# See URI::Generic.new.
|
114
|
+
#
|
115
|
+
# Examples:
|
93
116
|
#
|
94
|
-
#
|
95
|
-
#
|
117
|
+
# values = ['john.doe', 'www.example.com', '123', nil, '/forum/questions/', nil, 'tag=networking&order=newest', 'top']
|
118
|
+
# URI.for('https', *values)
|
119
|
+
# # => #<URI::HTTPS https://john.doe@www.example.com:123/forum/questions/?tag=networking&order=newest#top>
|
120
|
+
# URI.for('foo', *values, default: URI::HTTP)
|
121
|
+
# # => #<URI::HTTP foo://john.doe@www.example.com:123/forum/questions/?tag=networking&order=newest#top>
|
96
122
|
#
|
97
123
|
def self.for(scheme, *arguments, default: Generic)
|
98
124
|
const_name = scheme.to_s.upcase
|
@@ -123,95 +149,49 @@ module URI
|
|
123
149
|
#
|
124
150
|
class BadURIError < Error; end
|
125
151
|
|
126
|
-
#
|
127
|
-
#
|
128
|
-
#
|
129
|
-
#
|
130
|
-
#
|
131
|
-
#
|
132
|
-
#
|
133
|
-
#
|
134
|
-
#
|
135
|
-
#
|
136
|
-
#
|
137
|
-
#
|
138
|
-
#
|
139
|
-
#
|
140
|
-
#
|
141
|
-
#
|
142
|
-
#
|
143
|
-
# * Port
|
144
|
-
# * Registry
|
145
|
-
# * Path
|
146
|
-
# * Opaque
|
147
|
-
# * Query
|
148
|
-
# * Fragment
|
149
|
-
#
|
150
|
-
# == Usage
|
151
|
-
#
|
152
|
-
# require 'uri'
|
153
|
-
#
|
154
|
-
# URI.split("http://www.ruby-lang.org/")
|
155
|
-
# # => ["http", nil, "www.ruby-lang.org", nil, nil, "/", nil, nil, nil]
|
152
|
+
# Returns a 9-element array representing the parts of the \URI
|
153
|
+
# formed from the string +uri+;
|
154
|
+
# each array element is a string or +nil+:
|
155
|
+
#
|
156
|
+
# names = %w[scheme userinfo host port registry path opaque query fragment]
|
157
|
+
# values = URI.split('https://john.doe@www.example.com:123/forum/questions/?tag=networking&order=newest#top')
|
158
|
+
# names.zip(values)
|
159
|
+
# # =>
|
160
|
+
# [["scheme", "https"],
|
161
|
+
# ["userinfo", "john.doe"],
|
162
|
+
# ["host", "www.example.com"],
|
163
|
+
# ["port", "123"],
|
164
|
+
# ["registry", nil],
|
165
|
+
# ["path", "/forum/questions/"],
|
166
|
+
# ["opaque", nil],
|
167
|
+
# ["query", "tag=networking&order=newest"],
|
168
|
+
# ["fragment", "top"]]
|
156
169
|
#
|
157
170
|
def self.split(uri)
|
158
171
|
RFC3986_PARSER.split(uri)
|
159
172
|
end
|
160
173
|
|
174
|
+
# Returns a new \URI object constructed from the given string +uri+:
|
161
175
|
#
|
162
|
-
#
|
163
|
-
#
|
164
|
-
# URI
|
165
|
-
#
|
166
|
-
# == Args
|
167
|
-
#
|
168
|
-
# +uri_str+::
|
169
|
-
# String with URI.
|
170
|
-
#
|
171
|
-
# == Description
|
172
|
-
#
|
173
|
-
# Creates one of the URI's subclasses instance from the string.
|
174
|
-
#
|
175
|
-
# == Raises
|
176
|
-
#
|
177
|
-
# URI::InvalidURIError::
|
178
|
-
# Raised if URI given is not a correct one.
|
176
|
+
# URI.parse('https://john.doe@www.example.com:123/forum/questions/?tag=networking&order=newest#top')
|
177
|
+
# # => #<URI::HTTPS https://john.doe@www.example.com:123/forum/questions/?tag=networking&order=newest#top>
|
178
|
+
# URI.parse('http://john.doe@www.example.com:123/forum/questions/?tag=networking&order=newest#top')
|
179
|
+
# # => #<URI::HTTP http://john.doe@www.example.com:123/forum/questions/?tag=networking&order=newest#top>
|
179
180
|
#
|
180
|
-
#
|
181
|
-
#
|
182
|
-
# require 'uri'
|
183
|
-
#
|
184
|
-
# uri = URI.parse("http://www.ruby-lang.org/")
|
185
|
-
# # => #<URI::HTTP http://www.ruby-lang.org/>
|
186
|
-
# uri.scheme
|
187
|
-
# # => "http"
|
188
|
-
# uri.host
|
189
|
-
# # => "www.ruby-lang.org"
|
190
|
-
#
|
191
|
-
# It's recommended to first ::escape the provided +uri_str+ if there are any
|
192
|
-
# invalid URI characters.
|
181
|
+
# It's recommended to first ::escape string +uri+
|
182
|
+
# if it may contain invalid URI characters.
|
193
183
|
#
|
194
184
|
def self.parse(uri)
|
195
185
|
RFC3986_PARSER.parse(uri)
|
196
186
|
end
|
197
187
|
|
188
|
+
# Merges the given URI strings +str+
|
189
|
+
# per {RFC 2396}[https://www.rfc-editor.org/rfc/rfc2396.html].
|
198
190
|
#
|
199
|
-
#
|
200
|
-
#
|
201
|
-
# URI::join(str[, str, ...])
|
191
|
+
# Each string in +str+ is converted to an
|
192
|
+
# {RFC3986 URI}[https://www.rfc-editor.org/rfc/rfc3986.html] before being merged.
|
202
193
|
#
|
203
|
-
#
|
204
|
-
#
|
205
|
-
# +str+::
|
206
|
-
# String(s) to work with, will be converted to RFC3986 URIs before merging.
|
207
|
-
#
|
208
|
-
# == Description
|
209
|
-
#
|
210
|
-
# Joins URIs.
|
211
|
-
#
|
212
|
-
# == Usage
|
213
|
-
#
|
214
|
-
# require 'uri'
|
194
|
+
# Examples:
|
215
195
|
#
|
216
196
|
# URI.join("http://example.com/","main.rbx")
|
217
197
|
# # => #<URI::HTTP http://example.com/main.rbx>
|
@@ -256,7 +236,7 @@ module URI
|
|
256
236
|
# URI.extract("text here http://foo.example.org/bla and here mailto:test@example.com and here also.")
|
257
237
|
# # => ["http://foo.example.com/bla", "mailto:test@example.com"]
|
258
238
|
#
|
259
|
-
def self.extract(str, schemes = nil, &block)
|
239
|
+
def self.extract(str, schemes = nil, &block) # :nodoc:
|
260
240
|
warn "URI.extract is obsolete", uplevel: 1 if $VERBOSE
|
261
241
|
DEFAULT_PARSER.extract(str, schemes, &block)
|
262
242
|
end
|
@@ -293,7 +273,7 @@ module URI
|
|
293
273
|
# p $&
|
294
274
|
# end
|
295
275
|
#
|
296
|
-
def self.regexp(schemes = nil)
|
276
|
+
def self.regexp(schemes = nil)# :nodoc:
|
297
277
|
warn "URI.regexp is obsolete", uplevel: 1 if $VERBOSE
|
298
278
|
DEFAULT_PARSER.make_regexp(schemes)
|
299
279
|
end
|
@@ -316,40 +296,86 @@ module URI
|
|
316
296
|
TBLDECWWWCOMP_['+'] = ' '
|
317
297
|
TBLDECWWWCOMP_.freeze
|
318
298
|
|
319
|
-
#
|
299
|
+
# Returns a URL-encoded string derived from the given string +str+.
|
300
|
+
#
|
301
|
+
# The returned string:
|
302
|
+
#
|
303
|
+
# - Preserves:
|
304
|
+
#
|
305
|
+
# - Characters <tt>'*'</tt>, <tt>'.'</tt>, <tt>'-'</tt>, and <tt>'_'</tt>.
|
306
|
+
# - Character in ranges <tt>'a'..'z'</tt>, <tt>'A'..'Z'</tt>,
|
307
|
+
# and <tt>'0'..'9'</tt>.
|
308
|
+
#
|
309
|
+
# Example:
|
320
310
|
#
|
321
|
-
#
|
322
|
-
#
|
311
|
+
# URI.encode_www_form_component('*.-_azAZ09')
|
312
|
+
# # => "*.-_azAZ09"
|
323
313
|
#
|
324
|
-
#
|
314
|
+
# - Converts:
|
325
315
|
#
|
326
|
-
#
|
327
|
-
#
|
316
|
+
# - Character <tt>' '</tt> to character <tt>'+'</tt>.
|
317
|
+
# - Any other character to "percent notation";
|
318
|
+
# the percent notation for character <i>c</i> is <tt>'%%%X' % c.ord</tt>.
|
328
319
|
#
|
329
|
-
#
|
320
|
+
# Example:
|
321
|
+
#
|
322
|
+
# URI.encode_www_form_component('Here are some punctuation characters: ,;?:')
|
323
|
+
# # => "Here+are+some+punctuation+characters%3A+%2C%3B%3F%3A"
|
324
|
+
#
|
325
|
+
# Encoding:
|
326
|
+
#
|
327
|
+
# - If +str+ has encoding Encoding::ASCII_8BIT, argument +enc+ is ignored.
|
328
|
+
# - Otherwise +str+ is converted first to Encoding::UTF_8
|
329
|
+
# (with suitable character replacements),
|
330
|
+
# and then to encoding +enc+.
|
331
|
+
#
|
332
|
+
# In either case, the returned string has forced encoding Encoding::US_ASCII.
|
333
|
+
#
|
334
|
+
# Related: URI.encode_uri_component (encodes <tt>' '</tt> as <tt>'%20'</tt>).
|
330
335
|
def self.encode_www_form_component(str, enc=nil)
|
331
336
|
_encode_uri_component(/[^*\-.0-9A-Z_a-z]/, TBLENCWWWCOMP_, str, enc)
|
332
337
|
end
|
333
338
|
|
334
|
-
#
|
339
|
+
# Returns a string decoded from the given \URL-encoded string +str+.
|
340
|
+
#
|
341
|
+
# The given string is first encoded as Encoding::ASCII-8BIT (using String#b),
|
342
|
+
# then decoded (as below), and finally force-encoded to the given encoding +enc+.
|
343
|
+
#
|
344
|
+
# The returned string:
|
345
|
+
#
|
346
|
+
# - Preserves:
|
347
|
+
#
|
348
|
+
# - Characters <tt>'*'</tt>, <tt>'.'</tt>, <tt>'-'</tt>, and <tt>'_'</tt>.
|
349
|
+
# - Character in ranges <tt>'a'..'z'</tt>, <tt>'A'..'Z'</tt>,
|
350
|
+
# and <tt>'0'..'9'</tt>.
|
351
|
+
#
|
352
|
+
# Example:
|
353
|
+
#
|
354
|
+
# URI.decode_www_form_component('*.-_azAZ09')
|
355
|
+
# # => "*.-_azAZ09"
|
356
|
+
#
|
357
|
+
# - Converts:
|
358
|
+
#
|
359
|
+
# - Character <tt>'+'</tt> to character <tt>' '</tt>.
|
360
|
+
# - Each "percent notation" to an ASCII character.
|
335
361
|
#
|
336
|
-
#
|
362
|
+
# Example:
|
337
363
|
#
|
338
|
-
#
|
364
|
+
# URI.decode_www_form_component('Here+are+some+punctuation+characters%3A+%2C%3B%3F%3A')
|
365
|
+
# # => "Here are some punctuation characters: ,;?:"
|
366
|
+
#
|
367
|
+
# Related: URI.decode_uri_component (preserves <tt>'+'</tt>).
|
339
368
|
def self.decode_www_form_component(str, enc=Encoding::UTF_8)
|
340
369
|
_decode_uri_component(/\+|%\h\h/, str, enc)
|
341
370
|
end
|
342
371
|
|
343
|
-
#
|
344
|
-
#
|
345
|
-
# This encodes SP to %20 instead of +.
|
372
|
+
# Like URI.encode_www_form_component, except that <tt>' '</tt> (space)
|
373
|
+
# is encoded as <tt>'%20'</tt> (instead of <tt>'+'</tt>).
|
346
374
|
def self.encode_uri_component(str, enc=nil)
|
347
375
|
_encode_uri_component(/[^*\-.0-9A-Z_a-z]/, TBLENCURICOMP_, str, enc)
|
348
376
|
end
|
349
377
|
|
350
|
-
#
|
351
|
-
#
|
352
|
-
# This does not decode + to SP.
|
378
|
+
# Like URI.decode_www_form_component, except that <tt>'+'</tt> is preserved.
|
353
379
|
def self.decode_uri_component(str, enc=Encoding::UTF_8)
|
354
380
|
_decode_uri_component(/%\h\h/, str, enc)
|
355
381
|
end
|
@@ -374,33 +400,104 @@ module URI
|
|
374
400
|
end
|
375
401
|
private_class_method :_decode_uri_component
|
376
402
|
|
377
|
-
#
|
403
|
+
# Returns a URL-encoded string derived from the given
|
404
|
+
# {Enumerable}[https://docs.ruby-lang.org/en/master/Enumerable.html#module-Enumerable-label-Enumerable+in+Ruby+Classes]
|
405
|
+
# +enum+.
|
406
|
+
#
|
407
|
+
# The result is suitable for use as form data
|
408
|
+
# for an \HTTP request whose <tt>Content-Type</tt> is
|
409
|
+
# <tt>'application/x-www-form-urlencoded'</tt>.
|
410
|
+
#
|
411
|
+
# The returned string consists of the elements of +enum+,
|
412
|
+
# each converted to one or more URL-encoded strings,
|
413
|
+
# and all joined with character <tt>'&'</tt>.
|
414
|
+
#
|
415
|
+
# Simple examples:
|
416
|
+
#
|
417
|
+
# URI.encode_www_form([['foo', 0], ['bar', 1], ['baz', 2]])
|
418
|
+
# # => "foo=0&bar=1&baz=2"
|
419
|
+
# URI.encode_www_form({foo: 0, bar: 1, baz: 2})
|
420
|
+
# # => "foo=0&bar=1&baz=2"
|
421
|
+
#
|
422
|
+
# The returned string is formed using method URI.encode_www_form_component,
|
423
|
+
# which converts certain characters:
|
424
|
+
#
|
425
|
+
# URI.encode_www_form('f#o': '/', 'b-r': '$', 'b z': '@')
|
426
|
+
# # => "f%23o=%2F&b-r=%24&b+z=%40"
|
427
|
+
#
|
428
|
+
# When +enum+ is Array-like, each element +ele+ is converted to a field:
|
429
|
+
#
|
430
|
+
# - If +ele+ is an array of two or more elements,
|
431
|
+
# the field is formed from its first two elements
|
432
|
+
# (and any additional elements are ignored):
|
433
|
+
#
|
434
|
+
# name = URI.encode_www_form_component(ele[0], enc)
|
435
|
+
# value = URI.encode_www_form_component(ele[1], enc)
|
436
|
+
# "#{name}=#{value}"
|
378
437
|
#
|
379
|
-
#
|
380
|
-
# from given an Enumerable object.
|
438
|
+
# Examples:
|
381
439
|
#
|
382
|
-
#
|
440
|
+
# URI.encode_www_form([%w[foo bar], %w[baz bat bah]])
|
441
|
+
# # => "foo=bar&baz=bat"
|
442
|
+
# URI.encode_www_form([['foo', 0], ['bar', :baz, 'bat']])
|
443
|
+
# # => "foo=0&bar=baz"
|
383
444
|
#
|
384
|
-
#
|
385
|
-
#
|
386
|
-
# encoding or mixed encoding data. (Strings which are encoded in an HTML5
|
387
|
-
# ASCII incompatible encoding are converted to UTF-8.)
|
445
|
+
# - If +ele+ is an array of one element,
|
446
|
+
# the field is formed from <tt>ele[0]</tt>:
|
388
447
|
#
|
389
|
-
#
|
390
|
-
# multipart/form-data.
|
448
|
+
# URI.encode_www_form_component(ele[0])
|
391
449
|
#
|
392
|
-
#
|
450
|
+
# Example:
|
393
451
|
#
|
394
|
-
#
|
395
|
-
#
|
396
|
-
#
|
397
|
-
#
|
398
|
-
#
|
399
|
-
#
|
400
|
-
#
|
401
|
-
#
|
452
|
+
# URI.encode_www_form([['foo'], [:bar], [0]])
|
453
|
+
# # => "foo&bar&0"
|
454
|
+
#
|
455
|
+
# - Otherwise the field is formed from +ele+:
|
456
|
+
#
|
457
|
+
# URI.encode_www_form_component(ele)
|
458
|
+
#
|
459
|
+
# Example:
|
460
|
+
#
|
461
|
+
# URI.encode_www_form(['foo', :bar, 0])
|
462
|
+
# # => "foo&bar&0"
|
463
|
+
#
|
464
|
+
# The elements of an Array-like +enum+ may be mixture:
|
465
|
+
#
|
466
|
+
# URI.encode_www_form([['foo', 0], ['bar', 1, 2], ['baz'], :bat])
|
467
|
+
# # => "foo=0&bar=1&baz&bat"
|
468
|
+
#
|
469
|
+
# When +enum+ is Hash-like,
|
470
|
+
# each +key+/+value+ pair is converted to one or more fields:
|
471
|
+
#
|
472
|
+
# - If +value+ is
|
473
|
+
# {Array-convertible}[https://docs.ruby-lang.org/en/master/implicit_conversion_rdoc.html#label-Array-Convertible+Objects],
|
474
|
+
# each element +ele+ in +value+ is paired with +key+ to form a field:
|
475
|
+
#
|
476
|
+
# name = URI.encode_www_form_component(key, enc)
|
477
|
+
# value = URI.encode_www_form_component(ele, enc)
|
478
|
+
# "#{name}=#{value}"
|
479
|
+
#
|
480
|
+
# Example:
|
481
|
+
#
|
482
|
+
# URI.encode_www_form({foo: [:bar, 1], baz: [:bat, :bam, 2]})
|
483
|
+
# # => "foo=bar&foo=1&baz=bat&baz=bam&baz=2"
|
484
|
+
#
|
485
|
+
# - Otherwise, +key+ and +value+ are paired to form a field:
|
486
|
+
#
|
487
|
+
# name = URI.encode_www_form_component(key, enc)
|
488
|
+
# value = URI.encode_www_form_component(value, enc)
|
489
|
+
# "#{name}=#{value}"
|
490
|
+
#
|
491
|
+
# Example:
|
492
|
+
#
|
493
|
+
# URI.encode_www_form({foo: 0, bar: 1, baz: 2})
|
494
|
+
# # => "foo=0&bar=1&baz=2"
|
495
|
+
#
|
496
|
+
# The elements of a Hash-like +enum+ may be mixture:
|
497
|
+
#
|
498
|
+
# URI.encode_www_form({foo: [0, 1], bar: 2})
|
499
|
+
# # => "foo=0&foo=1&bar=2"
|
402
500
|
#
|
403
|
-
# See URI.encode_www_form_component, URI.decode_www_form.
|
404
501
|
def self.encode_www_form(enum, enc=nil)
|
405
502
|
enum.map do |k,v|
|
406
503
|
if v.nil?
|
@@ -421,22 +518,39 @@ module URI
|
|
421
518
|
end.join('&')
|
422
519
|
end
|
423
520
|
|
424
|
-
#
|
521
|
+
# Returns name/value pairs derived from the given string +str+,
|
522
|
+
# which must be an ASCII string.
|
523
|
+
#
|
524
|
+
# The method may be used to decode the body of Net::HTTPResponse object +res+
|
525
|
+
# for which <tt>res['Content-Type']</tt> is <tt>'application/x-www-form-urlencoded'</tt>.
|
526
|
+
#
|
527
|
+
# The returned data is an array of 2-element subarrays;
|
528
|
+
# each subarray is a name/value pair (both are strings).
|
529
|
+
# Each returned string has encoding +enc+,
|
530
|
+
# and has had invalid characters removed via
|
531
|
+
# {String#scrub}[https://docs.ruby-lang.org/en/master/String.html#method-i-scrub].
|
425
532
|
#
|
426
|
-
#
|
427
|
-
# and returns an array of key-value arrays.
|
533
|
+
# A simple example:
|
428
534
|
#
|
429
|
-
#
|
430
|
-
#
|
535
|
+
# URI.decode_www_form('foo=0&bar=1&baz')
|
536
|
+
# # => [["foo", "0"], ["bar", "1"], ["baz", ""]]
|
431
537
|
#
|
432
|
-
#
|
433
|
-
#
|
434
|
-
#
|
435
|
-
#
|
436
|
-
#
|
437
|
-
#
|
538
|
+
# The returned strings have certain conversions,
|
539
|
+
# similar to those performed in URI.decode_www_form_component:
|
540
|
+
#
|
541
|
+
# URI.decode_www_form('f%23o=%2F&b-r=%24&b+z=%40')
|
542
|
+
# # => [["f#o", "/"], ["b-r", "$"], ["b z", "@"]]
|
543
|
+
#
|
544
|
+
# The given string may contain consecutive separators:
|
545
|
+
#
|
546
|
+
# URI.decode_www_form('foo=0&&bar=1&&baz=2')
|
547
|
+
# # => [["foo", "0"], ["", ""], ["bar", "1"], ["", ""], ["baz", "2"]]
|
548
|
+
#
|
549
|
+
# A different separator may be specified:
|
550
|
+
#
|
551
|
+
# URI.decode_www_form('foo=0--bar=1--baz', separator: '--')
|
552
|
+
# # => [["foo", "0"], ["bar", "1"], ["baz", ""]]
|
438
553
|
#
|
439
|
-
# See URI.decode_www_form_component, URI.encode_www_form.
|
440
554
|
def self.decode_www_form(str, enc=Encoding::UTF_8, separator: '&', use__charset_: false, isindex: false)
|
441
555
|
raise ArgumentError, "the input of #{self.name}.#{__method__} must be ASCII only string" unless str.ascii_only?
|
442
556
|
ary = []
|
@@ -715,7 +829,15 @@ end # module URI
|
|
715
829
|
module Kernel
|
716
830
|
|
717
831
|
#
|
718
|
-
# Returns
|
832
|
+
# Returns a \URI object derived from the given +uri+,
|
833
|
+
# which may be a \URI string or an existing \URI object:
|
834
|
+
#
|
835
|
+
# # Returns a new URI.
|
836
|
+
# uri = URI('http://github.com/ruby/ruby')
|
837
|
+
# # => #<URI::HTTP http://github.com/ruby/ruby>
|
838
|
+
# # Returns the given URI.
|
839
|
+
# URI(uri)
|
840
|
+
# # => #<URI::HTTP http://github.com/ruby/ruby>
|
719
841
|
#
|
720
842
|
def URI(uri)
|
721
843
|
if uri.is_a?(URI::Generic)
|
data/lib/uri/generic.rb
CHANGED
@@ -1133,16 +1133,17 @@ module URI
|
|
1133
1133
|
base.fragment=(nil)
|
1134
1134
|
|
1135
1135
|
# RFC2396, Section 5.2, 4)
|
1136
|
-
if authority
|
1137
|
-
base.
|
1138
|
-
|
1139
|
-
|
1140
|
-
base.set_path(rel.path)
|
1141
|
-
elsif base.path && rel.path
|
1142
|
-
base.set_path(merge_path(base.path, rel.path))
|
1136
|
+
if !authority
|
1137
|
+
base.set_path(merge_path(base.path, rel.path)) if base.path && rel.path
|
1138
|
+
else
|
1139
|
+
# RFC2396, Section 5.2, 4)
|
1140
|
+
base.set_path(rel.path) if rel.path
|
1143
1141
|
end
|
1144
1142
|
|
1145
1143
|
# RFC2396, Section 5.2, 7)
|
1144
|
+
base.set_userinfo(rel.userinfo) if rel.userinfo
|
1145
|
+
base.set_host(rel.host) if rel.host
|
1146
|
+
base.set_port(rel.port) if rel.port
|
1146
1147
|
base.query = rel.query if rel.query
|
1147
1148
|
base.fragment=(rel.fragment) if rel.fragment
|
1148
1149
|
|
@@ -1375,6 +1376,7 @@ module URI
|
|
1375
1376
|
end
|
1376
1377
|
str
|
1377
1378
|
end
|
1379
|
+
alias to_str to_s
|
1378
1380
|
|
1379
1381
|
#
|
1380
1382
|
# Compares two URIs.
|
data/lib/uri/rfc3986_parser.rb
CHANGED
@@ -1,9 +1,73 @@
|
|
1
|
-
# frozen_string_literal:
|
1
|
+
# frozen_string_literal: true
|
2
2
|
module URI
|
3
3
|
class RFC3986_Parser # :nodoc:
|
4
4
|
# URI defined in RFC3986
|
5
|
-
|
6
|
-
|
5
|
+
HOST = %r[
|
6
|
+
(?<IP-literal>\[(?:
|
7
|
+
(?<IPv6address>
|
8
|
+
(?:\h{1,4}:){6}
|
9
|
+
(?<ls32>\h{1,4}:\h{1,4}
|
10
|
+
| (?<IPv4address>(?<dec-octet>[1-9]\d|1\d{2}|2[0-4]\d|25[0-5]|\d)
|
11
|
+
\.\g<dec-octet>\.\g<dec-octet>\.\g<dec-octet>)
|
12
|
+
)
|
13
|
+
| ::(?:\h{1,4}:){5}\g<ls32>
|
14
|
+
| \h{1,4}?::(?:\h{1,4}:){4}\g<ls32>
|
15
|
+
| (?:(?:\h{1,4}:)?\h{1,4})?::(?:\h{1,4}:){3}\g<ls32>
|
16
|
+
| (?:(?:\h{1,4}:){,2}\h{1,4})?::(?:\h{1,4}:){2}\g<ls32>
|
17
|
+
| (?:(?:\h{1,4}:){,3}\h{1,4})?::\h{1,4}:\g<ls32>
|
18
|
+
| (?:(?:\h{1,4}:){,4}\h{1,4})?::\g<ls32>
|
19
|
+
| (?:(?:\h{1,4}:){,5}\h{1,4})?::\h{1,4}
|
20
|
+
| (?:(?:\h{1,4}:){,6}\h{1,4})?::
|
21
|
+
)
|
22
|
+
| (?<IPvFuture>v\h++\.[!$&-.0-9:;=A-Z_a-z~]++)
|
23
|
+
)\])
|
24
|
+
| \g<IPv4address>
|
25
|
+
| (?<reg-name>(?:%\h\h|[!$&-.0-9;=A-Z_a-z~])*+)
|
26
|
+
]x
|
27
|
+
|
28
|
+
USERINFO = /(?:%\h\h|[!$&-.0-9:;=A-Z_a-z~])*+/
|
29
|
+
|
30
|
+
SCHEME = %r[[A-Za-z][+\-.0-9A-Za-z]*+].source
|
31
|
+
SEG = %r[(?:%\h\h|[!$&-.0-9:;=@A-Z_a-z~/])].source
|
32
|
+
SEG_NC = %r[(?:%\h\h|[!$&-.0-9;=@A-Z_a-z~])].source
|
33
|
+
FRAGMENT = %r[(?:%\h\h|[!$&-.0-9:;=@A-Z_a-z~/?])*+].source
|
34
|
+
|
35
|
+
RFC3986_URI = %r[\A
|
36
|
+
(?<seg>#{SEG}){0}
|
37
|
+
(?<URI>
|
38
|
+
(?<scheme>#{SCHEME}):
|
39
|
+
(?<hier-part>//
|
40
|
+
(?<authority>
|
41
|
+
(?:(?<userinfo>#{USERINFO.source})@)?
|
42
|
+
(?<host>#{HOST.source.delete(" \n")})
|
43
|
+
(?::(?<port>\d*+))?
|
44
|
+
)
|
45
|
+
(?<path-abempty>(?:/\g<seg>*+)?)
|
46
|
+
| (?<path-absolute>/((?!/)\g<seg>++)?)
|
47
|
+
| (?<path-rootless>(?!/)\g<seg>++)
|
48
|
+
| (?<path-empty>)
|
49
|
+
)
|
50
|
+
(?:\?(?<query>[^\#]*+))?
|
51
|
+
(?:\#(?<fragment>#{FRAGMENT}))?
|
52
|
+
)\z]x
|
53
|
+
|
54
|
+
RFC3986_relative_ref = %r[\A
|
55
|
+
(?<seg>#{SEG}){0}
|
56
|
+
(?<relative-ref>
|
57
|
+
(?<relative-part>//
|
58
|
+
(?<authority>
|
59
|
+
(?:(?<userinfo>#{USERINFO.source})@)?
|
60
|
+
(?<host>#{HOST.source.delete(" \n")}(?<!/))?
|
61
|
+
(?::(?<port>\d*+))?
|
62
|
+
)
|
63
|
+
(?<path-abempty>(?:/\g<seg>*+)?)
|
64
|
+
| (?<path-absolute>/\g<seg>*+)
|
65
|
+
| (?<path-noscheme>#{SEG_NC}++(?:/\g<seg>*+)?)
|
66
|
+
| (?<path-empty>)
|
67
|
+
)
|
68
|
+
(?:\?(?<query>[^#]*+))?
|
69
|
+
(?:\#(?<fragment>#{FRAGMENT}))?
|
70
|
+
)\z]x
|
7
71
|
attr_reader :regexp
|
8
72
|
|
9
73
|
def initialize
|
@@ -19,9 +83,9 @@ module URI
|
|
19
83
|
uri.ascii_only? or
|
20
84
|
raise InvalidURIError, "URI must be ascii only #{uri.dump}"
|
21
85
|
if m = RFC3986_URI.match(uri)
|
22
|
-
query = m["query"
|
23
|
-
scheme = m["scheme"
|
24
|
-
opaque = m["path-rootless"
|
86
|
+
query = m["query"]
|
87
|
+
scheme = m["scheme"]
|
88
|
+
opaque = m["path-rootless"]
|
25
89
|
if opaque
|
26
90
|
opaque << "?#{query}" if query
|
27
91
|
[ scheme,
|
@@ -32,35 +96,35 @@ module URI
|
|
32
96
|
nil, # path
|
33
97
|
opaque,
|
34
98
|
nil, # query
|
35
|
-
m["fragment"
|
99
|
+
m["fragment"]
|
36
100
|
]
|
37
101
|
else # normal
|
38
102
|
[ scheme,
|
39
|
-
m["userinfo"
|
40
|
-
m["host"
|
41
|
-
m["port"
|
103
|
+
m["userinfo"],
|
104
|
+
m["host"],
|
105
|
+
m["port"],
|
42
106
|
nil, # registry
|
43
|
-
(m["path-abempty"
|
44
|
-
m["path-absolute"
|
45
|
-
m["path-empty"
|
107
|
+
(m["path-abempty"] ||
|
108
|
+
m["path-absolute"] ||
|
109
|
+
m["path-empty"]),
|
46
110
|
nil, # opaque
|
47
111
|
query,
|
48
|
-
m["fragment"
|
112
|
+
m["fragment"]
|
49
113
|
]
|
50
114
|
end
|
51
115
|
elsif m = RFC3986_relative_ref.match(uri)
|
52
116
|
[ nil, # scheme
|
53
|
-
m["userinfo"
|
54
|
-
m["host"
|
55
|
-
m["port"
|
117
|
+
m["userinfo"],
|
118
|
+
m["host"],
|
119
|
+
m["port"],
|
56
120
|
nil, # registry,
|
57
|
-
(m["path-abempty"
|
58
|
-
m["path-absolute"
|
59
|
-
m["path-noscheme"
|
60
|
-
m["path-empty"
|
121
|
+
(m["path-abempty"] ||
|
122
|
+
m["path-absolute"] ||
|
123
|
+
m["path-noscheme"] ||
|
124
|
+
m["path-empty"]),
|
61
125
|
nil, # opaque
|
62
|
-
m["query"
|
63
|
-
m["fragment"
|
126
|
+
m["query"],
|
127
|
+
m["fragment"]
|
64
128
|
]
|
65
129
|
else
|
66
130
|
raise InvalidURIError, "bad URI(is not URI?): #{uri.inspect}"
|
@@ -92,14 +156,14 @@ module URI
|
|
92
156
|
|
93
157
|
def default_regexp # :nodoc:
|
94
158
|
{
|
95
|
-
SCHEME:
|
96
|
-
USERINFO:
|
97
|
-
HOST:
|
98
|
-
ABS_PATH:
|
99
|
-
REL_PATH:
|
100
|
-
QUERY:
|
101
|
-
FRAGMENT:
|
102
|
-
OPAQUE:
|
159
|
+
SCHEME: %r[\A#{SCHEME}\z]o,
|
160
|
+
USERINFO: %r[\A#{USERINFO}\z]o,
|
161
|
+
HOST: %r[\A#{HOST}\z]o,
|
162
|
+
ABS_PATH: %r[\A/#{SEG}*+\z]o,
|
163
|
+
REL_PATH: %r[\A(?!/)#{SEG}++\z]o,
|
164
|
+
QUERY: %r[\A(?:%\h\h|[!$&-.0-9:;=@A-Z_a-z~/?])*+\z],
|
165
|
+
FRAGMENT: %r[\A#{FRAGMENT}\z]o,
|
166
|
+
OPAQUE: %r[\A(?:[^/].*)?\z],
|
103
167
|
PORT: /\A[\x09\x0a\x0c\x0d ]*+\d*[\x09\x0a\x0c\x0d ]*\z/,
|
104
168
|
}
|
105
169
|
end
|
data/lib/uri/version.rb
CHANGED
@@ -0,0 +1,17 @@
|
|
1
|
+
task :sync_tool, [:from] do |t, from: nil|
|
2
|
+
from ||= (File.identical?(__dir__, "rakelib") ? "../ruby/tool" : File.dirname(__dir__))
|
3
|
+
|
4
|
+
require 'fileutils'
|
5
|
+
|
6
|
+
{
|
7
|
+
"rakelib/sync_tool.rake" => "rakelib",
|
8
|
+
"lib/core_assertions.rb" => "test/lib",
|
9
|
+
"lib/envutil.rb" => "test/lib",
|
10
|
+
"lib/find_executable.rb" => "test/lib",
|
11
|
+
"lib/helper.rb" => "test/lib",
|
12
|
+
}.each do |src, dest|
|
13
|
+
FileUtils.mkpath(dest)
|
14
|
+
FileUtils.cp "#{from}/#{src}", dest
|
15
|
+
rescue Errno::ENOENT
|
16
|
+
end
|
17
|
+
end
|
data/uri.gemspec
CHANGED
@@ -12,18 +12,26 @@ Gem::Specification.new do |spec|
|
|
12
12
|
|
13
13
|
spec.summary = %q{URI is a module providing classes to handle Uniform Resource Identifiers}
|
14
14
|
spec.description = spec.summary
|
15
|
-
|
15
|
+
|
16
|
+
github_link = "https://github.com/ruby/uri"
|
17
|
+
|
18
|
+
spec.homepage = github_link
|
16
19
|
spec.licenses = ["Ruby", "BSD-2-Clause"]
|
17
20
|
|
18
|
-
spec.required_ruby_version = '>= 2.
|
21
|
+
spec.required_ruby_version = '>= 2.5'
|
19
22
|
|
20
|
-
spec.metadata
|
21
|
-
|
23
|
+
spec.metadata = {
|
24
|
+
"bug_tracker_uri" => "#{github_link}/issues",
|
25
|
+
"changelog_uri" => "#{github_link}/releases",
|
26
|
+
"documentation_uri" => "https://ruby.github.io/uri/",
|
27
|
+
"homepage_uri" => spec.homepage,
|
28
|
+
"source_code_uri" => github_link
|
29
|
+
}
|
22
30
|
|
23
31
|
# Specify which files should be added to the gem when it is released.
|
24
32
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
25
33
|
spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
|
26
|
-
`git ls-files -z 2
|
34
|
+
`git ls-files -z 2>#{IO::NULL}`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
27
35
|
end
|
28
36
|
spec.bindir = "exe"
|
29
37
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: uri
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.13.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Akira Yamada
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-11-06 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: URI is a module providing classes to handle Uniform Resource Identifiers
|
14
14
|
email:
|
@@ -18,6 +18,7 @@ extensions: []
|
|
18
18
|
extra_rdoc_files: []
|
19
19
|
files:
|
20
20
|
- ".github/dependabot.yml"
|
21
|
+
- ".github/workflows/gh-pages.yml"
|
21
22
|
- ".github/workflows/test.yml"
|
22
23
|
- ".gitignore"
|
23
24
|
- Gemfile
|
@@ -41,12 +42,16 @@ files:
|
|
41
42
|
- lib/uri/version.rb
|
42
43
|
- lib/uri/ws.rb
|
43
44
|
- lib/uri/wss.rb
|
45
|
+
- rakelib/sync_tool.rake
|
44
46
|
- uri.gemspec
|
45
47
|
homepage: https://github.com/ruby/uri
|
46
48
|
licenses:
|
47
49
|
- Ruby
|
48
50
|
- BSD-2-Clause
|
49
51
|
metadata:
|
52
|
+
bug_tracker_uri: https://github.com/ruby/uri/issues
|
53
|
+
changelog_uri: https://github.com/ruby/uri/releases
|
54
|
+
documentation_uri: https://ruby.github.io/uri/
|
50
55
|
homepage_uri: https://github.com/ruby/uri
|
51
56
|
source_code_uri: https://github.com/ruby/uri
|
52
57
|
post_install_message:
|
@@ -57,14 +62,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
57
62
|
requirements:
|
58
63
|
- - ">="
|
59
64
|
- !ruby/object:Gem::Version
|
60
|
-
version: '2.
|
65
|
+
version: '2.5'
|
61
66
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
62
67
|
requirements:
|
63
68
|
- - ">="
|
64
69
|
- !ruby/object:Gem::Version
|
65
70
|
version: '0'
|
66
71
|
requirements: []
|
67
|
-
rubygems_version: 3.
|
72
|
+
rubygems_version: 3.5.0.dev
|
68
73
|
signing_key:
|
69
74
|
specification_version: 4
|
70
75
|
summary: URI is a module providing classes to handle Uniform Resource Identifiers
|