rubysl-uri 0.0.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (132) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +0 -1
  3. data/.travis.yml +7 -0
  4. data/README.md +2 -2
  5. data/Rakefile +0 -1
  6. data/lib/rubysl/uri.rb +2 -0
  7. data/lib/rubysl/uri/uri.rb +29 -0
  8. data/lib/rubysl/uri/version.rb +5 -0
  9. data/lib/uri.rb +1 -0
  10. data/lib/uri/common.rb +613 -0
  11. data/lib/uri/ftp.rb +198 -0
  12. data/lib/uri/generic.rb +1126 -0
  13. data/lib/uri/http.rb +100 -0
  14. data/lib/uri/https.rb +20 -0
  15. data/lib/uri/ldap.rb +190 -0
  16. data/lib/uri/ldaps.rb +12 -0
  17. data/lib/uri/mailto.rb +266 -0
  18. data/rubysl-uri.gemspec +18 -18
  19. data/spec/decode_www_form_component_spec.rb +7 -0
  20. data/spec/decode_www_form_spec.rb +7 -0
  21. data/spec/encode_www_form_component_spec.rb +7 -0
  22. data/spec/encode_www_form_spec.rb +7 -0
  23. data/spec/eql_spec.rb +11 -0
  24. data/spec/equality_spec.rb +47 -0
  25. data/spec/escape/decode_spec.rb +5 -0
  26. data/spec/escape/encode_spec.rb +5 -0
  27. data/spec/escape/escape_spec.rb +5 -0
  28. data/spec/escape/unescape_spec.rb +5 -0
  29. data/spec/extract_spec.rb +85 -0
  30. data/spec/fixtures/classes.rb +11 -0
  31. data/spec/fixtures/normalization.rb +54 -0
  32. data/spec/ftp/build_spec.rb +5 -0
  33. data/spec/ftp/merge_spec.rb +5 -0
  34. data/spec/ftp/new2_spec.rb +5 -0
  35. data/spec/ftp/path_spec.rb +55 -0
  36. data/spec/ftp/set_typecode_spec.rb +5 -0
  37. data/spec/ftp/to_s_spec.rb +24 -0
  38. data/spec/ftp/typecode_spec.rb +9 -0
  39. data/spec/generic/absolute_spec.rb +9 -0
  40. data/spec/generic/build2_spec.rb +5 -0
  41. data/spec/generic/build_spec.rb +5 -0
  42. data/spec/generic/coerce_spec.rb +5 -0
  43. data/spec/generic/component_ary_spec.rb +5 -0
  44. data/spec/generic/component_spec.rb +9 -0
  45. data/spec/generic/default_port_spec.rb +9 -0
  46. data/spec/generic/eql_spec.rb +5 -0
  47. data/spec/generic/equal_value_spec.rb +5 -0
  48. data/spec/generic/fragment_spec.rb +9 -0
  49. data/spec/generic/hash_spec.rb +5 -0
  50. data/spec/generic/hierarchical_spec.rb +5 -0
  51. data/spec/generic/host_spec.rb +9 -0
  52. data/spec/generic/inspect_spec.rb +5 -0
  53. data/spec/generic/merge_spec.rb +9 -0
  54. data/spec/generic/minus_spec.rb +5 -0
  55. data/spec/generic/normalize_spec.rb +9 -0
  56. data/spec/generic/opaque_spec.rb +9 -0
  57. data/spec/generic/password_spec.rb +9 -0
  58. data/spec/generic/path_spec.rb +9 -0
  59. data/spec/generic/plus_spec.rb +5 -0
  60. data/spec/generic/port_spec.rb +9 -0
  61. data/spec/generic/query_spec.rb +9 -0
  62. data/spec/generic/registry_spec.rb +9 -0
  63. data/spec/generic/relative_spec.rb +5 -0
  64. data/spec/generic/route_from_spec.rb +5 -0
  65. data/spec/generic/route_to_spec.rb +5 -0
  66. data/spec/generic/scheme_spec.rb +9 -0
  67. data/spec/generic/select_spec.rb +5 -0
  68. data/spec/generic/set_fragment_spec.rb +5 -0
  69. data/spec/generic/set_host_spec.rb +5 -0
  70. data/spec/generic/set_opaque_spec.rb +5 -0
  71. data/spec/generic/set_password_spec.rb +5 -0
  72. data/spec/generic/set_path_spec.rb +5 -0
  73. data/spec/generic/set_port_spec.rb +5 -0
  74. data/spec/generic/set_query_spec.rb +5 -0
  75. data/spec/generic/set_registry_spec.rb +5 -0
  76. data/spec/generic/set_scheme_spec.rb +5 -0
  77. data/spec/generic/set_user_spec.rb +5 -0
  78. data/spec/generic/set_userinfo_spec.rb +5 -0
  79. data/spec/generic/to_s_spec.rb +5 -0
  80. data/spec/generic/use_registry_spec.rb +5 -0
  81. data/spec/generic/user_spec.rb +9 -0
  82. data/spec/generic/userinfo_spec.rb +9 -0
  83. data/spec/http/build_spec.rb +5 -0
  84. data/spec/http/request_uri_spec.rb +15 -0
  85. data/spec/join_spec.rb +60 -0
  86. data/spec/ldap/attributes_spec.rb +9 -0
  87. data/spec/ldap/build_spec.rb +5 -0
  88. data/spec/ldap/dn_spec.rb +9 -0
  89. data/spec/ldap/extensions_spec.rb +9 -0
  90. data/spec/ldap/filter_spec.rb +9 -0
  91. data/spec/ldap/hierarchical_spec.rb +5 -0
  92. data/spec/ldap/scope_spec.rb +9 -0
  93. data/spec/ldap/set_attributes_spec.rb +5 -0
  94. data/spec/ldap/set_dn_spec.rb +5 -0
  95. data/spec/ldap/set_extensions_spec.rb +5 -0
  96. data/spec/ldap/set_filter_spec.rb +5 -0
  97. data/spec/ldap/set_scope_spec.rb +5 -0
  98. data/spec/mailto/build_spec.rb +98 -0
  99. data/spec/mailto/headers_spec.rb +9 -0
  100. data/spec/mailto/set_headers_spec.rb +5 -0
  101. data/spec/mailto/set_to_spec.rb +5 -0
  102. data/spec/mailto/to_mailtext_spec.rb +5 -0
  103. data/spec/mailto/to_rfc822text_spec.rb +5 -0
  104. data/spec/mailto/to_s_spec.rb +5 -0
  105. data/spec/mailto/to_spec.rb +9 -0
  106. data/spec/merge_spec.rb +21 -0
  107. data/spec/normalize_spec.rb +34 -0
  108. data/spec/parse_spec.rb +248 -0
  109. data/spec/parser/escape_spec.rb +7 -0
  110. data/spec/parser/extract_spec.rb +8 -0
  111. data/spec/parser/inspect_spec.rb +7 -0
  112. data/spec/parser/join_spec.rb +8 -0
  113. data/spec/parser/make_regexp_spec.rb +7 -0
  114. data/spec/parser/parse_spec.rb +8 -0
  115. data/spec/parser/split_spec.rb +7 -0
  116. data/spec/parser/unescape_spec.rb +7 -0
  117. data/spec/plus_spec.rb +488 -0
  118. data/spec/regexp_spec.rb +17 -0
  119. data/spec/route_from_spec.rb +24 -0
  120. data/spec/route_to_spec.rb +27 -0
  121. data/spec/select_spec.rb +30 -0
  122. data/spec/set_component_spec.rb +46 -0
  123. data/spec/shared/eql.rb +17 -0
  124. data/spec/shared/extract.rb +83 -0
  125. data/spec/shared/join.rb +58 -0
  126. data/spec/shared/parse.rb +245 -0
  127. data/spec/split_spec.rb +5 -0
  128. data/spec/uri_spec.rb +30 -0
  129. data/spec/util/make_components_hash_spec.rb +5 -0
  130. metadata +297 -88
  131. data/lib/rubysl-uri.rb +0 -7
  132. data/lib/rubysl-uri/version.rb +0 -5
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 9dc1de2a61a2cb733ce807462f966d2011278ba6
4
+ data.tar.gz: fc2994a37404922968e36219d439a21e2d906e6d
5
+ SHA512:
6
+ metadata.gz: 4d7d26cb2bcdf7a8dbe255b37012717439d9b79c901a056c0f3e6e6c4457807f3552be29252472883d15ec2ea9e27dfc80e255a36edf467c04c36d405499579c
7
+ data.tar.gz: 7915d126fdea40be02cde056bde73a3b51f400502c29099e172c3db08a67025f95103933e1c71ad94f78b2425060c8f40feea91fd39a066a4d96de8f97dd880d
data/.gitignore CHANGED
@@ -15,4 +15,3 @@ spec/reports
15
15
  test/tmp
16
16
  test/version_tmp
17
17
  tmp
18
- .rbx
data/.travis.yml ADDED
@@ -0,0 +1,7 @@
1
+ language: ruby
2
+ env:
3
+ - RUBYLIB=lib
4
+ script: bundle exec mspec
5
+ rvm:
6
+ - 1.8.7
7
+ - rbx-nightly-18mode
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # RubySL::Uri
1
+ # Rubysl::Uri
2
2
 
3
3
  TODO: Write a gem description
4
4
 
@@ -24,6 +24,6 @@ TODO: Write usage instructions here
24
24
 
25
25
  1. Fork it
26
26
  2. Create your feature branch (`git checkout -b my-new-feature`)
27
- 3. Commit your changes (`git commit -am 'Added some feature'`)
27
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
28
28
  4. Push to the branch (`git push origin my-new-feature`)
29
29
  5. Create new Pull Request
data/Rakefile CHANGED
@@ -1,2 +1 @@
1
- #!/usr/bin/env rake
2
1
  require "bundler/gem_tasks"
data/lib/rubysl/uri.rb ADDED
@@ -0,0 +1,2 @@
1
+ require "rubysl/uri/uri"
2
+ require "rubysl/uri/version"
@@ -0,0 +1,29 @@
1
+ #
2
+ # URI support for Ruby
3
+ #
4
+ # Author:: Akira Yamada <akira@ruby-lang.org>
5
+ # Documentation:: Akira Yamada <akira@ruby-lang.org>, Dmitry V. Sabanin <sdmitry@lrn.ru>
6
+ # License::
7
+ # Copyright (c) 2001 akira yamada <akira@ruby-lang.org>
8
+ # You can redistribute it and/or modify it under the same term as Ruby.
9
+ # Revision:: $Id: uri.rb 16038 2008-04-15 09:41:47Z kazu $
10
+ #
11
+ # See URI for documentation
12
+ #
13
+
14
+ module URI
15
+ # :stopdoc:
16
+ VERSION_CODE = '000911'.freeze
17
+ VERSION = VERSION_CODE.scan(/../).collect{|n| n.to_i}.join('.').freeze
18
+ # :startdoc:
19
+
20
+ end
21
+
22
+ require 'uri/common'
23
+ require 'uri/generic'
24
+ require 'uri/ftp'
25
+ require 'uri/http'
26
+ require 'uri/https'
27
+ require 'uri/ldap'
28
+ require 'uri/ldaps'
29
+ require 'uri/mailto'
@@ -0,0 +1,5 @@
1
+ module RubySL
2
+ module URI
3
+ VERSION = "1.0.0"
4
+ end
5
+ end
data/lib/uri.rb ADDED
@@ -0,0 +1 @@
1
+ require "rubysl/uri"
data/lib/uri/common.rb ADDED
@@ -0,0 +1,613 @@
1
+ # = uri/common.rb
2
+ #
3
+ # Author:: Akira Yamada <akira@ruby-lang.org>
4
+ # Revision:: $Id: common.rb 14178 2007-12-10 09:31:55Z matz $
5
+ # License::
6
+ # You can redistribute it and/or modify it under the same term as Ruby.
7
+ #
8
+
9
+ module URI
10
+ module REGEXP
11
+ #
12
+ # Patterns used to parse URI's
13
+ #
14
+ module PATTERN
15
+ # :stopdoc:
16
+
17
+ # RFC 2396 (URI Generic Syntax)
18
+ # RFC 2732 (IPv6 Literal Addresses in URL's)
19
+ # RFC 2373 (IPv6 Addressing Architecture)
20
+
21
+ # alpha = lowalpha | upalpha
22
+ ALPHA = "a-zA-Z"
23
+ # alphanum = alpha | digit
24
+ ALNUM = "#{ALPHA}\\d"
25
+
26
+ # hex = digit | "A" | "B" | "C" | "D" | "E" | "F" |
27
+ # "a" | "b" | "c" | "d" | "e" | "f"
28
+ HEX = "a-fA-F\\d"
29
+ # escaped = "%" hex hex
30
+ ESCAPED = "%[#{HEX}]{2}"
31
+ # mark = "-" | "_" | "." | "!" | "~" | "*" | "'" |
32
+ # "(" | ")"
33
+ # unreserved = alphanum | mark
34
+ UNRESERVED = "-_.!~*'()#{ALNUM}"
35
+ # reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" |
36
+ # "$" | ","
37
+ # reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" |
38
+ # "$" | "," | "[" | "]" (RFC 2732)
39
+ RESERVED = ";/?:@&=+$,\\[\\]"
40
+
41
+ # uric = reserved | unreserved | escaped
42
+ URIC = "(?:[#{UNRESERVED}#{RESERVED}]|#{ESCAPED})"
43
+ # uric_no_slash = unreserved | escaped | ";" | "?" | ":" | "@" |
44
+ # "&" | "=" | "+" | "$" | ","
45
+ URIC_NO_SLASH = "(?:[#{UNRESERVED};?:@&=+$,]|#{ESCAPED})"
46
+ # query = *uric
47
+ QUERY = "#{URIC}*"
48
+ # fragment = *uric
49
+ FRAGMENT = "#{URIC}*"
50
+
51
+ # domainlabel = alphanum | alphanum *( alphanum | "-" ) alphanum
52
+ DOMLABEL = "(?:[#{ALNUM}](?:[-#{ALNUM}]*[#{ALNUM}])?)"
53
+ # toplabel = alpha | alpha *( alphanum | "-" ) alphanum
54
+ TOPLABEL = "(?:[#{ALPHA}](?:[-#{ALNUM}]*[#{ALNUM}])?)"
55
+ # hostname = *( domainlabel "." ) toplabel [ "." ]
56
+ HOSTNAME = "(?:#{DOMLABEL}\\.)*#{TOPLABEL}\\.?"
57
+
58
+ # RFC 2373, APPENDIX B:
59
+ # IPv6address = hexpart [ ":" IPv4address ]
60
+ # IPv4address = 1*3DIGIT "." 1*3DIGIT "." 1*3DIGIT "." 1*3DIGIT
61
+ # hexpart = hexseq | hexseq "::" [ hexseq ] | "::" [ hexseq ]
62
+ # hexseq = hex4 *( ":" hex4)
63
+ # hex4 = 1*4HEXDIG
64
+ #
65
+ # XXX: This definition has a flaw. "::" + IPv4address must be
66
+ # allowed too. Here is a replacement.
67
+ #
68
+ # IPv4address = 1*3DIGIT "." 1*3DIGIT "." 1*3DIGIT "." 1*3DIGIT
69
+ IPV4ADDR = "\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}"
70
+ # hex4 = 1*4HEXDIG
71
+ HEX4 = "[#{HEX}]{1,4}"
72
+ # lastpart = hex4 | IPv4address
73
+ LASTPART = "(?:#{HEX4}|#{IPV4ADDR})"
74
+ # hexseq1 = *( hex4 ":" ) hex4
75
+ HEXSEQ1 = "(?:#{HEX4}:)*#{HEX4}"
76
+ # hexseq2 = *( hex4 ":" ) lastpart
77
+ HEXSEQ2 = "(?:#{HEX4}:)*#{LASTPART}"
78
+ # IPv6address = hexseq2 | [ hexseq1 ] "::" [ hexseq2 ]
79
+ IPV6ADDR = "(?:#{HEXSEQ2}|(?:#{HEXSEQ1})?::(?:#{HEXSEQ2})?)"
80
+
81
+ # IPv6prefix = ( hexseq1 | [ hexseq1 ] "::" [ hexseq1 ] ) "/" 1*2DIGIT
82
+ # unused
83
+
84
+ # ipv6reference = "[" IPv6address "]" (RFC 2732)
85
+ IPV6REF = "\\[#{IPV6ADDR}\\]"
86
+
87
+ # host = hostname | IPv4address
88
+ # host = hostname | IPv4address | IPv6reference (RFC 2732)
89
+ HOST = "(?:#{HOSTNAME}|#{IPV4ADDR}|#{IPV6REF})"
90
+ # port = *digit
91
+ PORT = '\d*'
92
+ # hostport = host [ ":" port ]
93
+ HOSTPORT = "#{HOST}(?::#{PORT})?"
94
+
95
+ # userinfo = *( unreserved | escaped |
96
+ # ";" | ":" | "&" | "=" | "+" | "$" | "," )
97
+ USERINFO = "(?:[#{UNRESERVED};:&=+$,]|#{ESCAPED})*"
98
+
99
+ # pchar = unreserved | escaped |
100
+ # ":" | "@" | "&" | "=" | "+" | "$" | ","
101
+ PCHAR = "(?:[#{UNRESERVED}:@&=+$,]|#{ESCAPED})"
102
+ # param = *pchar
103
+ PARAM = "#{PCHAR}*"
104
+ # segment = *pchar *( ";" param )
105
+ SEGMENT = "#{PCHAR}*(?:;#{PARAM})*"
106
+ # path_segments = segment *( "/" segment )
107
+ PATH_SEGMENTS = "#{SEGMENT}(?:/#{SEGMENT})*"
108
+
109
+ # server = [ [ userinfo "@" ] hostport ]
110
+ SERVER = "(?:#{USERINFO}@)?#{HOSTPORT}"
111
+ # reg_name = 1*( unreserved | escaped | "$" | "," |
112
+ # ";" | ":" | "@" | "&" | "=" | "+" )
113
+ REG_NAME = "(?:[#{UNRESERVED}$,;:@&=+]|#{ESCAPED})+"
114
+ # authority = server | reg_name
115
+ AUTHORITY = "(?:#{SERVER}|#{REG_NAME})"
116
+
117
+ # rel_segment = 1*( unreserved | escaped |
118
+ # ";" | "@" | "&" | "=" | "+" | "$" | "," )
119
+ REL_SEGMENT = "(?:[#{UNRESERVED};@&=+$,]|#{ESCAPED})+"
120
+
121
+ # scheme = alpha *( alpha | digit | "+" | "-" | "." )
122
+ SCHEME = "[#{ALPHA}][-+.#{ALPHA}\\d]*"
123
+
124
+ # abs_path = "/" path_segments
125
+ ABS_PATH = "/#{PATH_SEGMENTS}"
126
+ # rel_path = rel_segment [ abs_path ]
127
+ REL_PATH = "#{REL_SEGMENT}(?:#{ABS_PATH})?"
128
+ # net_path = "//" authority [ abs_path ]
129
+ NET_PATH = "//#{AUTHORITY}(?:#{ABS_PATH})?"
130
+
131
+ # hier_part = ( net_path | abs_path ) [ "?" query ]
132
+ HIER_PART = "(?:#{NET_PATH}|#{ABS_PATH})(?:\\?(?:#{QUERY}))?"
133
+ # opaque_part = uric_no_slash *uric
134
+ OPAQUE_PART = "#{URIC_NO_SLASH}#{URIC}*"
135
+
136
+ # absoluteURI = scheme ":" ( hier_part | opaque_part )
137
+ ABS_URI = "#{SCHEME}:(?:#{HIER_PART}|#{OPAQUE_PART})"
138
+ # relativeURI = ( net_path | abs_path | rel_path ) [ "?" query ]
139
+ REL_URI = "(?:#{NET_PATH}|#{ABS_PATH}|#{REL_PATH})(?:\\?#{QUERY})?"
140
+
141
+ # URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ]
142
+ URI_REF = "(?:#{ABS_URI}|#{REL_URI})?(?:##{FRAGMENT})?"
143
+
144
+ # XXX:
145
+ X_ABS_URI = "
146
+ (#{PATTERN::SCHEME}): (?# 1: scheme)
147
+ (?:
148
+ (#{PATTERN::OPAQUE_PART}) (?# 2: opaque)
149
+ |
150
+ (?:(?:
151
+ //(?:
152
+ (?:(?:(#{PATTERN::USERINFO})@)? (?# 3: userinfo)
153
+ (?:(#{PATTERN::HOST})(?::(\\d*))?))?(?# 4: host, 5: port)
154
+ |
155
+ (#{PATTERN::REG_NAME}) (?# 6: registry)
156
+ )
157
+ |
158
+ (?!//)) (?# XXX: '//' is the mark for hostport)
159
+ (#{PATTERN::ABS_PATH})? (?# 7: path)
160
+ )(?:\\?(#{PATTERN::QUERY}))? (?# 8: query)
161
+ )
162
+ (?:\\#(#{PATTERN::FRAGMENT}))? (?# 9: fragment)
163
+ "
164
+ X_REL_URI = "
165
+ (?:
166
+ (?:
167
+ //
168
+ (?:
169
+ (?:(#{PATTERN::USERINFO})@)? (?# 1: userinfo)
170
+ (#{PATTERN::HOST})?(?::(\\d*))? (?# 2: host, 3: port)
171
+ |
172
+ (#{PATTERN::REG_NAME}) (?# 4: registry)
173
+ )
174
+ )
175
+ |
176
+ (#{PATTERN::REL_SEGMENT}) (?# 5: rel_segment)
177
+ )?
178
+ (#{PATTERN::ABS_PATH})? (?# 6: abs_path)
179
+ (?:\\?(#{PATTERN::QUERY}))? (?# 7: query)
180
+ (?:\\#(#{PATTERN::FRAGMENT}))? (?# 8: fragment)
181
+ "
182
+ # :startdoc:
183
+ end # PATTERN
184
+
185
+ # :stopdoc:
186
+
187
+ # for URI::split
188
+ ABS_URI = Regexp.new('^' + PATTERN::X_ABS_URI + '$', #'
189
+ Regexp::EXTENDED, 'N').freeze
190
+ REL_URI = Regexp.new('^' + PATTERN::X_REL_URI + '$', #'
191
+ Regexp::EXTENDED, 'N').freeze
192
+
193
+ # for URI::extract
194
+ URI_REF = Regexp.new(PATTERN::URI_REF, false, 'N').freeze
195
+ ABS_URI_REF = Regexp.new(PATTERN::X_ABS_URI, Regexp::EXTENDED, 'N').freeze
196
+ REL_URI_REF = Regexp.new(PATTERN::X_REL_URI, Regexp::EXTENDED, 'N').freeze
197
+
198
+ # for URI::escape/unescape
199
+ ESCAPED = Regexp.new(PATTERN::ESCAPED, false, 'N').freeze
200
+ UNSAFE = Regexp.new("[^#{PATTERN::UNRESERVED}#{PATTERN::RESERVED}]",
201
+ false, 'N').freeze
202
+
203
+ # for Generic#initialize
204
+ SCHEME = Regexp.new("^#{PATTERN::SCHEME}$", false, 'N').freeze #"
205
+ USERINFO = Regexp.new("^#{PATTERN::USERINFO}$", false, 'N').freeze #"
206
+ HOST = Regexp.new("^#{PATTERN::HOST}$", false, 'N').freeze #"
207
+ PORT = Regexp.new("^#{PATTERN::PORT}$", false, 'N').freeze #"
208
+ OPAQUE = Regexp.new("^#{PATTERN::OPAQUE_PART}$", false, 'N').freeze #"
209
+ REGISTRY = Regexp.new("^#{PATTERN::REG_NAME}$", false, 'N').freeze #"
210
+ ABS_PATH = Regexp.new("^#{PATTERN::ABS_PATH}$", false, 'N').freeze #"
211
+ REL_PATH = Regexp.new("^#{PATTERN::REL_PATH}$", false, 'N').freeze #"
212
+ QUERY = Regexp.new("^#{PATTERN::QUERY}$", false, 'N').freeze #"
213
+ FRAGMENT = Regexp.new("^#{PATTERN::FRAGMENT}$", false, 'N').freeze #"
214
+ # :startdoc:
215
+ end # REGEXP
216
+
217
+ module Util # :nodoc:
218
+ def make_components_hash(klass, array_hash)
219
+ tmp = {}
220
+ if array_hash.kind_of?(Array) &&
221
+ array_hash.size == klass.component.size - 1
222
+ klass.component[1..-1].each_index do |i|
223
+ begin
224
+ tmp[klass.component[i + 1]] = array_hash[i].clone
225
+ rescue TypeError
226
+ tmp[klass.component[i + 1]] = array_hash[i]
227
+ end
228
+ end
229
+
230
+ elsif array_hash.kind_of?(Hash)
231
+ array_hash.each do |key, value|
232
+ begin
233
+ tmp[key] = value.clone
234
+ rescue TypeError
235
+ tmp[key] = value
236
+ end
237
+ end
238
+ else
239
+ raise ArgumentError,
240
+ "expected Array of or Hash of components of #{klass.to_s} (#{klass.component[1..-1].join(', ')})"
241
+ end
242
+ tmp[:scheme] = klass.to_s.sub(/\A.*::/, '').downcase
243
+
244
+ return tmp
245
+ end
246
+ module_function :make_components_hash
247
+ end
248
+
249
+ module Escape
250
+ include REGEXP
251
+
252
+ #
253
+ # == Synopsis
254
+ #
255
+ # URI.escape(str [, unsafe])
256
+ #
257
+ # == Args
258
+ #
259
+ # +str+::
260
+ # String to replaces in.
261
+ # +unsafe+::
262
+ # Regexp that matches all symbols that must be replaced with codes.
263
+ # By default uses <tt>REGEXP::UNSAFE</tt>.
264
+ # When this argument is a String, it represents a character set.
265
+ #
266
+ # == Description
267
+ #
268
+ # Escapes the string, replacing all unsafe characters with codes.
269
+ #
270
+ # == Usage
271
+ #
272
+ # require 'uri'
273
+ #
274
+ # enc_uri = URI.escape("http://example.com/?a=\11\15")
275
+ # p enc_uri
276
+ # # => "http://example.com/?a=%09%0D"
277
+ #
278
+ # p URI.unescape(enc_uri)
279
+ # # => "http://example.com/?a=\t\r"
280
+ #
281
+ # p URI.escape("@?@!", "!?")
282
+ # # => "@%3F@%21"
283
+ #
284
+ def escape(str, unsafe = UNSAFE)
285
+ unless unsafe.kind_of?(Regexp)
286
+ # perhaps unsafe is String object
287
+ unsafe = Regexp.new("[#{Regexp.quote(unsafe)}]", false, 'N')
288
+ end
289
+ str.gsub(unsafe) do |us|
290
+ tmp = ''
291
+ us.each_byte do |uc|
292
+ tmp << sprintf('%%%02X', uc)
293
+ end
294
+ tmp
295
+ end
296
+ end
297
+ alias encode escape
298
+ #
299
+ # == Synopsis
300
+ #
301
+ # URI.unescape(str)
302
+ #
303
+ # == Args
304
+ #
305
+ # +str+::
306
+ # Unescapes the string.
307
+ #
308
+ # == Usage
309
+ #
310
+ # require 'uri'
311
+ #
312
+ # enc_uri = URI.escape("http://example.com/?a=\11\15")
313
+ # p enc_uri
314
+ # # => "http://example.com/?a=%09%0D"
315
+ #
316
+ # p URI.unescape(enc_uri)
317
+ # # => "http://example.com/?a=\t\r"
318
+ #
319
+ def unescape(str)
320
+ str.gsub(ESCAPED) do
321
+ $&[1,2].hex.chr
322
+ end
323
+ end
324
+ alias decode unescape
325
+ end
326
+
327
+ include REGEXP
328
+ extend Escape
329
+
330
+ @@schemes = {}
331
+
332
+ #
333
+ # Base class for all URI exceptions.
334
+ #
335
+ class Error < StandardError; end
336
+ #
337
+ # Not a URI.
338
+ #
339
+ class InvalidURIError < Error; end
340
+ #
341
+ # Not a URI component.
342
+ #
343
+ class InvalidComponentError < Error; end
344
+ #
345
+ # URI is valid, bad usage is not.
346
+ #
347
+ class BadURIError < Error; end
348
+
349
+ #
350
+ # == Synopsis
351
+ #
352
+ # URI::split(uri)
353
+ #
354
+ # == Args
355
+ #
356
+ # +uri+::
357
+ # String with URI.
358
+ #
359
+ # == Description
360
+ #
361
+ # Splits the string on following parts and returns array with result:
362
+ #
363
+ # * Scheme
364
+ # * Userinfo
365
+ # * Host
366
+ # * Port
367
+ # * Registry
368
+ # * Path
369
+ # * Opaque
370
+ # * Query
371
+ # * Fragment
372
+ #
373
+ # == Usage
374
+ #
375
+ # require 'uri'
376
+ #
377
+ # p URI.split("http://www.ruby-lang.org/")
378
+ # # => ["http", nil, "www.ruby-lang.org", nil, nil, "/", nil, nil, nil]
379
+ #
380
+ def self.split(uri)
381
+ case uri
382
+ when ''
383
+ # null uri
384
+
385
+ when ABS_URI
386
+ scheme, opaque, userinfo, host, port,
387
+ registry, path, query, fragment = $~[1..-1]
388
+
389
+ # URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ]
390
+
391
+ # absoluteURI = scheme ":" ( hier_part | opaque_part )
392
+ # hier_part = ( net_path | abs_path ) [ "?" query ]
393
+ # opaque_part = uric_no_slash *uric
394
+
395
+ # abs_path = "/" path_segments
396
+ # net_path = "//" authority [ abs_path ]
397
+
398
+ # authority = server | reg_name
399
+ # server = [ [ userinfo "@" ] hostport ]
400
+
401
+ if !scheme
402
+ raise InvalidURIError,
403
+ "bad URI(absolute but no scheme): #{uri}"
404
+ end
405
+ if !opaque && (!path && (!host && !registry))
406
+ raise InvalidURIError,
407
+ "bad URI(absolute but no path): #{uri}"
408
+ end
409
+
410
+ when REL_URI
411
+ scheme = nil
412
+ opaque = nil
413
+
414
+ userinfo, host, port, registry,
415
+ rel_segment, abs_path, query, fragment = $~[1..-1]
416
+ if rel_segment && abs_path
417
+ path = rel_segment + abs_path
418
+ elsif rel_segment
419
+ path = rel_segment
420
+ elsif abs_path
421
+ path = abs_path
422
+ end
423
+
424
+ # URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ]
425
+
426
+ # relativeURI = ( net_path | abs_path | rel_path ) [ "?" query ]
427
+
428
+ # net_path = "//" authority [ abs_path ]
429
+ # abs_path = "/" path_segments
430
+ # rel_path = rel_segment [ abs_path ]
431
+
432
+ # authority = server | reg_name
433
+ # server = [ [ userinfo "@" ] hostport ]
434
+
435
+ else
436
+ raise InvalidURIError, "bad URI(is not URI?): #{uri}"
437
+ end
438
+
439
+ path = '' if !path && !opaque # (see RFC2396 Section 5.2)
440
+ ret = [
441
+ scheme,
442
+ userinfo, host, port, # X
443
+ registry, # X
444
+ path, # Y
445
+ opaque, # Y
446
+ query,
447
+ fragment
448
+ ]
449
+ return ret
450
+ end
451
+
452
+ #
453
+ # == Synopsis
454
+ #
455
+ # URI::parse(uri_str)
456
+ #
457
+ # == Args
458
+ #
459
+ # +uri_str+::
460
+ # String with URI.
461
+ #
462
+ # == Description
463
+ #
464
+ # Creates one of the URI's subclasses instance from the string.
465
+ #
466
+ # == Raises
467
+ #
468
+ # URI::InvalidURIError
469
+ # Raised if URI given is not a correct one.
470
+ #
471
+ # == Usage
472
+ #
473
+ # require 'uri'
474
+ #
475
+ # uri = URI.parse("http://www.ruby-lang.org/")
476
+ # p uri
477
+ # # => #<URI::HTTP:0x202281be URL:http://www.ruby-lang.org/>
478
+ # p uri.scheme
479
+ # # => "http"
480
+ # p uri.host
481
+ # # => "www.ruby-lang.org"
482
+ #
483
+ def self.parse(uri)
484
+ scheme, userinfo, host, port,
485
+ registry, path, opaque, query, fragment = self.split(uri)
486
+
487
+ if scheme && @@schemes.include?(scheme.upcase)
488
+ @@schemes[scheme.upcase].new(scheme, userinfo, host, port,
489
+ registry, path, opaque, query,
490
+ fragment)
491
+ else
492
+ Generic.new(scheme, userinfo, host, port,
493
+ registry, path, opaque, query,
494
+ fragment)
495
+ end
496
+ end
497
+
498
+ #
499
+ # == Synopsis
500
+ #
501
+ # URI::join(str[, str, ...])
502
+ #
503
+ # == Args
504
+ #
505
+ # +str+::
506
+ # String(s) to work with
507
+ #
508
+ # == Description
509
+ #
510
+ # Joins URIs.
511
+ #
512
+ # == Usage
513
+ #
514
+ # require 'uri'
515
+ #
516
+ # p URI.join("http://localhost/","main.rbx")
517
+ # # => #<URI::HTTP:0x2022ac02 URL:http://localhost/main.rbx>
518
+ #
519
+ def self.join(*str)
520
+ u = self.parse(str[0])
521
+ str[1 .. -1].each do |x|
522
+ u = u.merge(x)
523
+ end
524
+ u
525
+ end
526
+
527
+ #
528
+ # == Synopsis
529
+ #
530
+ # URI::extract(str[, schemes][,&blk])
531
+ #
532
+ # == Args
533
+ #
534
+ # +str+::
535
+ # String to extract URIs from.
536
+ # +schemes+::
537
+ # Limit URI matching to a specific schemes.
538
+ #
539
+ # == Description
540
+ #
541
+ # Extracts URIs from a string. If block given, iterates through all matched URIs.
542
+ # Returns nil if block given or array with matches.
543
+ #
544
+ # == Usage
545
+ #
546
+ # require "uri"
547
+ #
548
+ # URI.extract("text here http://foo.example.org/bla and here mailto:test@example.com and here also.")
549
+ # # => ["http://foo.example.com/bla", "mailto:test@example.com"]
550
+ #
551
+ def self.extract(str, schemes = nil, &block)
552
+ if block_given?
553
+ str.scan(regexp(schemes)) { yield $& }
554
+ nil
555
+ else
556
+ result = []
557
+ str.scan(regexp(schemes)) { result.push $& }
558
+ result
559
+ end
560
+ end
561
+
562
+ #
563
+ # == Synopsis
564
+ #
565
+ # URI::regexp([match_schemes])
566
+ #
567
+ # == Args
568
+ #
569
+ # +match_schemes+::
570
+ # Array of schemes. If given, resulting regexp matches to URIs
571
+ # whose scheme is one of the match_schemes.
572
+ #
573
+ # == Description
574
+ # Returns a Regexp object which matches to URI-like strings.
575
+ # The Regexp object returned by this method includes arbitrary
576
+ # number of capture group (parentheses). Never rely on it's number.
577
+ #
578
+ # == Usage
579
+ #
580
+ # require 'uri'
581
+ #
582
+ # # extract first URI from html_string
583
+ # html_string.slice(URI.regexp)
584
+ #
585
+ # # remove ftp URIs
586
+ # html_string.sub(URI.regexp(['ftp'])
587
+ #
588
+ # # You should not rely on the number of parentheses
589
+ # html_string.scan(URI.regexp) do |*matches|
590
+ # p $&
591
+ # end
592
+ #
593
+ def self.regexp(schemes = nil)
594
+ unless schemes
595
+ ABS_URI_REF
596
+ else
597
+ /(?=#{Regexp.union(*schemes)}:)#{PATTERN::X_ABS_URI}/xn
598
+ end
599
+ end
600
+
601
+ end
602
+
603
+ module Kernel
604
+ # alias for URI.parse.
605
+ #
606
+ # This method is introduced at 1.8.2.
607
+ def URI(uri_str) # :doc:
608
+ return uri_str if uri_str.is_a? URI
609
+
610
+ URI.parse(uri_str)
611
+ end
612
+ module_function :URI
613
+ end