opal 0.3.15 → 0.3.16
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/.gitignore +1 -1
- data/Gemfile +8 -2
- data/README.md +1 -1
- data/Rakefile +51 -57
- data/bin/opal +50 -2
- data/{runtime/corelib → core}/alpha.rb +6 -1
- data/{runtime/corelib → core}/array.rb +38 -42
- data/{runtime/corelib → core}/basic_object.rb +6 -17
- data/core/boolean.rb +40 -0
- data/core/class.rb +69 -0
- data/{runtime/corelib → core}/comparable.rb +0 -0
- data/core/debug.js +59 -0
- data/core/debug.rb +35 -0
- data/core/dir.rb +90 -0
- data/core/enumerable.rb +331 -0
- data/core/enumerator.rb +126 -0
- data/core/error.rb +40 -0
- data/{runtime/corelib → core}/file.rb +6 -3
- data/core/gemlib.rb +30 -0
- data/{runtime/corelib → core}/hash.rb +37 -35
- data/{runtime/corelib → core}/io.rb +0 -0
- data/{runtime/corelib → core}/kernel.rb +26 -21
- data/{runtime/corelib → core}/load_order +2 -5
- data/{runtime/corelib → core}/match_data.rb +2 -4
- data/core/module.rb +204 -0
- data/{runtime/corelib → core}/nil_class.rb +1 -7
- data/{runtime/corelib → core}/numeric.rb +9 -13
- data/core/object.rb +17 -0
- data/{runtime/corelib → core}/proc.rb +2 -13
- data/{runtime/corelib → core}/range.rb +19 -7
- data/{runtime/corelib → core}/rational.rb +0 -0
- data/{runtime/corelib → core}/regexp.rb +2 -6
- data/core/runtime.js +672 -0
- data/{runtime/corelib → core}/string.rb +25 -9
- data/{runtime/corelib → core}/struct.rb +0 -0
- data/core/time.rb +111 -0
- data/{runtime/corelib → core}/top_self.rb +0 -0
- data/{runtime/spec → core_spec}/README.md +0 -0
- data/{runtime/spec → core_spec}/core/array/allocate_spec.rb +0 -0
- data/{runtime/spec → core_spec}/core/array/append_spec.rb +0 -0
- data/{runtime/spec → core_spec}/core/array/assoc_spec.rb +0 -0
- data/{runtime/spec → core_spec}/core/array/at_spec.rb +0 -0
- data/{runtime/spec → core_spec}/core/array/clear_spec.rb +0 -0
- data/{runtime/spec → core_spec}/core/array/collect_spec.rb +0 -0
- data/{runtime/spec → core_spec}/core/array/compact_spec.rb +0 -0
- data/{runtime/spec → core_spec}/core/array/concat_spec.rb +0 -0
- data/{runtime/spec → core_spec}/core/array/constructor_spec.rb +0 -0
- data/{runtime/spec → core_spec}/core/array/count_spec.rb +0 -0
- data/{runtime/spec → core_spec}/core/array/delete_at_spec.rb +0 -0
- data/{runtime/spec → core_spec}/core/array/delete_if_spec.rb +0 -0
- data/{runtime/spec → core_spec}/core/array/delete_spec.rb +0 -0
- data/{runtime/spec → core_spec}/core/array/each_index_spec.rb +0 -0
- data/{runtime/spec → core_spec}/core/array/each_spec.rb +0 -0
- data/{runtime/spec → core_spec}/core/array/element_reference_spec.rb +0 -0
- data/{runtime/spec → core_spec}/core/array/element_set_spec.rb +0 -0
- data/{runtime/spec → core_spec}/core/array/empty_spec.rb +0 -0
- data/{runtime/spec → core_spec}/core/array/eql_spec.rb +0 -0
- data/{runtime/spec → core_spec}/core/array/equal_value_spec.rb +0 -0
- data/{runtime/spec → core_spec}/core/array/fetch_spec.rb +0 -0
- data/{runtime/spec → core_spec}/core/array/first_spec.rb +0 -0
- data/{runtime/spec → core_spec}/core/array/fixtures/classes.rb +0 -0
- data/{runtime/spec → core_spec}/core/array/flatten_spec.rb +0 -0
- data/{runtime/spec → core_spec}/core/array/include_spec.rb +0 -0
- data/{runtime/spec → core_spec}/core/array/insert_spec.rb +0 -0
- data/{runtime/spec → core_spec}/core/array/last_spec.rb +0 -0
- data/{runtime/spec → core_spec}/core/array/length_spec.rb +0 -0
- data/{runtime/spec → core_spec}/core/array/map_spec.rb +0 -0
- data/{runtime/spec → core_spec}/core/array/plus_spec.rb +0 -0
- data/{runtime/spec → core_spec}/core/array/pop_spec.rb +0 -0
- data/{runtime/spec → core_spec}/core/array/push_spec.rb +0 -0
- data/{runtime/spec → core_spec}/core/array/rassoc_spec.rb +0 -0
- data/{runtime/spec → core_spec}/core/array/reject_spec.rb +0 -0
- data/{runtime/spec → core_spec}/core/array/replace_spec.rb +0 -0
- data/{runtime/spec → core_spec}/core/array/reverse_each_spec.rb +0 -0
- data/{runtime/spec → core_spec}/core/array/reverse_spec.rb +0 -0
- data/{runtime/spec → core_spec}/core/array/shared/collect.rb +0 -0
- data/{runtime/spec → core_spec}/core/array/shared/eql.rb +0 -0
- data/{runtime/spec → core_spec}/core/array/shared/length.rb +0 -0
- data/{runtime/spec → core_spec}/core/array/shared/replace.rb +0 -0
- data/{runtime/spec → core_spec}/core/class/new_spec.rb +0 -0
- data/{runtime/spec → core_spec}/core/enumerable/all_spec.rb +0 -0
- data/{runtime/spec → core_spec}/core/enumerable/any_spec.rb +0 -0
- data/{runtime/spec → core_spec}/core/enumerable/collect_spec.rb +0 -0
- data/{runtime/spec → core_spec}/core/enumerable/count_spec.rb +0 -0
- data/{runtime/spec → core_spec}/core/enumerable/detect_spec.rb +0 -0
- data/{runtime/spec → core_spec}/core/enumerable/find_spec.rb +0 -0
- data/core_spec/core/enumerable/first_spec.rb +3 -0
- data/{runtime/spec → core_spec}/core/enumerable/fixtures/classes.rb +0 -0
- data/{runtime/spec → core_spec}/core/enumerable/shared/collect.rb +0 -0
- data/{runtime/spec → core_spec}/core/enumerable/shared/entries.rb +0 -0
- data/{runtime/spec → core_spec}/core/enumerable/shared/find.rb +0 -0
- data/core_spec/core/enumerable/shared/take.rb +31 -0
- data/{runtime/spec → core_spec}/core/enumerable/to_a_spec.rb +0 -0
- data/{runtime/spec → core_spec}/core/false/and_spec.rb +0 -0
- data/{runtime/spec → core_spec}/core/false/inspect_spec.rb +0 -0
- data/{runtime/spec → core_spec}/core/false/or_spec.rb +0 -0
- data/{runtime/spec → core_spec}/core/false/to_s_spec.rb +0 -0
- data/{runtime/spec → core_spec}/core/false/xor_spec.rb +0 -0
- data/{runtime/spec → core_spec}/core/hash/allocate_spec.rb +0 -0
- data/{runtime/spec → core_spec}/core/hash/assoc_spec.rb +0 -0
- data/{runtime/spec → core_spec}/core/hash/clear_spec.rb +0 -0
- data/{runtime/spec → core_spec}/core/hash/clone_spec.rb +0 -0
- data/{runtime/spec → core_spec}/core/hash/default_spec.rb +0 -0
- data/{runtime/spec → core_spec}/core/hash/delete_if_spec.rb +0 -0
- data/{runtime/spec → core_spec}/core/hash/element_reference_spec.rb +0 -0
- data/{runtime/spec → core_spec}/core/hash/element_set_spec.rb +0 -0
- data/{runtime/spec → core_spec}/core/hash/new_spec.rb +0 -0
- data/{runtime/spec → core_spec}/core/matchdata/to_a_spec.rb +0 -0
- data/{runtime/spec → core_spec}/core/nil/and_spec.rb +0 -0
- data/{runtime/spec → core_spec}/core/nil/inspect_spec.rb +0 -0
- data/{runtime/spec → core_spec}/core/nil/nil_spec.rb +0 -0
- data/{runtime/spec → core_spec}/core/nil/or_spec.rb +0 -0
- data/{runtime/spec → core_spec}/core/nil/to_a_spec.rb +0 -0
- data/{runtime/spec → core_spec}/core/nil/to_f_spec.rb +0 -0
- data/{runtime/spec → core_spec}/core/nil/to_i_spec.rb +0 -0
- data/{runtime/spec → core_spec}/core/nil/to_s_spec.rb +0 -0
- data/{runtime/spec → core_spec}/core/nil/xor_spec.rb +0 -0
- data/{runtime/spec → core_spec}/core/numeric/equal_value_spec.rb +0 -0
- data/{runtime/spec → core_spec}/core/object/is_a_spec.rb +0 -0
- data/{runtime/spec → core_spec}/core/object/shared/kind_of.rb +0 -0
- data/{runtime/spec → core_spec}/core/regexp/match_spec.rb +0 -0
- data/{runtime/spec → core_spec}/core/regexp/shared/match.rb +0 -0
- data/{runtime/spec → core_spec}/core/symbol/to_proc_spec.rb +0 -0
- data/{runtime/spec → core_spec}/core/true/and_spec.rb +0 -0
- data/{runtime/spec → core_spec}/core/true/inspect_spec.rb +0 -0
- data/{runtime/spec → core_spec}/core/true/or_spec.rb +0 -0
- data/{runtime/spec → core_spec}/core/true/to_s_spec.rb +0 -0
- data/{runtime/spec → core_spec}/core/true/xor_spec.rb +0 -0
- data/{runtime/spec → core_spec}/language/alias_spec.rb +0 -0
- data/{runtime/spec → core_spec}/language/and_spec.rb +0 -0
- data/{runtime/spec → core_spec}/language/array_spec.rb +0 -0
- data/{runtime/spec → core_spec}/language/block_spec.rb +0 -0
- data/{runtime/spec → core_spec}/language/break_spec.rb +0 -0
- data/{runtime/spec → core_spec}/language/case_spec.rb +0 -0
- data/{runtime/spec → core_spec}/language/defined_spec.rb +0 -0
- data/{runtime/spec → core_spec}/language/ensure_spec.rb +0 -0
- data/{runtime/spec → core_spec}/language/fixtures/block.rb +0 -0
- data/{runtime/spec → core_spec}/language/fixtures/break.rb +0 -0
- data/{runtime/spec → core_spec}/language/fixtures/defined.rb +0 -0
- data/{runtime/spec → core_spec}/language/fixtures/ensure.rb +0 -0
- data/{runtime/spec → core_spec}/language/fixtures/next.rb +0 -0
- data/{runtime/spec → core_spec}/language/fixtures/send.rb +0 -0
- data/{runtime/spec → core_spec}/language/fixtures/super.rb +0 -0
- data/{runtime/spec → core_spec}/language/hash_spec.rb +0 -0
- data/{runtime/spec → core_spec}/language/if_spec.rb +0 -0
- data/{runtime/spec → core_spec}/language/loop_spec.rb +0 -0
- data/{runtime/spec → core_spec}/language/next_spec.rb +0 -0
- data/{runtime/spec → core_spec}/language/or_spec.rb +0 -0
- data/{runtime/spec → core_spec}/language/predefined_spec.rb +0 -0
- data/{runtime/spec → core_spec}/language/regexp/interpolation_spec.rb +8 -0
- data/{runtime/spec → core_spec}/language/regexp_spec.rb +0 -0
- data/{runtime/spec → core_spec}/language/send_spec.rb +0 -0
- data/{runtime/spec → core_spec}/language/string_spec.rb +0 -0
- data/{runtime/spec → core_spec}/language/super_spec.rb +0 -0
- data/{runtime/spec → core_spec}/language/symbol_spec.rb +0 -0
- data/{runtime/spec → core_spec}/language/undef_spec.rb +0 -0
- data/{runtime/spec → core_spec}/language/unless_spec.rb +0 -0
- data/{runtime/spec → core_spec}/language/until_spec.rb +0 -0
- data/core_spec/language/variables_spec.rb +112 -0
- data/{runtime/spec → core_spec}/language/versions/hash_1.9.rb +0 -0
- data/{runtime/spec → core_spec}/language/while_spec.rb +0 -0
- data/{runtime/spec → core_spec}/opal/opal/defined_spec.rb +0 -0
- data/{runtime/spec → core_spec}/opal/opal/function_spec.rb +0 -0
- data/{runtime/spec → core_spec}/opal/opal/native_spec.rb +0 -0
- data/{runtime/spec → core_spec}/opal/opal/null_spec.rb +0 -0
- data/{runtime/spec → core_spec}/opal/opal/number_spec.rb +0 -0
- data/{runtime/spec → core_spec}/opal/opal/object_spec.rb +0 -0
- data/{runtime/spec → core_spec}/opal/opal/string_spec.rb +0 -0
- data/{runtime/spec → core_spec}/opal/opal/typeof_spec.rb +0 -0
- data/{runtime/spec → core_spec}/opal/opal/undefined_spec.rb +0 -0
- data/{runtime/spec → core_spec}/opal/true/case_compare_spec.rb +0 -0
- data/{runtime/spec → core_spec}/opal/true/class_spec.rb +0 -0
- data/{docs/spec_runner.html → core_spec/release_runner.html} +4 -3
- data/core_spec/runner.html +16 -0
- data/core_spec/spec_helper.rb +23 -0
- data/lib/opal.rb +85 -2
- data/lib/opal/builder.rb +129 -46
- data/lib/opal/context.rb +47 -26
- data/lib/opal/dependency_builder.rb +113 -14
- data/lib/opal/environment.rb +40 -45
- data/lib/opal/parser/grammar.rb +2296 -2254
- data/lib/opal/parser/grammar.y +27 -8
- data/lib/opal/parser/lexer.rb +12 -3
- data/lib/opal/parser/parser.rb +117 -30
- data/lib/opal/parser/scope.rb +2 -2
- data/lib/opal/version.rb +1 -1
- data/opal.gemspec +3 -8
- data/spec/grammar/masgn_spec.rb +37 -0
- metadata +177 -227
- data/index.html +0 -434
- data/lib/opal/command.rb +0 -73
- data/runtime/README.md +0 -25
- data/runtime/corelib/boolean.rb +0 -44
- data/runtime/corelib/class.rb +0 -43
- data/runtime/corelib/complex.rb +0 -2
- data/runtime/corelib/dir.rb +0 -29
- data/runtime/corelib/enumerable.rb +0 -316
- data/runtime/corelib/enumerator.rb +0 -80
- data/runtime/corelib/error.rb +0 -25
- data/runtime/corelib/module.rb +0 -171
- data/runtime/corelib/native.rb +0 -50
- data/runtime/corelib/object.rb +0 -21
- data/runtime/corelib/time.rb +0 -196
- data/runtime/gemlib/alpha.rb +0 -5
- data/runtime/gemlib/kernel.rb +0 -17
- data/runtime/gemlib/load_order +0 -2
- data/runtime/kernel/class.js +0 -256
- data/runtime/kernel/debug.js +0 -42
- data/runtime/kernel/init.js +0 -114
- data/runtime/kernel/load_order +0 -5
- data/runtime/kernel/loader.js +0 -151
- data/runtime/kernel/runtime.js +0 -414
- data/runtime/spec/language/variables_spec.rb +0 -28
- data/runtime/spec/library/stringscanner/scan_spec.rb +0 -36
- data/runtime/spec/opal/forwardable/def_instance_delegator_spec.rb +0 -49
- data/runtime/spec/spec_helper.rb +0 -25
- data/runtime/stdlib/base64.rb +0 -91
- data/runtime/stdlib/date.rb +0 -4
- data/runtime/stdlib/dev.rb +0 -171
- data/runtime/stdlib/forwardable.rb +0 -33
- data/runtime/stdlib/optparse.rb +0 -0
- data/runtime/stdlib/pp.rb +0 -6
- data/runtime/stdlib/racc/parser.rb +0 -159
- data/runtime/stdlib/rbconfig.rb +0 -0
- data/runtime/stdlib/si.rb +0 -17
- data/runtime/stdlib/strscan.rb +0 -53
- data/runtime/stdlib/uri.rb +0 -111
- data/runtime/stdlib/uri/common.rb +0 -1014
- data/runtime/stdlib/uri/ftp.rb +0 -261
- data/runtime/stdlib/uri/generic.rb +0 -1599
- data/runtime/stdlib/uri/http.rb +0 -106
- data/runtime/stdlib/uri/https.rb +0 -22
- data/runtime/stdlib/uri/ldap.rb +0 -260
- data/runtime/stdlib/uri/ldaps.rb +0 -20
- data/runtime/stdlib/uri/mailto.rb +0 -280
- data/spec/builder/output_path_spec.rb +0 -50
data/runtime/stdlib/optparse.rb
DELETED
File without changes
|
data/runtime/stdlib/pp.rb
DELETED
@@ -1,159 +0,0 @@
|
|
1
|
-
# Opal port of racc/parser.rb.
|
2
|
-
#
|
3
|
-
# Original license:
|
4
|
-
#
|
5
|
-
# $originalId: parser.rb,v 1.8 2006/07/06 11:42:07 aamine Exp $
|
6
|
-
#
|
7
|
-
# Copyright (c) 1999-2006 Minero Aoki
|
8
|
-
#
|
9
|
-
# This program is free software.
|
10
|
-
# You can distribute/modify this program under the same terms of ruby.
|
11
|
-
#
|
12
|
-
# As a special exception, when this code is copied by Racc
|
13
|
-
# into a Racc output file, you may use that output file
|
14
|
-
# without restriction.
|
15
|
-
module Racc
|
16
|
-
|
17
|
-
class Parser
|
18
|
-
|
19
|
-
def _racc_setup
|
20
|
-
Racc_arg
|
21
|
-
end
|
22
|
-
|
23
|
-
def do_parse
|
24
|
-
_racc_do_parse_rb _racc_setup, false
|
25
|
-
end
|
26
|
-
|
27
|
-
def _racc_do_parse_rb(arg, in_debug)
|
28
|
-
action_table = arg[0]
|
29
|
-
action_check = arg[1]
|
30
|
-
action_default = arg[2]
|
31
|
-
action_pointer = arg[3]
|
32
|
-
|
33
|
-
goto_table = arg[4]
|
34
|
-
goto_check = arg[5]
|
35
|
-
goto_default = arg[6]
|
36
|
-
goto_pointer = arg[7]
|
37
|
-
|
38
|
-
nt_base = arg[8]
|
39
|
-
reduce_table = arg[9]
|
40
|
-
token_table = arg[10]
|
41
|
-
shift_n = arg[11]
|
42
|
-
reduce_n = arg[12]
|
43
|
-
|
44
|
-
use_result = arg[13]
|
45
|
-
|
46
|
-
# racc sys vars
|
47
|
-
racc_state = [0]
|
48
|
-
racc_tstack = []
|
49
|
-
racc_vstack = []
|
50
|
-
|
51
|
-
racc_t = nil
|
52
|
-
racc_tok = nil
|
53
|
-
racc_val = nil
|
54
|
-
racc_read_next = true
|
55
|
-
|
56
|
-
racc_user_yyerror = false
|
57
|
-
racc_error_status = 0
|
58
|
-
|
59
|
-
token = nil; act = nil; i = nil; nerr = nil; custate = nil
|
60
|
-
|
61
|
-
while true
|
62
|
-
i = action_pointer[racc_state[-1]]
|
63
|
-
|
64
|
-
if i
|
65
|
-
if racc_read_next
|
66
|
-
if racc_t != 0 # not EOF
|
67
|
-
token = next_token
|
68
|
-
|
69
|
-
racc_tok = token[0]
|
70
|
-
racc_val = token[1]
|
71
|
-
|
72
|
-
if racc_tok == false # EOF
|
73
|
-
racc_t = 0
|
74
|
-
else
|
75
|
-
racc_t = token_table[racc_tok]
|
76
|
-
racc_t = 1 unless racc_t
|
77
|
-
# racc_t ||= 1
|
78
|
-
end
|
79
|
-
|
80
|
-
racc_read_next = false
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
i += racc_t
|
85
|
-
|
86
|
-
if (i < 0) || (act = action_table[i]).nil? || (action_check[i] != racc_state[-1])
|
87
|
-
act = action_default[racc_state[-1]]
|
88
|
-
end
|
89
|
-
|
90
|
-
else
|
91
|
-
act = action_default[racc_state[-1]]
|
92
|
-
end
|
93
|
-
|
94
|
-
if act > 0 && act < shift_n
|
95
|
-
if racc_error_status > 0
|
96
|
-
if racc_t != 1
|
97
|
-
racc_error_status -= 1
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
101
|
-
racc_vstack.push racc_val
|
102
|
-
curstate = act
|
103
|
-
racc_state << act
|
104
|
-
racc_read_next = true
|
105
|
-
|
106
|
-
elsif act < 0 && act > -reduce_n
|
107
|
-
reduce_i = act * -3
|
108
|
-
reduce_len = reduce_table[reduce_i]
|
109
|
-
reduce_to = reduce_table[reduce_i + 1]
|
110
|
-
method_id = reduce_table[reduce_i + 2]
|
111
|
-
|
112
|
-
tmp_v = racc_vstack.last reduce_len
|
113
|
-
|
114
|
-
racc_state.pop reduce_len
|
115
|
-
racc_vstack.pop reduce_len
|
116
|
-
racc_tstack.pop reduce_len
|
117
|
-
|
118
|
-
if use_result
|
119
|
-
reduce_call_result = self.__send__ method_id, tmp_v, nil, tmp_v[0]
|
120
|
-
racc_vstack.push reduce_call_result
|
121
|
-
else
|
122
|
-
raise "not using result??"
|
123
|
-
end
|
124
|
-
|
125
|
-
racc_tstack.push reduce_to
|
126
|
-
|
127
|
-
k1 = reduce_to - nt_base
|
128
|
-
|
129
|
-
if (reduce_i = goto_pointer[k1]) != nil
|
130
|
-
reduce_i += racc_state[-1]
|
131
|
-
|
132
|
-
if (reduce_i >= 0) && ((curstate = goto_table[reduce_i]) != nil) && (goto_check[reduce_i] == k1)
|
133
|
-
racc_state.push curstate
|
134
|
-
else
|
135
|
-
racc_state.push goto_default[k1]
|
136
|
-
end
|
137
|
-
|
138
|
-
else
|
139
|
-
racc_state.push goto_default[k1]
|
140
|
-
end
|
141
|
-
|
142
|
-
elsif act == shift_n
|
143
|
-
# action
|
144
|
-
return racc_vstack[0]
|
145
|
-
|
146
|
-
elsif act == -reduce_n
|
147
|
-
# reduce
|
148
|
-
raise "Opal Syntax Error: unexpected '#{racc_tok.inspect}'"
|
149
|
-
|
150
|
-
else
|
151
|
-
raise "Rac: unknown action: #{act}"
|
152
|
-
end
|
153
|
-
|
154
|
-
# raise "and finished loop"
|
155
|
-
end
|
156
|
-
end # _racc_do_parse_rb
|
157
|
-
end
|
158
|
-
end
|
159
|
-
|
data/runtime/stdlib/rbconfig.rb
DELETED
File without changes
|
data/runtime/stdlib/si.rb
DELETED
data/runtime/stdlib/strscan.rb
DELETED
@@ -1,53 +0,0 @@
|
|
1
|
-
class StringScanner
|
2
|
-
def initialize(string)
|
3
|
-
@string = string
|
4
|
-
@at = 0
|
5
|
-
@matched = ''
|
6
|
-
@working = string
|
7
|
-
end
|
8
|
-
|
9
|
-
def scan(regex)
|
10
|
-
%x{
|
11
|
-
var regex = new RegExp('^' + regex.toString().substring(1, regex.toString().length - 1)),
|
12
|
-
result = regex.exec(#@working);
|
13
|
-
|
14
|
-
if (result == null) {
|
15
|
-
#@matched = '';
|
16
|
-
|
17
|
-
return nil;
|
18
|
-
}
|
19
|
-
else if (typeof(result) === 'object') {
|
20
|
-
#@at += result[0].length;
|
21
|
-
#@working = #@working.substring(result[0].length);
|
22
|
-
#@matched = result[0];
|
23
|
-
|
24
|
-
return result[0];
|
25
|
-
}
|
26
|
-
else if (typeof(result) === 'string') {
|
27
|
-
#@at += result.length;
|
28
|
-
#@working = #@working.substring(result.length);
|
29
|
-
|
30
|
-
return result;
|
31
|
-
}
|
32
|
-
else {
|
33
|
-
return nil;
|
34
|
-
}
|
35
|
-
}
|
36
|
-
end
|
37
|
-
|
38
|
-
def check(regex)
|
39
|
-
`!!new RegExp('^' + regex.toString().substring(1, regex.toString().length - 1)).exec(#@working)`
|
40
|
-
end
|
41
|
-
|
42
|
-
def peek(length)
|
43
|
-
`#@working.substring(0, length)`
|
44
|
-
end
|
45
|
-
|
46
|
-
def eos?
|
47
|
-
`#@working.length === 0`
|
48
|
-
end
|
49
|
-
|
50
|
-
def matched
|
51
|
-
@matched
|
52
|
-
end
|
53
|
-
end
|
data/runtime/stdlib/uri.rb
DELETED
@@ -1,111 +0,0 @@
|
|
1
|
-
# URI is a module providing classes to handle Uniform Resource Identifiers
|
2
|
-
# (RFC2396[http://tools.ietf.org/html/rfc2396])
|
3
|
-
#
|
4
|
-
# == Features
|
5
|
-
#
|
6
|
-
# * Uniform handling of handling URIs
|
7
|
-
# * Flexibility to introduce custom URI schemes
|
8
|
-
# * Flexibility to have an alternate URI::Parser (or just different patterns
|
9
|
-
# and regexp's)
|
10
|
-
#
|
11
|
-
# == Basic example
|
12
|
-
#
|
13
|
-
# require 'uri'
|
14
|
-
#
|
15
|
-
# uri = URI("http://foo.com/posts?id=30&limit=5#time=1305298413")
|
16
|
-
# #=> #<URI::HTTP:0x00000000b14880
|
17
|
-
# URL:http://foo.com/posts?id=30&limit=5#time=1305298413>
|
18
|
-
# uri.scheme
|
19
|
-
# #=> "http"
|
20
|
-
# uri.host
|
21
|
-
# #=> "foo.com"
|
22
|
-
# uri.path
|
23
|
-
# #=> "/posts"
|
24
|
-
# uri.query
|
25
|
-
# #=> "id=30&limit=5"
|
26
|
-
# uri.fragment
|
27
|
-
# #=> "time=1305298413"
|
28
|
-
#
|
29
|
-
# uri.to_s
|
30
|
-
# #=> "http://foo.com/posts?id=30&limit=5#time=1305298413"
|
31
|
-
#
|
32
|
-
# == Adding custom URIs
|
33
|
-
#
|
34
|
-
# module URI
|
35
|
-
# class RSYNC < Generic
|
36
|
-
# DEFAULT_PORT = 873
|
37
|
-
# end
|
38
|
-
# @@schemes['RSYNC'] = RSYNC
|
39
|
-
# end
|
40
|
-
# #=> URI::RSYNC
|
41
|
-
#
|
42
|
-
# URI.scheme_list
|
43
|
-
# #=> {"FTP"=>URI::FTP, "HTTP"=>URI::HTTP, "HTTPS"=>URI::HTTPS,
|
44
|
-
# "LDAP"=>URI::LDAP, "LDAPS"=>URI::LDAPS, "MAILTO"=>URI::MailTo,
|
45
|
-
# "RSYNC"=>URI::RSYNC}
|
46
|
-
#
|
47
|
-
# uri = URI("rsync://rsync.foo.com")
|
48
|
-
# #=> #<URI::RSYNC:0x00000000f648c8 URL:rsync://rsync.foo.com>
|
49
|
-
#
|
50
|
-
# == RFC References
|
51
|
-
#
|
52
|
-
# A good place to view an RFC spec is http://www.ietf.org/rfc.html
|
53
|
-
#
|
54
|
-
# Here is a list of all related RFC's.
|
55
|
-
# - RFC822[http://tools.ietf.org/html/rfc822]
|
56
|
-
# - RFC1738[http://tools.ietf.org/html/rfc1738]
|
57
|
-
# - RFC2255[http://tools.ietf.org/html/rfc2255]
|
58
|
-
# - RFC2368[http://tools.ietf.org/html/rfc2368]
|
59
|
-
# - RFC2373[http://tools.ietf.org/html/rfc2373]
|
60
|
-
# - RFC2396[http://tools.ietf.org/html/rfc2396]
|
61
|
-
# - RFC2732[http://tools.ietf.org/html/rfc2732]
|
62
|
-
# - RFC3986[http://tools.ietf.org/html/rfc3986]
|
63
|
-
#
|
64
|
-
# == Class tree
|
65
|
-
#
|
66
|
-
# - URI::Generic (in uri/generic.rb)
|
67
|
-
# - URI::FTP - (in uri/ftp.rb)
|
68
|
-
# - URI::HTTP - (in uri/http.rb)
|
69
|
-
# - URI::HTTPS - (in uri/https.rb)
|
70
|
-
# - URI::LDAP - (in uri/ldap.rb)
|
71
|
-
# - URI::LDAPS - (in uri/ldaps.rb)
|
72
|
-
# - URI::MailTo - (in uri/mailto.rb)
|
73
|
-
# - URI::Parser - (in uri/common.rb)
|
74
|
-
# - URI::REGEXP - (in uri/common.rb)
|
75
|
-
# - URI::REGEXP::PATTERN - (in uri/common.rb)
|
76
|
-
# - URI::Util - (in uri/common.rb)
|
77
|
-
# - URI::Escape - (in uri/common.rb)
|
78
|
-
# - URI::Error - (in uri/common.rb)
|
79
|
-
# - URI::InvalidURIError - (in uri/common.rb)
|
80
|
-
# - URI::InvalidComponentError - (in uri/common.rb)
|
81
|
-
# - URI::BadURIError - (in uri/common.rb)
|
82
|
-
#
|
83
|
-
# == Copyright Info
|
84
|
-
#
|
85
|
-
# Author:: Akira Yamada <akira@ruby-lang.org>
|
86
|
-
# Documentation::
|
87
|
-
# Akira Yamada <akira@ruby-lang.org>
|
88
|
-
# Dmitry V. Sabanin <sdmitry@lrn.ru>
|
89
|
-
# Vincent Batts <vbatts@hashbangbash.com>
|
90
|
-
# License::
|
91
|
-
# Copyright (c) 2001 akira yamada <akira@ruby-lang.org>
|
92
|
-
# You can redistribute it and/or modify it under the same term as Ruby.
|
93
|
-
# Revision:: $Id$
|
94
|
-
#
|
95
|
-
|
96
|
-
module URI
|
97
|
-
# :stopdoc:
|
98
|
-
VERSION_CODE = '000911'.freeze
|
99
|
-
VERSION = VERSION_CODE.scan(/../).collect{|n| n.to_i}.join('.').freeze
|
100
|
-
# :startdoc:
|
101
|
-
|
102
|
-
end
|
103
|
-
|
104
|
-
require 'uri/common'
|
105
|
-
require 'uri/generic'
|
106
|
-
require 'uri/ftp'
|
107
|
-
require 'uri/http'
|
108
|
-
require 'uri/https'
|
109
|
-
require 'uri/ldap'
|
110
|
-
require 'uri/ldaps'
|
111
|
-
require 'uri/mailto'
|
@@ -1,1014 +0,0 @@
|
|
1
|
-
#--
|
2
|
-
# = uri/common.rb
|
3
|
-
#
|
4
|
-
# Author:: Akira Yamada <akira@ruby-lang.org>
|
5
|
-
# Revision:: $Id$
|
6
|
-
# License::
|
7
|
-
# You can redistribute it and/or modify it under the same term as Ruby.
|
8
|
-
#
|
9
|
-
# See URI for general documentation
|
10
|
-
#
|
11
|
-
|
12
|
-
module URI
|
13
|
-
#
|
14
|
-
# Includes URI::REGEXP::PATTERN
|
15
|
-
#
|
16
|
-
module REGEXP
|
17
|
-
#
|
18
|
-
# Patterns used to parse URI's
|
19
|
-
#
|
20
|
-
module PATTERN
|
21
|
-
# :stopdoc:
|
22
|
-
|
23
|
-
# RFC 2396 (URI Generic Syntax)
|
24
|
-
# RFC 2732 (IPv6 Literal Addresses in URL's)
|
25
|
-
# RFC 2373 (IPv6 Addressing Architecture)
|
26
|
-
|
27
|
-
# alpha = lowalpha | upalpha
|
28
|
-
ALPHA = "a-zA-Z"
|
29
|
-
# alphanum = alpha | digit
|
30
|
-
ALNUM = "#{ALPHA}\\d"
|
31
|
-
|
32
|
-
# hex = digit | "A" | "B" | "C" | "D" | "E" | "F" |
|
33
|
-
# "a" | "b" | "c" | "d" | "e" | "f"
|
34
|
-
HEX = "a-fA-F\\d"
|
35
|
-
# escaped = "%" hex hex
|
36
|
-
ESCAPED = "%[#{HEX}]{2}"
|
37
|
-
# mark = "-" | "_" | "." | "!" | "~" | "*" | "'" |
|
38
|
-
# "(" | ")"
|
39
|
-
# unreserved = alphanum | mark
|
40
|
-
UNRESERVED = "\\-_.!~*'()#{ALNUM}"
|
41
|
-
# reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" |
|
42
|
-
# "$" | ","
|
43
|
-
# reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" |
|
44
|
-
# "$" | "," | "[" | "]" (RFC 2732)
|
45
|
-
RESERVED = ";/?:@&=+$,\\[\\]"
|
46
|
-
|
47
|
-
# domainlabel = alphanum | alphanum *( alphanum | "-" ) alphanum
|
48
|
-
DOMLABEL = "(?:[#{ALNUM}](?:[-#{ALNUM}]*[#{ALNUM}])?)"
|
49
|
-
# toplabel = alpha | alpha *( alphanum | "-" ) alphanum
|
50
|
-
TOPLABEL = "(?:[#{ALPHA}](?:[-#{ALNUM}]*[#{ALNUM}])?)"
|
51
|
-
# hostname = *( domainlabel "." ) toplabel [ "." ]
|
52
|
-
HOSTNAME = "(?:#{DOMLABEL}\\.)*#{TOPLABEL}\\.?"
|
53
|
-
|
54
|
-
# :startdoc:
|
55
|
-
end # PATTERN
|
56
|
-
|
57
|
-
# :startdoc:
|
58
|
-
end # REGEXP
|
59
|
-
|
60
|
-
# class that Parses String's into URI's
|
61
|
-
#
|
62
|
-
# It contains a Hash set of patterns and Regexp's that match and validate.
|
63
|
-
#
|
64
|
-
class Parser
|
65
|
-
include REGEXP
|
66
|
-
|
67
|
-
#
|
68
|
-
# == Synopsis
|
69
|
-
#
|
70
|
-
# URI::Parser.new([opts])
|
71
|
-
#
|
72
|
-
# == Args
|
73
|
-
#
|
74
|
-
# The constructor accepts a hash as options for parser.
|
75
|
-
# Keys of options are pattern names of URI components
|
76
|
-
# and values of options are pattern strings.
|
77
|
-
# The constructor generetes set of regexps for parsing URIs.
|
78
|
-
#
|
79
|
-
# You can use the following keys:
|
80
|
-
#
|
81
|
-
# * :ESCAPED (URI::PATTERN::ESCAPED in default)
|
82
|
-
# * :UNRESERVED (URI::PATTERN::UNRESERVED in default)
|
83
|
-
# * :DOMLABEL (URI::PATTERN::DOMLABEL in default)
|
84
|
-
# * :TOPLABEL (URI::PATTERN::TOPLABEL in default)
|
85
|
-
# * :HOSTNAME (URI::PATTERN::HOSTNAME in default)
|
86
|
-
#
|
87
|
-
# == Examples
|
88
|
-
#
|
89
|
-
# p = URI::Parser.new(:ESCAPED => "(?:%[a-fA-F0-9]{2}|%u[a-fA-F0-9]{4})")
|
90
|
-
# u = p.parse("http://example.jp/%uABCD") #=> #<URI::HTTP:0xb78cf4f8 URL:http://example.jp/%uABCD>
|
91
|
-
# URI.parse(u.to_s) #=> raises URI::InvalidURIError
|
92
|
-
#
|
93
|
-
# s = "http://examle.com/ABCD"
|
94
|
-
# u1 = p.parse(s) #=> #<URI::HTTP:0xb78c3220 URL:http://example.com/ABCD>
|
95
|
-
# u2 = URI.parse(s) #=> #<URI::HTTP:0xb78b6d54 URL:http://example.com/ABCD>
|
96
|
-
# u1 == u2 #=> true
|
97
|
-
# u1.eql?(u2) #=> false
|
98
|
-
#
|
99
|
-
def initialize(opts = {})
|
100
|
-
@pattern = initialize_pattern(opts)
|
101
|
-
@pattern.each_value {|v| v.freeze}
|
102
|
-
@pattern.freeze
|
103
|
-
|
104
|
-
@regexp = initialize_regexp(@pattern)
|
105
|
-
@regexp.each_value {|v| v.freeze}
|
106
|
-
@regexp.freeze
|
107
|
-
end
|
108
|
-
|
109
|
-
# The Hash of patterns.
|
110
|
-
#
|
111
|
-
# see also URI::Parser.initialize_pattern
|
112
|
-
attr_reader :pattern
|
113
|
-
|
114
|
-
# The Hash of Regexp
|
115
|
-
#
|
116
|
-
# see also URI::Parser.initialize_regexp
|
117
|
-
attr_reader :regexp
|
118
|
-
|
119
|
-
# Returns a split URI against regexp[:ABS_URI]
|
120
|
-
def split(uri)
|
121
|
-
case uri
|
122
|
-
when ''
|
123
|
-
# null uri
|
124
|
-
|
125
|
-
when @regexp[:ABS_URI]
|
126
|
-
scheme, opaque, userinfo, host, port,
|
127
|
-
registry, path, query, fragment = $~[1..-1]
|
128
|
-
|
129
|
-
# URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ]
|
130
|
-
|
131
|
-
# absoluteURI = scheme ":" ( hier_part | opaque_part )
|
132
|
-
# hier_part = ( net_path | abs_path ) [ "?" query ]
|
133
|
-
# opaque_part = uric_no_slash *uric
|
134
|
-
|
135
|
-
# abs_path = "/" path_segments
|
136
|
-
# net_path = "//" authority [ abs_path ]
|
137
|
-
|
138
|
-
# authority = server | reg_name
|
139
|
-
# server = [ [ userinfo "@" ] hostport ]
|
140
|
-
|
141
|
-
if !scheme
|
142
|
-
raise InvalidURIError,
|
143
|
-
"bad URI(absolute but no scheme): #{uri}"
|
144
|
-
end
|
145
|
-
if !opaque && (!path && (!host && !registry))
|
146
|
-
raise InvalidURIError,
|
147
|
-
"bad URI(absolute but no path): #{uri}"
|
148
|
-
end
|
149
|
-
|
150
|
-
when @regexp[:REL_URI]
|
151
|
-
scheme = nil
|
152
|
-
opaque = nil
|
153
|
-
|
154
|
-
userinfo, host, port, registry,
|
155
|
-
rel_segment, abs_path, query, fragment = $~[1..-1]
|
156
|
-
if rel_segment && abs_path
|
157
|
-
path = rel_segment + abs_path
|
158
|
-
elsif rel_segment
|
159
|
-
path = rel_segment
|
160
|
-
elsif abs_path
|
161
|
-
path = abs_path
|
162
|
-
end
|
163
|
-
|
164
|
-
# URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ]
|
165
|
-
|
166
|
-
# relativeURI = ( net_path | abs_path | rel_path ) [ "?" query ]
|
167
|
-
|
168
|
-
# net_path = "//" authority [ abs_path ]
|
169
|
-
# abs_path = "/" path_segments
|
170
|
-
# rel_path = rel_segment [ abs_path ]
|
171
|
-
|
172
|
-
# authority = server | reg_name
|
173
|
-
# server = [ [ userinfo "@" ] hostport ]
|
174
|
-
|
175
|
-
else
|
176
|
-
raise InvalidURIError, "bad URI(is not URI?): #{uri}"
|
177
|
-
end
|
178
|
-
|
179
|
-
path = '' if !path && !opaque # (see RFC2396 Section 5.2)
|
180
|
-
ret = [
|
181
|
-
scheme,
|
182
|
-
userinfo, host, port, # X
|
183
|
-
registry, # X
|
184
|
-
path, # Y
|
185
|
-
opaque, # Y
|
186
|
-
query,
|
187
|
-
fragment
|
188
|
-
]
|
189
|
-
return ret
|
190
|
-
end
|
191
|
-
|
192
|
-
#
|
193
|
-
# == Args
|
194
|
-
#
|
195
|
-
# +uri+::
|
196
|
-
# String
|
197
|
-
#
|
198
|
-
# == Description
|
199
|
-
#
|
200
|
-
# parses +uri+ and constructs either matching URI scheme object
|
201
|
-
# (FTP, HTTP, HTTPS, LDAP, LDAPS, or MailTo) or URI::Generic
|
202
|
-
#
|
203
|
-
# == Usage
|
204
|
-
#
|
205
|
-
# p = URI::Parser.new
|
206
|
-
# p.parse("ldap://ldap.example.com/dc=example?user=john")
|
207
|
-
# #=> #<URI::LDAP:0x00000000b9e7e8 URL:ldap://ldap.example.com/dc=example?user=john>
|
208
|
-
#
|
209
|
-
def parse(uri)
|
210
|
-
scheme, userinfo, host, port,
|
211
|
-
registry, path, opaque, query, fragment = self.split(uri)
|
212
|
-
|
213
|
-
if scheme && URI.scheme_list.include?(scheme.upcase)
|
214
|
-
URI.scheme_list[scheme.upcase].new(scheme, userinfo, host, port,
|
215
|
-
registry, path, opaque, query,
|
216
|
-
fragment, self)
|
217
|
-
else
|
218
|
-
Generic.new(scheme, userinfo, host, port,
|
219
|
-
registry, path, opaque, query,
|
220
|
-
fragment, self)
|
221
|
-
end
|
222
|
-
end
|
223
|
-
|
224
|
-
|
225
|
-
#
|
226
|
-
# == Args
|
227
|
-
#
|
228
|
-
# +uris+::
|
229
|
-
# an Array of Strings
|
230
|
-
#
|
231
|
-
# == Description
|
232
|
-
#
|
233
|
-
# Attempts to parse and merge a set of URIs
|
234
|
-
#
|
235
|
-
def join(*uris)
|
236
|
-
uris[0] = convert_to_uri(uris[0])
|
237
|
-
uris.inject :merge
|
238
|
-
end
|
239
|
-
|
240
|
-
#
|
241
|
-
# :call-seq:
|
242
|
-
# extract( str )
|
243
|
-
# extract( str, schemes )
|
244
|
-
# extract( str, schemes ) {|item| block }
|
245
|
-
#
|
246
|
-
# == Args
|
247
|
-
#
|
248
|
-
# +str+::
|
249
|
-
# String to search
|
250
|
-
# +schemes+::
|
251
|
-
# Patterns to apply to +str+
|
252
|
-
#
|
253
|
-
# == Description
|
254
|
-
#
|
255
|
-
# Attempts to parse and merge a set of URIs
|
256
|
-
# If no +block+ given , then returns the result,
|
257
|
-
# else it calls +block+ for each element in result.
|
258
|
-
#
|
259
|
-
# see also URI::Parser.make_regexp
|
260
|
-
#
|
261
|
-
def extract(str, schemes = nil, &block)
|
262
|
-
if block_given?
|
263
|
-
str.scan(make_regexp(schemes)) { yield $& }
|
264
|
-
nil
|
265
|
-
else
|
266
|
-
result = []
|
267
|
-
str.scan(make_regexp(schemes)) { result.push $& }
|
268
|
-
result
|
269
|
-
end
|
270
|
-
end
|
271
|
-
|
272
|
-
# returns Regexp that is default self.regexp[:ABS_URI_REF],
|
273
|
-
# unless +schemes+ is provided. Then it is a Regexp.union with self.pattern[:X_ABS_URI]
|
274
|
-
def make_regexp(schemes = nil)
|
275
|
-
unless schemes
|
276
|
-
@regexp[:ABS_URI_REF]
|
277
|
-
else
|
278
|
-
/(?=#{Regexp.union(*schemes)}:)#{@pattern[:X_ABS_URI]}/x
|
279
|
-
end
|
280
|
-
end
|
281
|
-
|
282
|
-
#
|
283
|
-
# :call-seq:
|
284
|
-
# escape( str )
|
285
|
-
# escape( str, unsafe )
|
286
|
-
#
|
287
|
-
# == Args
|
288
|
-
#
|
289
|
-
# +str+::
|
290
|
-
# String to make safe
|
291
|
-
# +unsafe+::
|
292
|
-
# Regexp to apply. Defaults to self.regexp[:UNSAFE]
|
293
|
-
#
|
294
|
-
# == Description
|
295
|
-
#
|
296
|
-
# constructs a safe String from +str+, removing unsafe characters,
|
297
|
-
# replacing them with codes.
|
298
|
-
#
|
299
|
-
def escape(str, unsafe = @regexp[:UNSAFE])
|
300
|
-
unless unsafe.kind_of?(Regexp)
|
301
|
-
# perhaps unsafe is String object
|
302
|
-
unsafe = Regexp.new("[#{Regexp.quote(unsafe)}]", false)
|
303
|
-
end
|
304
|
-
str.gsub(unsafe) do
|
305
|
-
us = $&
|
306
|
-
tmp = ''
|
307
|
-
us.each_byte do |uc|
|
308
|
-
tmp << sprintf('%%%02X', uc)
|
309
|
-
end
|
310
|
-
tmp
|
311
|
-
end.force_encoding(Encoding::US_ASCII)
|
312
|
-
end
|
313
|
-
|
314
|
-
#
|
315
|
-
# :call-seq:
|
316
|
-
# unescape( str )
|
317
|
-
# unescape( str, unsafe )
|
318
|
-
#
|
319
|
-
# == Args
|
320
|
-
#
|
321
|
-
# +str+::
|
322
|
-
# String to remove escapes from
|
323
|
-
# +unsafe+::
|
324
|
-
# Regexp to apply. Defaults to self.regexp[:ESCAPED]
|
325
|
-
#
|
326
|
-
# == Description
|
327
|
-
#
|
328
|
-
# Removes escapes from +str+
|
329
|
-
#
|
330
|
-
def unescape(str, escaped = @regexp[:ESCAPED])
|
331
|
-
str.gsub(escaped) { [$&[1, 2].hex].pack('C') }.force_encoding(str.encoding)
|
332
|
-
end
|
333
|
-
|
334
|
-
@@to_s = Kernel.instance_method(:to_s)
|
335
|
-
def inspect
|
336
|
-
@@to_s.bind(self).call
|
337
|
-
end
|
338
|
-
|
339
|
-
private
|
340
|
-
|
341
|
-
# Constructs the default Hash of patterns
|
342
|
-
def initialize_pattern(opts = {})
|
343
|
-
ret = {}
|
344
|
-
ret[:ESCAPED] = escaped = (opts.delete(:ESCAPED) || PATTERN::ESCAPED)
|
345
|
-
ret[:UNRESERVED] = unreserved = opts.delete(:UNRESERVED) || PATTERN::UNRESERVED
|
346
|
-
ret[:RESERVED] = reserved = opts.delete(:RESERVED) || PATTERN::RESERVED
|
347
|
-
ret[:DOMLABEL] = opts.delete(:DOMLABEL) || PATTERN::DOMLABEL
|
348
|
-
ret[:TOPLABEL] = opts.delete(:TOPLABEL) || PATTERN::TOPLABEL
|
349
|
-
ret[:HOSTNAME] = hostname = opts.delete(:HOSTNAME)
|
350
|
-
|
351
|
-
# RFC 2396 (URI Generic Syntax)
|
352
|
-
# RFC 2732 (IPv6 Literal Addresses in URL's)
|
353
|
-
# RFC 2373 (IPv6 Addressing Architecture)
|
354
|
-
|
355
|
-
# uric = reserved | unreserved | escaped
|
356
|
-
ret[:URIC] = uric = "(?:[#{unreserved}#{reserved}]|#{escaped})"
|
357
|
-
# uric_no_slash = unreserved | escaped | ";" | "?" | ":" | "@" |
|
358
|
-
# "&" | "=" | "+" | "$" | ","
|
359
|
-
ret[:URIC_NO_SLASH] = uric_no_slash = "(?:[#{unreserved};?:@&=+$,]|#{escaped})"
|
360
|
-
# query = *uric
|
361
|
-
ret[:QUERY] = query = "#{uric}*"
|
362
|
-
# fragment = *uric
|
363
|
-
ret[:FRAGMENT] = fragment = "#{uric}*"
|
364
|
-
|
365
|
-
# hostname = *( domainlabel "." ) toplabel [ "." ]
|
366
|
-
# reg-name = *( unreserved / pct-encoded / sub-delims ) # RFC3986
|
367
|
-
unless hostname
|
368
|
-
ret[:HOSTNAME] = hostname = "(?:[a-zA-Z0-9\\-.]|%\\h\\h)+"
|
369
|
-
end
|
370
|
-
|
371
|
-
# RFC 2373, APPENDIX B:
|
372
|
-
# IPv6address = hexpart [ ":" IPv4address ]
|
373
|
-
# IPv4address = 1*3DIGIT "." 1*3DIGIT "." 1*3DIGIT "." 1*3DIGIT
|
374
|
-
# hexpart = hexseq | hexseq "::" [ hexseq ] | "::" [ hexseq ]
|
375
|
-
# hexseq = hex4 *( ":" hex4)
|
376
|
-
# hex4 = 1*4HEXDIG
|
377
|
-
#
|
378
|
-
# XXX: This definition has a flaw. "::" + IPv4address must be
|
379
|
-
# allowed too. Here is a replacement.
|
380
|
-
#
|
381
|
-
# IPv4address = 1*3DIGIT "." 1*3DIGIT "." 1*3DIGIT "." 1*3DIGIT
|
382
|
-
ret[:IPV4ADDR] = ipv4addr = "\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}"
|
383
|
-
# hex4 = 1*4HEXDIG
|
384
|
-
hex4 = "[#{PATTERN::HEX}]{1,4}"
|
385
|
-
# lastpart = hex4 | IPv4address
|
386
|
-
lastpart = "(?:#{hex4}|#{ipv4addr})"
|
387
|
-
# hexseq1 = *( hex4 ":" ) hex4
|
388
|
-
hexseq1 = "(?:#{hex4}:)*#{hex4}"
|
389
|
-
# hexseq2 = *( hex4 ":" ) lastpart
|
390
|
-
hexseq2 = "(?:#{hex4}:)*#{lastpart}"
|
391
|
-
# IPv6address = hexseq2 | [ hexseq1 ] "::" [ hexseq2 ]
|
392
|
-
ret[:IPV6ADDR] = ipv6addr = "(?:#{hexseq2}|(?:#{hexseq1})?::(?:#{hexseq2})?)"
|
393
|
-
|
394
|
-
# IPv6prefix = ( hexseq1 | [ hexseq1 ] "::" [ hexseq1 ] ) "/" 1*2DIGIT
|
395
|
-
# unused
|
396
|
-
|
397
|
-
# ipv6reference = "[" IPv6address "]" (RFC 2732)
|
398
|
-
ret[:IPV6REF] = ipv6ref = "\\[#{ipv6addr}\\]"
|
399
|
-
|
400
|
-
# host = hostname | IPv4address
|
401
|
-
# host = hostname | IPv4address | IPv6reference (RFC 2732)
|
402
|
-
ret[:HOST] = host = "(?:#{hostname}|#{ipv4addr}|#{ipv6ref})"
|
403
|
-
# port = *digit
|
404
|
-
port = '\d*'
|
405
|
-
# hostport = host [ ":" port ]
|
406
|
-
ret[:HOSTPORT] = hostport = "#{host}(?::#{port})?"
|
407
|
-
|
408
|
-
# userinfo = *( unreserved | escaped |
|
409
|
-
# ";" | ":" | "&" | "=" | "+" | "$" | "," )
|
410
|
-
ret[:USERINFO] = userinfo = "(?:[#{unreserved};:&=+$,]|#{escaped})*"
|
411
|
-
|
412
|
-
# pchar = unreserved | escaped |
|
413
|
-
# ":" | "@" | "&" | "=" | "+" | "$" | ","
|
414
|
-
pchar = "(?:[#{unreserved}:@&=+$,]|#{escaped})"
|
415
|
-
# param = *pchar
|
416
|
-
param = "#{pchar}*"
|
417
|
-
# segment = *pchar *( ";" param )
|
418
|
-
segment = "#{pchar}*(?:;#{param})*"
|
419
|
-
# path_segments = segment *( "/" segment )
|
420
|
-
ret[:PATH_SEGMENTS] = path_segments = "#{segment}(?:/#{segment})*"
|
421
|
-
|
422
|
-
# server = [ [ userinfo "@" ] hostport ]
|
423
|
-
server = "(?:#{userinfo}@)?#{hostport}"
|
424
|
-
# reg_name = 1*( unreserved | escaped | "$" | "," |
|
425
|
-
# ";" | ":" | "@" | "&" | "=" | "+" )
|
426
|
-
ret[:REG_NAME] = reg_name = "(?:[#{unreserved}$,;:@&=+]|#{escaped})+"
|
427
|
-
# authority = server | reg_name
|
428
|
-
authority = "(?:#{server}|#{reg_name})"
|
429
|
-
|
430
|
-
# rel_segment = 1*( unreserved | escaped |
|
431
|
-
# ";" | "@" | "&" | "=" | "+" | "$" | "," )
|
432
|
-
ret[:REL_SEGMENT] = rel_segment = "(?:[#{unreserved};@&=+$,]|#{escaped})+"
|
433
|
-
|
434
|
-
# scheme = alpha *( alpha | digit | "+" | "-" | "." )
|
435
|
-
ret[:SCHEME] = scheme = "[#{PATTERN::ALPHA}][\\-+.#{PATTERN::ALPHA}\\d]*"
|
436
|
-
|
437
|
-
# abs_path = "/" path_segments
|
438
|
-
ret[:ABS_PATH] = abs_path = "/#{path_segments}"
|
439
|
-
# rel_path = rel_segment [ abs_path ]
|
440
|
-
ret[:REL_PATH] = rel_path = "#{rel_segment}(?:#{abs_path})?"
|
441
|
-
# net_path = "//" authority [ abs_path ]
|
442
|
-
ret[:NET_PATH] = net_path = "//#{authority}(?:#{abs_path})?"
|
443
|
-
|
444
|
-
# hier_part = ( net_path | abs_path ) [ "?" query ]
|
445
|
-
ret[:HIER_PART] = hier_part = "(?:#{net_path}|#{abs_path})(?:\\?(?:#{query}))?"
|
446
|
-
# opaque_part = uric_no_slash *uric
|
447
|
-
ret[:OPAQUE_PART] = opaque_part = "#{uric_no_slash}#{uric}*"
|
448
|
-
|
449
|
-
# absoluteURI = scheme ":" ( hier_part | opaque_part )
|
450
|
-
ret[:ABS_URI] = abs_uri = "#{scheme}:(?:#{hier_part}|#{opaque_part})"
|
451
|
-
# relativeURI = ( net_path | abs_path | rel_path ) [ "?" query ]
|
452
|
-
ret[:REL_URI] = rel_uri = "(?:#{net_path}|#{abs_path}|#{rel_path})(?:\\?#{query})?"
|
453
|
-
|
454
|
-
# URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ]
|
455
|
-
ret[:URI_REF] = "(?:#{abs_uri}|#{rel_uri})?(?:##{fragment})?"
|
456
|
-
|
457
|
-
ret[:X_ABS_URI] = "
|
458
|
-
(#{scheme}): (?# 1: scheme)
|
459
|
-
(?:
|
460
|
-
(#{opaque_part}) (?# 2: opaque)
|
461
|
-
|
|
462
|
-
(?:(?:
|
463
|
-
//(?:
|
464
|
-
(?:(?:(#{userinfo})@)? (?# 3: userinfo)
|
465
|
-
(?:(#{host})(?::(\\d*))?))? (?# 4: host, 5: port)
|
466
|
-
|
|
467
|
-
(#{reg_name}) (?# 6: registry)
|
468
|
-
)
|
469
|
-
|
|
470
|
-
(?!//)) (?# XXX: '//' is the mark for hostport)
|
471
|
-
(#{abs_path})? (?# 7: path)
|
472
|
-
)(?:\\?(#{query}))? (?# 8: query)
|
473
|
-
)
|
474
|
-
(?:\\#(#{fragment}))? (?# 9: fragment)
|
475
|
-
"
|
476
|
-
|
477
|
-
ret[:X_REL_URI] = "
|
478
|
-
(?:
|
479
|
-
(?:
|
480
|
-
//
|
481
|
-
(?:
|
482
|
-
(?:(#{userinfo})@)? (?# 1: userinfo)
|
483
|
-
(#{host})?(?::(\\d*))? (?# 2: host, 3: port)
|
484
|
-
|
|
485
|
-
(#{reg_name}) (?# 4: registry)
|
486
|
-
)
|
487
|
-
)
|
488
|
-
|
|
489
|
-
(#{rel_segment}) (?# 5: rel_segment)
|
490
|
-
)?
|
491
|
-
(#{abs_path})? (?# 6: abs_path)
|
492
|
-
(?:\\?(#{query}))? (?# 7: query)
|
493
|
-
(?:\\#(#{fragment}))? (?# 8: fragment)
|
494
|
-
"
|
495
|
-
|
496
|
-
ret
|
497
|
-
end
|
498
|
-
|
499
|
-
# Constructs the default Hash of Regexp's
|
500
|
-
def initialize_regexp(pattern)
|
501
|
-
ret = {}
|
502
|
-
|
503
|
-
# for URI::split
|
504
|
-
ret[:ABS_URI] = Regexp.new('\A\s*' + pattern[:X_ABS_URI] + '\s*\z', Regexp::EXTENDED)
|
505
|
-
ret[:REL_URI] = Regexp.new('\A\s*' + pattern[:X_REL_URI] + '\s*\z', Regexp::EXTENDED)
|
506
|
-
|
507
|
-
# for URI::extract
|
508
|
-
ret[:URI_REF] = Regexp.new(pattern[:URI_REF])
|
509
|
-
ret[:ABS_URI_REF] = Regexp.new(pattern[:X_ABS_URI], Regexp::EXTENDED)
|
510
|
-
ret[:REL_URI_REF] = Regexp.new(pattern[:X_REL_URI], Regexp::EXTENDED)
|
511
|
-
|
512
|
-
# for URI::escape/unescape
|
513
|
-
ret[:ESCAPED] = Regexp.new(pattern[:ESCAPED])
|
514
|
-
ret[:UNSAFE] = Regexp.new("[^#{pattern[:UNRESERVED]}#{pattern[:RESERVED]}]")
|
515
|
-
|
516
|
-
# for Generic#initialize
|
517
|
-
ret[:SCHEME] = Regexp.new("^#{pattern[:SCHEME]}$")
|
518
|
-
ret[:USERINFO] = Regexp.new("^#{pattern[:USERINFO]}$")
|
519
|
-
ret[:HOST] = Regexp.new("^#{pattern[:HOST]}$")
|
520
|
-
ret[:PORT] = Regexp.new("^#{pattern[:PORT]}$")
|
521
|
-
ret[:OPAQUE] = Regexp.new("^#{pattern[:OPAQUE_PART]}$")
|
522
|
-
ret[:REGISTRY] = Regexp.new("^#{pattern[:REG_NAME]}$")
|
523
|
-
ret[:ABS_PATH] = Regexp.new("^#{pattern[:ABS_PATH]}$")
|
524
|
-
ret[:REL_PATH] = Regexp.new("^#{pattern[:REL_PATH]}$")
|
525
|
-
ret[:QUERY] = Regexp.new("^#{pattern[:QUERY]}$")
|
526
|
-
ret[:FRAGMENT] = Regexp.new("^#{pattern[:FRAGMENT]}$")
|
527
|
-
|
528
|
-
ret
|
529
|
-
end
|
530
|
-
|
531
|
-
def convert_to_uri(uri)
|
532
|
-
if uri.is_a?(URI::Generic)
|
533
|
-
uri
|
534
|
-
elsif uri = String.try_convert(uri)
|
535
|
-
parse(uri)
|
536
|
-
else
|
537
|
-
raise ArgumentError,
|
538
|
-
"bad argument (expected URI object or URI string)"
|
539
|
-
end
|
540
|
-
end
|
541
|
-
|
542
|
-
end # class Parser
|
543
|
-
|
544
|
-
# URI::Parser.new
|
545
|
-
DEFAULT_PARSER = Parser.new
|
546
|
-
DEFAULT_PARSER.pattern.each_pair do |sym, str|
|
547
|
-
unless REGEXP::PATTERN.const_defined?(sym)
|
548
|
-
REGEXP::PATTERN.const_set(sym, str)
|
549
|
-
end
|
550
|
-
end
|
551
|
-
DEFAULT_PARSER.regexp.each_pair do |sym, str|
|
552
|
-
const_set(sym, str)
|
553
|
-
end
|
554
|
-
|
555
|
-
module Util # :nodoc:
|
556
|
-
def make_components_hash(klass, array_hash)
|
557
|
-
tmp = {}
|
558
|
-
if array_hash.kind_of?(Array) &&
|
559
|
-
array_hash.size == klass.component.size - 1
|
560
|
-
klass.component[1..-1].each_index do |i|
|
561
|
-
begin
|
562
|
-
tmp[klass.component[i + 1]] = array_hash[i].clone
|
563
|
-
rescue TypeError
|
564
|
-
tmp[klass.component[i + 1]] = array_hash[i]
|
565
|
-
end
|
566
|
-
end
|
567
|
-
|
568
|
-
elsif array_hash.kind_of?(Hash)
|
569
|
-
array_hash.each do |key, value|
|
570
|
-
begin
|
571
|
-
tmp[key] = value.clone
|
572
|
-
rescue TypeError
|
573
|
-
tmp[key] = value
|
574
|
-
end
|
575
|
-
end
|
576
|
-
else
|
577
|
-
raise ArgumentError,
|
578
|
-
"expected Array of or Hash of components of #{klass.to_s} (#{klass.component[1..-1].join(', ')})"
|
579
|
-
end
|
580
|
-
tmp[:scheme] = klass.to_s.sub(/\A.*::/, '').downcase
|
581
|
-
|
582
|
-
return tmp
|
583
|
-
end
|
584
|
-
module_function :make_components_hash
|
585
|
-
end
|
586
|
-
|
587
|
-
# module for escaping unsafe characters with codes.
|
588
|
-
module Escape
|
589
|
-
#
|
590
|
-
# == Synopsis
|
591
|
-
#
|
592
|
-
# URI.escape(str [, unsafe])
|
593
|
-
#
|
594
|
-
# == Args
|
595
|
-
#
|
596
|
-
# +str+::
|
597
|
-
# String to replaces in.
|
598
|
-
# +unsafe+::
|
599
|
-
# Regexp that matches all symbols that must be replaced with codes.
|
600
|
-
# By default uses <tt>REGEXP::UNSAFE</tt>.
|
601
|
-
# When this argument is a String, it represents a character set.
|
602
|
-
#
|
603
|
-
# == Description
|
604
|
-
#
|
605
|
-
# Escapes the string, replacing all unsafe characters with codes.
|
606
|
-
#
|
607
|
-
# == Usage
|
608
|
-
#
|
609
|
-
# require 'uri'
|
610
|
-
#
|
611
|
-
# enc_uri = URI.escape("http://example.com/?a=\11\15")
|
612
|
-
# p enc_uri
|
613
|
-
# # => "http://example.com/?a=%09%0D"
|
614
|
-
#
|
615
|
-
# p URI.unescape(enc_uri)
|
616
|
-
# # => "http://example.com/?a=\t\r"
|
617
|
-
#
|
618
|
-
# p URI.escape("@?@!", "!?")
|
619
|
-
# # => "@%3F@%21"
|
620
|
-
#
|
621
|
-
def escape(*arg)
|
622
|
-
warn "#{caller(1)[0]}: warning: URI.escape is obsolete" if $VERBOSE
|
623
|
-
DEFAULT_PARSER.escape(*arg)
|
624
|
-
end
|
625
|
-
alias encode escape
|
626
|
-
#
|
627
|
-
# == Synopsis
|
628
|
-
#
|
629
|
-
# URI.unescape(str)
|
630
|
-
#
|
631
|
-
# == Args
|
632
|
-
#
|
633
|
-
# +str+::
|
634
|
-
# Unescapes the string.
|
635
|
-
#
|
636
|
-
# == Usage
|
637
|
-
#
|
638
|
-
# require 'uri'
|
639
|
-
#
|
640
|
-
# enc_uri = URI.escape("http://example.com/?a=\11\15")
|
641
|
-
# p enc_uri
|
642
|
-
# # => "http://example.com/?a=%09%0D"
|
643
|
-
#
|
644
|
-
# p URI.unescape(enc_uri)
|
645
|
-
# # => "http://example.com/?a=\t\r"
|
646
|
-
#
|
647
|
-
def unescape(*arg)
|
648
|
-
warn "#{caller(1)[0]}: warning: URI.unescape is obsolete" if $VERBOSE
|
649
|
-
DEFAULT_PARSER.unescape(*arg)
|
650
|
-
end
|
651
|
-
alias decode unescape
|
652
|
-
end # module Escape
|
653
|
-
|
654
|
-
extend Escape
|
655
|
-
include REGEXP
|
656
|
-
|
657
|
-
@@schemes = {}
|
658
|
-
# Returns a Hash of the defined schemes
|
659
|
-
def self.scheme_list
|
660
|
-
@@schemes
|
661
|
-
end
|
662
|
-
|
663
|
-
#
|
664
|
-
# Base class for all URI exceptions.
|
665
|
-
#
|
666
|
-
class Error < StandardError; end
|
667
|
-
#
|
668
|
-
# Not a URI.
|
669
|
-
#
|
670
|
-
class InvalidURIError < Error; end
|
671
|
-
#
|
672
|
-
# Not a URI component.
|
673
|
-
#
|
674
|
-
class InvalidComponentError < Error; end
|
675
|
-
#
|
676
|
-
# URI is valid, bad usage is not.
|
677
|
-
#
|
678
|
-
class BadURIError < Error; end
|
679
|
-
|
680
|
-
#
|
681
|
-
# == Synopsis
|
682
|
-
#
|
683
|
-
# URI::split(uri)
|
684
|
-
#
|
685
|
-
# == Args
|
686
|
-
#
|
687
|
-
# +uri+::
|
688
|
-
# String with URI.
|
689
|
-
#
|
690
|
-
# == Description
|
691
|
-
#
|
692
|
-
# Splits the string on following parts and returns array with result:
|
693
|
-
#
|
694
|
-
# * Scheme
|
695
|
-
# * Userinfo
|
696
|
-
# * Host
|
697
|
-
# * Port
|
698
|
-
# * Registry
|
699
|
-
# * Path
|
700
|
-
# * Opaque
|
701
|
-
# * Query
|
702
|
-
# * Fragment
|
703
|
-
#
|
704
|
-
# == Usage
|
705
|
-
#
|
706
|
-
# require 'uri'
|
707
|
-
#
|
708
|
-
# p URI.split("http://www.ruby-lang.org/")
|
709
|
-
# # => ["http", nil, "www.ruby-lang.org", nil, nil, "/", nil, nil, nil]
|
710
|
-
#
|
711
|
-
def self.split(uri)
|
712
|
-
DEFAULT_PARSER.split(uri)
|
713
|
-
end
|
714
|
-
|
715
|
-
#
|
716
|
-
# == Synopsis
|
717
|
-
#
|
718
|
-
# URI::parse(uri_str)
|
719
|
-
#
|
720
|
-
# == Args
|
721
|
-
#
|
722
|
-
# +uri_str+::
|
723
|
-
# String with URI.
|
724
|
-
#
|
725
|
-
# == Description
|
726
|
-
#
|
727
|
-
# Creates one of the URI's subclasses instance from the string.
|
728
|
-
#
|
729
|
-
# == Raises
|
730
|
-
#
|
731
|
-
# URI::InvalidURIError
|
732
|
-
# Raised if URI given is not a correct one.
|
733
|
-
#
|
734
|
-
# == Usage
|
735
|
-
#
|
736
|
-
# require 'uri'
|
737
|
-
#
|
738
|
-
# uri = URI.parse("http://www.ruby-lang.org/")
|
739
|
-
# p uri
|
740
|
-
# # => #<URI::HTTP:0x202281be URL:http://www.ruby-lang.org/>
|
741
|
-
# p uri.scheme
|
742
|
-
# # => "http"
|
743
|
-
# p uri.host
|
744
|
-
# # => "www.ruby-lang.org"
|
745
|
-
#
|
746
|
-
def self.parse(uri)
|
747
|
-
DEFAULT_PARSER.parse(uri)
|
748
|
-
end
|
749
|
-
|
750
|
-
#
|
751
|
-
# == Synopsis
|
752
|
-
#
|
753
|
-
# URI::join(str[, str, ...])
|
754
|
-
#
|
755
|
-
# == Args
|
756
|
-
#
|
757
|
-
# +str+::
|
758
|
-
# String(s) to work with
|
759
|
-
#
|
760
|
-
# == Description
|
761
|
-
#
|
762
|
-
# Joins URIs.
|
763
|
-
#
|
764
|
-
# == Usage
|
765
|
-
#
|
766
|
-
# require 'uri'
|
767
|
-
#
|
768
|
-
# p URI.join("http://example.com/","main.rbx")
|
769
|
-
# # => #<URI::HTTP:0x2022ac02 URL:http://localhost/main.rbx>
|
770
|
-
#
|
771
|
-
# p URI.join('http://example.com', 'foo')
|
772
|
-
# # => #<URI::HTTP:0x01ab80a0 URL:http://example.com/foo>
|
773
|
-
#
|
774
|
-
# p URI.join('http://example.com', '/foo', '/bar')
|
775
|
-
# # => #<URI::HTTP:0x01aaf0b0 URL:http://example.com/bar>
|
776
|
-
#
|
777
|
-
# p URI.join('http://example.com', '/foo', 'bar')
|
778
|
-
# # => #<URI::HTTP:0x801a92af0 URL:http://example.com/bar>
|
779
|
-
#
|
780
|
-
# p URI.join('http://example.com', '/foo/', 'bar')
|
781
|
-
# # => #<URI::HTTP:0x80135a3a0 URL:http://example.com/foo/bar>
|
782
|
-
#
|
783
|
-
#
|
784
|
-
def self.join(*str)
|
785
|
-
DEFAULT_PARSER.join(*str)
|
786
|
-
end
|
787
|
-
|
788
|
-
#
|
789
|
-
# == Synopsis
|
790
|
-
#
|
791
|
-
# URI::extract(str[, schemes][,&blk])
|
792
|
-
#
|
793
|
-
# == Args
|
794
|
-
#
|
795
|
-
# +str+::
|
796
|
-
# String to extract URIs from.
|
797
|
-
# +schemes+::
|
798
|
-
# Limit URI matching to a specific schemes.
|
799
|
-
#
|
800
|
-
# == Description
|
801
|
-
#
|
802
|
-
# Extracts URIs from a string. If block given, iterates through all matched URIs.
|
803
|
-
# Returns nil if block given or array with matches.
|
804
|
-
#
|
805
|
-
# == Usage
|
806
|
-
#
|
807
|
-
# require "uri"
|
808
|
-
#
|
809
|
-
# URI.extract("text here http://foo.example.org/bla and here mailto:test@example.com and here also.")
|
810
|
-
# # => ["http://foo.example.com/bla", "mailto:test@example.com"]
|
811
|
-
#
|
812
|
-
def self.extract(str, schemes = nil, &block)
|
813
|
-
DEFAULT_PARSER.extract(str, schemes, &block)
|
814
|
-
end
|
815
|
-
|
816
|
-
#
|
817
|
-
# == Synopsis
|
818
|
-
#
|
819
|
-
# URI::regexp([match_schemes])
|
820
|
-
#
|
821
|
-
# == Args
|
822
|
-
#
|
823
|
-
# +match_schemes+::
|
824
|
-
# Array of schemes. If given, resulting regexp matches to URIs
|
825
|
-
# whose scheme is one of the match_schemes.
|
826
|
-
#
|
827
|
-
# == Description
|
828
|
-
# Returns a Regexp object which matches to URI-like strings.
|
829
|
-
# The Regexp object returned by this method includes arbitrary
|
830
|
-
# number of capture group (parentheses). Never rely on it's number.
|
831
|
-
#
|
832
|
-
# == Usage
|
833
|
-
#
|
834
|
-
# require 'uri'
|
835
|
-
#
|
836
|
-
# # extract first URI from html_string
|
837
|
-
# html_string.slice(URI.regexp)
|
838
|
-
#
|
839
|
-
# # remove ftp URIs
|
840
|
-
# html_string.sub(URI.regexp(['ftp'])
|
841
|
-
#
|
842
|
-
# # You should not rely on the number of parentheses
|
843
|
-
# html_string.scan(URI.regexp) do |*matches|
|
844
|
-
# p $&
|
845
|
-
# end
|
846
|
-
#
|
847
|
-
def self.regexp(schemes = nil)
|
848
|
-
DEFAULT_PARSER.make_regexp(schemes)
|
849
|
-
end
|
850
|
-
|
851
|
-
TBLENCWWWCOMP_ = {} # :nodoc:
|
852
|
-
TBLDECWWWCOMP_ = {} # :nodoc:
|
853
|
-
HTML5ASCIIINCOMPAT = [Encoding::UTF_7, Encoding::UTF_16BE, Encoding::UTF_16LE,
|
854
|
-
Encoding::UTF_32BE, Encoding::UTF_32LE] # :nodoc:
|
855
|
-
|
856
|
-
# Encode given +str+ to URL-encoded form data.
|
857
|
-
#
|
858
|
-
# This method doesn't convert *, -, ., 0-9, A-Z, _, a-z, but does convert SP
|
859
|
-
# (ASCII space) to + and converts others to %XX.
|
860
|
-
#
|
861
|
-
# This is an implementation of
|
862
|
-
# http://www.w3.org/TR/html5/forms.html#url-encoded-form-data
|
863
|
-
#
|
864
|
-
# See URI.decode_www_form_component, URI.encode_www_form
|
865
|
-
def self.encode_www_form_component(str)
|
866
|
-
if TBLENCWWWCOMP_.empty?
|
867
|
-
tbl = {}
|
868
|
-
256.times do |i|
|
869
|
-
tbl[i.chr] = '%%%02X' % i
|
870
|
-
end
|
871
|
-
tbl[' '] = '+'
|
872
|
-
begin
|
873
|
-
TBLENCWWWCOMP_.replace(tbl)
|
874
|
-
TBLENCWWWCOMP_.freeze
|
875
|
-
rescue
|
876
|
-
end
|
877
|
-
end
|
878
|
-
str = str.to_s
|
879
|
-
if HTML5ASCIIINCOMPAT.include?(str.encoding)
|
880
|
-
str = str.encode(Encoding::UTF_8)
|
881
|
-
else
|
882
|
-
str = str.dup
|
883
|
-
end
|
884
|
-
str.force_encoding(Encoding::ASCII_8BIT)
|
885
|
-
str.gsub!(/[^*\-.0-9A-Z_a-z]/, TBLENCWWWCOMP_)
|
886
|
-
str.force_encoding(Encoding::US_ASCII)
|
887
|
-
end
|
888
|
-
|
889
|
-
# Decode given +str+ of URL-encoded form data.
|
890
|
-
#
|
891
|
-
# This decods + to SP.
|
892
|
-
#
|
893
|
-
# See URI.encode_www_form_component, URI.decode_www_form
|
894
|
-
def self.decode_www_form_component(str, enc=Encoding::UTF_8)
|
895
|
-
if TBLDECWWWCOMP_.empty?
|
896
|
-
tbl = {}
|
897
|
-
256.times do |i|
|
898
|
-
h, l = i>>4, i&15
|
899
|
-
tbl['%%%X%X' % [h, l]] = i.chr
|
900
|
-
tbl['%%%x%X' % [h, l]] = i.chr
|
901
|
-
tbl['%%%X%x' % [h, l]] = i.chr
|
902
|
-
tbl['%%%x%x' % [h, l]] = i.chr
|
903
|
-
end
|
904
|
-
tbl['+'] = ' '
|
905
|
-
begin
|
906
|
-
TBLDECWWWCOMP_.replace(tbl)
|
907
|
-
TBLDECWWWCOMP_.freeze
|
908
|
-
rescue
|
909
|
-
end
|
910
|
-
end
|
911
|
-
raise ArgumentError, "invalid %-encoding (#{str})" unless /\A[^%]*(?:%\h\h[^%]*)*\z/ =~ str
|
912
|
-
str.gsub(/\+|%\h\h/, TBLDECWWWCOMP_).force_encoding(enc)
|
913
|
-
end
|
914
|
-
|
915
|
-
# Generate URL-encoded form data from given +enum+.
|
916
|
-
#
|
917
|
-
# This generates application/x-www-form-urlencoded data defined in HTML5
|
918
|
-
# from given an Enumerable object.
|
919
|
-
#
|
920
|
-
# This internally uses URI.encode_www_form_component(str).
|
921
|
-
#
|
922
|
-
# This method doesn't convert the encoding of given items, so convert them
|
923
|
-
# before call this method if you want to send data as other than original
|
924
|
-
# encoding or mixed encoding data. (Strings which are encoded in an HTML5
|
925
|
-
# ASCII incompatible encoding are converted to UTF-8.)
|
926
|
-
#
|
927
|
-
# This method doesn't handle files. When you send a file, use
|
928
|
-
# multipart/form-data.
|
929
|
-
#
|
930
|
-
# This is an implementation of
|
931
|
-
# http://www.w3.org/TR/html5/forms.html#url-encoded-form-data
|
932
|
-
#
|
933
|
-
# URI.encode_www_form([["q", "ruby"], ["lang", "en"]])
|
934
|
-
# #=> "q=ruby&lang=en"
|
935
|
-
# URI.encode_www_form("q" => "ruby", "lang" => "en")
|
936
|
-
# #=> "q=ruby&lang=en"
|
937
|
-
# URI.encode_www_form("q" => ["ruby", "perl"], "lang" => "en")
|
938
|
-
# #=> "q=ruby&q=perl&lang=en"
|
939
|
-
# URI.encode_www_form([["q", "ruby"], ["q", "perl"], ["lang", "en"]])
|
940
|
-
# #=> "q=ruby&q=perl&lang=en"
|
941
|
-
#
|
942
|
-
# See URI.encode_www_form_component, URI.decode_www_form
|
943
|
-
def self.encode_www_form(enum)
|
944
|
-
enum.map do |k,v|
|
945
|
-
if v.nil?
|
946
|
-
encode_www_form_component(k)
|
947
|
-
elsif v.respond_to?(:to_ary)
|
948
|
-
v.to_ary.map do |w|
|
949
|
-
str = encode_www_form_component(k)
|
950
|
-
unless w.nil?
|
951
|
-
str << '='
|
952
|
-
str << encode_www_form_component(w)
|
953
|
-
end
|
954
|
-
end.join('&')
|
955
|
-
else
|
956
|
-
str = encode_www_form_component(k)
|
957
|
-
str << '='
|
958
|
-
str << encode_www_form_component(v)
|
959
|
-
end
|
960
|
-
end.join('&')
|
961
|
-
end
|
962
|
-
|
963
|
-
WFKV_ = '(?:[^%#=;&]*(?:%\h\h[^%#=;&]*)*)' # :nodoc:
|
964
|
-
|
965
|
-
# Decode URL-encoded form data from given +str+.
|
966
|
-
#
|
967
|
-
# This decodes application/x-www-form-urlencoded data
|
968
|
-
# and returns array of key-value array.
|
969
|
-
# This internally uses URI.decode_www_form_component.
|
970
|
-
#
|
971
|
-
# _charset_ hack is not supported now because the mapping from given charset
|
972
|
-
# to Ruby's encoding is not clear yet.
|
973
|
-
# see also http://www.w3.org/TR/html5/syntax.html#character-encodings-0
|
974
|
-
#
|
975
|
-
# This refers http://www.w3.org/TR/html5/forms.html#url-encoded-form-data
|
976
|
-
#
|
977
|
-
# ary = URI.decode_www_form("a=1&a=2&b=3")
|
978
|
-
# p ary #=> [['a', '1'], ['a', '2'], ['b', '3']]
|
979
|
-
# p ary.assoc('a').last #=> '1'
|
980
|
-
# p ary.assoc('b').last #=> '3'
|
981
|
-
# p ary.rassoc('a').last #=> '2'
|
982
|
-
# p Hash[ary] # => {"a"=>"2", "b"=>"3"}
|
983
|
-
#
|
984
|
-
# See URI.decode_www_form_component, URI.encode_www_form
|
985
|
-
def self.decode_www_form(str, enc=Encoding::UTF_8)
|
986
|
-
return [] if str.empty?
|
987
|
-
unless /\A#{WFKV_}=#{WFKV_}(?:[;&]#{WFKV_}=#{WFKV_})*\z/o =~ str
|
988
|
-
raise ArgumentError, "invalid data of application/x-www-form-urlencoded (#{str})"
|
989
|
-
end
|
990
|
-
ary = []
|
991
|
-
$&.scan(/([^=;&]+)=([^;&]*)/) do
|
992
|
-
ary << [decode_www_form_component($1, enc), decode_www_form_component($2, enc)]
|
993
|
-
end
|
994
|
-
ary
|
995
|
-
end
|
996
|
-
end # module URI
|
997
|
-
|
998
|
-
module Kernel
|
999
|
-
|
1000
|
-
#
|
1001
|
-
# Returns +uri+ converted to a URI object.
|
1002
|
-
#
|
1003
|
-
def URI(uri)
|
1004
|
-
if uri.is_a?(URI::Generic)
|
1005
|
-
uri
|
1006
|
-
elsif uri = String.try_convert(uri)
|
1007
|
-
URI.parse(uri)
|
1008
|
-
else
|
1009
|
-
raise ArgumentError,
|
1010
|
-
"bad argument (expected URI object or URI string)"
|
1011
|
-
end
|
1012
|
-
end
|
1013
|
-
module_function :URI
|
1014
|
-
end
|