proxy_pac_rb 0.0.2 → 0.0.3
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/.rdebugrc +7 -0
- data/.rspec +3 -0
- data/.simplecov +8 -0
- data/.yardopts +5 -0
- data/README.md +12 -0
- data/files/sample2.pac +7 -0
- data/files/sample3.pac +7 -0
- data/lib/proxy_pac_rb.rb +8 -28
- data/lib/proxy_pac_rb/encoding.rb +33 -0
- data/lib/proxy_pac_rb/environment.rb +203 -0
- data/lib/proxy_pac_rb/exceptions.rb +3 -0
- data/lib/proxy_pac_rb/file.rb +11 -7
- data/lib/proxy_pac_rb/parser.rb +45 -0
- data/lib/proxy_pac_rb/proxy_pac_js.rb +194 -0
- data/lib/proxy_pac_rb/runtime.rb +61 -0
- data/lib/proxy_pac_rb/runtimes.rb +16 -7
- data/lib/proxy_pac_rb/runtimes/rubyracer.rb +74 -58
- data/lib/proxy_pac_rb/runtimes/rubyrhino.rb +68 -58
- data/lib/proxy_pac_rb/version.rb +1 -1
- data/proxy_pac_rb.gemspec +3 -0
- data/script/acceptance_test +4 -0
- data/script/bootstrap +5 -0
- data/script/ci +3 -0
- data/script/console +14 -0
- data/script/release +3 -0
- data/script/unit_test +3 -0
- data/spec/environment_spec.rb +193 -0
- data/spec/file_spec.rb +45 -0
- data/spec/parser_spec.rb +116 -0
- data/tmp/functions.js +61 -0
- data/tmp/functions.rb +11 -0
- data/tmp/script.rb +22 -0
- metadata +61 -14
- data/lib/proxy_pac_rb/functions.rb +0 -128
- data/spec/proxy_pac_rb/functions_spec.rb +0 -18
- data/spec/proxy_pac_rb_spec.rb +0 -112
@@ -0,0 +1,194 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module ProxyPacRb
|
3
|
+
class ProxyPacJs
|
4
|
+
class << self
|
5
|
+
def my_ip_address_template(value)
|
6
|
+
<<-EOS.strip_heredoc
|
7
|
+
function MyIpAddress() {
|
8
|
+
return "#{value}";
|
9
|
+
}
|
10
|
+
EOS
|
11
|
+
end
|
12
|
+
|
13
|
+
|
14
|
+
# taken from releases-mozilla-release / netwerk / base / src / ProxyAutoConfig.cpp @ bitbucket.org
|
15
|
+
# https://bitbucket.org/mozilla/releases-mozilla-release/raw/dece38633cf1adcab2071d69fea264580d24cc9e/netwerk/base/src/ProxyAutoConfig.cpp
|
16
|
+
def time_variables
|
17
|
+
<<-EOS.strip_heredoc
|
18
|
+
var wdays = {SUN: 0, MON: 1, TUE: 2, WED: 3, THU: 4, FRI: 5, SAT: 6};
|
19
|
+
var months = {JAN: 0, FEB: 1, MAR: 2, APR: 3, MAY: 4, JUN: 5, JUL: 6, AUG: 7, SEP: 8, OCT: 9, NOV: 10, DEC: 11};
|
20
|
+
EOS
|
21
|
+
end
|
22
|
+
|
23
|
+
def week_day_range_template(value = nil)
|
24
|
+
value = %Q{"#{value}"} if value
|
25
|
+
|
26
|
+
<<-EOS.strip_heredoc
|
27
|
+
function weekdayRange() {
|
28
|
+
function getDay(weekday) {
|
29
|
+
if (weekday in wdays) {
|
30
|
+
return wdays[weekday];
|
31
|
+
}
|
32
|
+
return -1;
|
33
|
+
}
|
34
|
+
var date = new Date(#{value});
|
35
|
+
var argc = arguments.length;
|
36
|
+
var wday;
|
37
|
+
if (argc < 1)
|
38
|
+
return false;
|
39
|
+
if (arguments[argc - 1] == 'GMT') {
|
40
|
+
argc--;
|
41
|
+
wday = date.getUTCDay();
|
42
|
+
} else {
|
43
|
+
wday = date.getDay();
|
44
|
+
}
|
45
|
+
var wd1 = getDay(arguments[0]);
|
46
|
+
var wd2 = (argc == 2) ? getDay(arguments[1]) : wd1;
|
47
|
+
return (wd1 == -1 || wd2 == -1) ? false
|
48
|
+
: (wd1 <= wday && wday <= wd2);
|
49
|
+
}
|
50
|
+
EOS
|
51
|
+
end
|
52
|
+
|
53
|
+
def date_range_template(value = nil)
|
54
|
+
value = %Q{"#{value}"} if value
|
55
|
+
|
56
|
+
<<-EOS.strip_heredoc
|
57
|
+
function dateRange() {
|
58
|
+
function getMonth(name) {
|
59
|
+
if (name in months) {
|
60
|
+
return months[name];
|
61
|
+
}
|
62
|
+
return -1;
|
63
|
+
}
|
64
|
+
var date = new Date(#{value});
|
65
|
+
var argc = arguments.length;
|
66
|
+
if (argc < 1) {
|
67
|
+
return false;
|
68
|
+
}
|
69
|
+
var isGMT = (arguments[argc - 1] == 'GMT');
|
70
|
+
|
71
|
+
if (isGMT) {
|
72
|
+
argc--;
|
73
|
+
}
|
74
|
+
// function will work even without explict handling of this case
|
75
|
+
if (argc == 1) {
|
76
|
+
var tmp = parseInt(arguments[0]);
|
77
|
+
if (isNaN(tmp)) {
|
78
|
+
return ((isGMT ? date.getUTCMonth() : date.getMonth()) ==
|
79
|
+
getMonth(arguments[0]));
|
80
|
+
} else if (tmp < 32) {
|
81
|
+
return ((isGMT ? date.getUTCDate() : date.getDate()) == tmp);
|
82
|
+
} else {
|
83
|
+
return ((isGMT ? date.getUTCFullYear() : date.getFullYear()) ==
|
84
|
+
tmp);
|
85
|
+
}
|
86
|
+
}
|
87
|
+
var year = date.getFullYear();
|
88
|
+
var date1, date2;
|
89
|
+
date1 = new Date(year, 0, 1, 0, 0, 0);
|
90
|
+
date2 = new Date(year, 11, 31, 23, 59, 59);
|
91
|
+
var adjustMonth = false;
|
92
|
+
for (var i = 0; i < (argc >> 1); i++) {
|
93
|
+
var tmp = parseInt(arguments[i]);
|
94
|
+
if (isNaN(tmp)) {
|
95
|
+
var mon = getMonth(arguments[i]);
|
96
|
+
date1.setMonth(mon);
|
97
|
+
} else if (tmp < 32) {
|
98
|
+
adjustMonth = (argc <= 2);
|
99
|
+
date1.setDate(tmp);
|
100
|
+
} else {
|
101
|
+
date1.setFullYear(tmp);
|
102
|
+
}
|
103
|
+
}
|
104
|
+
for (var i = (argc >> 1); i < argc; i++) {
|
105
|
+
var tmp = parseInt(arguments[i]);
|
106
|
+
if (isNaN(tmp)) {
|
107
|
+
var mon = getMonth(arguments[i]);
|
108
|
+
date2.setMonth(mon);
|
109
|
+
} else if (tmp < 32) {
|
110
|
+
date2.setDate(tmp);
|
111
|
+
} else {
|
112
|
+
date2.setFullYear(tmp);
|
113
|
+
}
|
114
|
+
}
|
115
|
+
if (adjustMonth) {
|
116
|
+
date1.setMonth(date.getMonth());
|
117
|
+
date2.setMonth(date.getMonth());
|
118
|
+
}
|
119
|
+
if (isGMT) {
|
120
|
+
var tmp = date;
|
121
|
+
tmp.setFullYear(date.getUTCFullYear());
|
122
|
+
tmp.setMonth(date.getUTCMonth());
|
123
|
+
tmp.setDate(date.getUTCDate());
|
124
|
+
tmp.setHours(date.getUTCHours());
|
125
|
+
tmp.setMinutes(date.getUTCMinutes());
|
126
|
+
tmp.setSeconds(date.getUTCSeconds());
|
127
|
+
date = tmp;
|
128
|
+
}
|
129
|
+
return ((date1 <= date) && (date <= date2));
|
130
|
+
}
|
131
|
+
EOS
|
132
|
+
end
|
133
|
+
|
134
|
+
def time_range_template(value = nil)
|
135
|
+
value = %Q{"#{value}"} if value
|
136
|
+
|
137
|
+
<<-EOS.strip_heredoc
|
138
|
+
function timeRange() {
|
139
|
+
var argc = arguments.length;
|
140
|
+
var date = new Date(#{value});
|
141
|
+
var isGMT= false;
|
142
|
+
|
143
|
+
if (argc < 1) {
|
144
|
+
return false;
|
145
|
+
}
|
146
|
+
if (arguments[argc - 1] == 'GMT') {
|
147
|
+
isGMT = true;
|
148
|
+
argc--;
|
149
|
+
}
|
150
|
+
|
151
|
+
var hour = isGMT ? date.getUTCHours() : date.getHours();
|
152
|
+
var date1, date2;
|
153
|
+
date1 = new Date();
|
154
|
+
date2 = new Date();
|
155
|
+
|
156
|
+
if (argc == 1) {
|
157
|
+
return (hour == arguments[0]);
|
158
|
+
} else if (argc == 2) {
|
159
|
+
return ((arguments[0] <= hour) && (hour <= arguments[1]));
|
160
|
+
} else {
|
161
|
+
switch (argc) {
|
162
|
+
case 6:
|
163
|
+
date1.setSeconds(arguments[2]);
|
164
|
+
date2.setSeconds(arguments[5]);
|
165
|
+
case 4:
|
166
|
+
var middle = argc >> 1;
|
167
|
+
date1.setHours(arguments[0]);
|
168
|
+
date1.setMinutes(arguments[1]);
|
169
|
+
date2.setHours(arguments[middle]);
|
170
|
+
date2.setMinutes(arguments[middle + 1]);
|
171
|
+
if (middle == 2) {
|
172
|
+
date2.setSeconds(59);
|
173
|
+
}
|
174
|
+
break;
|
175
|
+
default:
|
176
|
+
throw 'timeRange: bad number of arguments'
|
177
|
+
}
|
178
|
+
}
|
179
|
+
|
180
|
+
if (isGMT) {
|
181
|
+
date.setFullYear(date.getUTCFullYear());
|
182
|
+
date.setMonth(date.getUTCMonth());
|
183
|
+
date.setDate(date.getUTCDate());
|
184
|
+
date.setHours(date.getUTCHours());
|
185
|
+
date.setMinutes(date.getUTCMinutes());
|
186
|
+
date.setSeconds(date.getUTCSeconds());
|
187
|
+
}
|
188
|
+
return ((date1 <= date) && (date <= date2));
|
189
|
+
}
|
190
|
+
EOS
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
194
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module ProxyPacRb
|
2
|
+
# Abstract base class for runtimes
|
3
|
+
class Runtime
|
4
|
+
class Context
|
5
|
+
include Encoding
|
6
|
+
|
7
|
+
attr_accessor :context
|
8
|
+
|
9
|
+
def include(environment)
|
10
|
+
environment.available_methods.each do |name|
|
11
|
+
context[name] = environment.method(name)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def initialize(runtime, source = "")
|
16
|
+
end
|
17
|
+
|
18
|
+
def exec(source, options = {})
|
19
|
+
fail NotImplementedError
|
20
|
+
end
|
21
|
+
|
22
|
+
def eval(source, options = {})
|
23
|
+
fail NotImplementedError
|
24
|
+
end
|
25
|
+
|
26
|
+
def call(properties, *args)
|
27
|
+
fail NotImplementedError
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def name
|
32
|
+
fail NotImplementedError
|
33
|
+
end
|
34
|
+
|
35
|
+
def context_class
|
36
|
+
self.class::Context
|
37
|
+
end
|
38
|
+
|
39
|
+
def exec(source)
|
40
|
+
context = context_class.new(self)
|
41
|
+
context.exec(source)
|
42
|
+
end
|
43
|
+
|
44
|
+
def eval(source)
|
45
|
+
context = context_class.new(self)
|
46
|
+
context.eval(source)
|
47
|
+
end
|
48
|
+
|
49
|
+
def compile(source)
|
50
|
+
context_class.new(self, source)
|
51
|
+
end
|
52
|
+
|
53
|
+
def deprecated?
|
54
|
+
false
|
55
|
+
end
|
56
|
+
|
57
|
+
def available?
|
58
|
+
fail NotImplementedError
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -5,7 +5,13 @@ module ProxyPacRb
|
|
5
5
|
|
6
6
|
class << self
|
7
7
|
def autodetect
|
8
|
-
from_environment || best_available ||
|
8
|
+
from_environment || best_available ||
|
9
|
+
fail(Exceptions::RuntimeUnavailable, "Could not find a JavaScript runtime. " +
|
10
|
+
"See https://github.com/sstephenson/execjs for a list of available runtimes.")
|
11
|
+
end
|
12
|
+
|
13
|
+
def best_available
|
14
|
+
runtimes.reject(&:deprecated?).find(&:available?)
|
9
15
|
end
|
10
16
|
|
11
17
|
def from_environment
|
@@ -22,17 +28,20 @@ module ProxyPacRb
|
|
22
28
|
end
|
23
29
|
end
|
24
30
|
|
25
|
-
def
|
26
|
-
|
31
|
+
def names
|
32
|
+
@names ||= constants.inject({}) { |h, name| h.merge(const_get(name) => name) }.values
|
27
33
|
end
|
28
34
|
|
29
35
|
def runtimes
|
30
|
-
@runtimes ||= [
|
36
|
+
@runtimes ||= [
|
37
|
+
RubyRacer,
|
38
|
+
RubyRhino,
|
39
|
+
]
|
31
40
|
end
|
32
41
|
end
|
33
|
-
end
|
34
42
|
|
35
|
-
|
36
|
-
|
43
|
+
def runtimes
|
44
|
+
Runtimes.runtimes
|
45
|
+
end
|
37
46
|
end
|
38
47
|
end
|
@@ -1,87 +1,103 @@
|
|
1
1
|
module ProxyPacRb
|
2
|
-
|
3
|
-
class
|
4
|
-
|
5
|
-
|
6
|
-
source = source.encode("UTF-8") if source.respond_to?(:encode)
|
2
|
+
class RubyRacerRuntime < Runtime
|
3
|
+
class Context < Runtime::Context
|
4
|
+
def initialize(runtime, source = "", environment = nil)
|
5
|
+
source = encode(source)
|
7
6
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
end
|
7
|
+
lock do
|
8
|
+
self.context = ::V8::Context.new
|
9
|
+
context.eval(source)
|
12
10
|
end
|
11
|
+
end
|
13
12
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
13
|
+
def exec(source, options = {})
|
14
|
+
source = encode(source)
|
15
|
+
|
16
|
+
if /\S/ =~ source
|
17
|
+
eval "(function(){#{source}})()", options
|
18
18
|
end
|
19
|
+
end
|
19
20
|
|
20
|
-
|
21
|
+
def eval(source, options = {})
|
22
|
+
source = encode(source)
|
23
|
+
|
24
|
+
if /\S/ =~ source
|
21
25
|
lock do
|
22
26
|
begin
|
23
|
-
unbox
|
27
|
+
unbox context.eval("(#{source})")
|
24
28
|
rescue ::V8::JSError => e
|
25
29
|
if e.value["name"] == "SyntaxError"
|
26
|
-
|
30
|
+
fail RuntimeError, e.value.to_s
|
27
31
|
else
|
28
|
-
raise Exceptions::ProgramError, e.
|
32
|
+
raise Exceptions::ProgramError, e.value.to_s
|
29
33
|
end
|
30
34
|
end
|
31
35
|
end
|
32
36
|
end
|
37
|
+
end
|
33
38
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
value
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
vs
|
39
|
+
def call(properties, *args)
|
40
|
+
lock do
|
41
|
+
begin
|
42
|
+
unbox context.eval(properties).call(*args)
|
43
|
+
rescue ::V8::JSError => e
|
44
|
+
if e.value["name"] == "SyntaxError"
|
45
|
+
raise RuntimeError, e.value.to_s
|
46
|
+
else
|
47
|
+
raise Exceptions::ProgramError, e.value.to_s
|
44
48
|
end
|
45
|
-
when String
|
46
|
-
value.respond_to?(:force_encoding) ? value.force_encoding("UTF-8") : value
|
47
|
-
else
|
48
|
-
value
|
49
49
|
end
|
50
50
|
end
|
51
|
+
end
|
51
52
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
53
|
+
def unbox(value)
|
54
|
+
case value
|
55
|
+
when ::V8::Function
|
56
|
+
nil
|
57
|
+
when ::V8::Array
|
58
|
+
value.map { |v| unbox(v) }
|
59
|
+
when ::V8::Object
|
60
|
+
value.inject({}) do |vs, (k, v)|
|
61
|
+
vs[k] = unbox(v) unless v.is_a?(::V8::Function)
|
62
|
+
vs
|
63
|
+
end
|
64
|
+
when String
|
65
|
+
value.respond_to?(:force_encoding) ?
|
66
|
+
value.force_encoding('UTF-8') :
|
67
|
+
value
|
68
|
+
else
|
69
|
+
value
|
70
|
+
end
|
71
|
+
end
|
62
72
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
73
|
+
private
|
74
|
+
def lock
|
75
|
+
result, exception = nil, nil
|
76
|
+
V8::C::Locker() do
|
77
|
+
begin
|
78
|
+
result = yield
|
79
|
+
rescue Exception => e
|
80
|
+
exception = e
|
67
81
|
end
|
68
82
|
end
|
69
|
-
end
|
70
83
|
|
71
|
-
|
72
|
-
|
73
|
-
|
84
|
+
if exception
|
85
|
+
raise exception
|
86
|
+
else
|
87
|
+
result
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
74
91
|
|
75
|
-
|
76
|
-
|
77
|
-
|
92
|
+
def name
|
93
|
+
"therubyracer (V8)"
|
94
|
+
end
|
78
95
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
end
|
96
|
+
def available?
|
97
|
+
require "v8"
|
98
|
+
true
|
99
|
+
rescue LoadError
|
100
|
+
false
|
85
101
|
end
|
86
102
|
end
|
87
103
|
end
|