aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2007-08-01 03:40:08 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2007-08-01 03:40:08 +0000
commit12b1e59f2eacd346da550bbc30cc3644909cb314 (patch)
tree4c51f2ea60eb996b8fe2eee32632a4420003131e
parenta16bdfdfba95abeec8cff6ea6f8381292ade248a (diff)
downloadruby-12b1e59f2eacd346da550bbc30cc3644909cb314.tar.gz
* generic.rb (URI::Generic::merge_path): behave as RFC 3986.
[ruby-talk:252052] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12860 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog5
-rw-r--r--lib/uri/generic.rb104
-rw-r--r--test/uri/test_generic.rb75
-rw-r--r--version.h8
4 files changed, 122 insertions, 70 deletions
diff --git a/ChangeLog b/ChangeLog
index d4c0f3c7f8..bfc1bc3add 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+Wed Aug 1 12:40:05 2007 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * generic.rb (URI::Generic::merge_path): behave as RFC 3986.
+ [ruby-talk:252052]
+
Tue Jul 31 23:38:09 2007 Tadayoshi Funaba <tadf@dotrb.org>
* lib/date/format.rb (_parse): now interprets slashed numerical
diff --git a/lib/uri/generic.rb b/lib/uri/generic.rb
index 2b66adeb93..bcf293ec0a 100644
--- a/lib/uri/generic.rb
+++ b/lib/uri/generic.rb
@@ -616,65 +616,65 @@ module URI
private :split_path
def merge_path(base, rel)
+
# RFC2396, Section 5.2, 5)
- if rel[0] == ?/ #/
- # RFC2396, Section 5.2, 5)
- return rel
+ # RFC2396, Section 5.2, 6)
+ base_path = split_path(base)
+ rel_path = split_path(rel)
+
+ # RFC2396, Section 5.2, 6), a)
+ base_path << '' if base_path.last == '..'
+ while i = base_path.index('..')
+ base_path.slice!(i - 1, 2)
+ end
- else
- # RFC2396, Section 5.2, 6)
- base_path = split_path(base)
- rel_path = split_path(rel)
-
- # RFC2396, Section 5.2, 6), a)
- base_path << '' if base_path.last == '..'
- while i = base_path.index('..')
- base_path.slice!(i - 1, 2)
- end
- if base_path.empty?
- base_path = [''] # keep '/' for root directory
- else
- base_path.pop
- end
+ if (first = rel_path.first) and first.empty?
+ base_path.clear
+ rel_path.shift
+ end
- # RFC2396, Section 5.2, 6), c)
- # RFC2396, Section 5.2, 6), d)
- rel_path.push('') if rel_path.last == '.' || rel_path.last == '..'
- rel_path.delete('.')
-
- # RFC2396, Section 5.2, 6), e)
- tmp = []
- rel_path.each do |x|
- if x == '..' &&
- !(tmp.empty? || tmp.last == '..')
- tmp.pop
- else
- tmp << x
- end
+ # RFC2396, Section 5.2, 6), c)
+ # RFC2396, Section 5.2, 6), d)
+ rel_path.push('') if rel_path.last == '.' || rel_path.last == '..'
+ rel_path.delete('.')
+
+ # RFC2396, Section 5.2, 6), e)
+ tmp = []
+ rel_path.each do |x|
+ if x == '..' &&
+ !(tmp.empty? || tmp.last == '..')
+ tmp.pop
+ else
+ tmp << x
end
+ end
- add_trailer_slash = true
- while x = tmp.shift
- if x == '..' && base_path.size > 1
- # RFC2396, Section 4
- # a .. or . in an absolute path has no special meaning
- base_path.pop
- else
- # if x == '..'
- # valid absolute (but abnormal) path "/../..."
- # else
- # valid absolute path
- # end
- base_path << x
- tmp.each {|t| base_path << t}
- add_trailer_slash = false
- break
- end
+ add_trailer_slash = !tmp.empty?
+ if base_path.empty?
+ base_path = [''] # keep '/' for root directory
+ elsif add_trailer_slash
+ base_path.pop
+ end
+ while x = tmp.shift
+ if x == '..'
+ # RFC2396, Section 4
+ # a .. or . in an absolute path has no special meaning
+ base_path.pop if base_path.size > 1
+ else
+ # if x == '..'
+ # valid absolute (but abnormal) path "/../..."
+ # else
+ # valid absolute path
+ # end
+ base_path << x
+ tmp.each {|t| base_path << t}
+ add_trailer_slash = false
+ break
end
- base_path.push('') if add_trailer_slash
-
- return base_path.join('/')
end
+ base_path.push('') if add_trailer_slash
+
+ return base_path.join('/')
end
private :merge_path
diff --git a/test/uri/test_generic.rb b/test/uri/test_generic.rb
index 96707abbbc..8ac0149c60 100644
--- a/test/uri/test_generic.rb
+++ b/test/uri/test_generic.rb
@@ -1,10 +1,7 @@
require 'test/unit'
require 'uri'
-module URI
-
-
-class TestGeneric < Test::Unit::TestCase
+class URI::TestGeneric < Test::Unit::TestCase
def setup
@url = 'http://a/b/c/d;p?q'
@base_url = URI.parse(@url)
@@ -296,11 +293,11 @@ class TestGeneric < Test::Unit::TestCase
assert_equal('//g', url.to_s)
# http://a/b/c/d;p?q
-# ?y = http://a/b/c/?y
+# ?y = http://a/b/c/d;p?y
url = @base_url.merge('?y')
assert_kind_of(URI::HTTP, url)
- assert_equal('http://a/b/c/?y', url.to_s)
- url = @base_url.route_to('http://a/b/c/?y')
+ assert_equal('http://a/b/c/d;p?y', url.to_s)
+ url = @base_url.route_to('http://a/b/c/d;p?y')
assert_kind_of(URI::Generic, url)
assert_equal('?y', url.to_s)
@@ -452,10 +449,10 @@ class TestGeneric < Test::Unit::TestCase
assert_equal('', url.to_s)
# http://a/b/c/d;p?q
-# /./g = http://a/./g
+# /./g = http://a/g
url = @base_url.merge('/./g')
assert_kind_of(URI::HTTP, url)
- assert_equal('http://a/./g', url.to_s)
+ assert_equal('http://a/g', url.to_s)
url = @base_url.route_to('http://a/./g')
assert_kind_of(URI::Generic, url)
assert_equal('/./g', url.to_s)
@@ -464,7 +461,7 @@ class TestGeneric < Test::Unit::TestCase
# /../g = http://a/../g
url = @base_url.merge('/../g')
assert_kind_of(URI::HTTP, url)
- assert_equal('http://a/../g', url.to_s)
+ assert_equal('http://a/g', url.to_s)
url = @base_url.route_to('http://a/../g')
assert_kind_of(URI::Generic, url)
assert_equal('/../g', url.to_s)
@@ -506,10 +503,10 @@ class TestGeneric < Test::Unit::TestCase
assert_equal('..g', url.to_s)
# http://a/b/c/d;p?q
-# ../../../g = http://a/../g
+# ../../../g = http://a/g
url = @base_url.merge('../../../g')
assert_kind_of(URI::HTTP, url)
- assert_equal('http://a/../g', url.to_s)
+ assert_equal('http://a/g', url.to_s)
url = @base_url.route_to('http://a/../g')
assert_kind_of(URI::Generic, url)
assert('../../../g' != url.to_s) # ok? yes, it confuses you
@@ -519,7 +516,7 @@ class TestGeneric < Test::Unit::TestCase
# ../../../../g = http://a/../../g
url = @base_url.merge('../../../../g')
assert_kind_of(URI::HTTP, url)
- assert_equal('http://a/../../g', url.to_s)
+ assert_equal('http://a/g', url.to_s)
url = @base_url.route_to('http://a/../../g')
assert_kind_of(URI::Generic, url)
assert('../../../../g' != url.to_s) # ok? yes, it confuses you
@@ -692,7 +689,57 @@ class TestGeneric < Test::Unit::TestCase
assert_raises(URI::InvalidURIError) { uri.path = 'bar' }
assert_raises(URI::InvalidURIError) { uri.query = 'bar' }
end
-end
+ def m(s)
+ @base_url.merge(s).to_s
+end
+ def test_rfc3986_examples
+ assert_equal("g:h", m("g:h"))
+ assert_equal("http://a/b/c/g", m("g"))
+ assert_equal("http://a/b/c/g", m("./g"))
+ assert_equal("http://a/b/c/g/", m("g/"))
+ assert_equal("http://a/g", m("/g"))
+ assert_equal("http://g", m("//g"))
+ assert_equal("http://a/b/c/d;p?y", m("?y"))
+ assert_equal("http://a/b/c/g?y", m("g?y"))
+ assert_equal("http://a/b/c/d;p?q#s", m("#s"))
+ assert_equal("http://a/b/c/g#s", m("g#s"))
+ assert_equal("http://a/b/c/g?y#s", m("g?y#s"))
+ assert_equal("http://a/b/c/;x", m(";x"))
+ assert_equal("http://a/b/c/g;x", m("g;x"))
+ assert_equal("http://a/b/c/g;x?y#s", m("g;x?y#s"))
+ assert_equal("http://a/b/c/d;p?q", m(""))
+ assert_equal("http://a/b/c/", m("."))
+ assert_equal("http://a/b/c/", m("./"))
+ assert_equal("http://a/b/", m(".."))
+ assert_equal("http://a/b/", m("../"))
+ assert_equal("http://a/b/g", m("../g"))
+ assert_equal("http://a/", m("../.."))
+ assert_equal("http://a/", m("../../"))
+ assert_equal("http://a/g", m("../../g"))
+ assert_equal("http://a/g", m("../../../g"))
+ assert_equal("http://a/g", m("../../../../g"))
+
+ assert_equal("http://a/g", m("/./g"))
+ assert_equal("http://a/g", m("/../g"))
+ assert_equal("http://a/b/c/g.", m("g."))
+ assert_equal("http://a/b/c/.g", m(".g"))
+ assert_equal("http://a/b/c/g..", m("g.."))
+ assert_equal("http://a/b/c/..g", m("..g"))
+
+ assert_equal("http://a/b/g", m("./../g"))
+ assert_equal("http://a/b/c/g/", m("./g/."))
+ assert_equal("http://a/b/c/g/h", m("g/./h"))
+ assert_equal("http://a/b/c/h", m("g/../h"))
+ assert_equal("http://a/b/c/g;x=1/y", m("g;x=1/./y"))
+ assert_equal("http://a/b/c/y", m("g;x=1/../y"))
+
+ assert_equal("http://a/b/c/g?y/./x", m("g?y/./x"))
+ assert_equal("http://a/b/c/g?y/../x", m("g?y/../x"))
+ assert_equal("http://a/b/c/g#s/./x", m("g#s/./x"))
+ assert_equal("http://a/b/c/g#s/../x", m("g#s/../x"))
+
+ assert_equal("http:g", m("http:g"))
+ end
end
diff --git a/version.h b/version.h
index 8c57c87729..09aef04f12 100644
--- a/version.h
+++ b/version.h
@@ -1,15 +1,15 @@
#define RUBY_VERSION "1.9.0"
-#define RUBY_RELEASE_DATE "2007-07-30"
+#define RUBY_RELEASE_DATE "2007-08-01"
#define RUBY_VERSION_CODE 190
-#define RUBY_RELEASE_CODE 20070730
+#define RUBY_RELEASE_CODE 20070801
#define RUBY_PATCHLEVEL 0
#define RUBY_VERSION_MAJOR 1
#define RUBY_VERSION_MINOR 9
#define RUBY_VERSION_TEENY 0
#define RUBY_RELEASE_YEAR 2007
-#define RUBY_RELEASE_MONTH 7
-#define RUBY_RELEASE_DAY 30
+#define RUBY_RELEASE_MONTH 8
+#define RUBY_RELEASE_DAY 1
#ifdef RUBY_EXTERN
RUBY_EXTERN const char ruby_version[];