addressable 2.4.0 → 2.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/CHANGELOG.md +54 -0
- data/Gemfile +13 -12
- data/README.md +31 -15
- data/Rakefile +5 -3
- data/addressable.gemspec +23 -20
- data/lib/addressable/idna/native.rb +11 -5
- data/lib/addressable/idna/pure.rb +61 -55
- data/lib/addressable/idna.rb +3 -1
- data/lib/addressable/template.rb +64 -84
- data/lib/addressable/uri.rb +228 -96
- data/lib/addressable/version.rb +4 -2
- data/lib/addressable.rb +2 -0
- data/spec/addressable/idna_spec.rb +35 -3
- data/spec/addressable/net_http_compat_spec.rb +3 -1
- data/spec/addressable/security_spec.rb +3 -1
- data/spec/addressable/template_spec.rb +77 -3
- data/spec/addressable/uri_spec.rb +663 -203
- data/spec/spec_helper.rb +12 -0
- data/tasks/clobber.rake +2 -0
- data/tasks/gem.rake +9 -14
- data/tasks/git.rake +2 -0
- data/tasks/metrics.rake +2 -0
- data/tasks/profile.rake +72 -0
- data/tasks/rspec.rake +3 -1
- data/tasks/yard.rake +2 -0
- metadata +36 -11
- data/spec/addressable/rack_mount_compat_spec.rb +0 -104
data/lib/addressable/version.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# encoding:utf-8
|
2
4
|
#--
|
3
|
-
# Copyright (C)
|
5
|
+
# Copyright (C) Bob Aman
|
4
6
|
#
|
5
7
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
8
|
# you may not use this file except in compliance with the License.
|
@@ -21,7 +23,7 @@ if !defined?(Addressable::VERSION)
|
|
21
23
|
module Addressable
|
22
24
|
module VERSION
|
23
25
|
MAJOR = 2
|
24
|
-
MINOR =
|
26
|
+
MINOR = 8
|
25
27
|
TINY = 0
|
26
28
|
|
27
29
|
STRING = [MAJOR, MINOR, TINY].join('.')
|
data/lib/addressable.rb
CHANGED
@@ -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.
|
@@ -26,6 +28,11 @@ shared_examples_for "converting from unicode to ASCII" do
|
|
26
28
|
expect(Addressable::IDNA.to_ascii("www.google.com")).to eq("www.google.com")
|
27
29
|
end
|
28
30
|
|
31
|
+
long = 'AcinusFallumTrompetumNullunCreditumVisumEstAtCuadLongumEtCefallum.com'
|
32
|
+
it "should convert '#{long}' correctly" do
|
33
|
+
expect(Addressable::IDNA.to_ascii(long)).to eq(long)
|
34
|
+
end
|
35
|
+
|
29
36
|
it "should convert 'www.詹姆斯.com' correctly" do
|
30
37
|
expect(Addressable::IDNA.to_ascii(
|
31
38
|
"www.詹姆斯.com"
|
@@ -129,6 +136,12 @@ shared_examples_for "converting from unicode to ASCII" do
|
|
129
136
|
)).to eq("xn--4ud")
|
130
137
|
end
|
131
138
|
|
139
|
+
it "should convert '🌹🌹🌹.ws' correctly" do
|
140
|
+
expect(Addressable::IDNA.to_ascii(
|
141
|
+
"\360\237\214\271\360\237\214\271\360\237\214\271.ws"
|
142
|
+
)).to eq("xn--2h8haa.ws")
|
143
|
+
end
|
144
|
+
|
132
145
|
it "should handle two adjacent '.'s correctly" do
|
133
146
|
expect(Addressable::IDNA.to_ascii(
|
134
147
|
"example..host"
|
@@ -137,12 +150,23 @@ shared_examples_for "converting from unicode to ASCII" do
|
|
137
150
|
end
|
138
151
|
|
139
152
|
shared_examples_for "converting from ASCII to unicode" do
|
153
|
+
long = 'AcinusFallumTrompetumNullunCreditumVisumEstAtCuadLongumEtCefallum.com'
|
154
|
+
it "should convert '#{long}' correctly" do
|
155
|
+
expect(Addressable::IDNA.to_unicode(long)).to eq(long)
|
156
|
+
end
|
157
|
+
|
158
|
+
it "should return the identity conversion when punycode decode fails" do
|
159
|
+
expect(Addressable::IDNA.to_unicode("xn--zckp1cyg1.sblo.jp")).to eq(
|
160
|
+
"xn--zckp1cyg1.sblo.jp")
|
161
|
+
end
|
162
|
+
|
140
163
|
it "should return the identity conversion when the ACE prefix has no suffix" do
|
141
164
|
expect(Addressable::IDNA.to_unicode("xn--...-")).to eq("xn--...-")
|
142
165
|
end
|
143
166
|
|
144
167
|
it "should convert 'www.google.com' correctly" do
|
145
|
-
expect(Addressable::IDNA.to_unicode("www.google.com")).to eq(
|
168
|
+
expect(Addressable::IDNA.to_unicode("www.google.com")).to eq(
|
169
|
+
"www.google.com")
|
146
170
|
end
|
147
171
|
|
148
172
|
it "should convert 'www.詹姆斯.com' correctly" do
|
@@ -215,6 +239,12 @@ shared_examples_for "converting from ASCII to unicode" do
|
|
215
239
|
)).to eq("\341\206\265")
|
216
240
|
end
|
217
241
|
|
242
|
+
it "should convert '🌹🌹🌹.ws' correctly" do
|
243
|
+
expect(Addressable::IDNA.to_unicode(
|
244
|
+
"xn--2h8haa.ws"
|
245
|
+
)).to eq("\360\237\214\271\360\237\214\271\360\237\214\271.ws")
|
246
|
+
end
|
247
|
+
|
218
248
|
it "should handle two adjacent '.'s correctly" do
|
219
249
|
expect(Addressable::IDNA.to_unicode(
|
220
250
|
"example..host"
|
@@ -264,7 +294,9 @@ begin
|
|
264
294
|
it_should_behave_like "converting from unicode to ASCII"
|
265
295
|
it_should_behave_like "converting from ASCII to unicode"
|
266
296
|
end
|
267
|
-
rescue LoadError
|
297
|
+
rescue LoadError => error
|
298
|
+
raise error if ENV["CI"] && TestHelper.native_supported?
|
299
|
+
|
268
300
|
# Cannot test the native implementation without libidn support.
|
269
301
|
warn('Could not load native IDN implementation.')
|
270
302
|
end
|
@@ -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.
|
@@ -17,6 +19,7 @@
|
|
17
19
|
require "spec_helper"
|
18
20
|
|
19
21
|
require "bigdecimal"
|
22
|
+
require "timeout"
|
20
23
|
require "addressable/template"
|
21
24
|
|
22
25
|
shared_examples_for 'expands' do |tests|
|
@@ -82,7 +85,7 @@ describe "Type conversion" do
|
|
82
85
|
:hello => 1234,
|
83
86
|
:nothing => nil,
|
84
87
|
:sym => :symbolic,
|
85
|
-
:decimal => BigDecimal
|
88
|
+
:decimal => BigDecimal('1')
|
86
89
|
}
|
87
90
|
}
|
88
91
|
|
@@ -91,7 +94,7 @@ describe "Type conversion" do
|
|
91
94
|
'{hello}' => '1234',
|
92
95
|
'{nothing}' => '',
|
93
96
|
'{sym}' => 'symbolic',
|
94
|
-
'{decimal}' => '0.1E1'
|
97
|
+
'{decimal}' => RUBY_VERSION < '2.4.0' ? '0.1E1' : '0.1e1'
|
95
98
|
}
|
96
99
|
end
|
97
100
|
|
@@ -851,6 +854,7 @@ describe Addressable::Template do
|
|
851
854
|
expect(match_data.uri).to eq(uri)
|
852
855
|
expect(match_data.template).to eq(subject)
|
853
856
|
expect(match_data.mapping).to be_empty
|
857
|
+
expect(match_data.inspect).to be_an String
|
854
858
|
end
|
855
859
|
end
|
856
860
|
end
|
@@ -948,6 +952,36 @@ describe Addressable::Template do
|
|
948
952
|
)
|
949
953
|
end
|
950
954
|
end
|
955
|
+
context "issue #307 - partial_expand form query with nil params" do
|
956
|
+
subject do
|
957
|
+
Addressable::Template.new("http://example.com/{?one,two,three}/")
|
958
|
+
end
|
959
|
+
it "builds a new pattern with two=nil" do
|
960
|
+
expect(subject.partial_expand(two: nil).pattern).to eq(
|
961
|
+
"http://example.com/{?one}{&three}/"
|
962
|
+
)
|
963
|
+
end
|
964
|
+
it "builds a new pattern with one=nil and two=nil" do
|
965
|
+
expect(subject.partial_expand(one: nil, two: nil).pattern).to eq(
|
966
|
+
"http://example.com/{?three}/"
|
967
|
+
)
|
968
|
+
end
|
969
|
+
it "builds a new pattern with one=1 and two=nil" do
|
970
|
+
expect(subject.partial_expand(one: 1, two: nil).pattern).to eq(
|
971
|
+
"http://example.com/?one=1{&three}/"
|
972
|
+
)
|
973
|
+
end
|
974
|
+
it "builds a new pattern with one=nil and two=2" do
|
975
|
+
expect(subject.partial_expand(one: nil, two: 2).pattern).to eq(
|
976
|
+
"http://example.com/?two=2{&three}/"
|
977
|
+
)
|
978
|
+
end
|
979
|
+
it "builds a new pattern with one=nil" do
|
980
|
+
expect(subject.partial_expand(one: nil).pattern).to eq(
|
981
|
+
"http://example.com/{?two}{&three}/"
|
982
|
+
)
|
983
|
+
end
|
984
|
+
end
|
951
985
|
context "partial_expand with query string" do
|
952
986
|
subject {
|
953
987
|
Addressable::Template.new("http://example.com/{?two,one}/")
|
@@ -968,6 +1002,24 @@ describe Addressable::Template do
|
|
968
1002
|
)
|
969
1003
|
end
|
970
1004
|
end
|
1005
|
+
context "partial expand with unicode values" do
|
1006
|
+
subject do
|
1007
|
+
Addressable::Template.new("http://example.com/{resource}/{query}/")
|
1008
|
+
end
|
1009
|
+
it "normalizes unicode by default" do
|
1010
|
+
template = subject.partial_expand("query" => "Cafe\u0301")
|
1011
|
+
expect(template.pattern).to eq(
|
1012
|
+
"http://example.com/{resource}/Caf%C3%A9/"
|
1013
|
+
)
|
1014
|
+
end
|
1015
|
+
|
1016
|
+
it "does not normalize unicode when byte semantics requested" do
|
1017
|
+
template = subject.partial_expand({"query" => "Cafe\u0301"}, nil, false)
|
1018
|
+
expect(template.pattern).to eq(
|
1019
|
+
"http://example.com/{resource}/Cafe%CC%81/"
|
1020
|
+
)
|
1021
|
+
end
|
1022
|
+
end
|
971
1023
|
end
|
972
1024
|
describe "Partial expand with strings" do
|
973
1025
|
context "partial_expand with two simple values" do
|
@@ -1012,6 +1064,20 @@ describe Addressable::Template do
|
|
1012
1064
|
end
|
1013
1065
|
end
|
1014
1066
|
describe "Expand" do
|
1067
|
+
context "expand with unicode values" do
|
1068
|
+
subject do
|
1069
|
+
Addressable::Template.new("http://example.com/search/{query}/")
|
1070
|
+
end
|
1071
|
+
it "normalizes unicode by default" do
|
1072
|
+
uri = subject.expand("query" => "Cafe\u0301").to_str
|
1073
|
+
expect(uri).to eq("http://example.com/search/Caf%C3%A9/")
|
1074
|
+
end
|
1075
|
+
|
1076
|
+
it "does not normalize unicode when byte semantics requested" do
|
1077
|
+
uri = subject.expand({ "query" => "Cafe\u0301" }, nil, false).to_str
|
1078
|
+
expect(uri).to eq("http://example.com/search/Cafe%CC%81/")
|
1079
|
+
end
|
1080
|
+
end
|
1015
1081
|
context "expand with a processor" do
|
1016
1082
|
subject {
|
1017
1083
|
Addressable::Template.new("http://example.com/search/{query}/")
|
@@ -1275,6 +1341,14 @@ describe Addressable::Template do
|
|
1275
1341
|
expect(subject).not_to match("foo_bar*")
|
1276
1342
|
expect(subject).not_to match("foo_bar:20")
|
1277
1343
|
end
|
1344
|
+
|
1345
|
+
it 'should parse in a reasonable time' do
|
1346
|
+
expect do
|
1347
|
+
Timeout.timeout(0.1) do
|
1348
|
+
expect(subject).not_to match("0"*25 + "!")
|
1349
|
+
end
|
1350
|
+
end.not_to raise_error
|
1351
|
+
end
|
1278
1352
|
end
|
1279
1353
|
context "VARIABLE_LIST" do
|
1280
1354
|
subject { Addressable::Template::VARIABLE_LIST }
|