addressable 2.3.7 → 2.7.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of addressable might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +60 -0
- data/Gemfile +22 -16
- data/README.md +31 -15
- data/Rakefile +8 -11
- data/lib/addressable.rb +4 -0
- data/lib/addressable/idna.rb +3 -1
- data/lib/addressable/idna/native.rb +11 -5
- data/lib/addressable/idna/pure.rb +29 -26
- data/lib/addressable/template.rb +135 -28
- data/lib/addressable/uri.rb +379 -202
- data/lib/addressable/version.rb +5 -3
- data/spec/addressable/idna_spec.rb +48 -2
- data/spec/addressable/net_http_compat_spec.rb +3 -1
- data/spec/addressable/rack_mount_compat_spec.rb +106 -0
- data/spec/addressable/security_spec.rb +59 -0
- data/spec/addressable/template_spec.rb +126 -15
- data/spec/addressable/uri_spec.rb +608 -29
- data/spec/spec_helper.rb +17 -1
- data/tasks/clobber.rake +2 -0
- data/tasks/gem.rake +22 -16
- data/tasks/git.rake +2 -0
- data/tasks/metrics.rake +2 -0
- data/tasks/rspec.rake +9 -29
- data/tasks/yard.rake +2 -0
- metadata +30 -57
- data/tasks/rubyforge.rake +0 -73
- data/website/index.html +0 -110
@@ -1,5 +1,7 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# coding: utf-8
|
2
|
-
# Copyright (C)
|
4
|
+
# Copyright (C) Bob Aman
|
3
5
|
#
|
4
6
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
7
|
# you may not use this file except in compliance with the License.
|
@@ -18,6 +20,7 @@ require "spec_helper"
|
|
18
20
|
|
19
21
|
require "addressable/uri"
|
20
22
|
require "uri"
|
23
|
+
require "ipaddr"
|
21
24
|
|
22
25
|
if !"".respond_to?("force_encoding")
|
23
26
|
class String
|
@@ -68,6 +71,14 @@ describe Addressable::URI, "when created with a non-numeric port number" do
|
|
68
71
|
end
|
69
72
|
end
|
70
73
|
|
74
|
+
describe Addressable::URI, "when created with a invalid encoded port number" do
|
75
|
+
it "should raise an error" do
|
76
|
+
expect(lambda do
|
77
|
+
Addressable::URI.new(:port => "%eb")
|
78
|
+
end).to raise_error(Addressable::URI::InvalidURIError)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
71
82
|
describe Addressable::URI, "when created with a non-string scheme" do
|
72
83
|
it "should raise an error" do
|
73
84
|
expect(lambda do
|
@@ -116,14 +127,6 @@ describe Addressable::URI, "when created with a non-string authority" do
|
|
116
127
|
end
|
117
128
|
end
|
118
129
|
|
119
|
-
describe Addressable::URI, "when created with a non-string authority" do
|
120
|
-
it "should raise an error" do
|
121
|
-
expect(lambda do
|
122
|
-
Addressable::URI.new(:authority => :bogus)
|
123
|
-
end).to raise_error(TypeError)
|
124
|
-
end
|
125
|
-
end
|
126
|
-
|
127
130
|
describe Addressable::URI, "when created with a non-string path" do
|
128
131
|
it "should raise an error" do
|
129
132
|
expect(lambda do
|
@@ -157,6 +160,51 @@ describe Addressable::URI, "when created with a scheme but no hierarchical " +
|
|
157
160
|
end
|
158
161
|
end
|
159
162
|
|
163
|
+
describe Addressable::URI, "quote handling" do
|
164
|
+
describe 'in host name' do
|
165
|
+
it "should raise an error for single quote" do
|
166
|
+
expect(lambda do
|
167
|
+
Addressable::URI.parse("http://local\"host/")
|
168
|
+
end).to raise_error(Addressable::URI::InvalidURIError)
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
describe Addressable::URI, "newline normalization" do
|
174
|
+
it "should not accept newlines in scheme" do
|
175
|
+
expect(lambda do
|
176
|
+
Addressable::URI.parse("ht%0atp://localhost/")
|
177
|
+
end).to raise_error(Addressable::URI::InvalidURIError)
|
178
|
+
end
|
179
|
+
|
180
|
+
it "should not unescape newline in path" do
|
181
|
+
uri = Addressable::URI.parse("http://localhost/%0a").normalize
|
182
|
+
expect(uri.to_s).to eq("http://localhost/%0A")
|
183
|
+
end
|
184
|
+
|
185
|
+
it "should not unescape newline in hostname" do
|
186
|
+
uri = Addressable::URI.parse("http://local%0ahost/").normalize
|
187
|
+
expect(uri.to_s).to eq("http://local%0Ahost/")
|
188
|
+
end
|
189
|
+
|
190
|
+
it "should not unescape newline in username" do
|
191
|
+
uri = Addressable::URI.parse("http://foo%0abar@localhost/").normalize
|
192
|
+
expect(uri.to_s).to eq("http://foo%0Abar@localhost/")
|
193
|
+
end
|
194
|
+
|
195
|
+
it "should not unescape newline in username" do
|
196
|
+
uri = Addressable::URI.parse("http://example:foo%0abar@example/").normalize
|
197
|
+
expect(uri.to_s).to eq("http://example:foo%0Abar@example/")
|
198
|
+
end
|
199
|
+
|
200
|
+
it "should not accept newline in hostname" do
|
201
|
+
uri = Addressable::URI.parse("http://localhost/")
|
202
|
+
expect(lambda do
|
203
|
+
uri.host = "local\nhost"
|
204
|
+
end).to raise_error(Addressable::URI::InvalidURIError)
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
160
208
|
describe Addressable::URI, "when created with ambiguous path" do
|
161
209
|
it "should raise an error" do
|
162
210
|
expect(lambda do
|
@@ -173,6 +221,28 @@ describe Addressable::URI, "when created with an invalid host" do
|
|
173
221
|
end
|
174
222
|
end
|
175
223
|
|
224
|
+
describe Addressable::URI, "when created with a host consisting of " +
|
225
|
+
"sub-delims characters" do
|
226
|
+
it "should not raise an error" do
|
227
|
+
expect(lambda do
|
228
|
+
Addressable::URI.new(
|
229
|
+
:host => Addressable::URI::CharacterClasses::SUB_DELIMS.gsub(/\\/, '')
|
230
|
+
)
|
231
|
+
end).not_to raise_error
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
describe Addressable::URI, "when created with a host consisting of " +
|
236
|
+
"unreserved characters" do
|
237
|
+
it "should not raise an error" do
|
238
|
+
expect(lambda do
|
239
|
+
Addressable::URI.new(
|
240
|
+
:host => Addressable::URI::CharacterClasses::UNRESERVED.gsub(/\\/, '')
|
241
|
+
)
|
242
|
+
end).not_to raise_error
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|
176
246
|
describe Addressable::URI, "when created from nil components" do
|
177
247
|
before do
|
178
248
|
@uri = Addressable::URI.new
|
@@ -210,6 +280,48 @@ describe Addressable::URI, "when created from nil components" do
|
|
210
280
|
end).to raise_error(Addressable::URI::InvalidURIError)
|
211
281
|
end
|
212
282
|
|
283
|
+
it "should raise an error if the scheme begins with a digit" do
|
284
|
+
expect(lambda do
|
285
|
+
@uri.scheme = "1scheme"
|
286
|
+
end).to raise_error(Addressable::URI::InvalidURIError)
|
287
|
+
end
|
288
|
+
|
289
|
+
it "should raise an error if the scheme begins with a plus" do
|
290
|
+
expect(lambda do
|
291
|
+
@uri.scheme = "+scheme"
|
292
|
+
end).to raise_error(Addressable::URI::InvalidURIError)
|
293
|
+
end
|
294
|
+
|
295
|
+
it "should raise an error if the scheme begins with a dot" do
|
296
|
+
expect(lambda do
|
297
|
+
@uri.scheme = ".scheme"
|
298
|
+
end).to raise_error(Addressable::URI::InvalidURIError)
|
299
|
+
end
|
300
|
+
|
301
|
+
it "should raise an error if the scheme begins with a dash" do
|
302
|
+
expect(lambda do
|
303
|
+
@uri.scheme = "-scheme"
|
304
|
+
end).to raise_error(Addressable::URI::InvalidURIError)
|
305
|
+
end
|
306
|
+
|
307
|
+
it "should raise an error if the scheme contains an illegal character" do
|
308
|
+
expect(lambda do
|
309
|
+
@uri.scheme = "scheme!"
|
310
|
+
end).to raise_error(Addressable::URI::InvalidURIError)
|
311
|
+
end
|
312
|
+
|
313
|
+
it "should raise an error if the scheme contains whitespace" do
|
314
|
+
expect(lambda do
|
315
|
+
@uri.scheme = "sch eme"
|
316
|
+
end).to raise_error(Addressable::URI::InvalidURIError)
|
317
|
+
end
|
318
|
+
|
319
|
+
it "should raise an error if the scheme contains a newline" do
|
320
|
+
expect(lambda do
|
321
|
+
@uri.scheme = "sch\neme"
|
322
|
+
end).to raise_error(Addressable::URI::InvalidURIError)
|
323
|
+
end
|
324
|
+
|
213
325
|
it "should raise an error if set into an invalid state" do
|
214
326
|
expect(lambda do
|
215
327
|
@uri.user = "user"
|
@@ -291,6 +403,10 @@ describe Addressable::URI, "when initialized from individual components" do
|
|
291
403
|
expect(@uri.normalized_host).to eq("example.com")
|
292
404
|
end
|
293
405
|
|
406
|
+
it "returns 'com' for #tld" do
|
407
|
+
expect(@uri.tld).to eq("com")
|
408
|
+
end
|
409
|
+
|
294
410
|
it "returns 'user:password@example.com:8080' for #authority" do
|
295
411
|
expect(@uri.authority).to eq("user:password@example.com:8080")
|
296
412
|
end
|
@@ -841,6 +957,10 @@ describe Addressable::URI, "when frozen" do
|
|
841
957
|
expect(@uri.normalize.query).to eq("a=1")
|
842
958
|
end
|
843
959
|
|
960
|
+
it "returns '/%70a%74%68?a=%31' for #request_uri" do
|
961
|
+
expect(@uri.request_uri).to eq("/%70a%74%68?a=%31")
|
962
|
+
end
|
963
|
+
|
844
964
|
it "returns '1%323' for #fragment" do
|
845
965
|
expect(@uri.fragment).to eq("1%323")
|
846
966
|
end
|
@@ -955,6 +1075,30 @@ describe Addressable::URI, "when created with a host with trailing dots" do
|
|
955
1075
|
end
|
956
1076
|
end
|
957
1077
|
|
1078
|
+
describe Addressable::URI, "when created with a host with a backslash" do
|
1079
|
+
it "should raise an error" do
|
1080
|
+
expect(lambda do
|
1081
|
+
Addressable::URI.new(:authority => "example\\example")
|
1082
|
+
end).to raise_error(Addressable::URI::InvalidURIError)
|
1083
|
+
end
|
1084
|
+
end
|
1085
|
+
|
1086
|
+
describe Addressable::URI, "when created with a host with a slash" do
|
1087
|
+
it "should raise an error" do
|
1088
|
+
expect(lambda do
|
1089
|
+
Addressable::URI.new(:authority => "example/example")
|
1090
|
+
end).to raise_error(Addressable::URI::InvalidURIError)
|
1091
|
+
end
|
1092
|
+
end
|
1093
|
+
|
1094
|
+
describe Addressable::URI, "when created with a host with a space" do
|
1095
|
+
it "should raise an error" do
|
1096
|
+
expect(lambda do
|
1097
|
+
Addressable::URI.new(:authority => "example example")
|
1098
|
+
end).to raise_error(Addressable::URI::InvalidURIError)
|
1099
|
+
end
|
1100
|
+
end
|
1101
|
+
|
958
1102
|
describe Addressable::URI, "when created with both a userinfo and a user" do
|
959
1103
|
it "should raise an error" do
|
960
1104
|
expect(lambda do
|
@@ -1025,6 +1169,26 @@ describe Addressable::URI, "when parsed from an Addressable::URI object" do
|
|
1025
1169
|
expect(original_uri.host).to eq('example.com')
|
1026
1170
|
expect(original_uri.to_s).to eq('http://example.com/')
|
1027
1171
|
end
|
1172
|
+
|
1173
|
+
it "should not have unexpected side-effects" do
|
1174
|
+
original_uri = Addressable::URI.parse("http://example.com/")
|
1175
|
+
new_uri = Addressable::URI.parse(original_uri)
|
1176
|
+
new_uri.origin = 'https://www.example.com:8080'
|
1177
|
+
expect(new_uri.host).to eq('www.example.com')
|
1178
|
+
expect(new_uri.to_s).to eq('https://www.example.com:8080/')
|
1179
|
+
expect(original_uri.host).to eq('example.com')
|
1180
|
+
expect(original_uri.to_s).to eq('http://example.com/')
|
1181
|
+
end
|
1182
|
+
|
1183
|
+
it "should not have unexpected side-effects" do
|
1184
|
+
original_uri = Addressable::URI.parse("http://example.com/")
|
1185
|
+
new_uri = Addressable::URI.heuristic_parse(original_uri)
|
1186
|
+
new_uri.origin = 'https://www.example.com:8080'
|
1187
|
+
expect(new_uri.host).to eq('www.example.com')
|
1188
|
+
expect(new_uri.to_s).to eq('https://www.example.com:8080/')
|
1189
|
+
expect(original_uri.host).to eq('example.com')
|
1190
|
+
expect(original_uri.to_s).to eq('http://example.com/')
|
1191
|
+
end
|
1028
1192
|
end
|
1029
1193
|
|
1030
1194
|
describe Addressable::URI, "when parsed from something that looks " +
|
@@ -1037,6 +1201,15 @@ describe Addressable::URI, "when parsed from something that looks " +
|
|
1037
1201
|
end
|
1038
1202
|
end
|
1039
1203
|
|
1204
|
+
describe Addressable::URI, "when parsed from a standard library URI object" do
|
1205
|
+
it "should parse without error" do
|
1206
|
+
uri = Addressable::URI.parse(URI.parse("http://example.com/"))
|
1207
|
+
expect(lambda do
|
1208
|
+
Addressable::URI.parse(uri)
|
1209
|
+
end).not_to raise_error
|
1210
|
+
end
|
1211
|
+
end
|
1212
|
+
|
1040
1213
|
describe Addressable::URI, "when parsed from ''" do
|
1041
1214
|
before do
|
1042
1215
|
@uri = Addressable::URI.parse("")
|
@@ -1628,7 +1801,7 @@ describe Addressable::URI, "when parsed from " +
|
|
1628
1801
|
end
|
1629
1802
|
|
1630
1803
|
it "should have the same hash as http://EXAMPLE.com after assignment" do
|
1631
|
-
@uri.
|
1804
|
+
@uri.origin = "http://EXAMPLE.com"
|
1632
1805
|
expect(@uri.hash).to eq(Addressable::URI.parse("http://EXAMPLE.com").hash)
|
1633
1806
|
end
|
1634
1807
|
|
@@ -1636,6 +1809,24 @@ describe Addressable::URI, "when parsed from " +
|
|
1636
1809
|
expect(@uri.hash).not_to eq(Addressable::URI.parse("http://EXAMPLE.com").hash)
|
1637
1810
|
end
|
1638
1811
|
|
1812
|
+
it "should not allow origin assignment without scheme" do
|
1813
|
+
expect(lambda do
|
1814
|
+
@uri.origin = "example.com"
|
1815
|
+
end).to raise_error(Addressable::URI::InvalidURIError)
|
1816
|
+
end
|
1817
|
+
|
1818
|
+
it "should not allow origin assignment without host" do
|
1819
|
+
expect(lambda do
|
1820
|
+
@uri.origin = "http://"
|
1821
|
+
end).to raise_error(Addressable::URI::InvalidURIError)
|
1822
|
+
end
|
1823
|
+
|
1824
|
+
it "should not allow origin assignment with bogus type" do
|
1825
|
+
expect(lambda do
|
1826
|
+
@uri.origin = :bogus
|
1827
|
+
end).to raise_error(TypeError)
|
1828
|
+
end
|
1829
|
+
|
1639
1830
|
# Section 6.2.3 of RFC 3986
|
1640
1831
|
it "should be equivalent to http://example.com/" do
|
1641
1832
|
expect(@uri).to eq(Addressable::URI.parse("http://example.com/"))
|
@@ -1786,15 +1977,29 @@ end
|
|
1786
1977
|
|
1787
1978
|
# Section 5.1.2 of RFC 2616
|
1788
1979
|
describe Addressable::URI, "when parsed from " +
|
1789
|
-
"'
|
1980
|
+
"'HTTP://www.w3.org/pub/WWW/TheProject.html'" do
|
1790
1981
|
before do
|
1791
|
-
@uri = Addressable::URI.parse("
|
1982
|
+
@uri = Addressable::URI.parse("HTTP://www.w3.org/pub/WWW/TheProject.html")
|
1792
1983
|
end
|
1793
1984
|
|
1794
1985
|
it "should have the correct request URI" do
|
1795
1986
|
expect(@uri.request_uri).to eq("/pub/WWW/TheProject.html")
|
1796
1987
|
end
|
1797
1988
|
|
1989
|
+
it "should have the correct request URI after assignment" do
|
1990
|
+
@uri.request_uri = "/pub/WWW/TheProject.html?"
|
1991
|
+
expect(@uri.request_uri).to eq("/pub/WWW/TheProject.html?")
|
1992
|
+
expect(@uri.path).to eq("/pub/WWW/TheProject.html")
|
1993
|
+
expect(@uri.query).to eq("")
|
1994
|
+
end
|
1995
|
+
|
1996
|
+
it "should have the correct request URI after assignment" do
|
1997
|
+
@uri.request_uri = "/some/where/else.html"
|
1998
|
+
expect(@uri.request_uri).to eq("/some/where/else.html")
|
1999
|
+
expect(@uri.path).to eq("/some/where/else.html")
|
2000
|
+
expect(@uri.query).to eq(nil)
|
2001
|
+
end
|
2002
|
+
|
1798
2003
|
it "should have the correct request URI after assignment" do
|
1799
2004
|
@uri.request_uri = "/some/where/else.html?query?string"
|
1800
2005
|
expect(@uri.request_uri).to eq("/some/where/else.html?query?string")
|
@@ -1823,7 +2028,7 @@ describe Addressable::URI, "when parsed from " +
|
|
1823
2028
|
|
1824
2029
|
it "should correctly convert to a hash" do
|
1825
2030
|
expect(@uri.to_hash).to eq({
|
1826
|
-
:scheme => "
|
2031
|
+
:scheme => "HTTP",
|
1827
2032
|
:user => nil,
|
1828
2033
|
:password => nil,
|
1829
2034
|
:host => "www.w3.org",
|
@@ -1886,6 +2091,12 @@ describe Addressable::URI, "when assigning IPv6 address" do
|
|
1886
2091
|
expect(uri.to_s).to eq('http://[3ffe:1900:4545:3:200:f8ff:fe21:67cf]/')
|
1887
2092
|
end
|
1888
2093
|
|
2094
|
+
it "should allow to set bare IPv6 address as hostname with IPAddr object" do
|
2095
|
+
uri = Addressable::URI.parse("http://[::1]/")
|
2096
|
+
uri.hostname = IPAddr.new('3ffe:1900:4545:3:200:f8ff:fe21:67cf')
|
2097
|
+
expect(uri.to_s).to eq('http://[3ffe:1900:4545:3:200:f8ff:fe21:67cf]/')
|
2098
|
+
end
|
2099
|
+
|
1889
2100
|
it "should not allow to set bare IPv6 address as host" do
|
1890
2101
|
uri = Addressable::URI.parse("http://[::1]/")
|
1891
2102
|
skip "not checked"
|
@@ -2167,6 +2378,80 @@ describe Addressable::URI, "when parsed from " +
|
|
2167
2378
|
end
|
2168
2379
|
end
|
2169
2380
|
|
2381
|
+
describe Addressable::URI, "when parsed from " +
|
2382
|
+
"'HTTP://EXAMPLE.COM/'" do
|
2383
|
+
before do
|
2384
|
+
@uri = Addressable::URI.parse("HTTP://EXAMPLE.COM/")
|
2385
|
+
end
|
2386
|
+
|
2387
|
+
it "should be equivalent to http://example.com" do
|
2388
|
+
expect(@uri).to eq(Addressable::URI.parse("http://example.com"))
|
2389
|
+
end
|
2390
|
+
|
2391
|
+
it "should correctly convert to a hash" do
|
2392
|
+
expect(@uri.to_hash).to eq({
|
2393
|
+
:scheme => "HTTP",
|
2394
|
+
:user => nil,
|
2395
|
+
:password => nil,
|
2396
|
+
:host => "EXAMPLE.COM",
|
2397
|
+
:port => nil,
|
2398
|
+
:path => "/",
|
2399
|
+
:query => nil,
|
2400
|
+
:fragment => nil
|
2401
|
+
})
|
2402
|
+
end
|
2403
|
+
|
2404
|
+
it "should be identical to its duplicate" do
|
2405
|
+
expect(@uri).to eq(@uri.dup)
|
2406
|
+
end
|
2407
|
+
|
2408
|
+
it "should have an origin of 'http://example.com'" do
|
2409
|
+
expect(@uri.origin).to eq('http://example.com')
|
2410
|
+
end
|
2411
|
+
|
2412
|
+
it "should have a tld of 'com'" do
|
2413
|
+
expect(@uri.tld).to eq('com')
|
2414
|
+
end
|
2415
|
+
end
|
2416
|
+
|
2417
|
+
describe Addressable::URI, "when parsed from " +
|
2418
|
+
"'http://www.example.co.uk/'" do
|
2419
|
+
before do
|
2420
|
+
@uri = Addressable::URI.parse("http://www.example.co.uk/")
|
2421
|
+
end
|
2422
|
+
|
2423
|
+
it "should have an origin of 'http://www.example.co.uk'" do
|
2424
|
+
expect(@uri.origin).to eq('http://www.example.co.uk')
|
2425
|
+
end
|
2426
|
+
|
2427
|
+
it "should have a tld of 'co.uk'" do
|
2428
|
+
expect(@uri.tld).to eq('co.uk')
|
2429
|
+
end
|
2430
|
+
|
2431
|
+
it "should have a domain of 'example.co.uk'" do
|
2432
|
+
expect(@uri.domain).to eq('example.co.uk')
|
2433
|
+
end
|
2434
|
+
end
|
2435
|
+
|
2436
|
+
describe Addressable::URI, "when parsed from " +
|
2437
|
+
"'http://sub_domain.blogspot.com/'" do
|
2438
|
+
before do
|
2439
|
+
@uri = Addressable::URI.parse("http://sub_domain.blogspot.com/")
|
2440
|
+
end
|
2441
|
+
|
2442
|
+
it "should have an origin of 'http://sub_domain.blogspot.com'" do
|
2443
|
+
expect(@uri.origin).to eq('http://sub_domain.blogspot.com')
|
2444
|
+
end
|
2445
|
+
|
2446
|
+
it "should have a tld of 'com'" do
|
2447
|
+
expect(@uri.tld).to eq('com')
|
2448
|
+
end
|
2449
|
+
|
2450
|
+
it "should have a domain of 'blogspot.com'" do
|
2451
|
+
expect(@uri.domain).to eq('blogspot.com')
|
2452
|
+
end
|
2453
|
+
end
|
2454
|
+
|
2170
2455
|
describe Addressable::URI, "when parsed from " +
|
2171
2456
|
"'http://example.com/~smith/'" do
|
2172
2457
|
before do
|
@@ -2808,6 +3093,23 @@ describe Addressable::URI, "when parsed from " +
|
|
2808
3093
|
end
|
2809
3094
|
end
|
2810
3095
|
|
3096
|
+
describe Addressable::URI, "when parsed from " +
|
3097
|
+
"'/..//example.com'" do
|
3098
|
+
before do
|
3099
|
+
@uri = Addressable::URI.parse("/..//example.com")
|
3100
|
+
end
|
3101
|
+
|
3102
|
+
it "should become invalid when normalized" do
|
3103
|
+
expect(lambda do
|
3104
|
+
@uri.normalize
|
3105
|
+
end).to raise_error(Addressable::URI::InvalidURIError, /authority/)
|
3106
|
+
end
|
3107
|
+
|
3108
|
+
it "should have a path of '/..//example.com'" do
|
3109
|
+
expect(@uri.path).to eq("/..//example.com")
|
3110
|
+
end
|
3111
|
+
end
|
3112
|
+
|
2811
3113
|
describe Addressable::URI, "when parsed from '/a/b/c/./../../g'" do
|
2812
3114
|
before do
|
2813
3115
|
@uri = Addressable::URI.parse("/a/b/c/./../../g")
|
@@ -3564,15 +3866,6 @@ describe Addressable::URI, "when parsed from " +
|
|
3564
3866
|
expect(@uri.to_str).to eq(
|
3565
3867
|
"ftp://user:pass@example.com/path/to/resource?query=x#fragment"
|
3566
3868
|
)
|
3567
|
-
@uri.scheme = "bogus!"
|
3568
|
-
expect(@uri.scheme).to eq("bogus!")
|
3569
|
-
expect(@uri.normalized_scheme).to eq("bogus%21")
|
3570
|
-
expect(@uri.normalize.to_s).to eq(
|
3571
|
-
"bogus%21://user:pass@example.com/path/to/resource?query=x#fragment"
|
3572
|
-
)
|
3573
|
-
expect(@uri.normalize.to_str).to eq(
|
3574
|
-
"bogus%21://user:pass@example.com/path/to/resource?query=x#fragment"
|
3575
|
-
)
|
3576
3869
|
end
|
3577
3870
|
|
3578
3871
|
it "should have the correct site segment after assignment" do
|
@@ -3641,12 +3934,31 @@ describe Addressable::URI, "when parsed from " +
|
|
3641
3934
|
expect(@uri.authority).to eq("user:pass@newexample.com")
|
3642
3935
|
end
|
3643
3936
|
|
3937
|
+
it "should have the correct host after assignment" do
|
3938
|
+
@uri.hostname = "newexample.com"
|
3939
|
+
expect(@uri.host).to eq("newexample.com")
|
3940
|
+
expect(@uri.hostname).to eq("newexample.com")
|
3941
|
+
expect(@uri.authority).to eq("user:pass@newexample.com")
|
3942
|
+
end
|
3943
|
+
|
3944
|
+
it "should raise an error if assigning a bogus object to the hostname" do
|
3945
|
+
expect(lambda do
|
3946
|
+
@uri.hostname = Object.new
|
3947
|
+
end).to raise_error(TypeError)
|
3948
|
+
end
|
3949
|
+
|
3644
3950
|
it "should have the correct port after assignment" do
|
3645
3951
|
@uri.port = 8080
|
3646
3952
|
expect(@uri.port).to eq(8080)
|
3647
3953
|
expect(@uri.authority).to eq("user:pass@example.com:8080")
|
3648
3954
|
end
|
3649
3955
|
|
3956
|
+
it "should have the correct origin after assignment" do
|
3957
|
+
@uri.origin = "http://newexample.com"
|
3958
|
+
expect(@uri.host).to eq("newexample.com")
|
3959
|
+
expect(@uri.authority).to eq("newexample.com")
|
3960
|
+
end
|
3961
|
+
|
3650
3962
|
it "should have the correct path after assignment" do
|
3651
3963
|
@uri.path = "/newpath/to/resource"
|
3652
3964
|
expect(@uri.path).to eq("/newpath/to/resource")
|
@@ -3991,6 +4303,26 @@ describe Addressable::URI, "when parsed from " +
|
|
3991
4303
|
end
|
3992
4304
|
end
|
3993
4305
|
|
4306
|
+
describe Addressable::URI, "when parsed from 'http://example/?b=1&a=2&c=3'" do
|
4307
|
+
before do
|
4308
|
+
@uri = Addressable::URI.parse("http://example/?b=1&a=2&c=3")
|
4309
|
+
end
|
4310
|
+
|
4311
|
+
it "should have a sorted normalized query of 'a=2&b=1&c=3'" do
|
4312
|
+
expect(@uri.normalized_query(:sorted)).to eq("a=2&b=1&c=3")
|
4313
|
+
end
|
4314
|
+
end
|
4315
|
+
|
4316
|
+
describe Addressable::URI, "when parsed from 'http://example/?&a&&c&'" do
|
4317
|
+
before do
|
4318
|
+
@uri = Addressable::URI.parse("http://example/?&a&&c&")
|
4319
|
+
end
|
4320
|
+
|
4321
|
+
it "should have a compacted normalized query of 'a&c'" do
|
4322
|
+
expect(@uri.normalized_query(:compacted)).to eq("a&c")
|
4323
|
+
end
|
4324
|
+
end
|
4325
|
+
|
3994
4326
|
describe Addressable::URI, "when parsed from " +
|
3995
4327
|
"'http://example.com/sound%2bvision'" do
|
3996
4328
|
before do
|
@@ -4105,7 +4437,7 @@ describe Addressable::URI, "when parsed from " +
|
|
4105
4437
|
expect(lambda do
|
4106
4438
|
# This would create an invalid URI
|
4107
4439
|
@uri.authority = nil
|
4108
|
-
end).to raise_error
|
4440
|
+
end).to raise_error(Addressable::URI::InvalidURIError)
|
4109
4441
|
end
|
4110
4442
|
end
|
4111
4443
|
|
@@ -4508,7 +4840,7 @@ describe Addressable::URI, "when parsed from '?one=1&two=2&three=3'" do
|
|
4508
4840
|
|
4509
4841
|
it "should raise an error for invalid return type values" do
|
4510
4842
|
expect(lambda do
|
4511
|
-
@uri.query_values(
|
4843
|
+
@uri.query_values(Integer)
|
4512
4844
|
end).to raise_error(ArgumentError)
|
4513
4845
|
end
|
4514
4846
|
|
@@ -5194,6 +5526,31 @@ describe Addressable::URI, "when given the path '/one/two/'" do
|
|
5194
5526
|
end
|
5195
5527
|
end
|
5196
5528
|
|
5529
|
+
describe Addressable::URI, "when given the tld " do
|
5530
|
+
it "'uk' should have a tld of 'uk'" do
|
5531
|
+
uri = Addressable::URI.parse("http://example.com")
|
5532
|
+
uri.tld = "uk"
|
5533
|
+
|
5534
|
+
expect(uri.tld).to eq("uk")
|
5535
|
+
end
|
5536
|
+
|
5537
|
+
context "which " do
|
5538
|
+
let (:uri) { Addressable::URI.parse("http://www.comrade.net/path/to/source/") }
|
5539
|
+
|
5540
|
+
it "contains a subdomain" do
|
5541
|
+
uri.tld = "co.uk"
|
5542
|
+
|
5543
|
+
expect(uri.to_s).to eq("http://www.comrade.co.uk/path/to/source/")
|
5544
|
+
end
|
5545
|
+
|
5546
|
+
it "is part of the domain" do
|
5547
|
+
uri.tld = "com"
|
5548
|
+
|
5549
|
+
expect(uri.to_s).to eq("http://www.comrade.com/path/to/source/")
|
5550
|
+
end
|
5551
|
+
end
|
5552
|
+
end
|
5553
|
+
|
5197
5554
|
describe Addressable::URI, "when given the path " +
|
5198
5555
|
"'c:\\windows\\My Documents 100%20\\foo.txt'" do
|
5199
5556
|
before do
|
@@ -5313,7 +5670,7 @@ describe Addressable::URI, "when parsing a non-String object" do
|
|
5313
5670
|
it "should raise a TypeError for objects than cannot be converted" do
|
5314
5671
|
expect(lambda do
|
5315
5672
|
Addressable::URI.parse(42)
|
5316
|
-
end).to raise_error(TypeError
|
5673
|
+
end).to raise_error(TypeError)
|
5317
5674
|
end
|
5318
5675
|
|
5319
5676
|
it "should correctly parse heuristically anything with a 'to_str' method" do
|
@@ -5323,7 +5680,7 @@ describe Addressable::URI, "when parsing a non-String object" do
|
|
5323
5680
|
it "should raise a TypeError for objects than cannot be converted" do
|
5324
5681
|
expect(lambda do
|
5325
5682
|
Addressable::URI.heuristic_parse(42)
|
5326
|
-
end).to raise_error(TypeError
|
5683
|
+
end).to raise_error(TypeError)
|
5327
5684
|
end
|
5328
5685
|
end
|
5329
5686
|
|
@@ -5369,7 +5726,25 @@ describe Addressable::URI, "when form encoding a non-Array object" do
|
|
5369
5726
|
it "should raise a TypeError for objects than cannot be converted" do
|
5370
5727
|
expect(lambda do
|
5371
5728
|
Addressable::URI.form_encode(42)
|
5372
|
-
end).to raise_error(TypeError
|
5729
|
+
end).to raise_error(TypeError)
|
5730
|
+
end
|
5731
|
+
end
|
5732
|
+
|
5733
|
+
# See https://tools.ietf.org/html/rfc6749#appendix-B
|
5734
|
+
describe Addressable::URI, "when form encoding the example value from OAuth 2" do
|
5735
|
+
it "should result in correct values" do
|
5736
|
+
expect(Addressable::URI.form_encode(
|
5737
|
+
{"value" => " %&+£€"}
|
5738
|
+
)).to eq("value=+%25%26%2B%C2%A3%E2%82%AC")
|
5739
|
+
end
|
5740
|
+
end
|
5741
|
+
|
5742
|
+
# See https://tools.ietf.org/html/rfc6749#appendix-B
|
5743
|
+
describe Addressable::URI, "when form unencoding the example value from OAuth 2" do
|
5744
|
+
it "should result in correct values" do
|
5745
|
+
expect(Addressable::URI.form_unencode(
|
5746
|
+
"value=+%25%26%2B%C2%A3%E2%82%AC"
|
5747
|
+
)).to eq([["value", " %&+£€"]])
|
5373
5748
|
end
|
5374
5749
|
end
|
5375
5750
|
|
@@ -5419,7 +5794,7 @@ describe Addressable::URI, "when form unencoding a non-String object" do
|
|
5419
5794
|
it "should raise a TypeError for objects than cannot be converted" do
|
5420
5795
|
expect(lambda do
|
5421
5796
|
Addressable::URI.form_unencode(42)
|
5422
|
-
end).to raise_error(TypeError
|
5797
|
+
end).to raise_error(TypeError)
|
5423
5798
|
end
|
5424
5799
|
end
|
5425
5800
|
|
@@ -5431,7 +5806,7 @@ describe Addressable::URI, "when normalizing a non-String object" do
|
|
5431
5806
|
it "should raise a TypeError for objects than cannot be converted" do
|
5432
5807
|
expect(lambda do
|
5433
5808
|
Addressable::URI.normalize_component(42)
|
5434
|
-
end).to raise_error(TypeError
|
5809
|
+
end).to raise_error(TypeError)
|
5435
5810
|
end
|
5436
5811
|
|
5437
5812
|
it "should raise a TypeError for objects than cannot be converted" do
|
@@ -5697,6 +6072,136 @@ describe Addressable::URI, "when given the input " +
|
|
5697
6072
|
end
|
5698
6073
|
end
|
5699
6074
|
|
6075
|
+
describe Addressable::URI, "when given the input " +
|
6076
|
+
"'http://prefix\\.example.com/'" do
|
6077
|
+
before do
|
6078
|
+
@input = "http://prefix\\.example.com/"
|
6079
|
+
end
|
6080
|
+
|
6081
|
+
it "should heuristically parse to 'http://prefix/.example.com/'" do
|
6082
|
+
@uri = Addressable::URI.heuristic_parse(@input)
|
6083
|
+
expect(@uri.authority).to eq("prefix")
|
6084
|
+
expect(@uri.to_s).to eq("http://prefix/.example.com/")
|
6085
|
+
end
|
6086
|
+
|
6087
|
+
it "should heuristically parse to 'http://prefix/.example.com/' " +
|
6088
|
+
"even with a scheme hint of 'ftp'" do
|
6089
|
+
@uri = Addressable::URI.heuristic_parse(@input, {:scheme => 'ftp'})
|
6090
|
+
expect(@uri.to_s).to eq("http://prefix/.example.com/")
|
6091
|
+
end
|
6092
|
+
end
|
6093
|
+
|
6094
|
+
describe Addressable::URI, "when given the input " +
|
6095
|
+
"'http://p:\\/'" do
|
6096
|
+
before do
|
6097
|
+
@input = "http://p:\\/"
|
6098
|
+
end
|
6099
|
+
|
6100
|
+
it "should heuristically parse to 'http://p//'" do
|
6101
|
+
@uri = Addressable::URI.heuristic_parse(@input)
|
6102
|
+
expect(@uri.authority).to eq("p")
|
6103
|
+
expect(@uri.to_s).to eq("http://p//")
|
6104
|
+
end
|
6105
|
+
|
6106
|
+
it "should heuristically parse to 'http://p//' " +
|
6107
|
+
"even with a scheme hint of 'ftp'" do
|
6108
|
+
@uri = Addressable::URI.heuristic_parse(@input, {:scheme => 'ftp'})
|
6109
|
+
expect(@uri.to_s).to eq("http://p//")
|
6110
|
+
end
|
6111
|
+
end
|
6112
|
+
|
6113
|
+
describe Addressable::URI, "when given the input " +
|
6114
|
+
"'http://p://'" do
|
6115
|
+
before do
|
6116
|
+
@input = "http://p://"
|
6117
|
+
end
|
6118
|
+
|
6119
|
+
it "should heuristically parse to 'http://p//'" do
|
6120
|
+
@uri = Addressable::URI.heuristic_parse(@input)
|
6121
|
+
expect(@uri.authority).to eq("p")
|
6122
|
+
expect(@uri.to_s).to eq("http://p//")
|
6123
|
+
end
|
6124
|
+
|
6125
|
+
it "should heuristically parse to 'http://p//' " +
|
6126
|
+
"even with a scheme hint of 'ftp'" do
|
6127
|
+
@uri = Addressable::URI.heuristic_parse(@input, {:scheme => 'ftp'})
|
6128
|
+
expect(@uri.to_s).to eq("http://p//")
|
6129
|
+
end
|
6130
|
+
end
|
6131
|
+
|
6132
|
+
describe Addressable::URI, "when given the input " +
|
6133
|
+
"'http://p://p'" do
|
6134
|
+
before do
|
6135
|
+
@input = "http://p://p"
|
6136
|
+
end
|
6137
|
+
|
6138
|
+
it "should heuristically parse to 'http://p//p'" do
|
6139
|
+
@uri = Addressable::URI.heuristic_parse(@input)
|
6140
|
+
expect(@uri.authority).to eq("p")
|
6141
|
+
expect(@uri.to_s).to eq("http://p//p")
|
6142
|
+
end
|
6143
|
+
|
6144
|
+
it "should heuristically parse to 'http://p//p' " +
|
6145
|
+
"even with a scheme hint of 'ftp'" do
|
6146
|
+
@uri = Addressable::URI.heuristic_parse(@input, {:scheme => 'ftp'})
|
6147
|
+
expect(@uri.to_s).to eq("http://p//p")
|
6148
|
+
end
|
6149
|
+
end
|
6150
|
+
|
6151
|
+
describe Addressable::URI, "when given the input " +
|
6152
|
+
"'http://prefix .example.com/'" do
|
6153
|
+
before do
|
6154
|
+
@input = "http://prefix .example.com/"
|
6155
|
+
end
|
6156
|
+
|
6157
|
+
# Justification here being that no browser actually tries to resolve this.
|
6158
|
+
# They all treat this as a web search.
|
6159
|
+
it "should heuristically parse to 'http://prefix%20.example.com/'" do
|
6160
|
+
@uri = Addressable::URI.heuristic_parse(@input)
|
6161
|
+
expect(@uri.authority).to eq("prefix%20.example.com")
|
6162
|
+
expect(@uri.to_s).to eq("http://prefix%20.example.com/")
|
6163
|
+
end
|
6164
|
+
|
6165
|
+
it "should heuristically parse to 'http://prefix%20.example.com/' " +
|
6166
|
+
"even with a scheme hint of 'ftp'" do
|
6167
|
+
@uri = Addressable::URI.heuristic_parse(@input, {:scheme => 'ftp'})
|
6168
|
+
expect(@uri.to_s).to eq("http://prefix%20.example.com/")
|
6169
|
+
end
|
6170
|
+
end
|
6171
|
+
|
6172
|
+
describe Addressable::URI, "when given the input " +
|
6173
|
+
"' http://www.example.com/ '" do
|
6174
|
+
before do
|
6175
|
+
@input = " http://www.example.com/ "
|
6176
|
+
end
|
6177
|
+
|
6178
|
+
it "should heuristically parse to 'http://prefix%20.example.com/'" do
|
6179
|
+
@uri = Addressable::URI.heuristic_parse(@input)
|
6180
|
+
expect(@uri.scheme).to eq("http")
|
6181
|
+
expect(@uri.path).to eq("/")
|
6182
|
+
expect(@uri.to_s).to eq("http://www.example.com/")
|
6183
|
+
end
|
6184
|
+
end
|
6185
|
+
|
6186
|
+
describe Addressable::URI, "when given the input " +
|
6187
|
+
"'http://prefix%2F.example.com/'" do
|
6188
|
+
before do
|
6189
|
+
@input = "http://prefix%2F.example.com/"
|
6190
|
+
end
|
6191
|
+
|
6192
|
+
it "should heuristically parse to 'http://prefix%2F.example.com/'" do
|
6193
|
+
@uri = Addressable::URI.heuristic_parse(@input)
|
6194
|
+
expect(@uri.authority).to eq("prefix%2F.example.com")
|
6195
|
+
expect(@uri.to_s).to eq("http://prefix%2F.example.com/")
|
6196
|
+
end
|
6197
|
+
|
6198
|
+
it "should heuristically parse to 'http://prefix%2F.example.com/' " +
|
6199
|
+
"even with a scheme hint of 'ftp'" do
|
6200
|
+
@uri = Addressable::URI.heuristic_parse(@input, {:scheme => 'ftp'})
|
6201
|
+
expect(@uri.to_s).to eq("http://prefix%2F.example.com/")
|
6202
|
+
end
|
6203
|
+
end
|
6204
|
+
|
5700
6205
|
describe Addressable::URI, "when given the input " +
|
5701
6206
|
"'/path/to/resource'" do
|
5702
6207
|
before do
|
@@ -5783,6 +6288,18 @@ describe Addressable::URI, "when given the input " +
|
|
5783
6288
|
end
|
5784
6289
|
end
|
5785
6290
|
|
6291
|
+
describe Addressable::URI, "when given the input which "\
|
6292
|
+
"start with digits and has specified port" do
|
6293
|
+
before do
|
6294
|
+
@input = "7777.example.org:8089"
|
6295
|
+
end
|
6296
|
+
|
6297
|
+
it "should heuristically parse to 'http://7777.example.org:8089'" do
|
6298
|
+
uri = Addressable::URI.heuristic_parse(@input)
|
6299
|
+
expect(uri.to_s).to eq("http://7777.example.org:8089")
|
6300
|
+
end
|
6301
|
+
end
|
6302
|
+
|
5786
6303
|
describe Addressable::URI, "when given the input " +
|
5787
6304
|
"'feed:///example.com'" do
|
5788
6305
|
before do
|
@@ -5795,6 +6312,18 @@ describe Addressable::URI, "when given the input " +
|
|
5795
6312
|
end
|
5796
6313
|
end
|
5797
6314
|
|
6315
|
+
describe Addressable::URI, "when given the input " +
|
6316
|
+
"'file://localhost/path/to/resource/'" do
|
6317
|
+
before do
|
6318
|
+
@input = "file://localhost/path/to/resource/"
|
6319
|
+
end
|
6320
|
+
|
6321
|
+
it "should heuristically parse to 'file:///path/to/resource/'" do
|
6322
|
+
@uri = Addressable::URI.heuristic_parse(@input)
|
6323
|
+
expect(@uri.to_s).to eq("file:///path/to/resource/")
|
6324
|
+
end
|
6325
|
+
end
|
6326
|
+
|
5798
6327
|
describe Addressable::URI, "when given the input " +
|
5799
6328
|
"'file://path/to/resource/'" do
|
5800
6329
|
before do
|
@@ -5807,6 +6336,18 @@ describe Addressable::URI, "when given the input " +
|
|
5807
6336
|
end
|
5808
6337
|
end
|
5809
6338
|
|
6339
|
+
describe Addressable::URI, "when given the input " +
|
6340
|
+
"'file://///path/to/resource/'" do
|
6341
|
+
before do
|
6342
|
+
@input = "file:///////path/to/resource/"
|
6343
|
+
end
|
6344
|
+
|
6345
|
+
it "should heuristically parse to 'file:////path/to/resource/'" do
|
6346
|
+
@uri = Addressable::URI.heuristic_parse(@input)
|
6347
|
+
expect(@uri.to_s).to eq("file:////path/to/resource/")
|
6348
|
+
end
|
6349
|
+
end
|
6350
|
+
|
5810
6351
|
describe Addressable::URI, "when given the input " +
|
5811
6352
|
"'feed://http://example.com'" do
|
5812
6353
|
before do
|
@@ -5831,6 +6372,44 @@ describe Addressable::URI, "when given the input " +
|
|
5831
6372
|
end
|
5832
6373
|
end
|
5833
6374
|
|
6375
|
+
describe Addressable::URI, "when given the input: 'user@domain.com'" do
|
6376
|
+
before do
|
6377
|
+
@input = "user@domain.com"
|
6378
|
+
end
|
6379
|
+
|
6380
|
+
context "for heuristic parse" do
|
6381
|
+
it "should remain 'mailto:user@domain.com'" do
|
6382
|
+
uri = Addressable::URI.heuristic_parse("mailto:#{@input}")
|
6383
|
+
expect(uri.to_s).to eq("mailto:user@domain.com")
|
6384
|
+
end
|
6385
|
+
|
6386
|
+
it "should have a scheme of 'mailto'" do
|
6387
|
+
uri = Addressable::URI.heuristic_parse(@input)
|
6388
|
+
expect(uri.to_s).to eq("mailto:user@domain.com")
|
6389
|
+
expect(uri.scheme).to eq("mailto")
|
6390
|
+
end
|
6391
|
+
|
6392
|
+
it "should remain 'acct:user@domain.com'" do
|
6393
|
+
uri = Addressable::URI.heuristic_parse("acct:#{@input}")
|
6394
|
+
expect(uri.to_s).to eq("acct:user@domain.com")
|
6395
|
+
end
|
6396
|
+
|
6397
|
+
context "HTTP" do
|
6398
|
+
before do
|
6399
|
+
@uri = Addressable::URI.heuristic_parse("http://#{@input}/")
|
6400
|
+
end
|
6401
|
+
|
6402
|
+
it "should remain 'http://user@domain.com/'" do
|
6403
|
+
expect(@uri.to_s).to eq("http://user@domain.com/")
|
6404
|
+
end
|
6405
|
+
|
6406
|
+
it "should have the username 'user' for HTTP basic authentication" do
|
6407
|
+
expect(@uri.user).to eq("user")
|
6408
|
+
end
|
6409
|
+
end
|
6410
|
+
end
|
6411
|
+
end
|
6412
|
+
|
5834
6413
|
describe Addressable::URI, "when assigning query values" do
|
5835
6414
|
before do
|
5836
6415
|
@uri = Addressable::URI.new
|