honkster-addressable 2.1.2 → 2.2.3
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.
- data/CHANGELOG +82 -59
- data/LICENSE +1 -1
- data/README +12 -2
- data/Rakefile +0 -32
- data/lib/addressable/template.rb +1 -1
- data/lib/addressable/uri.rb +330 -105
- data/lib/addressable/version.rb +3 -3
- data/spec/addressable/uri_spec.rb +726 -21
- data/tasks/gem.rake +16 -0
- data/tasks/rdoc.rake +0 -3
- data/tasks/rubyforge.rake +2 -2
- data/tasks/yard.rake +26 -0
- data/website/index.html +110 -0
- metadata +70 -25
- data/spec/addressable/spec_helper.rb +0 -5
- data/spec/data/rfc3986.txt +0 -3419
data/CHANGELOG
CHANGED
@@ -1,86 +1,109 @@
|
|
1
|
+
=== Addressable 2.2.5
|
2
|
+
- 'parsing' a pre-parsed URI object is now a dup operation
|
3
|
+
|
4
|
+
=== Addressable 2.2.4
|
5
|
+
- added origin support from draft-ietf-websec-origin-00
|
6
|
+
- resolved issue with attempting to navigate below root
|
7
|
+
- fixed bug with string splitting in query strings
|
8
|
+
|
9
|
+
=== Addressable 2.2.3
|
10
|
+
- added :flat_array notation for query strings
|
11
|
+
|
12
|
+
=== Addressable 2.2.2
|
13
|
+
- fixed issue with percent escaping of '+' character in query strings
|
14
|
+
|
15
|
+
=== Addressable 2.2.1
|
16
|
+
- added support for application/x-www-form-urlencoded.
|
17
|
+
|
18
|
+
=== Addressable 2.2.0
|
19
|
+
- added site methods
|
20
|
+
- improved documentation
|
21
|
+
|
1
22
|
=== Addressable 2.1.2
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
23
|
+
- added HTTP request URI methods
|
24
|
+
- better handling of Windows file paths
|
25
|
+
- validation_deferred boolean replaced with defer_validation block
|
26
|
+
- normalization of percent-encoded paths should now be correct
|
27
|
+
- fixed issue with constructing URIs with relative paths
|
28
|
+
- fixed warnings
|
6
29
|
|
7
30
|
=== Addressable 2.1.1
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
31
|
+
- more type checking changes
|
32
|
+
- fixed issue with unicode normalization
|
33
|
+
- added method to find template defaults
|
34
|
+
- symbolic keys are now allowed in template mappings
|
35
|
+
- numeric values and symbolic values are now allowed in template mappings
|
13
36
|
|
14
37
|
=== Addressable 2.1.0
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
38
|
+
- refactored URI template support out into its own class
|
39
|
+
- removed extract method due to being useless and unreliable
|
40
|
+
- removed Addressable::URI.expand_template
|
41
|
+
- removed Addressable::URI#extract_mapping
|
42
|
+
- added partial template expansion
|
43
|
+
- fixed minor bugs in the parse and heuristic_parse methods
|
44
|
+
- fixed incompatibility with Ruby 1.9.1
|
45
|
+
- fixed bottleneck in Addressable::URI#hash and Addressable::URI#to_s
|
46
|
+
- fixed unicode normalization exception
|
47
|
+
- updated query_values methods to better handle subscript notation
|
48
|
+
- worked around issue with freezing URIs
|
49
|
+
- improved specs
|
27
50
|
|
28
51
|
=== Addressable 2.0.2
|
29
|
-
|
30
|
-
|
52
|
+
- fixed issue with URI template expansion
|
53
|
+
- fixed issue with percent escaping characters 0-15
|
31
54
|
|
32
55
|
=== Addressable 2.0.1
|
33
|
-
|
34
|
-
|
56
|
+
- fixed issue with query string assignment
|
57
|
+
- fixed issue with improperly encoded components
|
35
58
|
|
36
59
|
=== Addressable 2.0.0
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
60
|
+
- the initialize method now takes an options hash as its only parameter
|
61
|
+
- added query_values method to URI class
|
62
|
+
- completely replaced IDNA implementation with pure Ruby
|
63
|
+
- renamed Addressable::ADDRESSABLE_VERSION to Addressable::VERSION
|
64
|
+
- completely reworked the Rakefile
|
65
|
+
- changed the behavior of the port method significantly
|
66
|
+
- Addressable::URI.encode_segment, Addressable::URI.unencode_segment renamed
|
67
|
+
- documentation is now in YARD format
|
68
|
+
- more rigorous type checking
|
69
|
+
- to_str method implemented, implicit conversion to Strings now allowed
|
70
|
+
- Addressable::URI#omit method added, Addressable::URI#merge method replaced
|
71
|
+
- updated URI Template code to match v 03 of the draft spec
|
72
|
+
- added a bunch of new specifications
|
50
73
|
|
51
74
|
=== Addressable 1.0.4
|
52
|
-
|
53
|
-
|
75
|
+
- switched to using RSpec's pending system for specs that rely on IDN
|
76
|
+
- fixed issue with creating URIs with paths that are not prefixed with '/'
|
54
77
|
|
55
78
|
=== Addressable 1.0.3
|
56
|
-
|
79
|
+
- implemented a hash method
|
57
80
|
|
58
81
|
=== Addressable 1.0.2
|
59
|
-
|
82
|
+
- fixed minor bug with the extract_mapping method
|
60
83
|
|
61
84
|
=== Addressable 1.0.1
|
62
|
-
|
85
|
+
- fixed minor bug with the extract_mapping method
|
63
86
|
|
64
87
|
=== Addressable 1.0.0
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
88
|
+
- heuristic parse method added
|
89
|
+
- parsing is slightly more strict
|
90
|
+
- replaced to_h with to_hash
|
91
|
+
- fixed routing methods
|
92
|
+
- improved specifications
|
93
|
+
- improved heckle rake task
|
94
|
+
- no surviving heckle mutations
|
72
95
|
|
73
96
|
=== Addressable 0.1.2
|
74
|
-
|
75
|
-
|
76
|
-
|
97
|
+
- improved normalization
|
98
|
+
- fixed bug in joining algorithm
|
99
|
+
- updated specifications
|
77
100
|
|
78
101
|
=== Addressable 0.1.1
|
79
|
-
|
80
|
-
|
102
|
+
- updated documentation
|
103
|
+
- added URI Template variable extraction
|
81
104
|
|
82
105
|
=== Addressable 0.1.0
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
106
|
+
- initial release
|
107
|
+
- implementation based on RFC 3986, 3987
|
108
|
+
- support for IRIs via libidn
|
109
|
+
- support for the URI Template draft spec
|
data/LICENSE
CHANGED
data/README
CHANGED
@@ -1,10 +1,20 @@
|
|
1
|
+
== About
|
2
|
+
|
3
|
+
Homepage:: Addressable[http://addressable.rubyforge.org/]
|
4
|
+
Authors:: Bob Aman (mailto:bob@sporkmonger.com)
|
5
|
+
Copyright:: Copyright 2010 Bob Aman
|
6
|
+
License:: MIT
|
7
|
+
|
1
8
|
Addressable is a replacement for the URI implementation that is part of
|
2
9
|
Ruby's standard library. It more closely conforms to the relevant RFCs and
|
3
10
|
adds support for IRIs and URI templates. Additionally, it provides extensive
|
4
11
|
support for URI templates.
|
5
12
|
|
6
|
-
|
7
|
-
|
13
|
+
== Classes
|
14
|
+
- {Addressable::URI}
|
15
|
+
- {Addressable::Template}
|
16
|
+
|
17
|
+
== Example usage
|
8
18
|
require "addressable/uri"
|
9
19
|
|
10
20
|
uri = Addressable::URI.parse("http://example.com/path/to/resource/")
|
data/Rakefile
CHANGED
@@ -27,38 +27,6 @@ Ruby's standard library. It more closely conforms to the relevant RFCs and
|
|
27
27
|
adds support for IRIs and URI templates.
|
28
28
|
TEXT
|
29
29
|
|
30
|
-
desc "generates .gemspec file"
|
31
|
-
task :gemspec do
|
32
|
-
spec = Gem::Specification.new do |p|
|
33
|
-
p.name = ENV["GEM_PREFIX"] ? "#{ENV["GEM_PREFIX"]}-addressable" : 'addressable'
|
34
|
-
p.version = PKG_VERSION
|
35
|
-
|
36
|
-
p.summary = PKG_SUMMARY
|
37
|
-
p.description = PKG_DESCRIPTION
|
38
|
-
|
39
|
-
p.author = 'Bob Aman'
|
40
|
-
p.email = 'bob@sporkmonger.com'
|
41
|
-
p.homepage = 'http://github.com/mislav/addressable'
|
42
|
-
p.rubyforge_project = nil
|
43
|
-
|
44
|
-
p.files = FileList['Rakefile', '{bin,lib,tasks,spec}/**/*', 'README*', 'LICENSE*', 'CHANGELOG*'] & `git ls-files`.split
|
45
|
-
|
46
|
-
p.executables = Dir['bin/*'].map { |f| File.basename(f) }
|
47
|
-
|
48
|
-
p.has_rdoc = true
|
49
|
-
end
|
50
|
-
|
51
|
-
spec_string = spec.to_ruby
|
52
|
-
|
53
|
-
begin
|
54
|
-
Thread.new { eval("$SAFE = 3\n#{spec_string}", binding) }.join
|
55
|
-
rescue
|
56
|
-
abort "unsafe gemspec: #{$!}"
|
57
|
-
else
|
58
|
-
File.open("#{spec.name}.gemspec", 'w') { |file| file.write spec_string }
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
30
|
PKG_FILES = FileList[
|
63
31
|
"lib/**/*", "spec/**/*", "vendor/**/*",
|
64
32
|
"tasks/**/*", "website/**/*",
|
data/lib/addressable/template.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# encoding:utf-8
|
2
2
|
#--
|
3
|
-
# Addressable, Copyright (c) 2006-
|
3
|
+
# Addressable, Copyright (c) 2006-2010 Bob Aman
|
4
4
|
#
|
5
5
|
# Permission is hereby granted, free of charge, to any person obtaining
|
6
6
|
# a copy of this software and associated documentation files (the
|
data/lib/addressable/uri.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# encoding:utf-8
|
2
2
|
#--
|
3
|
-
# Addressable, Copyright (c) 2006-
|
3
|
+
# Addressable, Copyright (c) 2006-2010 Bob Aman
|
4
4
|
#
|
5
5
|
# Permission is hereby granted, free of charge, to any person obtaining
|
6
6
|
# a copy of this software and associated documentation files (the
|
@@ -59,15 +59,15 @@ module Addressable
|
|
59
59
|
#
|
60
60
|
# @param [String, Addressable::URI, #to_str] uri
|
61
61
|
# The URI string to parse.
|
62
|
-
#
|
63
|
-
#
|
62
|
+
# No parsing is performed if the object is already an
|
63
|
+
# <code>Addressable::URI</code>.
|
64
64
|
#
|
65
65
|
# @return [Addressable::URI] The parsed URI.
|
66
66
|
def self.parse(uri)
|
67
67
|
# If we were given nil, return nil.
|
68
68
|
return nil unless uri
|
69
69
|
# If a URI object is passed, just return itself.
|
70
|
-
return uri if uri.kind_of?(self)
|
70
|
+
return uri.dup if uri.kind_of?(self)
|
71
71
|
|
72
72
|
# If a URI object of the Ruby standard library variety is passed,
|
73
73
|
# convert it to a string, then parse the string.
|
@@ -130,18 +130,18 @@ module Addressable
|
|
130
130
|
#
|
131
131
|
# @param [String, Addressable::URI, #to_str] uri
|
132
132
|
# The URI string to parse.
|
133
|
-
#
|
134
|
-
#
|
133
|
+
# No parsing is performed if the object is already an
|
134
|
+
# <code>Addressable::URI</code>.
|
135
135
|
# @param [Hash] hints
|
136
|
-
# A <
|
137
|
-
#
|
136
|
+
# A <code>Hash</code> of hints to the heuristic parser.
|
137
|
+
# Defaults to <code>{:scheme => "http"}</code>.
|
138
138
|
#
|
139
139
|
# @return [Addressable::URI] The parsed URI.
|
140
140
|
def self.heuristic_parse(uri, hints={})
|
141
141
|
# If we were given nil, return nil.
|
142
142
|
return nil unless uri
|
143
143
|
# If a URI object is passed, just return itself.
|
144
|
-
return uri if uri.kind_of?(self)
|
144
|
+
return uri.dup if uri.kind_of?(self)
|
145
145
|
if !uri.respond_to?(:to_str)
|
146
146
|
raise TypeError, "Can't convert #{uri.class} into String."
|
147
147
|
end
|
@@ -167,11 +167,13 @@ module Addressable
|
|
167
167
|
if parsed.path.include?(".")
|
168
168
|
new_host = parsed.path[/^([^\/]+\.[^\/]*)/, 1]
|
169
169
|
if new_host
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
170
|
+
parsed.defer_validation do
|
171
|
+
new_path = parsed.path.gsub(
|
172
|
+
Regexp.new("^" + Regexp.escape(new_host)), "")
|
173
|
+
parsed.host = new_host
|
174
|
+
parsed.path = new_path
|
175
|
+
parsed.scheme = hints[:scheme] unless parsed.scheme
|
176
|
+
end
|
175
177
|
end
|
176
178
|
end
|
177
179
|
return parsed
|
@@ -181,13 +183,13 @@ module Addressable
|
|
181
183
|
# Converts a path to a file scheme URI. If the path supplied is
|
182
184
|
# relative, it will be returned as a relative URI. If the path supplied
|
183
185
|
# is actually a non-file URI, it will parse the URI as if it had been
|
184
|
-
# parsed with <
|
186
|
+
# parsed with <code>Addressable::URI.parse</code>. Handles all of the
|
185
187
|
# various Microsoft-specific formats for specifying paths.
|
186
188
|
#
|
187
189
|
# @param [String, Addressable::URI, #to_str] path
|
188
|
-
#
|
189
|
-
#
|
190
|
-
#
|
190
|
+
# Typically a <code>String</code> path to a file or directory, but
|
191
|
+
# will return a sensible return value if an absolute URI is supplied
|
192
|
+
# instead.
|
191
193
|
#
|
192
194
|
# @return [Addressable::URI]
|
193
195
|
# The parsed file scheme URI or the original URI if some other URI
|
@@ -277,17 +279,17 @@ module Addressable
|
|
277
279
|
# @param [String, #to_str] component The URI component to encode.
|
278
280
|
#
|
279
281
|
# @param [String, Regexp] character_class
|
280
|
-
#
|
281
|
-
#
|
282
|
-
#
|
283
|
-
#
|
284
|
-
#
|
285
|
-
#
|
286
|
-
#
|
287
|
-
#
|
288
|
-
#
|
289
|
-
#
|
290
|
-
# href="http://www.ietf.org/rfc/rfc3986.txt">RFC 3986</a>.
|
282
|
+
# The characters which are not percent encoded. If a <code>String</code>
|
283
|
+
# is passed, the <code>String</code> must be formatted as a regular
|
284
|
+
# expression character class. (Do not include the surrounding square
|
285
|
+
# brackets.) For example, <code>"b-zB-Z0-9"</code> would cause
|
286
|
+
# everything but the letters 'b' through 'z' and the numbers '0' through
|
287
|
+
# '9' to be percent encoded. If a <code>Regexp</code> is passed, the
|
288
|
+
# value <code>/[^b-zB-Z0-9]/</code> would have the same effect. A set of
|
289
|
+
# useful <code>String</code> values may be found in the
|
290
|
+
# <code>Addressable::URI::CharacterClasses</code> module. The default
|
291
|
+
# value is the reserved plus unreserved character classes specified in
|
292
|
+
# <a href="http://www.ietf.org/rfc/rfc3986.txt">RFC 3986</a>.
|
291
293
|
#
|
292
294
|
# @return [String] The encoded component.
|
293
295
|
#
|
@@ -332,21 +334,21 @@ module Addressable
|
|
332
334
|
##
|
333
335
|
# Unencodes any percent encoded characters within a URI component.
|
334
336
|
# This method may be used for unencoding either components or full URIs,
|
335
|
-
# however, it is recommended to use the <
|
336
|
-
# when unencoding components.
|
337
|
+
# however, it is recommended to use the <code>unencode_component</code>
|
338
|
+
# alias when unencoding components.
|
337
339
|
#
|
338
340
|
# @param [String, Addressable::URI, #to_str] uri
|
339
341
|
# The URI or component to unencode.
|
340
342
|
#
|
341
343
|
# @param [Class] returning
|
342
344
|
# The type of object to return.
|
343
|
-
#
|
344
|
-
#
|
345
|
-
# <
|
345
|
+
# This value may only be set to <code>String</code> or
|
346
|
+
# <code>Addressable::URI</code>. All other values are invalid. Defaults
|
347
|
+
# to <code>String</code>.
|
346
348
|
#
|
347
349
|
# @return [String, Addressable::URI]
|
348
350
|
# The unencoded component or URI.
|
349
|
-
#
|
351
|
+
# The return type is determined by the <code>returning</code> parameter.
|
350
352
|
def self.unencode(uri, returning=String)
|
351
353
|
return nil if uri.nil?
|
352
354
|
if !uri.respond_to?(:to_str)
|
@@ -381,17 +383,17 @@ module Addressable
|
|
381
383
|
# @param [String, #to_str] component The URI component to encode.
|
382
384
|
#
|
383
385
|
# @param [String, Regexp] character_class
|
384
|
-
#
|
385
|
-
#
|
386
|
-
#
|
387
|
-
#
|
388
|
-
#
|
389
|
-
#
|
390
|
-
#
|
391
|
-
#
|
392
|
-
#
|
393
|
-
#
|
394
|
-
# href="http://www.ietf.org/rfc/rfc3986.txt">RFC 3986</a>.
|
386
|
+
# The characters which are not percent encoded. If a <code>String</code>
|
387
|
+
# is passed, the <code>String</code> must be formatted as a regular
|
388
|
+
# expression character class. (Do not include the surrounding square
|
389
|
+
# brackets.) For example, <code>"b-zB-Z0-9"</code> would cause
|
390
|
+
# everything but the letters 'b' through 'z' and the numbers '0' through
|
391
|
+
# '9' to be percent encoded. If a <code>Regexp</code> is passed, the
|
392
|
+
# value <code>/[^b-zB-Z0-9]/</code> would have the same effect. A set of
|
393
|
+
# useful <code>String</code> values may be found in the
|
394
|
+
# <code>Addressable::URI::CharacterClasses</code> module. The default
|
395
|
+
# value is the reserved plus unreserved character classes specified in
|
396
|
+
# <a href="http://www.ietf.org/rfc/rfc3986.txt">RFC 3986</a>.
|
395
397
|
#
|
396
398
|
# @return [String] The normalized component.
|
397
399
|
#
|
@@ -447,13 +449,13 @@ module Addressable
|
|
447
449
|
#
|
448
450
|
# @param [Class] returning
|
449
451
|
# The type of object to return.
|
450
|
-
#
|
451
|
-
#
|
452
|
-
# <
|
452
|
+
# This value may only be set to <code>String</code> or
|
453
|
+
# <code>Addressable::URI</code>. All other values are invalid. Defaults
|
454
|
+
# to <code>String</code>.
|
453
455
|
#
|
454
456
|
# @return [String, Addressable::URI]
|
455
457
|
# The encoded URI.
|
456
|
-
#
|
458
|
+
# The return type is determined by the <code>returning</code> parameter.
|
457
459
|
def self.encode(uri, returning=String)
|
458
460
|
return nil if uri.nil?
|
459
461
|
if !uri.respond_to?(:to_str)
|
@@ -497,13 +499,13 @@ module Addressable
|
|
497
499
|
#
|
498
500
|
# @param [Class] returning
|
499
501
|
# The type of object to return.
|
500
|
-
#
|
501
|
-
#
|
502
|
-
# <
|
502
|
+
# This value may only be set to <code>String</code> or
|
503
|
+
# <code>Addressable::URI</code>. All other values are invalid. Defaults
|
504
|
+
# to <code>String</code>.
|
503
505
|
#
|
504
506
|
# @return [String, Addressable::URI]
|
505
507
|
# The encoded URI.
|
506
|
-
#
|
508
|
+
# The return type is determined by the <code>returning</code> parameter.
|
507
509
|
def self.normalized_encode(uri, returning=String)
|
508
510
|
if !uri.respond_to?(:to_str)
|
509
511
|
raise TypeError, "Can't convert #{uri.class} into String."
|
@@ -558,6 +560,81 @@ module Addressable
|
|
558
560
|
end
|
559
561
|
end
|
560
562
|
|
563
|
+
##
|
564
|
+
# Encodes a set of key/value pairs according to the rules for the
|
565
|
+
# <code>application/x-www-form-urlencoded</code> MIME type.
|
566
|
+
#
|
567
|
+
# @param [#to_hash, #to_ary] form_values
|
568
|
+
# The form values to encode.
|
569
|
+
#
|
570
|
+
# @param [TrueClass, FalseClass] sort
|
571
|
+
# Sort the key/value pairs prior to encoding.
|
572
|
+
# Defaults to <code>false</code>.
|
573
|
+
#
|
574
|
+
# @return [String]
|
575
|
+
# The encoded value.
|
576
|
+
def self.form_encode(form_values, sort=false)
|
577
|
+
if form_values.respond_to?(:to_hash)
|
578
|
+
form_values = form_values.to_hash.to_a
|
579
|
+
elsif form_values.respond_to?(:to_ary)
|
580
|
+
form_values = form_values.to_ary
|
581
|
+
else
|
582
|
+
raise TypeError, "Can't convert #{form_values.class} into Array."
|
583
|
+
end
|
584
|
+
form_values = form_values.map do |(key, value)|
|
585
|
+
[key.to_s, value.to_s]
|
586
|
+
end
|
587
|
+
if sort
|
588
|
+
# Useful for OAuth and optimizing caching systems
|
589
|
+
form_values = form_values.sort
|
590
|
+
end
|
591
|
+
escaped_form_values = form_values.map do |(key, value)|
|
592
|
+
# Line breaks are CRLF pairs
|
593
|
+
[
|
594
|
+
self.encode_component(
|
595
|
+
key.gsub(/(\r\n|\n|\r)/, "\r\n"),
|
596
|
+
CharacterClasses::UNRESERVED
|
597
|
+
).gsub("%20", "+"),
|
598
|
+
self.encode_component(
|
599
|
+
value.gsub(/(\r\n|\n|\r)/, "\r\n"),
|
600
|
+
CharacterClasses::UNRESERVED
|
601
|
+
).gsub("%20", "+")
|
602
|
+
]
|
603
|
+
end
|
604
|
+
return (escaped_form_values.map do |(key, value)|
|
605
|
+
"#{key}=#{value}"
|
606
|
+
end).join("&")
|
607
|
+
end
|
608
|
+
|
609
|
+
##
|
610
|
+
# Decodes a <code>String</code> according to the rules for the
|
611
|
+
# <code>application/x-www-form-urlencoded</code> MIME type.
|
612
|
+
#
|
613
|
+
# @param [String, #to_str] encoded_value
|
614
|
+
# The form values to decode.
|
615
|
+
#
|
616
|
+
# @return [Array]
|
617
|
+
# The decoded values.
|
618
|
+
# This is not a <code>Hash</code> because of the possibility for
|
619
|
+
# duplicate keys.
|
620
|
+
def self.form_unencode(encoded_value)
|
621
|
+
if !encoded_value.respond_to?(:to_str)
|
622
|
+
raise TypeError, "Can't convert #{encoded_value.class} into String."
|
623
|
+
end
|
624
|
+
encoded_value = encoded_value.to_str
|
625
|
+
split_values = encoded_value.split("&").map do |pair|
|
626
|
+
pair.split("=", 2)
|
627
|
+
end
|
628
|
+
return split_values.map do |(key, value)|
|
629
|
+
[
|
630
|
+
key ? self.unencode_component(
|
631
|
+
key.gsub("+", "%20")).gsub(/(\r\n|\n|\r)/, "\n") : nil,
|
632
|
+
value ? (self.unencode_component(
|
633
|
+
value.gsub("+", "%20")).gsub(/(\r\n|\n|\r)/, "\n")) : nil
|
634
|
+
]
|
635
|
+
end
|
636
|
+
end
|
637
|
+
|
561
638
|
##
|
562
639
|
# Creates a new uri object from component parts.
|
563
640
|
#
|
@@ -647,13 +724,19 @@ module Addressable
|
|
647
724
|
|
648
725
|
if new_scheme && !new_scheme.respond_to?(:to_str)
|
649
726
|
raise TypeError, "Can't convert #{new_scheme.class} into String."
|
727
|
+
elsif new_scheme
|
728
|
+
new_scheme = new_scheme.to_str
|
729
|
+
end
|
730
|
+
if new_scheme && new_scheme !~ /[a-z][a-z0-9\.\+\-]*/i
|
731
|
+
raise InvalidURIError, "Invalid scheme format."
|
650
732
|
end
|
651
|
-
@scheme = new_scheme
|
733
|
+
@scheme = new_scheme
|
652
734
|
@scheme = nil if @scheme.to_s.strip == ""
|
653
735
|
|
654
736
|
# Reset dependant values
|
655
737
|
@normalized_scheme = nil
|
656
738
|
@uri_string = nil
|
739
|
+
@hash = nil
|
657
740
|
|
658
741
|
# Ensure we haven't created an invalid URI
|
659
742
|
validate()
|
@@ -714,6 +797,7 @@ module Addressable
|
|
714
797
|
@authority = nil
|
715
798
|
@normalized_user = nil
|
716
799
|
@uri_string = nil
|
800
|
+
@hash = nil
|
717
801
|
|
718
802
|
# Ensure we haven't created an invalid URI
|
719
803
|
validate()
|
@@ -775,6 +859,7 @@ module Addressable
|
|
775
859
|
@authority = nil
|
776
860
|
@normalized_password = nil
|
777
861
|
@uri_string = nil
|
862
|
+
@hash = nil
|
778
863
|
|
779
864
|
# Ensure we haven't created an invalid URI
|
780
865
|
validate()
|
@@ -844,6 +929,7 @@ module Addressable
|
|
844
929
|
# Reset dependant values
|
845
930
|
@authority = nil
|
846
931
|
@uri_string = nil
|
932
|
+
@hash = nil
|
847
933
|
|
848
934
|
# Ensure we haven't created an invalid URI
|
849
935
|
validate()
|
@@ -899,6 +985,7 @@ module Addressable
|
|
899
985
|
@authority = nil
|
900
986
|
@normalized_host = nil
|
901
987
|
@uri_string = nil
|
988
|
+
@hash = nil
|
902
989
|
|
903
990
|
# Ensure we haven't created an invalid URI
|
904
991
|
validate()
|
@@ -984,14 +1071,35 @@ module Addressable
|
|
984
1071
|
@userinfo = nil
|
985
1072
|
@normalized_userinfo = nil
|
986
1073
|
@uri_string = nil
|
1074
|
+
@hash = nil
|
987
1075
|
|
988
1076
|
# Ensure we haven't created an invalid URI
|
989
1077
|
validate()
|
990
1078
|
end
|
991
1079
|
|
1080
|
+
##
|
1081
|
+
# The origin for this URI, serialized to ASCII, as per
|
1082
|
+
# draft-ietf-websec-origin-00, section 5.2.
|
1083
|
+
#
|
1084
|
+
# @return [String] The serialized origin.
|
1085
|
+
def origin
|
1086
|
+
return (if self.scheme && self.authority
|
1087
|
+
if self.normalized_port
|
1088
|
+
(
|
1089
|
+
"#{self.normalized_scheme}://#{self.normalized_host}" +
|
1090
|
+
":#{self.normalized_port}"
|
1091
|
+
)
|
1092
|
+
else
|
1093
|
+
"#{self.normalized_scheme}://#{self.normalized_host}"
|
1094
|
+
end
|
1095
|
+
else
|
1096
|
+
"null"
|
1097
|
+
end)
|
1098
|
+
end
|
1099
|
+
|
992
1100
|
# Returns an array of known ip-based schemes. These schemes typically
|
993
1101
|
# use a similar URI form:
|
994
|
-
#
|
1102
|
+
# <code>//<user>:<password>@<host>:<port>/<url-path></code>
|
995
1103
|
def self.ip_based_schemes
|
996
1104
|
return self.port_mapping.keys
|
997
1105
|
end
|
@@ -1065,6 +1173,7 @@ module Addressable
|
|
1065
1173
|
@inferred_port = nil
|
1066
1174
|
@normalized_port = nil
|
1067
1175
|
@uri_string = nil
|
1176
|
+
@hash = nil
|
1068
1177
|
|
1069
1178
|
# Ensure we haven't created an invalid URI
|
1070
1179
|
validate()
|
@@ -1090,6 +1199,76 @@ module Addressable
|
|
1090
1199
|
end)
|
1091
1200
|
end
|
1092
1201
|
|
1202
|
+
##
|
1203
|
+
# The combination of components that represent a site.
|
1204
|
+
# Combines the scheme, user, password, host, and port components.
|
1205
|
+
# Primarily useful for HTTP and HTTPS.
|
1206
|
+
#
|
1207
|
+
# For example, <code>"http://example.com/path?query"</code> would have a
|
1208
|
+
# <code>site</code> value of <code>"http://example.com"</code>.
|
1209
|
+
#
|
1210
|
+
# @return [String] The components that identify a site.
|
1211
|
+
def site
|
1212
|
+
@site ||= (begin
|
1213
|
+
if self.scheme || self.authority
|
1214
|
+
site_string = ""
|
1215
|
+
site_string << "#{self.scheme}:" if self.scheme != nil
|
1216
|
+
site_string << "//#{self.authority}" if self.authority != nil
|
1217
|
+
site_string
|
1218
|
+
else
|
1219
|
+
nil
|
1220
|
+
end
|
1221
|
+
end)
|
1222
|
+
end
|
1223
|
+
|
1224
|
+
##
|
1225
|
+
# The normalized combination of components that represent a site.
|
1226
|
+
# Combines the scheme, user, password, host, and port components.
|
1227
|
+
# Primarily useful for HTTP and HTTPS.
|
1228
|
+
#
|
1229
|
+
# For example, <code>"http://example.com/path?query"</code> would have a
|
1230
|
+
# <code>site</code> value of <code>"http://example.com"</code>.
|
1231
|
+
#
|
1232
|
+
# @return [String] The normalized components that identify a site.
|
1233
|
+
def normalized_site
|
1234
|
+
@site ||= (begin
|
1235
|
+
if self.normalized_scheme || self.normalized_authority
|
1236
|
+
site_string = ""
|
1237
|
+
if self.normalized_scheme != nil
|
1238
|
+
site_string << "#{self.normalized_scheme}:"
|
1239
|
+
end
|
1240
|
+
if self.normalized_authority != nil
|
1241
|
+
site_string << "//#{self.normalized_authority}"
|
1242
|
+
end
|
1243
|
+
site_string
|
1244
|
+
else
|
1245
|
+
nil
|
1246
|
+
end
|
1247
|
+
end)
|
1248
|
+
end
|
1249
|
+
|
1250
|
+
##
|
1251
|
+
# Sets the site value for this URI.
|
1252
|
+
#
|
1253
|
+
# @param [String, #to_str] new_site The new site value.
|
1254
|
+
def site=(new_site)
|
1255
|
+
if new_site
|
1256
|
+
if !new_site.respond_to?(:to_str)
|
1257
|
+
raise TypeError, "Can't convert #{new_site.class} into String."
|
1258
|
+
end
|
1259
|
+
new_site = new_site.to_str
|
1260
|
+
# These two regular expressions derived from the primary parsing
|
1261
|
+
# expression
|
1262
|
+
self.scheme = new_site[/^(?:([^:\/?#]+):)?(?:\/\/(?:[^\/?#]*))?$/, 1]
|
1263
|
+
self.authority = new_site[
|
1264
|
+
/^(?:(?:[^:\/?#]+):)?(?:\/\/([^\/?#]*))?$/, 1
|
1265
|
+
]
|
1266
|
+
else
|
1267
|
+
self.scheme = nil
|
1268
|
+
self.authority = nil
|
1269
|
+
end
|
1270
|
+
end
|
1271
|
+
|
1093
1272
|
##
|
1094
1273
|
# The path component for this URI.
|
1095
1274
|
#
|
@@ -1105,8 +1284,13 @@ module Addressable
|
|
1105
1284
|
# @return [String] The path component, normalized.
|
1106
1285
|
def normalized_path
|
1107
1286
|
@normalized_path ||= (begin
|
1287
|
+
if self.scheme == nil && self.path != nil && self.path != "" &&
|
1288
|
+
self.path =~ /^(?!\/)[^\/:]*:.*$/
|
1289
|
+
# Relative paths with colons in the first segment are ambiguous.
|
1290
|
+
self.path.sub!(":", "%2F")
|
1291
|
+
end
|
1108
1292
|
# String#split(delimeter, -1) uses the more strict splitting behavior
|
1109
|
-
# found in Python.
|
1293
|
+
# found by default in Python.
|
1110
1294
|
result = (self.path.strip.split("/", -1).map do |segment|
|
1111
1295
|
Addressable::URI.normalize_component(
|
1112
1296
|
segment,
|
@@ -1141,6 +1325,7 @@ module Addressable
|
|
1141
1325
|
# Reset dependant values
|
1142
1326
|
@normalized_path = nil
|
1143
1327
|
@uri_string = nil
|
1328
|
+
@hash = nil
|
1144
1329
|
end
|
1145
1330
|
|
1146
1331
|
##
|
@@ -1203,17 +1388,18 @@ module Addressable
|
|
1203
1388
|
# Reset dependant values
|
1204
1389
|
@normalized_query = nil
|
1205
1390
|
@uri_string = nil
|
1391
|
+
@hash = nil
|
1206
1392
|
end
|
1207
1393
|
|
1208
1394
|
##
|
1209
1395
|
# Converts the query component to a Hash value.
|
1210
1396
|
#
|
1211
1397
|
# @option [Symbol] notation
|
1212
|
-
# May be one of <
|
1213
|
-
# The <
|
1214
|
-
# value is <
|
1398
|
+
# May be one of <code>:flat</code>, <code>:dot</code>, or
|
1399
|
+
# <code>:subscript</code>. The <code>:dot</code> notation is not
|
1400
|
+
# supported for assignment. Default value is <code>:subscript</code>.
|
1215
1401
|
#
|
1216
|
-
# @return [Hash] The query string parsed as a Hash object.
|
1402
|
+
# @return [Hash, Array] The query string parsed as a Hash or Array object.
|
1217
1403
|
#
|
1218
1404
|
# @example
|
1219
1405
|
# Addressable::URI.parse("?one=1&two=2&three=3").query_values
|
@@ -1236,12 +1422,16 @@ module Addressable
|
|
1236
1422
|
# "?one[two][three][]=four&one[two][three][]=five"
|
1237
1423
|
# ).query_values
|
1238
1424
|
# #=> {"one" => {"two" => {"three" => ["four", "five"]}}}
|
1425
|
+
# Addressable::URI.parse(
|
1426
|
+
# "?one=two&one=three").query_values(:notation => :flat_array)
|
1427
|
+
# #=> [['one', 'two'], ['one', 'three']]
|
1239
1428
|
def query_values(options={})
|
1240
1429
|
defaults = {:notation => :subscript}
|
1241
1430
|
options = defaults.merge(options)
|
1242
|
-
if ![:flat, :dot, :subscript].include?(options[:notation])
|
1431
|
+
if ![:flat, :dot, :subscript, :flat_array].include?(options[:notation])
|
1243
1432
|
raise ArgumentError,
|
1244
|
-
"Invalid notation. Must be one of:
|
1433
|
+
"Invalid notation. Must be one of: " +
|
1434
|
+
"[:flat, :dot, :subscript, :flat_array]."
|
1245
1435
|
end
|
1246
1436
|
dehash = lambda do |hash|
|
1247
1437
|
hash.each do |(key, value)|
|
@@ -1258,19 +1448,22 @@ module Addressable
|
|
1258
1448
|
end
|
1259
1449
|
end
|
1260
1450
|
return nil if self.query == nil
|
1451
|
+
empty_accumulator = :flat_array == options[:notation] ? [] : {}
|
1261
1452
|
return ((self.query.split("&").map do |pair|
|
1262
|
-
pair.split("=")
|
1263
|
-
end).inject(
|
1453
|
+
pair.split("=", 2) if pair && pair != ""
|
1454
|
+
end).compact.inject(empty_accumulator.dup) do |accumulator, (key, value)|
|
1264
1455
|
value = true if value.nil?
|
1265
1456
|
key = self.class.unencode_component(key)
|
1266
1457
|
if value != true
|
1267
|
-
value = self.class.unencode_component(value
|
1458
|
+
value = self.class.unencode_component(value.gsub(/\+/, " "))
|
1268
1459
|
end
|
1269
1460
|
if options[:notation] == :flat
|
1270
1461
|
if accumulator[key]
|
1271
1462
|
raise ArgumentError, "Key was repeated: #{key.inspect}"
|
1272
1463
|
end
|
1273
1464
|
accumulator[key] = value
|
1465
|
+
elsif options[:notation] == :flat_array
|
1466
|
+
accumulator << [key, value]
|
1274
1467
|
else
|
1275
1468
|
if options[:notation] == :dot
|
1276
1469
|
array_value = false
|
@@ -1293,8 +1486,12 @@ module Addressable
|
|
1293
1486
|
end
|
1294
1487
|
end
|
1295
1488
|
accumulator
|
1296
|
-
end).inject(
|
1297
|
-
|
1489
|
+
end).inject(empty_accumulator.dup) do |accumulator, (key, value)|
|
1490
|
+
if options[:notation] == :flat_array
|
1491
|
+
accumulator << [key, value]
|
1492
|
+
else
|
1493
|
+
accumulator[key] = value.kind_of?(Hash) ? dehash.call(value) : value
|
1494
|
+
end
|
1298
1495
|
accumulator
|
1299
1496
|
end
|
1300
1497
|
end
|
@@ -1302,15 +1499,32 @@ module Addressable
|
|
1302
1499
|
##
|
1303
1500
|
# Sets the query component for this URI from a Hash object.
|
1304
1501
|
# This method produces a query string using the :subscript notation.
|
1502
|
+
# An empty Hash will result in a nil query.
|
1305
1503
|
#
|
1306
|
-
# @param [Hash, #to_hash] new_query_values The new query values.
|
1504
|
+
# @param [Hash, #to_hash, Array] new_query_values The new query values.
|
1307
1505
|
def query_values=(new_query_values)
|
1308
1506
|
# Check for frozenness
|
1309
1507
|
raise TypeError, "Can't modify frozen URI." if self.frozen?
|
1310
|
-
if
|
1311
|
-
|
1508
|
+
if new_query_values == nil
|
1509
|
+
self.query = nil
|
1510
|
+
return nil
|
1511
|
+
end
|
1512
|
+
|
1513
|
+
if !new_query_values.is_a?(Array)
|
1514
|
+
if !new_query_values.respond_to?(:to_hash)
|
1515
|
+
raise TypeError,
|
1516
|
+
"Can't convert #{new_query_values.class} into Hash."
|
1517
|
+
end
|
1518
|
+
new_query_values = new_query_values.to_hash
|
1519
|
+
new_query_values = new_query_values.map do |key, value|
|
1520
|
+
key = key.to_s if key.kind_of?(Symbol)
|
1521
|
+
[key, value]
|
1522
|
+
end
|
1523
|
+
# Useful default for OAuth and caching.
|
1524
|
+
# Only to be used for non-Array inputs. Arrays should preserve order.
|
1525
|
+
new_query_values.sort!
|
1312
1526
|
end
|
1313
|
-
new_query_values
|
1527
|
+
# new_query_values have form [['key1', 'value1'], ['key2', 'value2']]
|
1314
1528
|
|
1315
1529
|
# Algorithm shamelessly stolen from Julien Genestoux, slightly modified
|
1316
1530
|
buffer = ""
|
@@ -1344,11 +1558,7 @@ module Addressable
|
|
1344
1558
|
end
|
1345
1559
|
end
|
1346
1560
|
end
|
1347
|
-
|
1348
|
-
|
1349
|
-
# Reset dependant values
|
1350
|
-
@normalized_query = nil
|
1351
|
-
@uri_string = nil
|
1561
|
+
self.query = buffer.chop
|
1352
1562
|
end
|
1353
1563
|
|
1354
1564
|
##
|
@@ -1386,6 +1596,7 @@ module Addressable
|
|
1386
1596
|
|
1387
1597
|
# Reset dependant values
|
1388
1598
|
@uri_string = nil
|
1599
|
+
@hash = nil
|
1389
1600
|
end
|
1390
1601
|
|
1391
1602
|
##
|
@@ -1429,6 +1640,7 @@ module Addressable
|
|
1429
1640
|
# Reset dependant values
|
1430
1641
|
@normalized_fragment = nil
|
1431
1642
|
@uri_string = nil
|
1643
|
+
@hash = nil
|
1432
1644
|
|
1433
1645
|
# Ensure we haven't created an invalid URI
|
1434
1646
|
validate()
|
@@ -1438,8 +1650,8 @@ module Addressable
|
|
1438
1650
|
# Determines if the scheme indicates an IP-based protocol.
|
1439
1651
|
#
|
1440
1652
|
# @return [TrueClass, FalseClass]
|
1441
|
-
#
|
1442
|
-
#
|
1653
|
+
# <code>true</code> if the scheme indicates an IP-based protocol.
|
1654
|
+
# <code>false</code> otherwise.
|
1443
1655
|
def ip_based?
|
1444
1656
|
if self.scheme
|
1445
1657
|
return self.class.ip_based_schemes.include?(
|
@@ -1452,7 +1664,8 @@ module Addressable
|
|
1452
1664
|
# Determines if the URI is relative.
|
1453
1665
|
#
|
1454
1666
|
# @return [TrueClass, FalseClass]
|
1455
|
-
#
|
1667
|
+
# <code>true</code> if the URI is relative. <code>false</code>
|
1668
|
+
# otherwise.
|
1456
1669
|
def relative?
|
1457
1670
|
return self.scheme.nil?
|
1458
1671
|
end
|
@@ -1461,7 +1674,8 @@ module Addressable
|
|
1461
1674
|
# Determines if the URI is absolute.
|
1462
1675
|
#
|
1463
1676
|
# @return [TrueClass, FalseClass]
|
1464
|
-
#
|
1677
|
+
# <code>true</code> if the URI is absolute. <code>false</code>
|
1678
|
+
# otherwise.
|
1465
1679
|
def absolute?
|
1466
1680
|
return !relative?
|
1467
1681
|
end
|
@@ -1568,7 +1782,7 @@ module Addressable
|
|
1568
1782
|
alias_method :+, :join
|
1569
1783
|
|
1570
1784
|
##
|
1571
|
-
# Destructive form of <
|
1785
|
+
# Destructive form of <code>join</code>.
|
1572
1786
|
#
|
1573
1787
|
# @param [String, Addressable::URI, #to_str] The URI to join with.
|
1574
1788
|
#
|
@@ -1580,10 +1794,10 @@ module Addressable
|
|
1580
1794
|
end
|
1581
1795
|
|
1582
1796
|
##
|
1583
|
-
# Merges a URI with a <
|
1584
|
-
# This method has different behavior from <
|
1585
|
-
# present in the <
|
1586
|
-
# components. The path component is not treated specially.
|
1797
|
+
# Merges a URI with a <code>Hash</code> of components.
|
1798
|
+
# This method has different behavior from <code>join</code>. Any
|
1799
|
+
# components present in the <code>hash</code> parameter will override the
|
1800
|
+
# original components. The path component is not treated specially.
|
1587
1801
|
#
|
1588
1802
|
# @param [Hash, Addressable::URI, #to_hash] The components to merge with.
|
1589
1803
|
#
|
@@ -1648,7 +1862,7 @@ module Addressable
|
|
1648
1862
|
end
|
1649
1863
|
|
1650
1864
|
##
|
1651
|
-
# Destructive form of <
|
1865
|
+
# Destructive form of <code>merge</code>.
|
1652
1866
|
#
|
1653
1867
|
# @param [Hash, Addressable::URI, #to_hash] The components to merge with.
|
1654
1868
|
#
|
@@ -1662,7 +1876,7 @@ module Addressable
|
|
1662
1876
|
##
|
1663
1877
|
# Returns the shortest normalized relative form of this URI that uses the
|
1664
1878
|
# supplied URI as a base for resolution. Returns an absolute URI if
|
1665
|
-
# necessary. This is effectively the opposite of <
|
1879
|
+
# necessary. This is effectively the opposite of <code>route_to</code>.
|
1666
1880
|
#
|
1667
1881
|
# @param [String, Addressable::URI, #to_str] uri The URI to route from.
|
1668
1882
|
#
|
@@ -1720,7 +1934,7 @@ module Addressable
|
|
1720
1934
|
##
|
1721
1935
|
# Returns the shortest normalized relative form of the supplied URI that
|
1722
1936
|
# uses this URI as a base for resolution. Returns an absolute URI if
|
1723
|
-
# necessary. This is effectively the opposite of <
|
1937
|
+
# necessary. This is effectively the opposite of <code>route_from</code>.
|
1724
1938
|
#
|
1725
1939
|
# @param [String, Addressable::URI, #to_str] uri The URI to route to.
|
1726
1940
|
#
|
@@ -1784,14 +1998,15 @@ module Addressable
|
|
1784
1998
|
end
|
1785
1999
|
|
1786
2000
|
##
|
1787
|
-
# Returns <
|
2001
|
+
# Returns <code>true</code> if the URI objects are equal. This method
|
1788
2002
|
# normalizes both URIs before doing the comparison, and allows comparison
|
1789
|
-
# against <
|
2003
|
+
# against <code>Strings</code>.
|
1790
2004
|
#
|
1791
2005
|
# @param [Object] uri The URI to compare.
|
1792
2006
|
#
|
1793
2007
|
# @return [TrueClass, FalseClass]
|
1794
|
-
# <
|
2008
|
+
# <code>true</code> if the URIs are equivalent, <code>false</code>
|
2009
|
+
# otherwise.
|
1795
2010
|
def ===(uri)
|
1796
2011
|
if uri.respond_to?(:normalize)
|
1797
2012
|
uri_string = uri.normalize.to_s
|
@@ -1806,26 +2021,28 @@ module Addressable
|
|
1806
2021
|
end
|
1807
2022
|
|
1808
2023
|
##
|
1809
|
-
# Returns <
|
2024
|
+
# Returns <code>true</code> if the URI objects are equal. This method
|
1810
2025
|
# normalizes both URIs before doing the comparison.
|
1811
2026
|
#
|
1812
2027
|
# @param [Object] uri The URI to compare.
|
1813
2028
|
#
|
1814
2029
|
# @return [TrueClass, FalseClass]
|
1815
|
-
# <
|
2030
|
+
# <code>true</code> if the URIs are equivalent, <code>false</code>
|
2031
|
+
# otherwise.
|
1816
2032
|
def ==(uri)
|
1817
2033
|
return false unless uri.kind_of?(self.class)
|
1818
2034
|
return self.normalize.to_s == uri.normalize.to_s
|
1819
2035
|
end
|
1820
2036
|
|
1821
2037
|
##
|
1822
|
-
# Returns <
|
2038
|
+
# Returns <code>true</code> if the URI objects are equal. This method
|
1823
2039
|
# does NOT normalize either URI before doing the comparison.
|
1824
2040
|
#
|
1825
2041
|
# @param [Object] uri The URI to compare.
|
1826
2042
|
#
|
1827
2043
|
# @return [TrueClass, FalseClass]
|
1828
|
-
# <
|
2044
|
+
# <code>true</code> if the URIs are equivalent, <code>false</code>
|
2045
|
+
# otherwise.
|
1829
2046
|
def eql?(uri)
|
1830
2047
|
return false unless uri.kind_of?(self.class)
|
1831
2048
|
return self.to_s == uri.to_s
|
@@ -1875,7 +2092,7 @@ module Addressable
|
|
1875
2092
|
# Determines if the URI is frozen.
|
1876
2093
|
#
|
1877
2094
|
# @return [TrueClass, FalseClass]
|
1878
|
-
#
|
2095
|
+
# <code>true</code> if the URI is frozen, <code>false</code> otherwise.
|
1879
2096
|
def frozen?
|
1880
2097
|
self.to_s.frozen?
|
1881
2098
|
end
|
@@ -1924,9 +2141,9 @@ module Addressable
|
|
1924
2141
|
end
|
1925
2142
|
|
1926
2143
|
##
|
1927
|
-
# Converts the URI to a <
|
2144
|
+
# Converts the URI to a <code>String</code>.
|
1928
2145
|
#
|
1929
|
-
# @return [String] The URI's <
|
2146
|
+
# @return [String] The URI's <code>String</code> representation.
|
1930
2147
|
def to_s
|
1931
2148
|
@uri_string ||= (begin
|
1932
2149
|
uri_string = ""
|
@@ -1943,13 +2160,13 @@ module Addressable
|
|
1943
2160
|
end
|
1944
2161
|
|
1945
2162
|
##
|
1946
|
-
# URI's are glorified <
|
2163
|
+
# URI's are glorified <code>Strings</code>. Allow implicit conversion.
|
1947
2164
|
alias_method :to_str, :to_s
|
1948
2165
|
|
1949
2166
|
##
|
1950
2167
|
# Returns a Hash of the URI components.
|
1951
2168
|
#
|
1952
|
-
# @return [Hash] The URI as a <
|
2169
|
+
# @return [Hash] The URI as a <code>Hash</code> of components.
|
1953
2170
|
def to_hash
|
1954
2171
|
return {
|
1955
2172
|
:scheme => self.scheme,
|
@@ -1964,9 +2181,9 @@ module Addressable
|
|
1964
2181
|
end
|
1965
2182
|
|
1966
2183
|
##
|
1967
|
-
# Returns a <
|
2184
|
+
# Returns a <code>String</code> representation of the URI object's state.
|
1968
2185
|
#
|
1969
|
-
# @return [String] The URI object's state, as a <
|
2186
|
+
# @return [String] The URI object's state, as a <code>String</code>.
|
1970
2187
|
def inspect
|
1971
2188
|
sprintf("#<%s:%#0x URI:%s>", self.class.to_s, self.object_id, self.to_s)
|
1972
2189
|
end
|
@@ -2015,6 +2232,9 @@ module Addressable
|
|
2015
2232
|
end
|
2016
2233
|
normalized_path.gsub!(/^\.\.?\/?/, "")
|
2017
2234
|
normalized_path.gsub!(/^\/\.\.?\//, "/")
|
2235
|
+
|
2236
|
+
# Non-standard
|
2237
|
+
normalized_path.gsub!(/^(\/\.\.?)+\/?$/, "/")
|
2018
2238
|
end until previous_state == normalized_path
|
2019
2239
|
return normalized_path
|
2020
2240
|
end
|
@@ -2036,6 +2256,11 @@ module Addressable
|
|
2036
2256
|
raise InvalidURIError, "Hostname not supplied: '#{self.to_s}'"
|
2037
2257
|
end
|
2038
2258
|
end
|
2259
|
+
if self.path != nil && self.path != "" && self.path[0..0] != "/" &&
|
2260
|
+
self.authority != nil
|
2261
|
+
raise InvalidURIError,
|
2262
|
+
"Cannot have a relative path with an authority set: '#{self.to_s}'"
|
2263
|
+
end
|
2039
2264
|
return nil
|
2040
2265
|
end
|
2041
2266
|
|
@@ -2043,9 +2268,9 @@ module Addressable
|
|
2043
2268
|
# Replaces the internal state of self with the specified URI's state.
|
2044
2269
|
# Used in destructive operations to avoid massive code repetition.
|
2045
2270
|
#
|
2046
|
-
# @param [Addressable::URI] uri The URI to replace <
|
2271
|
+
# @param [Addressable::URI] uri The URI to replace <code>self</code> with.
|
2047
2272
|
#
|
2048
|
-
# @return [Addressable::URI] <
|
2273
|
+
# @return [Addressable::URI] <code>self</code>.
|
2049
2274
|
def replace_self(uri)
|
2050
2275
|
# Reset dependant values
|
2051
2276
|
instance_variables.each do |var|
|