addressable 2.6.0 → 2.8.1
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.
- checksums.yaml +5 -5
- data/CHANGELOG.md +35 -0
- data/Gemfile +14 -16
- data/README.md +12 -10
- data/Rakefile +3 -3
- data/lib/addressable/idna/native.rb +0 -1
- data/lib/addressable/idna/pure.rb +52 -51
- data/lib/addressable/idna.rb +0 -1
- data/lib/addressable/template.rb +28 -43
- data/lib/addressable/uri.rb +129 -79
- data/lib/addressable/version.rb +2 -3
- data/spec/addressable/idna_spec.rb +3 -2
- data/spec/addressable/net_http_compat_spec.rb +0 -1
- data/spec/addressable/security_spec.rb +0 -1
- data/spec/addressable/template_spec.rb +18 -1
- data/spec/addressable/uri_spec.rb +408 -208
- data/spec/spec_helper.rb +9 -0
- data/tasks/gem.rake +9 -7
- data/tasks/profile.rake +72 -0
- data/tasks/rspec.rake +1 -1
- metadata +15 -15
- data/spec/addressable/rack_mount_compat_spec.rb +0 -106
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 3ddda72232f6aef9f6f4311c2855f1b3fea9acc80f51c4e5e90bd23820b0d74e
|
4
|
+
data.tar.gz: 88f208cb2d73dec64663e6e3c1710dc08b188402937038fefce6a2d47debc97d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4e1b0c83fc2f2e54cba6804f3840c8bb29f0d73259979d5bf678ebd5d32257b91585d9b71a780321427835d10f98b9c07969267878f0b032c53d031c30202a4c
|
7
|
+
data.tar.gz: 35abc3652c8ff92032411e4daad7133b7c4649aff4a1a25fe622cf1c9b661d56f096a1084392e053788baea79f551a9d4a448d16c9e61e23bf4d9692a6728bf3
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,38 @@
|
|
1
|
+
# Addressable 2.8.1
|
2
|
+
- refactor `Addressable::URI.normalize_path` to address linter offenses ([#430](https://github.com/sporkmonger/addressable/pull/430))
|
3
|
+
- remove redundant colon in `Addressable::URI::CharacterClasses::AUTHORITY` regex ([#438](https://github.com/sporkmonger/addressable/pull/438))
|
4
|
+
- update gemspec to reflect supported Ruby versions ([#466], [#464], [#463])
|
5
|
+
- compatibility w/ public_suffix 5.x ([#466], [#465], [#460])
|
6
|
+
- fixes "invalid byte sequence in UTF-8" exception when unencoding URLs containing non UTF-8 characters ([#459](https://github.com/sporkmonger/addressable/pull/459))
|
7
|
+
- `Ractor` compatibility ([#449](https://github.com/sporkmonger/addressable/pull/449))
|
8
|
+
- use the whole string instead of a single line for template match ([#431](https://github.com/sporkmonger/addressable/pull/431))
|
9
|
+
- force UTF-8 encoding only if needed ([#341](https://github.com/sporkmonger/addressable/pull/341))
|
10
|
+
|
11
|
+
[#460]: https://github.com/sporkmonger/addressable/pull/460
|
12
|
+
[#463]: https://github.com/sporkmonger/addressable/pull/463
|
13
|
+
[#464]: https://github.com/sporkmonger/addressable/pull/464
|
14
|
+
[#465]: https://github.com/sporkmonger/addressable/pull/465
|
15
|
+
[#466]: https://github.com/sporkmonger/addressable/pull/466
|
16
|
+
|
17
|
+
# Addressable 2.8.0
|
18
|
+
- fixes ReDoS vulnerability in Addressable::Template#match
|
19
|
+
- no longer replaces `+` with spaces in queries for non-http(s) schemes
|
20
|
+
- fixed encoding ipv6 literals
|
21
|
+
- the `:compacted` flag for `normalized_query` now dedupes parameters
|
22
|
+
- fix broken `escape_component` alias
|
23
|
+
- dropping support for Ruby 2.0 and 2.1
|
24
|
+
- adding Ruby 3.0 compatibility for development tasks
|
25
|
+
- drop support for `rack-mount` and remove Addressable::Template#generate
|
26
|
+
- performance improvements
|
27
|
+
- switch CI/CD to GitHub Actions
|
28
|
+
|
29
|
+
# Addressable 2.7.0
|
30
|
+
- added `:compacted` flag to `normalized_query`
|
31
|
+
- `heuristic_parse` handles `mailto:` more intuitively
|
32
|
+
- dropped explicit support for JRuby 9.0.5.0
|
33
|
+
- compatibility w/ public_suffix 4.x
|
34
|
+
- performance improvements
|
35
|
+
|
1
36
|
# Addressable 2.6.0
|
2
37
|
- added `tld=` method to allow assignment to the public suffix
|
3
38
|
- most `heuristic_parse` patterns are now case-insensitive
|
data/Gemfile
CHANGED
@@ -1,10 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
source 'https://rubygems.org'
|
2
4
|
|
3
5
|
gemspec
|
4
6
|
|
5
7
|
group :test do
|
6
|
-
gem 'rspec', '~> 3.
|
7
|
-
gem 'rspec-its', '~> 1.
|
8
|
+
gem 'rspec', '~> 3.8'
|
9
|
+
gem 'rspec-its', '~> 1.3'
|
10
|
+
end
|
11
|
+
|
12
|
+
group :coverage do
|
13
|
+
gem "coveralls", "> 0.7", require: false, platforms: :mri
|
14
|
+
gem "simplecov", require: false
|
8
15
|
end
|
9
16
|
|
10
17
|
group :development do
|
@@ -14,19 +21,10 @@ group :development do
|
|
14
21
|
end
|
15
22
|
|
16
23
|
group :test, :development do
|
17
|
-
gem '
|
18
|
-
gem
|
19
|
-
gem 'coveralls', :require => false, :platforms => [
|
20
|
-
:ruby_20, :ruby_21, :ruby_22, :ruby_23
|
21
|
-
]
|
22
|
-
# Used to test compatibility.
|
23
|
-
gem 'rack-mount', git: 'https://github.com/sporkmonger/rack-mount.git', require: 'rack/mount'
|
24
|
-
|
25
|
-
if RUBY_VERSION.start_with?('2.0', '2.1')
|
26
|
-
gem 'rack', '< 2', :require => false
|
27
|
-
else
|
28
|
-
gem 'rack', :require => false
|
29
|
-
end
|
24
|
+
gem 'memory_profiler'
|
25
|
+
gem "rake", ">= 12.3.3"
|
30
26
|
end
|
31
27
|
|
32
|
-
|
28
|
+
unless ENV["IDNA_MODE"] == "pure"
|
29
|
+
gem "idn-ruby", platform: :mri
|
30
|
+
end
|
data/README.md
CHANGED
@@ -7,21 +7,23 @@
|
|
7
7
|
<dt>License</dt><dd>Apache 2.0</dd>
|
8
8
|
</dl>
|
9
9
|
|
10
|
-
[][gem]
|
11
|
+
[][actions]
|
12
12
|
[][coveralls]
|
13
|
-
[][inch]
|
14
14
|
|
15
15
|
[gem]: https://rubygems.org/gems/addressable
|
16
|
-
[
|
16
|
+
[actions]: https://github.com/sporkmonger/addressable/actions
|
17
17
|
[coveralls]: https://coveralls.io/r/sporkmonger/addressable
|
18
|
-
[inch]:
|
18
|
+
[inch]: https://inch-ci.org/github/sporkmonger/addressable
|
19
19
|
|
20
20
|
# Description
|
21
21
|
|
22
|
-
Addressable is
|
23
|
-
Ruby's standard library. It
|
24
|
-
|
22
|
+
Addressable is an alternative implementation to the URI implementation
|
23
|
+
that is part of Ruby's standard library. It is flexible, offers heuristic
|
24
|
+
parsing, and additionally provides extensive support for IRIs and URI templates.
|
25
|
+
|
26
|
+
Addressable closely conforms to RFC 3986, RFC 3987, and RFC 6570 (level 4).
|
25
27
|
|
26
28
|
# Reference
|
27
29
|
|
@@ -96,7 +98,7 @@ You may optionally turn on native IDN support by installing libidn and the
|
|
96
98
|
idn gem:
|
97
99
|
|
98
100
|
```console
|
99
|
-
$ sudo apt-get install
|
101
|
+
$ sudo apt-get install libidn11-dev # Debian/Ubuntu
|
100
102
|
$ brew install libidn # OS X
|
101
103
|
$ gem install idn-ruby
|
102
104
|
```
|
@@ -108,7 +110,7 @@ dependency using a pessimistic version constraint covering the major and minor
|
|
108
110
|
values:
|
109
111
|
|
110
112
|
```ruby
|
111
|
-
spec.add_dependency 'addressable', '~> 2.
|
113
|
+
spec.add_dependency 'addressable', '~> 2.7'
|
112
114
|
```
|
113
115
|
|
114
116
|
If you need a specific bug fix, you can also specify minimum tiny versions
|
data/Rakefile
CHANGED
@@ -14,9 +14,9 @@ RELEASE_NAME = "REL #{PKG_VERSION}"
|
|
14
14
|
|
15
15
|
PKG_SUMMARY = "URI Implementation"
|
16
16
|
PKG_DESCRIPTION = <<-TEXT
|
17
|
-
Addressable is
|
18
|
-
Ruby's standard library. It
|
19
|
-
|
17
|
+
Addressable is an alternative implementation to the URI implementation that is
|
18
|
+
part of Ruby's standard library. It is flexible, offers heuristic parsing, and
|
19
|
+
additionally provides extensive support for IRIs and URI templates.
|
20
20
|
TEXT
|
21
21
|
|
22
22
|
PKG_FILES = FileList[
|
@@ -1,6 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
# encoding:utf-8
|
4
3
|
#--
|
5
4
|
# Copyright (C) Bob Aman
|
6
5
|
#
|
@@ -135,7 +134,7 @@ module Addressable
|
|
135
134
|
unpacked.map! { |codepoint| lookup_unicode_lowercase(codepoint) }
|
136
135
|
return unpacked.pack("U*")
|
137
136
|
end
|
138
|
-
|
137
|
+
private_class_method :unicode_downcase
|
139
138
|
|
140
139
|
def self.unicode_compose(unpacked)
|
141
140
|
unpacked_result = []
|
@@ -160,7 +159,7 @@ module Addressable
|
|
160
159
|
unpacked_result << starter
|
161
160
|
return unpacked_result
|
162
161
|
end
|
163
|
-
|
162
|
+
private_class_method :unicode_compose
|
164
163
|
|
165
164
|
def self.unicode_compose_pair(ch_one, ch_two)
|
166
165
|
if ch_one >= HANGUL_LBASE && ch_one < HANGUL_LBASE + HANGUL_LCOUNT &&
|
@@ -178,43 +177,45 @@ module Addressable
|
|
178
177
|
end
|
179
178
|
|
180
179
|
p = []
|
181
|
-
ucs4_to_utf8 = lambda do |ch|
|
182
|
-
if ch < 128
|
183
|
-
p << ch
|
184
|
-
elsif ch < 2048
|
185
|
-
p << (ch >> 6 | 192)
|
186
|
-
p << (ch & 63 | 128)
|
187
|
-
elsif ch < 0x10000
|
188
|
-
p << (ch >> 12 | 224)
|
189
|
-
p << (ch >> 6 & 63 | 128)
|
190
|
-
p << (ch & 63 | 128)
|
191
|
-
elsif ch < 0x200000
|
192
|
-
p << (ch >> 18 | 240)
|
193
|
-
p << (ch >> 12 & 63 | 128)
|
194
|
-
p << (ch >> 6 & 63 | 128)
|
195
|
-
p << (ch & 63 | 128)
|
196
|
-
elsif ch < 0x4000000
|
197
|
-
p << (ch >> 24 | 248)
|
198
|
-
p << (ch >> 18 & 63 | 128)
|
199
|
-
p << (ch >> 12 & 63 | 128)
|
200
|
-
p << (ch >> 6 & 63 | 128)
|
201
|
-
p << (ch & 63 | 128)
|
202
|
-
elsif ch < 0x80000000
|
203
|
-
p << (ch >> 30 | 252)
|
204
|
-
p << (ch >> 24 & 63 | 128)
|
205
|
-
p << (ch >> 18 & 63 | 128)
|
206
|
-
p << (ch >> 12 & 63 | 128)
|
207
|
-
p << (ch >> 6 & 63 | 128)
|
208
|
-
p << (ch & 63 | 128)
|
209
|
-
end
|
210
|
-
end
|
211
180
|
|
212
|
-
ucs4_to_utf8
|
213
|
-
ucs4_to_utf8
|
181
|
+
ucs4_to_utf8(ch_one, p)
|
182
|
+
ucs4_to_utf8(ch_two, p)
|
214
183
|
|
215
184
|
return lookup_unicode_composition(p)
|
216
185
|
end
|
217
|
-
|
186
|
+
private_class_method :unicode_compose_pair
|
187
|
+
|
188
|
+
def self.ucs4_to_utf8(char, buffer)
|
189
|
+
if char < 128
|
190
|
+
buffer << char
|
191
|
+
elsif char < 2048
|
192
|
+
buffer << (char >> 6 | 192)
|
193
|
+
buffer << (char & 63 | 128)
|
194
|
+
elsif char < 0x10000
|
195
|
+
buffer << (char >> 12 | 224)
|
196
|
+
buffer << (char >> 6 & 63 | 128)
|
197
|
+
buffer << (char & 63 | 128)
|
198
|
+
elsif char < 0x200000
|
199
|
+
buffer << (char >> 18 | 240)
|
200
|
+
buffer << (char >> 12 & 63 | 128)
|
201
|
+
buffer << (char >> 6 & 63 | 128)
|
202
|
+
buffer << (char & 63 | 128)
|
203
|
+
elsif char < 0x4000000
|
204
|
+
buffer << (char >> 24 | 248)
|
205
|
+
buffer << (char >> 18 & 63 | 128)
|
206
|
+
buffer << (char >> 12 & 63 | 128)
|
207
|
+
buffer << (char >> 6 & 63 | 128)
|
208
|
+
buffer << (char & 63 | 128)
|
209
|
+
elsif char < 0x80000000
|
210
|
+
buffer << (char >> 30 | 252)
|
211
|
+
buffer << (char >> 24 & 63 | 128)
|
212
|
+
buffer << (char >> 18 & 63 | 128)
|
213
|
+
buffer << (char >> 12 & 63 | 128)
|
214
|
+
buffer << (char >> 6 & 63 | 128)
|
215
|
+
buffer << (char & 63 | 128)
|
216
|
+
end
|
217
|
+
end
|
218
|
+
private_class_method :ucs4_to_utf8
|
218
219
|
|
219
220
|
def self.unicode_sort_canonical(unpacked)
|
220
221
|
unpacked = unpacked.dup
|
@@ -238,7 +239,7 @@ module Addressable
|
|
238
239
|
end
|
239
240
|
return unpacked
|
240
241
|
end
|
241
|
-
|
242
|
+
private_class_method :unicode_sort_canonical
|
242
243
|
|
243
244
|
def self.unicode_decompose(unpacked)
|
244
245
|
unpacked_result = []
|
@@ -259,7 +260,7 @@ module Addressable
|
|
259
260
|
end
|
260
261
|
return unpacked_result
|
261
262
|
end
|
262
|
-
|
263
|
+
private_class_method :unicode_decompose
|
263
264
|
|
264
265
|
def self.unicode_decompose_hangul(codepoint)
|
265
266
|
sindex = codepoint - HANGUL_SBASE;
|
@@ -276,7 +277,7 @@ module Addressable
|
|
276
277
|
end
|
277
278
|
return l, v, t
|
278
279
|
end
|
279
|
-
|
280
|
+
private_class_method :unicode_decompose_hangul
|
280
281
|
|
281
282
|
def self.lookup_unicode_combining_class(codepoint)
|
282
283
|
codepoint_data = UNICODE_DATA[codepoint]
|
@@ -284,14 +285,14 @@ module Addressable
|
|
284
285
|
(codepoint_data[UNICODE_DATA_COMBINING_CLASS] || 0) :
|
285
286
|
0)
|
286
287
|
end
|
287
|
-
|
288
|
+
private_class_method :lookup_unicode_combining_class
|
288
289
|
|
289
290
|
def self.lookup_unicode_compatibility(codepoint)
|
290
291
|
codepoint_data = UNICODE_DATA[codepoint]
|
291
292
|
(codepoint_data ?
|
292
293
|
codepoint_data[UNICODE_DATA_COMPATIBILITY] : nil)
|
293
294
|
end
|
294
|
-
|
295
|
+
private_class_method :lookup_unicode_compatibility
|
295
296
|
|
296
297
|
def self.lookup_unicode_lowercase(codepoint)
|
297
298
|
codepoint_data = UNICODE_DATA[codepoint]
|
@@ -299,12 +300,12 @@ module Addressable
|
|
299
300
|
(codepoint_data[UNICODE_DATA_LOWERCASE] || codepoint) :
|
300
301
|
codepoint)
|
301
302
|
end
|
302
|
-
|
303
|
+
private_class_method :lookup_unicode_lowercase
|
303
304
|
|
304
305
|
def self.lookup_unicode_composition(unpacked)
|
305
306
|
return COMPOSITION_TABLE[unpacked]
|
306
307
|
end
|
307
|
-
|
308
|
+
private_class_method :lookup_unicode_composition
|
308
309
|
|
309
310
|
HANGUL_SBASE = 0xac00
|
310
311
|
HANGUL_LBASE = 0x1100
|
@@ -341,7 +342,7 @@ module Addressable
|
|
341
342
|
end
|
342
343
|
|
343
344
|
COMPOSITION_TABLE = {}
|
344
|
-
|
345
|
+
UNICODE_DATA.each do |codepoint, data|
|
345
346
|
canonical = data[UNICODE_DATA_CANONICAL]
|
346
347
|
exclusion = data[UNICODE_DATA_EXCLUSION]
|
347
348
|
|
@@ -500,7 +501,7 @@ module Addressable
|
|
500
501
|
|
501
502
|
output[0..outlen].map { |x| x.chr }.join("").sub(/\0+\z/, "")
|
502
503
|
end
|
503
|
-
|
504
|
+
private_class_method :punycode_encode
|
504
505
|
|
505
506
|
def self.punycode_decode(punycode)
|
506
507
|
input = []
|
@@ -622,22 +623,22 @@ module Addressable
|
|
622
623
|
|
623
624
|
output.pack("U*")
|
624
625
|
end
|
625
|
-
|
626
|
+
private_class_method :punycode_decode
|
626
627
|
|
627
628
|
def self.punycode_basic?(codepoint)
|
628
629
|
codepoint < 0x80
|
629
630
|
end
|
630
|
-
|
631
|
+
private_class_method :punycode_basic?
|
631
632
|
|
632
633
|
def self.punycode_delimiter?(codepoint)
|
633
634
|
codepoint == PUNYCODE_DELIMITER
|
634
635
|
end
|
635
|
-
|
636
|
+
private_class_method :punycode_delimiter?
|
636
637
|
|
637
638
|
def self.punycode_encode_digit(d)
|
638
639
|
d + 22 + 75 * ((d < 26) ? 1 : 0)
|
639
640
|
end
|
640
|
-
|
641
|
+
private_class_method :punycode_encode_digit
|
641
642
|
|
642
643
|
# Returns the numeric value of a basic codepoint
|
643
644
|
# (for use in representing integers) in the range 0 to
|
@@ -653,7 +654,7 @@ module Addressable
|
|
653
654
|
PUNYCODE_BASE
|
654
655
|
end
|
655
656
|
end
|
656
|
-
|
657
|
+
private_class_method :punycode_decode_digit
|
657
658
|
|
658
659
|
# Bias adaptation method
|
659
660
|
def self.punycode_adapt(delta, numpoints, firsttime)
|
@@ -670,7 +671,7 @@ module Addressable
|
|
670
671
|
|
671
672
|
k + (difference + 1) * delta / (delta + PUNYCODE_SKEW)
|
672
673
|
end
|
673
|
-
|
674
|
+
private_class_method :punycode_adapt
|
674
675
|
end
|
675
676
|
# :startdoc:
|
676
677
|
end
|
data/lib/addressable/idna.rb
CHANGED
data/lib/addressable/template.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
# encoding:utf-8
|
4
3
|
#--
|
5
4
|
# Copyright (C) Bob Aman
|
6
5
|
#
|
@@ -37,7 +36,7 @@ module Addressable
|
|
37
36
|
Addressable::URI::CharacterClasses::DIGIT + '_'
|
38
37
|
|
39
38
|
var_char =
|
40
|
-
"(
|
39
|
+
"(?>(?:[#{variable_char_class}]|%[a-fA-F0-9][a-fA-F0-9])+)"
|
41
40
|
RESERVED =
|
42
41
|
"(?:[#{anything}]|%[a-fA-F0-9][a-fA-F0-9])"
|
43
42
|
UNRESERVED =
|
@@ -412,7 +411,7 @@ module Addressable
|
|
412
411
|
# match.captures
|
413
412
|
# #=> ["a", ["b", "c"]]
|
414
413
|
def match(uri, processor=nil)
|
415
|
-
uri = Addressable::URI.parse(uri)
|
414
|
+
uri = Addressable::URI.parse(uri) unless uri.is_a?(Addressable::URI)
|
416
415
|
mapping = {}
|
417
416
|
|
418
417
|
# First, we need to process the pattern, and extract the values.
|
@@ -653,50 +652,16 @@ module Addressable
|
|
653
652
|
self.to_regexp.named_captures
|
654
653
|
end
|
655
654
|
|
656
|
-
##
|
657
|
-
# Generates a route result for a given set of parameters.
|
658
|
-
# Should only be used by rack-mount.
|
659
|
-
#
|
660
|
-
# @param params [Hash] The set of parameters used to expand the template.
|
661
|
-
# @param recall [Hash] Default parameters used to expand the template.
|
662
|
-
# @param options [Hash] Either a `:processor` or a `:parameterize` block.
|
663
|
-
#
|
664
|
-
# @api private
|
665
|
-
def generate(params={}, recall={}, options={})
|
666
|
-
merged = recall.merge(params)
|
667
|
-
if options[:processor]
|
668
|
-
processor = options[:processor]
|
669
|
-
elsif options[:parameterize]
|
670
|
-
# TODO: This is sending me into fits trying to shoe-horn this into
|
671
|
-
# the existing API. I think I've got this backwards and processors
|
672
|
-
# should be a set of 4 optional blocks named :validate, :transform,
|
673
|
-
# :match, and :restore. Having to use a singleton here is a huge
|
674
|
-
# code smell.
|
675
|
-
processor = Object.new
|
676
|
-
class <<processor
|
677
|
-
attr_accessor :block
|
678
|
-
def transform(name, value)
|
679
|
-
block.call(name, value)
|
680
|
-
end
|
681
|
-
end
|
682
|
-
processor.block = options[:parameterize]
|
683
|
-
else
|
684
|
-
processor = nil
|
685
|
-
end
|
686
|
-
result = self.expand(merged, processor)
|
687
|
-
result.to_s if result
|
688
|
-
end
|
689
|
-
|
690
655
|
private
|
691
656
|
def ordered_variable_defaults
|
692
657
|
@ordered_variable_defaults ||= begin
|
693
658
|
expansions, _ = parse_template_pattern(pattern)
|
694
|
-
expansions.
|
659
|
+
expansions.flat_map do |capture|
|
695
660
|
_, _, varlist = *capture.match(EXPRESSION)
|
696
661
|
varlist.split(',').map do |varspec|
|
697
662
|
varspec[VARSPEC, 1]
|
698
663
|
end
|
699
|
-
end
|
664
|
+
end
|
700
665
|
end
|
701
666
|
end
|
702
667
|
|
@@ -973,15 +938,35 @@ module Addressable
|
|
973
938
|
end
|
974
939
|
end
|
975
940
|
|
941
|
+
##
|
942
|
+
# Generates the <tt>Regexp</tt> that parses a template pattern. Memoizes the
|
943
|
+
# value if template processor not set (processors may not be deterministic)
|
944
|
+
#
|
945
|
+
# @param [String] pattern The URI template pattern.
|
946
|
+
# @param [#match] processor The template processor to use.
|
947
|
+
#
|
948
|
+
# @return [Array, Regexp]
|
949
|
+
# An array of expansion variables nad a regular expression which may be
|
950
|
+
# used to parse a template pattern
|
951
|
+
def parse_template_pattern(pattern, processor = nil)
|
952
|
+
if processor.nil? && pattern == @pattern
|
953
|
+
@cached_template_parse ||=
|
954
|
+
parse_new_template_pattern(pattern, processor)
|
955
|
+
else
|
956
|
+
parse_new_template_pattern(pattern, processor)
|
957
|
+
end
|
958
|
+
end
|
959
|
+
|
976
960
|
##
|
977
961
|
# Generates the <tt>Regexp</tt> that parses a template pattern.
|
978
962
|
#
|
979
963
|
# @param [String] pattern The URI template pattern.
|
980
964
|
# @param [#match] processor The template processor to use.
|
981
965
|
#
|
982
|
-
# @return [Regexp]
|
983
|
-
#
|
984
|
-
|
966
|
+
# @return [Array, Regexp]
|
967
|
+
# An array of expansion variables nad a regular expression which may be
|
968
|
+
# used to parse a template pattern
|
969
|
+
def parse_new_template_pattern(pattern, processor = nil)
|
985
970
|
# Escape the pattern. The two gsubs restore the escaped curly braces
|
986
971
|
# back to their original form. Basically, escape everything that isn't
|
987
972
|
# within an expansion.
|
@@ -1037,7 +1022,7 @@ module Addressable
|
|
1037
1022
|
end
|
1038
1023
|
|
1039
1024
|
# Ensure that the regular expression matches the whole URI.
|
1040
|
-
regexp_string = "
|
1025
|
+
regexp_string = "\\A#{regexp_string}\\z"
|
1041
1026
|
return expansions, Regexp.new(regexp_string)
|
1042
1027
|
end
|
1043
1028
|
|