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
@@ -1,77 +1,87 @@
|
|
1
1
|
module ProxyPacRb
|
2
|
-
|
3
|
-
class
|
4
|
-
|
5
|
-
|
6
|
-
source = source.encode("UTF-8") if source.respond_to?(:encode)
|
2
|
+
class RubyRhinoRuntime < Runtime
|
3
|
+
class Context < Runtime::Context
|
4
|
+
def initialize(runtime, source = "")
|
5
|
+
source = encode(source)
|
7
6
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
7
|
+
self.context = ::Rhino::Context.new
|
8
|
+
fix_memory_limit! context
|
9
|
+
context.eval(source)
|
10
|
+
end
|
12
11
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
12
|
+
def exec(source, options = {})
|
13
|
+
source = encode(source)
|
14
|
+
|
15
|
+
if /\S/ =~ source
|
16
|
+
eval "(function(){#{source}})()", options
|
17
17
|
end
|
18
|
+
end
|
18
19
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
20
|
+
def eval(source, options = {})
|
21
|
+
source = encode(source)
|
22
|
+
|
23
|
+
if /\S/ =~ source
|
24
|
+
unbox context.eval("(#{source})")
|
25
|
+
end
|
26
|
+
rescue ::Rhino::JSError => e
|
27
|
+
if e.message =~ /^syntax error/
|
28
|
+
raise RuntimeError, e.message
|
29
|
+
else
|
30
|
+
raise Exceptions::ProgramError, e.message
|
27
31
|
end
|
32
|
+
end
|
28
33
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
when ::Rhino::NativeFunction, ::Rhino::J::Function
|
37
|
-
nil
|
38
|
-
else
|
39
|
-
vs[k] = unbox(v)
|
40
|
-
end
|
41
|
-
vs
|
42
|
-
end
|
43
|
-
when Array
|
44
|
-
value.map { |v| unbox(v) }
|
45
|
-
else
|
46
|
-
value
|
47
|
-
end
|
34
|
+
def call(properties, *args)
|
35
|
+
unbox context.eval(properties).call(*args)
|
36
|
+
rescue ::Rhino::JSError => e
|
37
|
+
if e.message == "syntax error"
|
38
|
+
raise RuntimeError, e.message
|
39
|
+
else
|
40
|
+
raise Exceptions::ProgramError, e.message
|
48
41
|
end
|
42
|
+
end
|
49
43
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
44
|
+
def unbox(value)
|
45
|
+
case value = ::Rhino::to_ruby(value)
|
46
|
+
when Java::OrgMozillaJavascript::NativeFunction
|
47
|
+
nil
|
48
|
+
when Java::OrgMozillaJavascript::NativeObject
|
49
|
+
value.inject({}) do |vs, (k, v)|
|
50
|
+
case v
|
51
|
+
when Java::OrgMozillaJavascript::NativeFunction, ::Rhino::JS::Function
|
52
|
+
nil
|
55
53
|
else
|
56
|
-
|
54
|
+
vs[k] = unbox(v)
|
57
55
|
end
|
56
|
+
vs
|
58
57
|
end
|
58
|
+
when Array
|
59
|
+
value.map { |v| unbox(v) }
|
60
|
+
else
|
61
|
+
value
|
62
|
+
end
|
59
63
|
end
|
60
64
|
|
61
|
-
|
62
|
-
|
63
|
-
|
65
|
+
private
|
66
|
+
# Disables bytecode compiling which limits you to 64K scripts
|
67
|
+
def fix_memory_limit!(cxt)
|
68
|
+
if cxt.respond_to?(:optimization_level=)
|
69
|
+
cxt.optimization_level = -1
|
70
|
+
else
|
71
|
+
cxt.instance_eval { @native.setOptimizationLevel(-1) }
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
64
75
|
|
65
|
-
|
66
|
-
|
67
|
-
|
76
|
+
def name
|
77
|
+
"therubyrhino (Rhino)"
|
78
|
+
end
|
68
79
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
end
|
80
|
+
def available?
|
81
|
+
require "rhino"
|
82
|
+
true
|
83
|
+
rescue LoadError
|
84
|
+
false
|
75
85
|
end
|
76
86
|
end
|
77
87
|
end
|
data/lib/proxy_pac_rb/version.rb
CHANGED
data/proxy_pac_rb.gemspec
CHANGED
@@ -23,4 +23,7 @@ DESC
|
|
23
23
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| ::File.basename(f) }
|
24
24
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
25
25
|
spec.require_paths = ['lib']
|
26
|
+
|
27
|
+
spec.add_runtime_dependency 'addressable'
|
28
|
+
spec.add_runtime_dependency 'activesupport'
|
26
29
|
end
|
data/script/bootstrap
ADDED
data/script/ci
ADDED
data/script/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
$LOAD_PATH << ::File.expand_path('../../lib', __FILE__)
|
4
|
+
|
5
|
+
# Pull in all of the gems including those in the `test` group
|
6
|
+
require 'bundler'
|
7
|
+
Bundler.require :default, :test, :development, :therubyracer
|
8
|
+
|
9
|
+
require 'irb'
|
10
|
+
require 'irb/completion'
|
11
|
+
require 'proxy_pac_rb'
|
12
|
+
|
13
|
+
ARGV.clear
|
14
|
+
IRB.start
|
data/script/release
ADDED
data/script/unit_test
ADDED
@@ -0,0 +1,193 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe ProxyPacRb::Environment do
|
5
|
+
let(:environment) do
|
6
|
+
Environment.new(my_ip_address: '127.0.0.1', time: Time.now)
|
7
|
+
end
|
8
|
+
|
9
|
+
describe "#isResolvable()" do
|
10
|
+
it "should return true for localhost" do
|
11
|
+
expect(environment.isResolvable("localhost")).to be_true
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should return false for awidhaowuhuiuhiuug" do
|
15
|
+
expect(environment.isResolvable('asdfasdfasdfasdf')).to be_false
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe '#isPlainHostName' do
|
20
|
+
it 'returns true for google' do
|
21
|
+
result = environment.isPlainHostName('google')
|
22
|
+
expect(result).to be_true
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'returns false for google.com' do
|
26
|
+
result = environment.isPlainHostName('google.com')
|
27
|
+
expect(result).to be_false
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe '#dnsDomainIs' do
|
32
|
+
it 'returns true for maps.google.com' do
|
33
|
+
result = environment.dnsDomainIs('maps.google.com', '.google.com')
|
34
|
+
expect(result).to be_true
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'returns false for maps.ms.com' do
|
38
|
+
result = environment.dnsDomainIs('maps.ms.com', '.google.com')
|
39
|
+
expect(result).to be_false
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe '#localHostOrDomainIs' do
|
44
|
+
it 'returns true for maps.google.com' do
|
45
|
+
result = environment.localHostOrDomainIs('maps.google.com', 'maps.google.com')
|
46
|
+
expect(result).to be_true
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'returns true for maps' do
|
50
|
+
result = environment.localHostOrDomainIs('maps', 'maps.google.com')
|
51
|
+
expect(result).to be_true
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'returns false for maps.ms.com' do
|
55
|
+
result = environment.dnsDomainIs('maps.ms.com', '.google.com')
|
56
|
+
expect(result).to be_false
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
describe '#isInNet' do
|
61
|
+
it 'returns true for 127.0.0.1' do
|
62
|
+
result = environment.isInNet('127.0.0.1', '127.0.0.0', '255.255.255.0')
|
63
|
+
expect(result).to be_true
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'returns false for 10.0.0.1' do
|
67
|
+
result = environment.isInNet('10.0.0.1', '127.0.0.0', '255.255.255.0')
|
68
|
+
expect(result).to be_false
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
describe '#dnsResolve' do
|
73
|
+
it 'returns the ip address for domain' do
|
74
|
+
ip = '8.8.8.8'
|
75
|
+
name = 'google-public-dns-a.google.com'
|
76
|
+
expect(environment.dnsResolve(name)).to eq(ip)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
describe '#MyIpAddress ' do
|
81
|
+
it 'returns the given ip address' do
|
82
|
+
ip = '127.0.0.1'
|
83
|
+
environment = Environment.new(my_ip_address: ip, time: Time.now)
|
84
|
+
|
85
|
+
expect(environment.MyIpAddress).to eq(ip)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
describe '#dnsDomainLevels' do
|
90
|
+
it 'returns the count of domain levels (dots)' do
|
91
|
+
result = environment.dnsDomainLevels('maps.google.com')
|
92
|
+
expect(result).to eq(2)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
describe '#shExpMatch' do
|
97
|
+
it 'returns true for maps.google.com' do
|
98
|
+
result = environment.shExpMatch('maps.google.com', '*.com')
|
99
|
+
expect(result).to be_true
|
100
|
+
end
|
101
|
+
|
102
|
+
it 'returns false for maps.ms.com' do
|
103
|
+
result = environment.shExpMatch('maps.ms.com', '*.de')
|
104
|
+
expect(result).to be_false
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
describe '#weekdayRange' do
|
109
|
+
let(:environment) { Environment.new(my_ip_address: '127.0.0.1', time: Time.parse('1991-08-25 12:00')) }
|
110
|
+
|
111
|
+
it 'returns true for SUN - MON' do
|
112
|
+
result = environment.weekdayRange("SUN", "MON")
|
113
|
+
expect(result).to be_true
|
114
|
+
end
|
115
|
+
|
116
|
+
it 'returns false for FR' do
|
117
|
+
result = environment.weekdayRange("FRI")
|
118
|
+
expect(result).to be_false
|
119
|
+
end
|
120
|
+
|
121
|
+
it 'fails if wd1 or wd2 are not valid, e.g. German SO for Sunday' do
|
122
|
+
expect {
|
123
|
+
environment.weekdayRange("SO")
|
124
|
+
}.to raise_error Exceptions::InvalidArgument
|
125
|
+
end
|
126
|
+
|
127
|
+
end
|
128
|
+
|
129
|
+
describe '#dateRange' do
|
130
|
+
let(:environment) { Environment.new(my_ip_address: '127.0.0.1', time: Time.parse('1991-08-25 12:00')) }
|
131
|
+
|
132
|
+
it 'returns true for JUL - SEP' do
|
133
|
+
result = environment.dateRange("JUL", "SEP")
|
134
|
+
expect(result).to be_true
|
135
|
+
end
|
136
|
+
|
137
|
+
it 'returns false for MAR' do
|
138
|
+
result = environment.dateRange("MAR")
|
139
|
+
expect(result).to be_false
|
140
|
+
end
|
141
|
+
|
142
|
+
it 'fails if range is not valid' do
|
143
|
+
expect {
|
144
|
+
environment.dateRange("SEPT")
|
145
|
+
}.to raise_error Exceptions::InvalidArgument
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
describe '#timeRange' do
|
150
|
+
let(:environment) { Environment.new(my_ip_address: '127.0.0.1', time: Time.parse('1991-08-25 12:00')) }
|
151
|
+
|
152
|
+
it 'returns true for 8 - 18h' do
|
153
|
+
result = environment.timeRange(8, 18)
|
154
|
+
expect(result).to be_true
|
155
|
+
end
|
156
|
+
|
157
|
+
it 'returns false for MAR' do
|
158
|
+
result = environment.timeRange(13,14)
|
159
|
+
expect(result).to be_false
|
160
|
+
end
|
161
|
+
|
162
|
+
it 'fails if range is not valid' do
|
163
|
+
expect {
|
164
|
+
environment.timeRange("SEPT")
|
165
|
+
}.to raise_error Exceptions::InvalidArgument
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
describe '#alert' do
|
170
|
+
it 'outputs msg' do
|
171
|
+
result = capture(:stderr) do
|
172
|
+
environment.alert('message')
|
173
|
+
end
|
174
|
+
|
175
|
+
expect(result.chomp).to eq('message')
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
describe '#prepare' do
|
180
|
+
it 'adds neccessary functions to source file' do
|
181
|
+
string = ''
|
182
|
+
environment.prepare(string)
|
183
|
+
|
184
|
+
%w[
|
185
|
+
MyIpAddress
|
186
|
+
weekdayRange
|
187
|
+
dateRange
|
188
|
+
timeRange
|
189
|
+
].each { |f| expect(string).to include(f) }
|
190
|
+
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
data/spec/file_spec.rb
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe File do
|
5
|
+
let(:simple) do
|
6
|
+
<<-EOS.strip_heredoc
|
7
|
+
function FindProxyForURL(url, host) {
|
8
|
+
return "DIRECT";
|
9
|
+
}
|
10
|
+
EOS
|
11
|
+
end
|
12
|
+
|
13
|
+
let(:client_ip_pac) do
|
14
|
+
<<-EOS.strip_heredoc
|
15
|
+
function FindProxyForURL(url, host) {
|
16
|
+
if ( MyIpAddress() == '127.0.0.2' ) {
|
17
|
+
return "DIRECT";
|
18
|
+
} else {
|
19
|
+
return "PROXY localhost:8080";
|
20
|
+
}
|
21
|
+
}
|
22
|
+
EOS
|
23
|
+
end
|
24
|
+
|
25
|
+
let(:time_pac) do
|
26
|
+
<<-EOS.strip_heredoc
|
27
|
+
function FindProxyForURL(url, host) {
|
28
|
+
if ( timeRange(8, 18) ) {
|
29
|
+
return "PROXY localhost:8080";
|
30
|
+
} else {
|
31
|
+
return "DIRECT";
|
32
|
+
}
|
33
|
+
}
|
34
|
+
EOS
|
35
|
+
end
|
36
|
+
|
37
|
+
context '#find' do
|
38
|
+
it 'returns result of proxy.pac' do
|
39
|
+
javascript = double('javascript')
|
40
|
+
expect(javascript).to receive(:call).with("FindProxyForURL", "http://localhost", "localhost")
|
41
|
+
|
42
|
+
ProxyPacRb::File.new(javascript).find("http://localhost")
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
data/spec/parser_spec.rb
ADDED
@@ -0,0 +1,116 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe ProxyPacRb::Parser do
|
5
|
+
let(:sample_pac) do
|
6
|
+
create_file 'sample.pac', <<-EOS.strip_heredoc
|
7
|
+
function FindProxyForURL(url, host) {
|
8
|
+
return "DIRECT";
|
9
|
+
}
|
10
|
+
EOS
|
11
|
+
end
|
12
|
+
|
13
|
+
context ".read" do
|
14
|
+
it "should load a file from a path" do
|
15
|
+
pac = ProxyPacRb::Parser.new.read(sample_pac)
|
16
|
+
expect(pac).not_to be_nil
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
context ".source" do
|
21
|
+
let(:source) do <<-JS.strip_heredoc
|
22
|
+
function FindProxyForURL(url, host) {
|
23
|
+
return "DIRECT";
|
24
|
+
}
|
25
|
+
JS
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should load source" do
|
29
|
+
pac = ProxyPacRb::Parser.new.source(source)
|
30
|
+
expect(pac).not_to be_nil
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
context 'compile' do
|
35
|
+
it 'supports a changeable ip address' do
|
36
|
+
string = <<-EOS
|
37
|
+
function FindProxyForURL(url, host) {
|
38
|
+
if ( MyIpAddress() == '127.0.0.2' ) {
|
39
|
+
return "DIRECT";
|
40
|
+
} else {
|
41
|
+
return "PROXY localhost:8080";
|
42
|
+
}
|
43
|
+
}
|
44
|
+
EOS
|
45
|
+
|
46
|
+
environment = ProxyPacRb::Environment.new(my_ip_address: '127.0.0.1')
|
47
|
+
file = ProxyPacRb::Parser.new(environment).source(string)
|
48
|
+
expect(file.find('http://localhost')).to eq('PROXY localhost:8080')
|
49
|
+
|
50
|
+
environment = ProxyPacRb::Environment.new(my_ip_address: '127.0.0.2')
|
51
|
+
file = ProxyPacRb::Parser.new(environment).source(string)
|
52
|
+
expect(file.find('http://localhost')).to eq('DIRECT')
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'supports a changeable date' do
|
56
|
+
string = <<-EOS
|
57
|
+
function FindProxyForURL(url, host) {
|
58
|
+
if (weekdayRange("FRI", "SAT")) {
|
59
|
+
return "PROXY localhost:8080";
|
60
|
+
} else {
|
61
|
+
return "DIRECT";
|
62
|
+
}
|
63
|
+
}
|
64
|
+
EOS
|
65
|
+
|
66
|
+
environment = Environment.new(time: Time.parse('2014-03-08 12:00'))
|
67
|
+
file = ProxyPacRb::Parser.new(environment).source(string)
|
68
|
+
expect(file.find('http://localhost')).to eq('PROXY localhost:8080')
|
69
|
+
|
70
|
+
environment = Environment.new(time: Time.parse('2014-03-06 12:00'))
|
71
|
+
file = ProxyPacRb::Parser.new(environment).source(string)
|
72
|
+
expect(file.find('http://localhost')).to eq('DIRECT')
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'supports time range' do
|
76
|
+
string = <<-EOS
|
77
|
+
function FindProxyForURL(url, host) {
|
78
|
+
if (timeRange(8, 18)) {
|
79
|
+
return "PROXY localhost:8080";
|
80
|
+
} else {
|
81
|
+
return "DIRECT";
|
82
|
+
}
|
83
|
+
}
|
84
|
+
EOS
|
85
|
+
|
86
|
+
environment = ProxyPacRb::Environment.new(time: Time.parse('2014-03-06 12:00'))
|
87
|
+
file = ProxyPacRb::Parser.new(environment).source(string)
|
88
|
+
expect(file.find('http://localhost')).to eq('PROXY localhost:8080')
|
89
|
+
|
90
|
+
environment = ProxyPacRb::Environment.new(time: Time.parse('2014-03-08 6:00'))
|
91
|
+
file = ProxyPacRb::Parser.new(environment).source(string)
|
92
|
+
expect(file.find('http://localhost')).to eq('DIRECT')
|
93
|
+
end
|
94
|
+
|
95
|
+
it 'supports a date range' do
|
96
|
+
string = <<-EOS
|
97
|
+
function FindProxyForURL(url, host) {
|
98
|
+
if (dateRange("JUL", "SEP")) {
|
99
|
+
return "PROXY localhost:8080";
|
100
|
+
} else {
|
101
|
+
return "DIRECT";
|
102
|
+
}
|
103
|
+
}
|
104
|
+
EOS
|
105
|
+
|
106
|
+
environment = ProxyPacRb::Environment.new(time: Time.parse('2014-07-06 12:00'))
|
107
|
+
file = ProxyPacRb::Parser.new(environment).source(string)
|
108
|
+
expect(file.find('http://localhost')).to eq('PROXY localhost:8080')
|
109
|
+
|
110
|
+
environment = ProxyPacRb::Environment.new(time: Time.parse('2014-03-08 6:00'))
|
111
|
+
file = ProxyPacRb::Parser.new(environment).source(string)
|
112
|
+
expect(file.find('http://localhost')).to eq('DIRECT')
|
113
|
+
end
|
114
|
+
|
115
|
+
end
|
116
|
+
end
|