ruby-web 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/ChangeLog +474 -0
- data/INSTALL.txt +9 -0
- data/InstalledFiles +180 -0
- data/LICENSE.txt +74 -0
- data/Rakefile +529 -0
- data/TODO +65 -0
- data/doc/additional.xml +149 -0
- data/doc/core.xml +652 -0
- data/doc/credits/index.xml +52 -0
- data/doc/credits/php.contributors.xml +118 -0
- data/doc/credits/php.language-snippets.ent +622 -0
- data/doc/install/index.xml +136 -0
- data/doc/install/mac/index.xml +21 -0
- data/doc/install/ruby-web.install.rb.instructions.xml +7 -0
- data/doc/install/unix/index.xml +46 -0
- data/doc/install/win/apache1.xml +166 -0
- data/doc/install/win/apache2.xml +141 -0
- data/doc/install/win/iis.xml +162 -0
- data/doc/install/win/index.xml +24 -0
- data/doc/install/win/installer.xml +31 -0
- data/doc/install/win/manual.xml +43 -0
- data/doc/manual.xml +69 -0
- data/doc/old/apache_cgi.txt +23 -0
- data/doc/old/fastcgi.txt +23 -0
- data/doc/old/mod_ruby.txt +21 -0
- data/doc/old/snippets.rdoc +183 -0
- data/doc/old/webrick.txt +23 -0
- data/doc/old/windows_cgi.txt +9 -0
- data/doc/tutorial.xml +14 -0
- data/doc/xsl/manual-multi.xsl +10 -0
- data/doc/xsl/manual-pdf.xsl +6 -0
- data/doc/xsl/manual-single.xsl +6 -0
- data/doc/xsl/manual.css +22 -0
- data/install.rb +1022 -0
- data/lib/formatter.rb +314 -0
- data/lib/html-parser.rb +429 -0
- data/lib/htmlrepair.rb +113 -0
- data/lib/htmlsplit.rb +842 -0
- data/lib/sgml-parser.rb +332 -0
- data/lib/web.rb +68 -0
- data/lib/web/assertinclude.rb +129 -0
- data/lib/web/config.rb +50 -0
- data/lib/web/connection.rb +1070 -0
- data/lib/web/convenience.rb +154 -0
- data/lib/web/formreader.rb +318 -0
- data/lib/web/htmlparser/html-parser.rb +429 -0
- data/lib/web/htmlparser/sgml-parser.rb +332 -0
- data/lib/web/htmltools/element.rb +296 -0
- data/lib/web/htmltools/stparser.rb +276 -0
- data/lib/web/htmltools/tags.rb +286 -0
- data/lib/web/htmltools/tree.rb +139 -0
- data/lib/web/htmltools/xmltree.rb +160 -0
- data/lib/web/htmltools/xpath.rb +71 -0
- data/lib/web/info.rb +63 -0
- data/lib/web/load.rb +210 -0
- data/lib/web/mime.rb +87 -0
- data/lib/web/phprb.rb +340 -0
- data/lib/web/resources/test/cookie.rb +33 -0
- data/lib/web/resources/test/counter.rb +20 -0
- data/lib/web/resources/test/multipart.rb +14 -0
- data/lib/web/resources/test/redirect.rb +8 -0
- data/lib/web/resources/test/stock.rb +33 -0
- data/lib/web/sapi/apache.rb +129 -0
- data/lib/web/sapi/fastcgi.rb +22 -0
- data/lib/web/sapi/install/apache.rb +180 -0
- data/lib/web/sapi/install/iis.rb +93 -0
- data/lib/web/sapi/install/macosx.rb +90 -0
- data/lib/web/sapi/webrick.rb +86 -0
- data/lib/web/session.rb +83 -0
- data/lib/web/shim/cgi.rb +129 -0
- data/lib/web/shim/rails.rb +175 -0
- data/lib/web/stringio.rb +78 -0
- data/lib/web/strscanparser.rb +24 -0
- data/lib/web/tagparser.rb +96 -0
- data/lib/web/testing.rb +666 -0
- data/lib/web/traceoutput.rb +75 -0
- data/lib/web/unit.rb +56 -0
- data/lib/web/upload.rb +59 -0
- data/lib/web/validate.rb +52 -0
- data/lib/web/wiki.rb +557 -0
- data/lib/web/wiki/linker.rb +72 -0
- data/lib/web/wiki/page.rb +201 -0
- data/lib/webunit.rb +27 -0
- data/lib/webunit/assert.rb +152 -0
- data/lib/webunit/converter.rb +154 -0
- data/lib/webunit/cookie.rb +118 -0
- data/lib/webunit/domwalker.rb +185 -0
- data/lib/webunit/exception.rb +14 -0
- data/lib/webunit/form.rb +116 -0
- data/lib/webunit/frame.rb +37 -0
- data/lib/webunit/htmlelem.rb +122 -0
- data/lib/webunit/image.rb +26 -0
- data/lib/webunit/jscript.rb +31 -0
- data/lib/webunit/link.rb +33 -0
- data/lib/webunit/params.rb +321 -0
- data/lib/webunit/parser.rb +229 -0
- data/lib/webunit/response.rb +464 -0
- data/lib/webunit/runtest.rb +41 -0
- data/lib/webunit/table.rb +148 -0
- data/lib/webunit/testcase.rb +45 -0
- data/lib/webunit/ui/cui/testrunner.rb +50 -0
- data/lib/webunit/utils.rb +68 -0
- data/lib/webunit/webunit.rb +28 -0
- data/test/dev/action.rb +83 -0
- data/test/dev/forms.rb +104 -0
- data/test/dev/forms2.rb +104 -0
- data/test/dev/parser.rb +17 -0
- data/test/dev/scripts/dump.rb +24 -0
- data/test/dev/scripts/makedist.rb +62 -0
- data/test/dev/scripts/uri.rb +41 -0
- data/test/dev/scripts/uri/common.rb +432 -0
- data/test/dev/scripts/uri/ftp.rb +149 -0
- data/test/dev/scripts/uri/generic.rb +1106 -0
- data/test/dev/scripts/uri/http.rb +76 -0
- data/test/dev/scripts/uri/https.rb +26 -0
- data/test/dev/scripts/uri/ldap.rb +238 -0
- data/test/dev/scripts/uri/mailto.rb +260 -0
- data/test/dev/scripts/urireg.rb +174 -0
- data/test/dev/simpledispatcher.rb +156 -0
- data/test/dev/test.action.rb +146 -0
- data/test/dev/test.formreader.rb +463 -0
- data/test/dev/test.simpledispatcher.rb +186 -0
- data/test/dev/webunit/conv/digit-0.rb +21 -0
- data/test/dev/webunit/conv/digit-1.rb +17 -0
- data/test/dev/webunit/conv/digit.rb +23 -0
- data/test/dev/webunit/conv/test_digit-0.rb +16 -0
- data/test/dev/webunit/conv/test_digit-1.rb +19 -0
- data/test/dev/webunit/conv/test_digit.rb +26 -0
- data/test/dev/webunit/conv/test_digit_view-0.rb +76 -0
- data/test/dev/webunit/conv/test_digit_view-1.rb +102 -0
- data/test/dev/webunit/conv/test_digit_view.rb +134 -0
- data/test/installation/htdocs/cgi_test.rb +296 -0
- data/test/installation/htdocs/test_install.rb +4 -0
- data/test/installation/runwebtest.rb +5 -0
- data/test/installation/test_cookie.rb +128 -0
- data/test/installation/test_form.rb +47 -0
- data/test/installation/test_multipart.rb +51 -0
- data/test/installation/test_request.rb +24 -0
- data/test/installation/test_response.rb +35 -0
- data/test/unit/htdocs/cookie.rb +32 -0
- data/test/unit/htdocs/multipart.rb +28 -0
- data/test/unit/htdocs/redirect.rb +12 -0
- data/test/unit/htdocs/simple.rb +13 -0
- data/test/unit/htdocs/stock.rb +33 -0
- data/test/unit/test_assert.rb +162 -0
- data/test/unit/test_cookie.rb +114 -0
- data/test/unit/test_domwalker.rb +77 -0
- data/test/unit/test_form.rb +42 -0
- data/test/unit/test_frame.rb +40 -0
- data/test/unit/test_htmlelem.rb +74 -0
- data/test/unit/test_image.rb +45 -0
- data/test/unit/test_jscript.rb +57 -0
- data/test/unit/test_link.rb +85 -0
- data/test/unit/test_multipart.rb +51 -0
- data/test/unit/test_params.rb +210 -0
- data/test/unit/test_parser.rb +53 -0
- data/test/unit/test_response.rb +150 -0
- data/test/unit/test_table.rb +70 -0
- data/test/unit/test_utils.rb +106 -0
- data/test/unit/test_webunit.rb +28 -0
- data/test/web/mod_ruby_stub.rb +39 -0
- data/test/web/test.assertinclude.rb +109 -0
- data/test/web/test.buffer.rb +182 -0
- data/test/web/test.code.loader.rb +78 -0
- data/test/web/test.config.rb +31 -0
- data/test/web/test.error.handling.rb +91 -0
- data/test/web/test.formreader-2.0.rb +352 -0
- data/test/web/test.load.rb +125 -0
- data/test/web/test.mime-type.rb +23 -0
- data/test/web/test.narf.cgi.rb +106 -0
- data/test/web/test.phprb.rb +239 -0
- data/test/web/test.request.rb +368 -0
- data/test/web/test.response.rb +637 -0
- data/test/web/test.ruby-web.rb +10 -0
- data/test/web/test.session.rb +50 -0
- data/test/web/test.shim.cgi.rb +96 -0
- data/test/web/test.tagparser.rb +65 -0
- data/test/web/test.template2.rb +297 -0
- data/test/web/test.testing2.rb +318 -0
- data/test/web/test.upload.rb +45 -0
- data/test/web/test.validate.rb +46 -0
- data/test/web/test.web.test.rb +495 -0
- data/test/wiki/test.history.rb +297 -0
- data/test/wiki/test.illustration_page.rb +287 -0
- data/test/wiki/test.linker.rb +197 -0
- data/test/wiki/test.tarpit.rb +56 -0
- data/test/wiki/test.wiki.rb +300 -0
- data/test/wikitestroot/admin.rb +7 -0
- data/test/wikitestroot/wiki.rb +6 -0
- metadata +234 -0
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
#
|
|
2
|
+
# $Id: ftp.rb,v 1.1.1.1 2002/11/29 04:34:25 patsplat Exp $
|
|
3
|
+
#
|
|
4
|
+
# Copyright (c) 2001 akira yamada <akira@ruby-lang.org>
|
|
5
|
+
# You can redistribute it and/or modify it under the same term as Ruby.
|
|
6
|
+
#
|
|
7
|
+
|
|
8
|
+
require 'uri/generic'
|
|
9
|
+
|
|
10
|
+
module URI
|
|
11
|
+
|
|
12
|
+
=begin
|
|
13
|
+
|
|
14
|
+
== URI::FTP
|
|
15
|
+
|
|
16
|
+
=== Super Class
|
|
17
|
+
|
|
18
|
+
((<URI::Generic>))
|
|
19
|
+
|
|
20
|
+
=end
|
|
21
|
+
|
|
22
|
+
# RFC1738 section 3.2.
|
|
23
|
+
class FTP < Generic
|
|
24
|
+
DEFAULT_PORT = 21
|
|
25
|
+
|
|
26
|
+
COMPONENT = [
|
|
27
|
+
:scheme,
|
|
28
|
+
:userinfo, :host, :port,
|
|
29
|
+
:path, :typecode
|
|
30
|
+
].freeze
|
|
31
|
+
|
|
32
|
+
TYPECODE = ['a', 'i', 'd'].freeze
|
|
33
|
+
TYPECODE_PREFIX = ';type='.freeze
|
|
34
|
+
|
|
35
|
+
=begin
|
|
36
|
+
|
|
37
|
+
=== Class Methods
|
|
38
|
+
|
|
39
|
+
--- URI::FTP::build
|
|
40
|
+
Create a new URI::FTP object from components of URI::FTP with
|
|
41
|
+
check. It is scheme, userinfo, host, port, path and typecode. It
|
|
42
|
+
provided by an Array or a Hash. typecode is "a", "i" or "d".
|
|
43
|
+
|
|
44
|
+
--- URI::FTP::new
|
|
45
|
+
Create a new URI::FTP object from ``generic'' components with no
|
|
46
|
+
check.
|
|
47
|
+
|
|
48
|
+
=end
|
|
49
|
+
|
|
50
|
+
def self.new2(user, password, host, port, path,
|
|
51
|
+
typecode = nil, arg_check = true)
|
|
52
|
+
typecode = nil if typecode.size == 0
|
|
53
|
+
if typecode && !TYPECODE.include?(typecode)
|
|
54
|
+
raise ArgumentError,
|
|
55
|
+
"bad typecode is specified: #{typecode}"
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# do escape
|
|
59
|
+
|
|
60
|
+
self.new('ftp',
|
|
61
|
+
[user, password],
|
|
62
|
+
host, port, nil,
|
|
63
|
+
typecode ? path + TYPECODE_PREFIX + typecode : path,
|
|
64
|
+
nil, nil, nil, arg_check)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def self.build(args)
|
|
68
|
+
tmp = Util::make_components_hash(self, args)
|
|
69
|
+
|
|
70
|
+
if tmp[:typecode]
|
|
71
|
+
if tmp[:typecode].size == 1
|
|
72
|
+
tmp[:typecode] = TYPECODE_PREFIX + tmp[:typecode]
|
|
73
|
+
end
|
|
74
|
+
tmp[:path] << tmp[:typecode]
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
return super(tmp)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def initialize(*arg)
|
|
81
|
+
super(*arg)
|
|
82
|
+
@typecode = nil
|
|
83
|
+
tmp = @path.index(TYPECODE_PREFIX)
|
|
84
|
+
if tmp
|
|
85
|
+
typecode = @path[tmp + TYPECODE_PREFIX.size..-1]
|
|
86
|
+
self.set_path(@path[0..tmp - 1])
|
|
87
|
+
|
|
88
|
+
if arg[-1]
|
|
89
|
+
self.typecode = typecode
|
|
90
|
+
else
|
|
91
|
+
self.set_typecode(typecode)
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
attr_reader :typecode
|
|
96
|
+
|
|
97
|
+
#
|
|
98
|
+
# methods for typecode
|
|
99
|
+
#
|
|
100
|
+
|
|
101
|
+
def check_typecode(v)
|
|
102
|
+
if TYPECODE.include?(v)
|
|
103
|
+
return true
|
|
104
|
+
else
|
|
105
|
+
raise InvalidComponentError,
|
|
106
|
+
"bad typecode(expected #{TYPECODE.join(', ')}): #{v}"
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
private :check_typecode
|
|
110
|
+
|
|
111
|
+
def set_typecode(v)
|
|
112
|
+
@typecode = v
|
|
113
|
+
end
|
|
114
|
+
protected :set_typecode
|
|
115
|
+
|
|
116
|
+
def typecode=(typecode)
|
|
117
|
+
check_typecode(typecode)
|
|
118
|
+
set_typecode(typecode)
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
=begin
|
|
122
|
+
=end
|
|
123
|
+
def merge(oth)
|
|
124
|
+
tmp = super(oth)
|
|
125
|
+
if self != tmp
|
|
126
|
+
tmp.set_typecode(oth.typecode)
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
return tmp
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
=begin
|
|
133
|
+
=end
|
|
134
|
+
def to_str
|
|
135
|
+
save_path = nil
|
|
136
|
+
if @typecode
|
|
137
|
+
save_path = @path
|
|
138
|
+
@path = @path + TYPECODE_PREFIX + @typecode
|
|
139
|
+
end
|
|
140
|
+
str = super
|
|
141
|
+
if @typecode
|
|
142
|
+
@path = save_path
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
return str
|
|
146
|
+
end
|
|
147
|
+
end # FTP
|
|
148
|
+
@@schemes['FTP'] = FTP
|
|
149
|
+
end # URI
|
|
@@ -0,0 +1,1106 @@
|
|
|
1
|
+
#
|
|
2
|
+
# $Id: generic.rb,v 1.1.1.1 2002/11/29 04:34:25 patsplat Exp $
|
|
3
|
+
#
|
|
4
|
+
# Copyright (c) 2001 akira yamada <akira@ruby-lang.org>
|
|
5
|
+
# You can redistribute it and/or modify it under the same term as Ruby.
|
|
6
|
+
#
|
|
7
|
+
|
|
8
|
+
require 'uri/common'
|
|
9
|
+
|
|
10
|
+
module URI
|
|
11
|
+
|
|
12
|
+
=begin
|
|
13
|
+
|
|
14
|
+
== URI::Generic
|
|
15
|
+
|
|
16
|
+
=== Super Class
|
|
17
|
+
|
|
18
|
+
Object
|
|
19
|
+
|
|
20
|
+
=end
|
|
21
|
+
|
|
22
|
+
class Generic
|
|
23
|
+
include REGEXP
|
|
24
|
+
|
|
25
|
+
=begin
|
|
26
|
+
|
|
27
|
+
=== Class Methods
|
|
28
|
+
|
|
29
|
+
--- URI::Generic::default_port
|
|
30
|
+
|
|
31
|
+
=end
|
|
32
|
+
DEFAULT_PORT = nil
|
|
33
|
+
|
|
34
|
+
def self.default_port
|
|
35
|
+
self::DEFAULT_PORT
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def default_port
|
|
39
|
+
self.type.default_port
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
=begin
|
|
43
|
+
--- URI::Generic::component
|
|
44
|
+
=end
|
|
45
|
+
COMPONENT = [
|
|
46
|
+
:scheme,
|
|
47
|
+
:userinfo, :host, :port, :registry,
|
|
48
|
+
:path, :opaque,
|
|
49
|
+
:query,
|
|
50
|
+
:fragment
|
|
51
|
+
].freeze
|
|
52
|
+
|
|
53
|
+
def self.component
|
|
54
|
+
self::COMPONENT
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
=begin
|
|
58
|
+
--- URI::Generic::use_registry
|
|
59
|
+
=end
|
|
60
|
+
USE_REGISTRY = false
|
|
61
|
+
|
|
62
|
+
def self.use_registry
|
|
63
|
+
self::USE_REGISTRY
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
=begin
|
|
67
|
+
|
|
68
|
+
--- URI::Generic::build2
|
|
69
|
+
At first, try to create a new URI::Generic object using
|
|
70
|
+
URI::Generic::build. But, if you get a exception
|
|
71
|
+
URI::InvalidComponentError, then re-try to create an object with
|
|
72
|
+
escaped components.
|
|
73
|
+
|
|
74
|
+
--- URI::Generic::build
|
|
75
|
+
Create a new URI::Generic object from components of URI::Generic
|
|
76
|
+
with check. It is scheme, userinfo, host, port, registry, path,
|
|
77
|
+
opaque, query and fragment. It provided by an Array of a Hash.
|
|
78
|
+
|
|
79
|
+
--- URI::Generic::new
|
|
80
|
+
Create new URI::Generic object from ``generic'' components with no
|
|
81
|
+
check.
|
|
82
|
+
|
|
83
|
+
=end
|
|
84
|
+
def self.build2(args)
|
|
85
|
+
begin
|
|
86
|
+
return self.build(args)
|
|
87
|
+
rescue InvalidComponentError
|
|
88
|
+
if args.kind_of?(Array)
|
|
89
|
+
return self.build(args.collect{|x|
|
|
90
|
+
if x
|
|
91
|
+
URI.escape(x)
|
|
92
|
+
else
|
|
93
|
+
x
|
|
94
|
+
end
|
|
95
|
+
})
|
|
96
|
+
elsif args.kind_of?(Hash)
|
|
97
|
+
tmp = {}
|
|
98
|
+
args.each do |key, value|
|
|
99
|
+
tmp[key] = if value
|
|
100
|
+
URI.escape(value)
|
|
101
|
+
else
|
|
102
|
+
value
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
return self.build(tmp)
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def self.build(args)
|
|
111
|
+
if args.kind_of?(Array) &&
|
|
112
|
+
args.size == ::URI::Generic::COMPONENT.size
|
|
113
|
+
tmp = args
|
|
114
|
+
elsif args.kind_of?(Hash)
|
|
115
|
+
tmp = ::URI::Generic::COMPONENT.collect do |c|
|
|
116
|
+
if args.include?(c)
|
|
117
|
+
args[c]
|
|
118
|
+
else
|
|
119
|
+
nil
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
else
|
|
123
|
+
raise ArgumentError,
|
|
124
|
+
"expected Array of or Hash of components of #{self.type} (#{self.type.component.join(', ')})"
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
tmp << true
|
|
128
|
+
return self.new(*tmp)
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
def initialize(scheme,
|
|
132
|
+
userinfo, host, port, registry,
|
|
133
|
+
path, opaque,
|
|
134
|
+
query,
|
|
135
|
+
fragment,
|
|
136
|
+
arg_check = false)
|
|
137
|
+
@scheme = nil
|
|
138
|
+
@user = nil
|
|
139
|
+
@password = nil
|
|
140
|
+
@host = nil
|
|
141
|
+
@port = nil
|
|
142
|
+
@path = nil
|
|
143
|
+
@query = nil
|
|
144
|
+
@opaque = nil
|
|
145
|
+
@registry = nil
|
|
146
|
+
@fragment = nil
|
|
147
|
+
|
|
148
|
+
if arg_check
|
|
149
|
+
self.scheme = scheme
|
|
150
|
+
self.userinfo = userinfo
|
|
151
|
+
self.host = host
|
|
152
|
+
self.port = port
|
|
153
|
+
self.path = path
|
|
154
|
+
self.query = query
|
|
155
|
+
self.opaque = opaque
|
|
156
|
+
self.registry = registry
|
|
157
|
+
self.fragment = fragment
|
|
158
|
+
else
|
|
159
|
+
self.set_scheme(scheme)
|
|
160
|
+
self.set_userinfo(userinfo)
|
|
161
|
+
self.set_host(host)
|
|
162
|
+
self.set_port(port)
|
|
163
|
+
self.set_path(path)
|
|
164
|
+
self.set_query(query)
|
|
165
|
+
self.set_opaque(opaque)
|
|
166
|
+
self.set_registry(registry)
|
|
167
|
+
self.set_fragment(fragment)
|
|
168
|
+
end
|
|
169
|
+
if @registry && !self.class.use_registry
|
|
170
|
+
raise InvalidURIError, "the scheme #{@scheme} does not accept registry part: #{@registry} (or bad hostname?)"
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
@scheme.freeze if @scheme
|
|
174
|
+
self.set_path('') if !@path && !@opaque # (see RFC2396 Section 5.2)
|
|
175
|
+
self.set_port(self.default_port) if self.default_port && !@port
|
|
176
|
+
end
|
|
177
|
+
attr_reader :scheme
|
|
178
|
+
attr_reader :host
|
|
179
|
+
attr_reader :port
|
|
180
|
+
attr_reader :registry
|
|
181
|
+
attr_reader :path
|
|
182
|
+
attr_reader :query
|
|
183
|
+
attr_reader :opaque
|
|
184
|
+
attr_reader :fragment
|
|
185
|
+
|
|
186
|
+
=begin
|
|
187
|
+
|
|
188
|
+
=== Instance Methods
|
|
189
|
+
|
|
190
|
+
=end
|
|
191
|
+
|
|
192
|
+
=begin
|
|
193
|
+
|
|
194
|
+
--- URI::Generic#component
|
|
195
|
+
|
|
196
|
+
=end
|
|
197
|
+
def component
|
|
198
|
+
self.type.component
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
# set_XXX method sets value to @XXX instance variable with no check,
|
|
202
|
+
# so be careful if you use these methods. or, you use these method
|
|
203
|
+
# with check_XXX method, or you use XXX= methods.
|
|
204
|
+
|
|
205
|
+
=begin
|
|
206
|
+
|
|
207
|
+
--- URI::Generic#scheme
|
|
208
|
+
|
|
209
|
+
--- URI::Generic#scheme=(v)
|
|
210
|
+
|
|
211
|
+
=end
|
|
212
|
+
#
|
|
213
|
+
# methods for scheme
|
|
214
|
+
#
|
|
215
|
+
def check_scheme(v)
|
|
216
|
+
if v && SCHEME !~ v
|
|
217
|
+
raise InvalidComponentError,
|
|
218
|
+
"bad component(expected scheme component): #{v}"
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
return true
|
|
222
|
+
end
|
|
223
|
+
private :check_scheme
|
|
224
|
+
|
|
225
|
+
def set_scheme(v)
|
|
226
|
+
@scheme = v
|
|
227
|
+
end
|
|
228
|
+
protected :set_scheme
|
|
229
|
+
|
|
230
|
+
def scheme=(v)
|
|
231
|
+
check_scheme(v)
|
|
232
|
+
set_scheme(v)
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
=begin
|
|
236
|
+
|
|
237
|
+
--- URI::Generic#userinfo
|
|
238
|
+
|
|
239
|
+
--- URI::Generic#userinfo=(v)
|
|
240
|
+
|
|
241
|
+
--- URI::Generic#user
|
|
242
|
+
|
|
243
|
+
--- URI::Generic#user=(v)
|
|
244
|
+
|
|
245
|
+
--- URI::Generic#password
|
|
246
|
+
|
|
247
|
+
--- URI::Generic#password=(v)
|
|
248
|
+
|
|
249
|
+
=end
|
|
250
|
+
#
|
|
251
|
+
# methods for userinfo
|
|
252
|
+
#
|
|
253
|
+
def check_userinfo(user, password = nil)
|
|
254
|
+
if (user || password) &&
|
|
255
|
+
(@registry || @opaque)
|
|
256
|
+
raise InvalidURIError,
|
|
257
|
+
"can not set userinfo with registry or opaque"
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
if !password
|
|
261
|
+
user, password = split_userinfo(user)
|
|
262
|
+
end
|
|
263
|
+
check_user(user)
|
|
264
|
+
check_password(password)
|
|
265
|
+
|
|
266
|
+
return true
|
|
267
|
+
end
|
|
268
|
+
private :check_userinfo
|
|
269
|
+
|
|
270
|
+
def check_user(v)
|
|
271
|
+
return v unless v
|
|
272
|
+
|
|
273
|
+
if USERINFO !~ v
|
|
274
|
+
raise InvalidComponentError,
|
|
275
|
+
"bad component(expected userinfo component or user component): #{v}"
|
|
276
|
+
end
|
|
277
|
+
|
|
278
|
+
return true
|
|
279
|
+
end
|
|
280
|
+
private :check_user
|
|
281
|
+
|
|
282
|
+
def check_password(v)
|
|
283
|
+
return v unless v
|
|
284
|
+
|
|
285
|
+
if !@password
|
|
286
|
+
raise InvalidURIError,
|
|
287
|
+
"password component depends user component"
|
|
288
|
+
end
|
|
289
|
+
|
|
290
|
+
if USERINFO !~ v
|
|
291
|
+
raise InvalidComponentError,
|
|
292
|
+
"bad component(expected user component): #{v}"
|
|
293
|
+
end
|
|
294
|
+
|
|
295
|
+
return true
|
|
296
|
+
end
|
|
297
|
+
private :check_password
|
|
298
|
+
|
|
299
|
+
def userinfo=(userinfo)
|
|
300
|
+
if userinfo.nil?
|
|
301
|
+
return nil
|
|
302
|
+
end
|
|
303
|
+
check_userinfo(*userinfo)
|
|
304
|
+
set_userinfo(*userinfo)
|
|
305
|
+
end
|
|
306
|
+
|
|
307
|
+
def user=(user)
|
|
308
|
+
check_user(user)
|
|
309
|
+
set_user(user)
|
|
310
|
+
end
|
|
311
|
+
|
|
312
|
+
def password=(password)
|
|
313
|
+
check_password(password)
|
|
314
|
+
set_password(password)
|
|
315
|
+
end
|
|
316
|
+
|
|
317
|
+
def set_userinfo(user, password = nil)
|
|
318
|
+
unless password
|
|
319
|
+
user, password = split_userinfo(user)
|
|
320
|
+
end
|
|
321
|
+
@user = user
|
|
322
|
+
@password = password if password
|
|
323
|
+
|
|
324
|
+
[@user, @password]
|
|
325
|
+
end
|
|
326
|
+
protected :set_userinfo
|
|
327
|
+
|
|
328
|
+
def set_user(v)
|
|
329
|
+
set_userinfo(v, @password)
|
|
330
|
+
v
|
|
331
|
+
end
|
|
332
|
+
protected :set_user
|
|
333
|
+
|
|
334
|
+
def set_password(v)
|
|
335
|
+
set_userinfo(@user, v)
|
|
336
|
+
v
|
|
337
|
+
end
|
|
338
|
+
protected :set_password
|
|
339
|
+
|
|
340
|
+
def split_userinfo(ui)
|
|
341
|
+
return nil, nil unless ui
|
|
342
|
+
tmp = ui.index(':')
|
|
343
|
+
if tmp
|
|
344
|
+
user = ui[0..tmp - 1]
|
|
345
|
+
password = ui[tmp + 1..-1]
|
|
346
|
+
else
|
|
347
|
+
user = ui
|
|
348
|
+
password = nil
|
|
349
|
+
end
|
|
350
|
+
|
|
351
|
+
return user, password
|
|
352
|
+
end
|
|
353
|
+
private :split_userinfo
|
|
354
|
+
|
|
355
|
+
def escape_userpass(v)
|
|
356
|
+
v = URI.escape(v, /[@:\/]/o) # RFC 1738 section 3.1 #/
|
|
357
|
+
end
|
|
358
|
+
private :escape_userpass
|
|
359
|
+
|
|
360
|
+
def userinfo
|
|
361
|
+
if !@password
|
|
362
|
+
@user
|
|
363
|
+
else
|
|
364
|
+
@user + ':' + @password
|
|
365
|
+
end
|
|
366
|
+
end
|
|
367
|
+
|
|
368
|
+
def user
|
|
369
|
+
@user
|
|
370
|
+
end
|
|
371
|
+
|
|
372
|
+
def password
|
|
373
|
+
@password
|
|
374
|
+
end
|
|
375
|
+
|
|
376
|
+
=begin
|
|
377
|
+
|
|
378
|
+
--- URI::Generic#host
|
|
379
|
+
|
|
380
|
+
--- URI::Generic#host=(v)
|
|
381
|
+
|
|
382
|
+
=end
|
|
383
|
+
#
|
|
384
|
+
# methods for host
|
|
385
|
+
#
|
|
386
|
+
|
|
387
|
+
def check_host(v)
|
|
388
|
+
return v unless v
|
|
389
|
+
|
|
390
|
+
if @registry || @opaque
|
|
391
|
+
raise InvalidURIError,
|
|
392
|
+
"can not set host with registry or opaque"
|
|
393
|
+
elsif HOST !~ v
|
|
394
|
+
raise InvalidComponentError,
|
|
395
|
+
"bad component(expected host component): #{v}"
|
|
396
|
+
end
|
|
397
|
+
|
|
398
|
+
return true
|
|
399
|
+
end
|
|
400
|
+
private :check_host
|
|
401
|
+
|
|
402
|
+
def set_host(v)
|
|
403
|
+
@host = v
|
|
404
|
+
end
|
|
405
|
+
protected :set_host
|
|
406
|
+
|
|
407
|
+
def host=(v)
|
|
408
|
+
check_host(v)
|
|
409
|
+
set_host(v)
|
|
410
|
+
end
|
|
411
|
+
|
|
412
|
+
=begin
|
|
413
|
+
|
|
414
|
+
--- URI::Generic#port
|
|
415
|
+
|
|
416
|
+
--- URI::Generic#port=(v)
|
|
417
|
+
|
|
418
|
+
=end
|
|
419
|
+
#
|
|
420
|
+
# methods for port
|
|
421
|
+
#
|
|
422
|
+
|
|
423
|
+
def check_port(v)
|
|
424
|
+
return v unless v
|
|
425
|
+
|
|
426
|
+
if @registry || @opaque
|
|
427
|
+
raise InvalidURIError,
|
|
428
|
+
"can not set port with registry or opaque"
|
|
429
|
+
elsif !v.kind_of?(Fixnum) && PORT !~ v
|
|
430
|
+
raise InvalidComponentError,
|
|
431
|
+
"bad component(expected port component): #{v}"
|
|
432
|
+
end
|
|
433
|
+
|
|
434
|
+
return true
|
|
435
|
+
end
|
|
436
|
+
private :check_port
|
|
437
|
+
|
|
438
|
+
def set_port(v)
|
|
439
|
+
v = v.to_i if v && !v.kind_of?(Fixnum)
|
|
440
|
+
@port = v
|
|
441
|
+
end
|
|
442
|
+
protected :set_port
|
|
443
|
+
|
|
444
|
+
def port=(v)
|
|
445
|
+
check_port(v)
|
|
446
|
+
set_port(v)
|
|
447
|
+
end
|
|
448
|
+
|
|
449
|
+
=begin
|
|
450
|
+
|
|
451
|
+
--- URI::Generic#registry
|
|
452
|
+
|
|
453
|
+
--- URI::Generic#registry=(v)
|
|
454
|
+
|
|
455
|
+
=end
|
|
456
|
+
#
|
|
457
|
+
# methods for registry
|
|
458
|
+
#
|
|
459
|
+
|
|
460
|
+
def check_registry(v)
|
|
461
|
+
return v unless v
|
|
462
|
+
|
|
463
|
+
# raise if both server and registry are not nil, because:
|
|
464
|
+
# authority = server | reg_name
|
|
465
|
+
# server = [ [ userinfo "@" ] hostport ]
|
|
466
|
+
if @host || @port || @user # userinfo = @user + ':' + @password
|
|
467
|
+
raise InvalidURIError,
|
|
468
|
+
"can not set registry with host, port, or userinfo"
|
|
469
|
+
elsif v && REGISTRY !~ v
|
|
470
|
+
raise InvalidComponentError,
|
|
471
|
+
"bad component(expected registry component): #{v}"
|
|
472
|
+
end
|
|
473
|
+
|
|
474
|
+
return true
|
|
475
|
+
end
|
|
476
|
+
private :check_registry
|
|
477
|
+
|
|
478
|
+
def set_registry(v)
|
|
479
|
+
@registry = v
|
|
480
|
+
end
|
|
481
|
+
protected :set_registry
|
|
482
|
+
|
|
483
|
+
def registry=(v)
|
|
484
|
+
check_registry(v)
|
|
485
|
+
set_registry(v)
|
|
486
|
+
end
|
|
487
|
+
|
|
488
|
+
=begin
|
|
489
|
+
|
|
490
|
+
--- URI::Generic#path
|
|
491
|
+
|
|
492
|
+
--- URI::Generic#path=(v)
|
|
493
|
+
|
|
494
|
+
=end
|
|
495
|
+
#
|
|
496
|
+
# methods for path
|
|
497
|
+
#
|
|
498
|
+
|
|
499
|
+
def check_path(v)
|
|
500
|
+
# raise if both hier and opaque are not nil, because:
|
|
501
|
+
# absoluteURI = scheme ":" ( hier_part | opaque_part )
|
|
502
|
+
# hier_part = ( net_path | abs_path ) [ "?" query ]
|
|
503
|
+
if v && @opaque
|
|
504
|
+
raise InvalidURIError,
|
|
505
|
+
"path conflicts with opaque"
|
|
506
|
+
end
|
|
507
|
+
|
|
508
|
+
if @scheme
|
|
509
|
+
if v && v != '' && ABS_PATH !~ v
|
|
510
|
+
raise InvalidComponentError,
|
|
511
|
+
"bad component(expected absolute path component): #{v}"
|
|
512
|
+
end
|
|
513
|
+
else
|
|
514
|
+
if v && v != '' && ABS_PATH !~ v && REL_PATH !~ v
|
|
515
|
+
raise InvalidComponentError,
|
|
516
|
+
"bad component(expected relative path component): #{v}"
|
|
517
|
+
end
|
|
518
|
+
end
|
|
519
|
+
|
|
520
|
+
return true
|
|
521
|
+
end
|
|
522
|
+
private :check_path
|
|
523
|
+
|
|
524
|
+
def set_path(v)
|
|
525
|
+
@path = v
|
|
526
|
+
end
|
|
527
|
+
protected :set_path
|
|
528
|
+
|
|
529
|
+
def path=(v)
|
|
530
|
+
check_path(v)
|
|
531
|
+
set_path(v)
|
|
532
|
+
end
|
|
533
|
+
|
|
534
|
+
=begin
|
|
535
|
+
|
|
536
|
+
--- URI::Generic#query
|
|
537
|
+
|
|
538
|
+
--- URI::Generic#query=(v)
|
|
539
|
+
|
|
540
|
+
=end
|
|
541
|
+
#
|
|
542
|
+
# methods for query
|
|
543
|
+
#
|
|
544
|
+
|
|
545
|
+
def check_query(v)
|
|
546
|
+
return v unless v
|
|
547
|
+
|
|
548
|
+
# raise if both hier and opaque are not nil, because:
|
|
549
|
+
# absoluteURI = scheme ":" ( hier_part | opaque_part )
|
|
550
|
+
# hier_part = ( net_path | abs_path ) [ "?" query ]
|
|
551
|
+
if @opaque
|
|
552
|
+
raise InvalidURIError,
|
|
553
|
+
"query conflicts with opaque"
|
|
554
|
+
end
|
|
555
|
+
|
|
556
|
+
if v && v != '' && QUERY !~ v
|
|
557
|
+
raise InvalidComponentError,
|
|
558
|
+
"bad component(expected query component): #{v}"
|
|
559
|
+
end
|
|
560
|
+
|
|
561
|
+
return true
|
|
562
|
+
end
|
|
563
|
+
private :check_query
|
|
564
|
+
|
|
565
|
+
def set_query(v)
|
|
566
|
+
@query = v
|
|
567
|
+
end
|
|
568
|
+
protected :set_query
|
|
569
|
+
|
|
570
|
+
def query=(v)
|
|
571
|
+
check_query(v)
|
|
572
|
+
set_query(v)
|
|
573
|
+
end
|
|
574
|
+
|
|
575
|
+
=begin
|
|
576
|
+
|
|
577
|
+
--- URI::Generic#opaque
|
|
578
|
+
|
|
579
|
+
--- URI::Generic#opaque=(v)
|
|
580
|
+
|
|
581
|
+
=end
|
|
582
|
+
#
|
|
583
|
+
# methods for opaque
|
|
584
|
+
#
|
|
585
|
+
|
|
586
|
+
def check_opaque(v)
|
|
587
|
+
return v unless v
|
|
588
|
+
|
|
589
|
+
# raise if both hier and opaque are not nil, because:
|
|
590
|
+
# absoluteURI = scheme ":" ( hier_part | opaque_part )
|
|
591
|
+
# hier_part = ( net_path | abs_path ) [ "?" query ]
|
|
592
|
+
if @host || @port || @usr || @path # userinfo = @user + ':' + @password
|
|
593
|
+
raise InvalidURIError,
|
|
594
|
+
"can not set opaque with host, port, userinfo or path"
|
|
595
|
+
elsif v && OPAQUE !~ v
|
|
596
|
+
raise InvalidComponentError,
|
|
597
|
+
"bad component(expected opaque component): #{v}"
|
|
598
|
+
end
|
|
599
|
+
|
|
600
|
+
return true
|
|
601
|
+
end
|
|
602
|
+
private :check_opaque
|
|
603
|
+
|
|
604
|
+
def set_opaque(v)
|
|
605
|
+
@opaque = v
|
|
606
|
+
end
|
|
607
|
+
protected :set_opaque
|
|
608
|
+
|
|
609
|
+
def opaque=(v)
|
|
610
|
+
check_opaque(v)
|
|
611
|
+
set_opaque(v)
|
|
612
|
+
end
|
|
613
|
+
|
|
614
|
+
=begin
|
|
615
|
+
|
|
616
|
+
--- URI::Generic#fragment
|
|
617
|
+
|
|
618
|
+
--- URI::Generic#fragment=(v)
|
|
619
|
+
|
|
620
|
+
=end
|
|
621
|
+
#
|
|
622
|
+
# methods for fragment
|
|
623
|
+
#
|
|
624
|
+
|
|
625
|
+
def check_fragment(v)
|
|
626
|
+
return v unless v
|
|
627
|
+
|
|
628
|
+
if v && v != '' && FRAGMENT !~ v
|
|
629
|
+
raise InvalidComponentError,
|
|
630
|
+
"bad component(expected fragment component): #{v}"
|
|
631
|
+
end
|
|
632
|
+
|
|
633
|
+
return true
|
|
634
|
+
end
|
|
635
|
+
private :check_fragment
|
|
636
|
+
|
|
637
|
+
def set_fragment(v)
|
|
638
|
+
@fragment = v
|
|
639
|
+
end
|
|
640
|
+
protected :set_fragment
|
|
641
|
+
|
|
642
|
+
def fragment=(v)
|
|
643
|
+
check_fragment(v)
|
|
644
|
+
set_fragment(v)
|
|
645
|
+
end
|
|
646
|
+
|
|
647
|
+
=begin
|
|
648
|
+
|
|
649
|
+
--- URI::Generic#hierarchical?
|
|
650
|
+
|
|
651
|
+
=end
|
|
652
|
+
def hierarchical?
|
|
653
|
+
if @path
|
|
654
|
+
true
|
|
655
|
+
else
|
|
656
|
+
false
|
|
657
|
+
end
|
|
658
|
+
end
|
|
659
|
+
|
|
660
|
+
=begin
|
|
661
|
+
|
|
662
|
+
--- URI::Generic#absolute?
|
|
663
|
+
|
|
664
|
+
=end
|
|
665
|
+
def absolute?
|
|
666
|
+
if @scheme
|
|
667
|
+
true
|
|
668
|
+
else
|
|
669
|
+
false
|
|
670
|
+
end
|
|
671
|
+
end
|
|
672
|
+
alias absolute absolute?
|
|
673
|
+
|
|
674
|
+
=begin
|
|
675
|
+
|
|
676
|
+
--- URI::Generic#relative?
|
|
677
|
+
|
|
678
|
+
=end
|
|
679
|
+
def relative?
|
|
680
|
+
!absolute?
|
|
681
|
+
end
|
|
682
|
+
|
|
683
|
+
=begin
|
|
684
|
+
|
|
685
|
+
--- URI::Generic#merge(rel)
|
|
686
|
+
--- URI::Generic#+(rel)
|
|
687
|
+
|
|
688
|
+
=end
|
|
689
|
+
def split_path(path)
|
|
690
|
+
path.split(%r{/+}, -1)
|
|
691
|
+
end
|
|
692
|
+
private :split_path
|
|
693
|
+
|
|
694
|
+
def merge_path(base, rel)
|
|
695
|
+
# RFC2396, Section 5.2, 5)
|
|
696
|
+
if rel[0] == ?/ #/
|
|
697
|
+
# RFC2396, Section 5.2, 5)
|
|
698
|
+
return rel
|
|
699
|
+
|
|
700
|
+
else
|
|
701
|
+
# RFC2396, Section 5.2, 6)
|
|
702
|
+
base_path = split_path(base)
|
|
703
|
+
rel_path = split_path(rel)
|
|
704
|
+
|
|
705
|
+
if base_path.empty?
|
|
706
|
+
base_path = [''] # XXX
|
|
707
|
+
end
|
|
708
|
+
|
|
709
|
+
# RFC2396, Section 5.2, 6), a)
|
|
710
|
+
base_path.pop unless base_path.size == 1
|
|
711
|
+
|
|
712
|
+
# RFC2396, Section 5.2, 6), c)
|
|
713
|
+
# RFC2396, Section 5.2, 6), d)
|
|
714
|
+
rel_path.push('') if rel_path.last == '.'
|
|
715
|
+
rel_path.delete('.')
|
|
716
|
+
|
|
717
|
+
# RFC2396, Section 5.2, 6), e)
|
|
718
|
+
tmp = []
|
|
719
|
+
rel_path.each do |x|
|
|
720
|
+
if x == '..' &&
|
|
721
|
+
!(tmp.empty? || tmp.last == '..')
|
|
722
|
+
tmp.pop
|
|
723
|
+
else
|
|
724
|
+
tmp << x
|
|
725
|
+
end
|
|
726
|
+
end
|
|
727
|
+
|
|
728
|
+
add_trailer_slash = true
|
|
729
|
+
while x = tmp.shift
|
|
730
|
+
if x == '..' && base_path.size > 1
|
|
731
|
+
# RFC2396, Section 4
|
|
732
|
+
# a .. or . in an absolute path has no special meaning
|
|
733
|
+
base_path.pop
|
|
734
|
+
else
|
|
735
|
+
# if x == '..'
|
|
736
|
+
# valid absolute (but abnormal) path "/../..."
|
|
737
|
+
# else
|
|
738
|
+
# valid absolute path
|
|
739
|
+
# end
|
|
740
|
+
base_path << x
|
|
741
|
+
tmp.each {|t| base_path << t}
|
|
742
|
+
add_trailer_slash = false
|
|
743
|
+
break
|
|
744
|
+
end
|
|
745
|
+
end
|
|
746
|
+
base_path.push('') if add_trailer_slash
|
|
747
|
+
|
|
748
|
+
return base_path.join('/')
|
|
749
|
+
end
|
|
750
|
+
end
|
|
751
|
+
private :merge_path
|
|
752
|
+
|
|
753
|
+
# abs(self) + rel(oth) => abs(new)
|
|
754
|
+
def merge(oth)
|
|
755
|
+
base, rel = merge0(oth)
|
|
756
|
+
if base == rel
|
|
757
|
+
return base
|
|
758
|
+
end
|
|
759
|
+
|
|
760
|
+
authority = rel.userinfo || rel.host || rel.port
|
|
761
|
+
|
|
762
|
+
# RFC2396, Section 5.2, 2)
|
|
763
|
+
if rel.path.empty? && !authority && !rel.query
|
|
764
|
+
base.set_fragment(rel.fragment) if rel.fragment
|
|
765
|
+
return base
|
|
766
|
+
end
|
|
767
|
+
|
|
768
|
+
base.set_query(nil)
|
|
769
|
+
base.set_fragment(nil)
|
|
770
|
+
|
|
771
|
+
# RFC2396, Section 5.2, 4)
|
|
772
|
+
if !authority
|
|
773
|
+
base.set_path(merge_path(base.path, rel.path))
|
|
774
|
+
else
|
|
775
|
+
# RFC2396, Section 5.2, 4)
|
|
776
|
+
base.set_path(rel.path)
|
|
777
|
+
end
|
|
778
|
+
|
|
779
|
+
# RFC2396, Section 5.2, 7)
|
|
780
|
+
base.set_userinfo(rel.userinfo) if rel.userinfo
|
|
781
|
+
base.set_host(rel.host) if rel.host
|
|
782
|
+
base.set_port(rel.port) if rel.port
|
|
783
|
+
base.set_query(rel.query) if rel.query
|
|
784
|
+
base.set_fragment(rel.fragment) if rel.fragment
|
|
785
|
+
|
|
786
|
+
return base
|
|
787
|
+
end # merge
|
|
788
|
+
alias + merge
|
|
789
|
+
|
|
790
|
+
# return base and rel.
|
|
791
|
+
# you can modify `base', but can not `rel'.
|
|
792
|
+
def merge0(oth)
|
|
793
|
+
case oth
|
|
794
|
+
when Generic
|
|
795
|
+
when String
|
|
796
|
+
oth = URI.parse(oth)
|
|
797
|
+
else
|
|
798
|
+
raise ArgumentError,
|
|
799
|
+
"bad argument(expected URI object or URI string)"
|
|
800
|
+
end
|
|
801
|
+
|
|
802
|
+
if self.relative? && oth.relative?
|
|
803
|
+
raise BadURIError,
|
|
804
|
+
"both URI are relative"
|
|
805
|
+
end
|
|
806
|
+
|
|
807
|
+
if self.absolute? && oth.absolute?
|
|
808
|
+
#raise BadURIError,
|
|
809
|
+
# "both URI are absolute"
|
|
810
|
+
# hmm... should return oth for usability?
|
|
811
|
+
return oth, oth
|
|
812
|
+
end
|
|
813
|
+
|
|
814
|
+
if !self.hierarchical?
|
|
815
|
+
raise BadURIError,
|
|
816
|
+
"not hierarchical URI: #{self}"
|
|
817
|
+
elsif !oth.hierarchical?
|
|
818
|
+
raise BadURIError,
|
|
819
|
+
"not hierarchical URI: #{oth}"
|
|
820
|
+
end
|
|
821
|
+
|
|
822
|
+
if self.absolute?
|
|
823
|
+
return self.dup, oth
|
|
824
|
+
else
|
|
825
|
+
return oth, oth
|
|
826
|
+
end
|
|
827
|
+
end
|
|
828
|
+
private :merge0
|
|
829
|
+
|
|
830
|
+
=begin
|
|
831
|
+
|
|
832
|
+
--- URI::Generic#route_from(src)
|
|
833
|
+
--- URI::Generic#-(src)
|
|
834
|
+
|
|
835
|
+
=end
|
|
836
|
+
def route_from_path(src, dst)
|
|
837
|
+
# RFC2396, Section 4.2
|
|
838
|
+
return '' if src == dst
|
|
839
|
+
|
|
840
|
+
src_path = split_path(src)
|
|
841
|
+
dst_path = split_path(dst)
|
|
842
|
+
|
|
843
|
+
# hmm... dst has abnormal absolute path,
|
|
844
|
+
# like "/./", "/../", "/x/../", ...
|
|
845
|
+
if dst_path.include?('..') ||
|
|
846
|
+
dst_path.include?('.')
|
|
847
|
+
return dst.dup
|
|
848
|
+
end
|
|
849
|
+
|
|
850
|
+
src_path.pop
|
|
851
|
+
|
|
852
|
+
# discard same parts
|
|
853
|
+
while dst_path.first == src_path.first
|
|
854
|
+
break if dst_path.empty?
|
|
855
|
+
|
|
856
|
+
src_path.shift
|
|
857
|
+
dst_path.shift
|
|
858
|
+
end
|
|
859
|
+
|
|
860
|
+
tmp = dst_path.join('/')
|
|
861
|
+
|
|
862
|
+
# calculate
|
|
863
|
+
if src_path.empty?
|
|
864
|
+
if tmp.empty?
|
|
865
|
+
return './'
|
|
866
|
+
elsif dst_path.first.include?(':') # (see RFC2396 Section 5)
|
|
867
|
+
return './' + tmp
|
|
868
|
+
else
|
|
869
|
+
return tmp
|
|
870
|
+
end
|
|
871
|
+
end
|
|
872
|
+
|
|
873
|
+
return '../' * src_path.size + tmp
|
|
874
|
+
end
|
|
875
|
+
private :route_from_path
|
|
876
|
+
|
|
877
|
+
def route_from0(oth)
|
|
878
|
+
case oth
|
|
879
|
+
when Generic
|
|
880
|
+
when String
|
|
881
|
+
oth = URI.parse(oth)
|
|
882
|
+
else
|
|
883
|
+
raise ArgumentError,
|
|
884
|
+
"bad argument(expected URI object or URI string)"
|
|
885
|
+
end
|
|
886
|
+
|
|
887
|
+
if self.relative?
|
|
888
|
+
raise BadURIError,
|
|
889
|
+
"relative URI: #{self}"
|
|
890
|
+
end
|
|
891
|
+
if oth.relative?
|
|
892
|
+
raise BadURIError,
|
|
893
|
+
"relative URI: #{oth}"
|
|
894
|
+
end
|
|
895
|
+
|
|
896
|
+
if !self.hierarchical? || !oth.hierarchical?
|
|
897
|
+
return self, self.dup
|
|
898
|
+
end
|
|
899
|
+
|
|
900
|
+
if self.scheme != oth.scheme
|
|
901
|
+
return oth, oth.dup
|
|
902
|
+
end
|
|
903
|
+
rel = URI::Generic.new(nil, # it is relative URI
|
|
904
|
+
self.userinfo, self.host, self.port,
|
|
905
|
+
self.registry, self.path, self.opaque,
|
|
906
|
+
self.query, self.fragment)
|
|
907
|
+
|
|
908
|
+
if rel.userinfo != oth.userinfo ||
|
|
909
|
+
rel.host != oth.host ||
|
|
910
|
+
rel.port != oth.port
|
|
911
|
+
rel.set_port(nil) if rel.port == oth.default_port
|
|
912
|
+
return rel, rel
|
|
913
|
+
end
|
|
914
|
+
rel.set_userinfo(nil)
|
|
915
|
+
rel.set_host(nil)
|
|
916
|
+
rel.set_port(nil)
|
|
917
|
+
|
|
918
|
+
if rel.path == oth.path
|
|
919
|
+
rel.set_path('')
|
|
920
|
+
rel.set_query(nil) if rel.query == oth.query
|
|
921
|
+
return rel, rel
|
|
922
|
+
end
|
|
923
|
+
|
|
924
|
+
# you can modify `rel', but can not `oth'.
|
|
925
|
+
return oth, rel
|
|
926
|
+
end
|
|
927
|
+
private :route_from0
|
|
928
|
+
|
|
929
|
+
# calculate relative path from oth to self
|
|
930
|
+
def route_from(oth)
|
|
931
|
+
# you can modify `rel', but can not `oth'.
|
|
932
|
+
oth, rel = route_from0(oth)
|
|
933
|
+
if oth == rel
|
|
934
|
+
return rel
|
|
935
|
+
end
|
|
936
|
+
|
|
937
|
+
rel.set_path(route_from_path(oth.path, self.path))
|
|
938
|
+
if rel.path == './' && self.query
|
|
939
|
+
# "./?foo" -> "?foo"
|
|
940
|
+
rel.set_path('')
|
|
941
|
+
end
|
|
942
|
+
|
|
943
|
+
return rel
|
|
944
|
+
end
|
|
945
|
+
# abs1 - abs2 => relative_path_to_abs1_from_abs2
|
|
946
|
+
# (see http://www.nikonet.or.jp/spring/what_v/what_v_4.htm :-)
|
|
947
|
+
alias - route_from
|
|
948
|
+
|
|
949
|
+
=begin
|
|
950
|
+
|
|
951
|
+
--- URI::Generic#route_to(dst)
|
|
952
|
+
|
|
953
|
+
=end
|
|
954
|
+
# calculate relative path to oth from self
|
|
955
|
+
def route_to(oth)
|
|
956
|
+
case oth
|
|
957
|
+
when Generic
|
|
958
|
+
when String
|
|
959
|
+
oth = URI.parse(oth)
|
|
960
|
+
else
|
|
961
|
+
raise ArgumentError,
|
|
962
|
+
"bad argument(expected URI object or URI string)"
|
|
963
|
+
end
|
|
964
|
+
|
|
965
|
+
oth.route_from(self)
|
|
966
|
+
end
|
|
967
|
+
|
|
968
|
+
=begin
|
|
969
|
+
|
|
970
|
+
--- URI::Generic#normalize
|
|
971
|
+
--- URI::Generic#normalize!
|
|
972
|
+
|
|
973
|
+
=end
|
|
974
|
+
def normalize
|
|
975
|
+
uri = dup
|
|
976
|
+
uri.normalize!
|
|
977
|
+
uri
|
|
978
|
+
end
|
|
979
|
+
|
|
980
|
+
def normalize!
|
|
981
|
+
if path && path == ''
|
|
982
|
+
set_path('/')
|
|
983
|
+
end
|
|
984
|
+
if host && host != host.downcase
|
|
985
|
+
set_host(self.host.downcase)
|
|
986
|
+
end
|
|
987
|
+
end
|
|
988
|
+
|
|
989
|
+
=begin
|
|
990
|
+
|
|
991
|
+
--- URI::Generic#to_s
|
|
992
|
+
|
|
993
|
+
=end
|
|
994
|
+
def path_query
|
|
995
|
+
str = @path
|
|
996
|
+
if @query
|
|
997
|
+
str += '?' + @query
|
|
998
|
+
end
|
|
999
|
+
str
|
|
1000
|
+
end
|
|
1001
|
+
private :path_query
|
|
1002
|
+
|
|
1003
|
+
def to_str
|
|
1004
|
+
str = ''
|
|
1005
|
+
if @scheme
|
|
1006
|
+
str << @scheme
|
|
1007
|
+
str << ':'
|
|
1008
|
+
end
|
|
1009
|
+
|
|
1010
|
+
if @opaque
|
|
1011
|
+
str << @opaque
|
|
1012
|
+
|
|
1013
|
+
else
|
|
1014
|
+
if @registry
|
|
1015
|
+
str << @registry
|
|
1016
|
+
else
|
|
1017
|
+
if @host
|
|
1018
|
+
str << '//'
|
|
1019
|
+
end
|
|
1020
|
+
if self.userinfo
|
|
1021
|
+
str << self.userinfo
|
|
1022
|
+
str << '@'
|
|
1023
|
+
end
|
|
1024
|
+
if @host
|
|
1025
|
+
str << @host
|
|
1026
|
+
end
|
|
1027
|
+
if @port && @port != self.default_port
|
|
1028
|
+
str << ':'
|
|
1029
|
+
str << @port.to_s
|
|
1030
|
+
end
|
|
1031
|
+
end
|
|
1032
|
+
|
|
1033
|
+
str << path_query
|
|
1034
|
+
end
|
|
1035
|
+
|
|
1036
|
+
if @fragment
|
|
1037
|
+
str << '#'
|
|
1038
|
+
str << @fragment
|
|
1039
|
+
end
|
|
1040
|
+
|
|
1041
|
+
str
|
|
1042
|
+
end
|
|
1043
|
+
|
|
1044
|
+
def to_s
|
|
1045
|
+
to_str
|
|
1046
|
+
end
|
|
1047
|
+
|
|
1048
|
+
=begin
|
|
1049
|
+
|
|
1050
|
+
--- URI::Generic#==(oth)
|
|
1051
|
+
|
|
1052
|
+
=end
|
|
1053
|
+
def ==(oth)
|
|
1054
|
+
if oth.kind_of?(String)
|
|
1055
|
+
oth = URI.parse(oth)
|
|
1056
|
+
end
|
|
1057
|
+
|
|
1058
|
+
if self.class == oth.class
|
|
1059
|
+
self.normalize.to_ary == oth.normalize.to_ary
|
|
1060
|
+
else
|
|
1061
|
+
false
|
|
1062
|
+
end
|
|
1063
|
+
end
|
|
1064
|
+
|
|
1065
|
+
=begin
|
|
1066
|
+
|
|
1067
|
+
--- URI::Generic#===(oth)
|
|
1068
|
+
|
|
1069
|
+
=end
|
|
1070
|
+
# def ===(oth)
|
|
1071
|
+
# raise NotImplementedError
|
|
1072
|
+
# end
|
|
1073
|
+
|
|
1074
|
+
=begin
|
|
1075
|
+
--- URI::Generic#to_a
|
|
1076
|
+
=end
|
|
1077
|
+
def to_ary
|
|
1078
|
+
component.collect do |x|
|
|
1079
|
+
self.send(x)
|
|
1080
|
+
end
|
|
1081
|
+
end
|
|
1082
|
+
|
|
1083
|
+
def to_a
|
|
1084
|
+
to_ary
|
|
1085
|
+
end
|
|
1086
|
+
|
|
1087
|
+
=begin
|
|
1088
|
+
=end
|
|
1089
|
+
def inspect
|
|
1090
|
+
sprintf("#<%s:0x%x URL:%s>", self.type.to_s, self.id, self.to_s)
|
|
1091
|
+
end
|
|
1092
|
+
|
|
1093
|
+
=begin
|
|
1094
|
+
=end
|
|
1095
|
+
def coerce(oth)
|
|
1096
|
+
case oth
|
|
1097
|
+
when String
|
|
1098
|
+
oth = URI.parse(oth)
|
|
1099
|
+
else
|
|
1100
|
+
super
|
|
1101
|
+
end
|
|
1102
|
+
|
|
1103
|
+
return oth, self
|
|
1104
|
+
end
|
|
1105
|
+
end # Generic
|
|
1106
|
+
end # URI
|