honkster-addressable 2.1.2 → 2.2.3
Sign up to get free protection for your applications and to get access to all the features.
- 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|
|