proxy_pac_rb 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ coverage
data/Gemfile ADDED
@@ -0,0 +1,50 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in local_pac.gemspec
4
+ gemspec
5
+
6
+ group :test do
7
+ gem 'rspec', require: false
8
+ gem 'fuubar', require: false
9
+ gem 'simplecov', require: false
10
+ gem 'rubocop', require: false
11
+ gem 'coveralls', require: false
12
+ gem 'cucumber', require: false
13
+ gem 'aruba', require: false
14
+ end
15
+
16
+ group :development do
17
+ gem 'debugger'
18
+ gem 'debugger-completion'
19
+ gem 'github-markup'
20
+ gem 'pry'
21
+ gem 'pry-debugger', require: false
22
+ gem 'pry-doc', require: false
23
+ gem 'redcarpet', require: false
24
+ gem 'tmrb', require: false
25
+ gem 'yard', require: false
26
+ gem 'inch', require: false
27
+ end
28
+
29
+ group :profile do
30
+ gem 'ruby-prof'
31
+ end
32
+
33
+ gem 'rake', group: [:development, :test], require: false
34
+ gem 'fedux_org-stdlib', group: [:development, :test], require: false
35
+ gem 'bundler', '~> 1.3', group: [:development, :test], require: false
36
+ gem 'erubis', group: [:development, :test]
37
+ gem 'versionomy', group: [:development, :test], require: false
38
+ gem 'activesupport', '~> 4.0.0', group: [:development, :test], require: false
39
+
40
+ gem 'awesome_print', group: [:development, :test], require: 'ap'
41
+
42
+ group :runtimes do
43
+ group :therubyracer do
44
+ gem 'therubyracer', require: 'v8'
45
+ end
46
+
47
+ group :therubyrhino do
48
+ gem 'therubyrhino', require: 'rhino'
49
+ end
50
+ end
data/LICENSE.md ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (C) 2014 by Denis Günnewig
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,94 @@
1
+ # Proxy Pac Rb
2
+
3
+ `proxy_pac_rb` is a gem to parse [proxy auto-config](http://en.wikipedia.org/wiki/Proxy_auto-config) files.
4
+ `proxy_pac_rb` uses a JavaScript runtime to evaulate a proxy auto-config file the same way a browser does to determine what proxy (if
5
+ any at all) should a program use to connect to a server. You must install on of the supported JavaScript runtimes:
6
+ therubyracer, therubyrhino
7
+
8
+ Big thanks to [sstephenson](https://github.com/sstephenson)'s [execjs](https://github.com/sstephenson/execjs) for the
9
+ runtime wrapper code and to
10
+ [samuelkadolph](https://github.com/samuelkadolph/ruby-pac)'s
11
+ [ruby-pac](https://github.com/samuelkadolph/ruby-pac) for the foundation of this gem.
12
+
13
+ ## Installing
14
+
15
+ Add this line to your application's Gemfile:
16
+
17
+ gem 'proxy_pac_rb'
18
+
19
+ And then execute:
20
+
21
+ $ bundle
22
+
23
+ Or install it yourself as:
24
+
25
+ $ gem install proxy_pac_rb
26
+
27
+
28
+ ## Requirements
29
+
30
+ After installing the `proxy_pac_rb` gem you must install a JavaScript runtime. Compatible runtimes include:
31
+
32
+ * [therubyracer](https://rubygems.org/gems/therubyracer) Google V8 embedded within Ruby
33
+ * [therubyrhino](https://rubygems.org/gems/therubyrhino/) Mozilla Rhino embedded within JRuby
34
+
35
+ ## Usage
36
+
37
+ ### Command Line
38
+
39
+ ```
40
+ parsepac https://github.com/dg-vrnetze/proxy_pac_rb/raw/master/files/sample.pac https://github.com
41
+ parsepac https://github.com/dg-vrnetze/proxy_pac_rb/raw/master/files/sample.pac http://ruby-lang.com
42
+ parsepac https://github.com/dg-vrnetze/proxy_pac_rb/raw/master/files/sample.pac http://samuel.kadolph.com
43
+ ```
44
+
45
+ ### Ruby
46
+
47
+ ```ruby
48
+ require "rubygems"
49
+ require "pac"
50
+
51
+ pac = PAC.load('https://github.com/dg-vrnetze/proxy_pac_rb/raw/master/files/sample.pac')
52
+ pac.find('https://github.com') # => "PROXY proxy:8080"
53
+ pac.find('http://ruby-lang.com') # => "PROXY proxy:8080; DIRECT"
54
+ pac.find('http://samuel.kadolph.com') # => "DIRECT"
55
+
56
+ pac = PAC.read("sample.pac")
57
+
58
+ pac = PAC.source <<-JS
59
+ function FindProxyForURL(url, host) {
60
+ return "DIRECT";
61
+ }
62
+ JS
63
+ pac.find('http://localhost') # => "DIRECT"
64
+ ```
65
+
66
+ ## Available JavaScript Functions
67
+
68
+ * isPlainHostName(host)
69
+ * dnsDomainIs(host, domain)
70
+ * localHostOrDomainIs(host, hostdom)
71
+ * isResolvable(host)
72
+ * isInNet(host, pattern, mask)
73
+ * dnsResolve(host)
74
+ * myIpAddress()
75
+ * dnsDomainLevels(host)
76
+ * shExpMatch(str, shexp)
77
+ * weekdayRange(wd1, wd2, gmt)
78
+ * dateRange(*args)
79
+ * timeRange(*args)
80
+
81
+ ## Developers
82
+
83
+ ### Contributing
84
+
85
+ If you want to contribute: fork, branch & pull request.
86
+
87
+ ### Running Tests
88
+
89
+ ```
90
+ bundle install
91
+ rake test:rspec
92
+ rake test:rubyracer
93
+ rake test:rubyrhino
94
+ ```
data/Rakefile ADDED
@@ -0,0 +1,81 @@
1
+ #!/usr/bin/env rake
2
+ #
3
+ require 'rake/testtask'
4
+ require 'fedux_org/stdlib/rake'
5
+ require 'proxy_pac_rb/version'
6
+
7
+ def software
8
+ 'proxy_pac_rb'
9
+ end
10
+
11
+ def version
12
+ ProxyPacRb::VERSION
13
+ end
14
+
15
+ def root_directory
16
+ ::File.expand_path('../', __FILE__)
17
+ end
18
+
19
+ def tar_file
20
+ ::File.join(pkg_directory, "#{software}-#{version}.tar.gz")
21
+ end
22
+
23
+ def tmp_directory
24
+ ::File.join(root_directory, 'tmp', "#{software}-#{version}")
25
+ end
26
+
27
+ def gem_file
28
+ ::File.join(root_directory, 'pkg', "#{software}-#{version}.gem")
29
+ end
30
+
31
+ def pkg_directory
32
+ ::File.join(root_directory, 'pkg')
33
+ end
34
+
35
+ def gem_directory
36
+ ::File.join(root_directory, 'vendor', 'cache')
37
+ end
38
+
39
+ task :default => 'gem:build'
40
+
41
+ file gem_file => 'gem:build'
42
+
43
+ file tmp_directory do
44
+ FileUtils.mkdir_p tmp_directory
45
+ end
46
+
47
+ namespace :gem do
48
+ desc 'build tar file'
49
+ task :package => [gem_file, tmp_directory] do
50
+ FileUtils.mv ::File.join(pkg_directory, "#{software}-#{version}.gem"), tmp_directory
51
+
52
+ Dir.chdir('tmp') do
53
+ sh "tar -czf #{tar_file} #{::File.basename tmp_directory}"
54
+ end
55
+ end
56
+ end
57
+
58
+ namespace 'test' do
59
+ require 'bundler'
60
+
61
+ desc 'Run tests with the rubyracer runtime'
62
+ task 'rubyracer' do
63
+ Bundler.require :default, :test, :development, :therubyracer
64
+ Rake::Task['test:rspec'].invoke
65
+ end
66
+
67
+ desc 'Run tests with the therubyrhino runtime'
68
+ task 'rubyrhino' do
69
+ Bundler.require :default, :test, :development, :therubyrhino
70
+ Rake::Task['test:rspec'].invoke
71
+ end
72
+ end
73
+
74
+
75
+ require 'coveralls/rake/task'
76
+ Coveralls::RakeTask.new
77
+
78
+ namespace :test do
79
+ desc 'Test with coveralls'
80
+ task :coveralls => ['test:rspec', 'test:cucumber', 'coveralls:push']
81
+ end
data/bin/parsepac ADDED
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ if ARGV.size < 2
4
+ puts "usage: parsepac pac-url-or-file url-to-test"
5
+ exit 1
6
+ else
7
+ require "pac"
8
+ puts PAC.load(ARGV.shift).find(ARGV.shift)
9
+ exit 0
10
+ end
data/files/sample.pac ADDED
@@ -0,0 +1,3 @@
1
+ function FindProxyForURL(url, host) {
2
+ return "DIRECT";
3
+ }
@@ -0,0 +1,10 @@
1
+ # encoding: utf-8
2
+ module ProxyPacRb
3
+ module Exceptions
4
+ #raise on error
5
+ class ProgramError < StandardError; end
6
+
7
+ #raise on java script runtime error
8
+ class RuntimeUnavailable < StandardError; end
9
+ end
10
+ end
@@ -0,0 +1,17 @@
1
+ module ProxyPacRb
2
+ class File
3
+ attr_reader :source, :context
4
+
5
+ def initialize(source)
6
+ @source = source.dup.freeze
7
+ @context = ProxyPacRb.runtime.compile(@source)
8
+ @context.include Functions
9
+ end
10
+
11
+ def find(url)
12
+ uri = URI.parse(url)
13
+ fail ArgumentError, "url is missing host" unless uri.host
14
+ context.call("FindProxyForURL", url, uri.host)
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,128 @@
1
+ module ProxyPacRb
2
+ module Functions
3
+ DAYS = { "MON" => 1, "TUE" => 2, "WED" => 3, "THU" => 4, "FRI" => 5, "SAT" => 6, "SUN" => 7 }
4
+ MONTHS = { "JAN" => 1, "FEB" => 2, "MAR" => 3, "APR" => 4, "MAY" => 5, "JUN" => 6,
5
+ "JUL" => 7, "AUG" => 8, "SEP" => 9, "OCT" => 10, "NOV" => 11, "DEC" => 12 }
6
+
7
+ class << self
8
+ def isPlainHostName(host)
9
+ not host.include? "."
10
+ end
11
+
12
+ def dnsDomainIs(host, domain)
13
+ host.end_with? domain
14
+ end
15
+
16
+ def localHostOrDomainIs(host, hostdom)
17
+ host == hostdom or hostdom.include? host
18
+ end
19
+
20
+ def isResolvable(host)
21
+ !!resolve_host(host)
22
+ end
23
+
24
+ def isInNet(host, pattern, mask)
25
+ IPAddr.new(pattern).mask(mask).include? resolve_host(host)
26
+ end
27
+
28
+ def dnsResolve(host)
29
+ resolve_host(host)
30
+ end
31
+
32
+ def myIpAddress()
33
+ resolve_host(Socket.gethostname)
34
+ end
35
+
36
+ def dnsDomainLevels(host)
37
+ host.scan(".").size
38
+ end
39
+
40
+ def shExpMatch(str, shexp)
41
+ ::File.fnmatch(shexp, str)
42
+ end
43
+
44
+ def weekdayRange(wd1, wd2 = nil, gmt = nil)
45
+ time = Time.now
46
+ time = time.utc if gmt == "GMT"
47
+
48
+ (DAYS[wd1]..DAYS[wd2 || wd1]).include? time.wday
49
+ end
50
+
51
+ def dateRange(*args)
52
+ time = Time.now
53
+ time = time.utc if args.last == "GMT" and args.pop
54
+
55
+ case args.size
56
+ when 1
57
+ check_date_part(time, args[0])
58
+ when 2
59
+ check_date_part(time, args[0]..args[1])
60
+ when 4
61
+ check_date_part(time, args[0]..args[2]) and
62
+ check_date_part(time, args[1]..args[3])
63
+ when 6
64
+ check_date_part(time, args[0]..args[3]) and
65
+ check_date_part(time, args[1]..args[4]) and
66
+ check_date_part(time, args[2]..args[5])
67
+ else
68
+ raise ArgumentError, "wrong number of arguments"
69
+ end
70
+ end
71
+
72
+ def timeRange(*args)
73
+ time = Time.now
74
+ time = time.utc if args.last == "GMT" and args.pop
75
+
76
+ case args.size
77
+ when 1
78
+ time.hour == args[0]
79
+ when 2
80
+ (args[0]..args[1]).include? time.hour
81
+ when 4
82
+ (args[0]..args[2]).include? time.hour and
83
+ (args[1]..args[3]).include? time.min
84
+ when 6
85
+ (args[0]..args[3]).include? time.hour and
86
+ (args[1]..args[4]).include? time.min and
87
+ (args[2]..args[5]).include? time.sec
88
+ else
89
+ raise ArgumentError, "wrong number of arguments"
90
+ end
91
+ end
92
+
93
+ private
94
+ def check_date_part(time, part, operation = :==)
95
+ case part
96
+ when String
97
+ time.month.send(operation, MONTHS[part])
98
+ when Integer
99
+ if part < 100
100
+ time.day.send(operation, part)
101
+ else
102
+ time.year.send(operation, part)
103
+ end
104
+ when Range
105
+ check_date_part(time, part.begin, :>=) and check_date_part(time, part.end, :<=)
106
+ else
107
+ raise ArgumentError, "wrong type"
108
+ end
109
+ end
110
+
111
+ def resolve_host(host)
112
+ Resolv.each_address(host) do |address|
113
+ begin
114
+ return address if IPAddr.new(address).ipv4?
115
+ rescue ArgumentError
116
+ end
117
+ end
118
+
119
+ # We couldn't find an IPv4 address for the host
120
+ nil
121
+ rescue Resolv::ResolvError, NoMethodError
122
+ # Have to rescue NoMethodError because jruby has a bug with non existant hostnames
123
+ # See http://jira.codehaus.org/browse/JRUBY-6054
124
+ nil
125
+ end
126
+ end
127
+ end
128
+ end
@@ -0,0 +1,87 @@
1
+ module ProxyPacRb
2
+ module Runtimes
3
+ class RubyRacerRuntime
4
+ class Context
5
+ def initialize(source = "")
6
+ source = source.encode("UTF-8") if source.respond_to?(:encode)
7
+
8
+ lock do
9
+ @v8_context = V8::Context.new
10
+ @v8_context.eval(source)
11
+ end
12
+ end
13
+
14
+ def include(mod)
15
+ (mod.methods - Module.methods).each do |name|
16
+ @v8_context[name] = mod.method(name)
17
+ end
18
+ end
19
+
20
+ def call(properties, *args)
21
+ lock do
22
+ begin
23
+ unbox @v8_context.eval(properties).call(*args)
24
+ rescue ::V8::JSError => e
25
+ if e.value["name"] == "SyntaxError"
26
+ raise RuntimeError, e.message
27
+ else
28
+ raise Exceptions::ProgramError, e.message
29
+ end
30
+ end
31
+ end
32
+ end
33
+
34
+ def unbox(value)
35
+ case value
36
+ when ::V8::Function
37
+ nil
38
+ when ::V8::Array
39
+ value.map { |v| unbox(v) }
40
+ when ::V8::Object
41
+ value.inject({}) do |vs, (k, v)|
42
+ vs[k] = unbox(v) unless v.is_a?(::V8::Function)
43
+ vs
44
+ end
45
+ when String
46
+ value.respond_to?(:force_encoding) ? value.force_encoding("UTF-8") : value
47
+ else
48
+ value
49
+ end
50
+ end
51
+
52
+ private
53
+ def lock
54
+ result, exception = nil, nil
55
+ V8::C::Locker() do
56
+ begin
57
+ result = yield
58
+ rescue Exception => e
59
+ exception = e
60
+ end
61
+ end
62
+
63
+ if exception
64
+ raise exception
65
+ else
66
+ result
67
+ end
68
+ end
69
+ end
70
+
71
+ def name
72
+ "therubyracer (V8)"
73
+ end
74
+
75
+ def compile(source)
76
+ Context.new(source)
77
+ end
78
+
79
+ def available?
80
+ require "v8"
81
+ true
82
+ rescue LoadError
83
+ false
84
+ end
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,77 @@
1
+ module ProxyPacRb
2
+ module Runtimes
3
+ class RubyRhinoRuntime
4
+ class Context
5
+ def initialize(source = "")
6
+ source = source.encode("UTF-8") if source.respond_to?(:encode)
7
+
8
+ @rhino_context = Rhino::Context.new
9
+ fix_memory_limit! @rhino_context
10
+ @rhino_context.eval(source)
11
+ end
12
+
13
+ def include(mod)
14
+ (mod.methods - Module.methods).each do |name|
15
+ @rhino_context[name] = mod.method(name)
16
+ end
17
+ end
18
+
19
+ def call(properties, *args)
20
+ unbox @rhino_context.eval(properties).call(*args)
21
+ rescue ::Rhino::JavascriptError => e
22
+ if e.message == "syntax error"
23
+ raise RuntimeError, e.message
24
+ else
25
+ raise Exceptions::ProgramError, e.message
26
+ end
27
+ end
28
+
29
+ def unbox(value)
30
+ case value = ::Rhino::To.ruby(value)
31
+ when ::Rhino::NativeFunction
32
+ nil
33
+ when ::Rhino::NativeObject
34
+ value.inject({}) do |vs, (k, v)|
35
+ case v
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
48
+ end
49
+
50
+ private
51
+ # Disables bytecode compiling which limits you to 64K scripts
52
+ def fix_memory_limit!(context)
53
+ if context.respond_to?(:optimization_level=)
54
+ context.optimization_level = -1
55
+ else
56
+ context.instance_eval { @native.setOptimizationLevel(-1) }
57
+ end
58
+ end
59
+ end
60
+
61
+ def name
62
+ "therubyrhino (Rhino)"
63
+ end
64
+
65
+ def compile(source)
66
+ Context.new(source)
67
+ end
68
+
69
+ def available?
70
+ require "rhino"
71
+ true
72
+ rescue LoadError
73
+ false
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,38 @@
1
+ module ProxyPacRb
2
+ module Runtimes
3
+ RubyRacer = RubyRacerRuntime.new
4
+ RubyRhino = RubyRhinoRuntime.new
5
+
6
+ class << self
7
+ def autodetect
8
+ from_environment || best_available || fail(Exceptions::RuntimeUnavailable, "Could not find a JavaScript runtime. See https://github.com/dg-vrnetze/proxy_pac_rb for a list of runtimes.")
9
+ end
10
+
11
+ def from_environment
12
+ if name = ENV["JS_RUNTIME"]
13
+ if runtime = const_get(name)
14
+ if runtime.available?
15
+ runtime if runtime.available?
16
+ else
17
+ fail Exceptions::RuntimeUnavailable, "#{runtime.name} runtime is not available on this system"
18
+ end
19
+ elsif !name.empty?
20
+ fail Exceptions::RuntimeUnavailable, "#{name} runtime is not defined"
21
+ end
22
+ end
23
+ end
24
+
25
+ def best_available
26
+ runtimes.find(&:available?)
27
+ end
28
+
29
+ def runtimes
30
+ @runtimes ||= [RubyRacer, RubyRhino]
31
+ end
32
+ end
33
+ end
34
+
35
+ def self.runtimes
36
+ Runtimes.runtimes
37
+ end
38
+ end
@@ -0,0 +1,4 @@
1
+ #main ProxyPacRb
2
+ module ProxyPacRb
3
+ VERSION = '0.0.2'
4
+ end
@@ -0,0 +1,38 @@
1
+ require 'uri'
2
+ require 'ipaddr'
3
+ require 'resolv'
4
+ require 'time'
5
+
6
+ require 'proxy_pac_rb/version'
7
+ require 'proxy_pac_rb/exceptions'
8
+ require 'proxy_pac_rb/functions'
9
+ require 'proxy_pac_rb/file'
10
+ require 'proxy_pac_rb/runtimes/rubyracer'
11
+ require 'proxy_pac_rb/runtimes/rubyrhino'
12
+ require 'proxy_pac_rb/runtimes'
13
+
14
+ module ProxyPacRb
15
+ class << self
16
+ attr_reader :runtime
17
+
18
+ def runtime=(runtime)
19
+ fail Exceptions::RuntimeUnavailable, "#{runtime.name} is unavailable on this system" unless runtime.available?
20
+ @runtime = runtime
21
+ end
22
+
23
+ def load(url, options = {})
24
+ require "open-uri"
25
+ File.new(open(url, { :proxy => false }.merge(options)).read)
26
+ end
27
+
28
+ def read(file)
29
+ File.new(::File.read(file))
30
+ end
31
+
32
+ def source(source)
33
+ File.new(source)
34
+ end
35
+ end
36
+
37
+ self.runtime = Runtimes.autodetect
38
+ end
@@ -0,0 +1,26 @@
1
+ # encoding: utf-8
2
+ lib = ::File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'proxy_pac_rb/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'proxy_pac_rb'
8
+ spec.version = ProxyPacRb::VERSION
9
+ spec.authors = ['Dennis Günnewig']
10
+ spec.email = ['dg1@vrnetze.de']
11
+ spec.homepage = 'https://github.com/dg-vrnetze/proxy_pac_rb'
12
+ spec.summary = %q{gem to parse proxy auto-config files.}
13
+ spec.description = <<-DESC
14
+ This gem uses a JavaScript runtime to evaulate a proxy auto-config file the same way a browser does to determine what proxy (if
15
+ any at all) should a program use to connect to a server. You must install on of the supported JavaScript runtimes:
16
+ therubyracer, therubyrhino, johnson or mustang.
17
+ DESC
18
+
19
+ spec.homepage = 'https://github.com/dg-vrnetze/ruby_pac_rb'
20
+ spec.license = 'MIT'
21
+
22
+ spec.files = `git ls-files -z`.split("\x0")
23
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| ::File.basename(f) }
24
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
25
+ spec.require_paths = ['lib']
26
+ end
@@ -0,0 +1,18 @@
1
+ # encoding: utf-8
2
+ require 'spec_helper'
3
+
4
+ describe ProxyPacRb::Functions do
5
+ describe "isResolvable()" do
6
+ let(:tester) do
7
+ ProxyPacRb::Functions
8
+ end
9
+
10
+ it "should return true for localhost" do
11
+ expect(tester.isResolvable("localhost")).to be_true
12
+ end
13
+
14
+ it "should return false for awidhaowuhuiuhiuug" do
15
+ expect(tester.isResolvable('asdfasdfasdfasdf')).to be_false
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,112 @@
1
+ # encoding: utf-8
2
+ require 'spec_helper'
3
+
4
+ describe ProxyPacRb do
5
+
6
+ let(:sample_pac) do
7
+ create_file 'sample.pac', <<-EOS.strip_heredoc
8
+ function FindProxyForURL(url, host) {
9
+ return "DIRECT";
10
+ }
11
+ EOS
12
+ end
13
+
14
+ let(:example_1) do
15
+ create_file 'example_1.pac', <<-EOS.strip_heredoc
16
+ // Taken from http://findproxyforurl.com/pac_file_examples.html
17
+ function FindProxyForURL(url, host) {
18
+
19
+ // If URL has no dots in host name, send traffic direct.
20
+ if (isPlainHostName(host))
21
+ return "DIRECT";
22
+
23
+ // If specific URL needs to bypass proxy, send traffic direct.
24
+ if (shExpMatch(url,"*domain.com*") ||
25
+ shExpMatch(url,"*vpn.domain.com*"))
26
+ return "DIRECT";
27
+
28
+ // If IP address is internal or hostname resolves to internal IP, send direct.
29
+ var resolved_ip = dnsResolve(host);
30
+
31
+ if (isInNet(resolved_ip, "10.0.0.0", "255.0.0.0") ||
32
+ isInNet(resolved_ip, "172.16.0.0", "255.240.0.0") ||
33
+ isInNet(resolved_ip, "192.168.0.0", "255.255.0.0") ||
34
+ isInNet(resolved_ip, "127.0.0.0", "255.255.255.0"))
35
+ return "DIRECT";
36
+
37
+ // If not on a internal/LAN IP address, send traffic direct.
38
+ if (!isInNet(myIpAddress(), "10.10.1.0", "255.255.255.0"))
39
+ return "DIRECT";
40
+
41
+ // All other traffic uses below proxies, in fail-over order.
42
+ return "PROXY 1.2.3.4:8080; PROXY 4.5.6.7:8080; DIRECT";
43
+
44
+ }
45
+ EOS
46
+ end
47
+
48
+ let(:example_2) do
49
+ create_file 'example_2.pac', <<-EOS.strip_heredoc
50
+ // Taken from http://findproxyforurl.com/pac_file_examples.html
51
+ function FindProxyForURL(url, host) {
52
+
53
+ // If IP address is internal or hostname resolves to internal IP, send direct.
54
+ var resolved_ip = dnsResolve(host);
55
+
56
+ if (isInNet(resolved_ip, "10.0.0.0", "255.0.0.0") ||
57
+ isInNet(resolved_ip, "172.16.0.0", "255.240.0.0") ||
58
+ isInNet(resolved_ip, "192.168.0.0", "255.255.0.0") ||
59
+ isInNet(resolved_ip, "127.0.0.0", "255.255.255.0"))
60
+ return "DIRECT";
61
+
62
+ // Use a different proxy for each protocol.
63
+ if (shExpMatch(url, "http:*")) return "PROXY proxy1.domain.com:3128";
64
+ if (shExpMatch(url, "https:*")) return "PROXY proxy2.domain.com:3128";
65
+ if (shExpMatch(url, "ftp:*")) return "PROXY proxy3.domain.com:3128";
66
+
67
+ }
68
+ EOS
69
+ end
70
+
71
+ let(:everything_but_local) do
72
+ create_file 'everything_but_local.pac', <<-EOS.strip_heredoc
73
+ function FindProxyForURL(url, host) {
74
+ if (isPlainHostName(host))
75
+ return "DIRECT";
76
+ else
77
+ return "PROXY proxy:8080; DIRECT";
78
+ }
79
+ EOS
80
+ end
81
+
82
+ describe ".read" do
83
+ it "should load a file from a path" do
84
+ pac = ProxyPacRb.read(sample_pac)
85
+ expect(pac).not_to be_nil
86
+ end
87
+
88
+ it "should return DIRECT for a url" do
89
+ pac = ProxyPacRb.read(sample_pac)
90
+ expect(pac.find('http://localhost')).to eq('DIRECT')
91
+ end
92
+ end
93
+
94
+ describe ".source" do
95
+ let(:source) do <<-JS.strip_heredoc
96
+ function FindProxyForURL(url, host) {
97
+ return "DIRECT";
98
+ }
99
+ JS
100
+ end
101
+
102
+ it "should load source" do
103
+ pac = ProxyPacRb.source(source)
104
+ expect(pac).not_to be_nil
105
+ end
106
+
107
+ it "should return DIRECT for a url" do
108
+ pac = ProxyPacRb.source(source)
109
+ expect(pac.find('http://localhost')).to eq('DIRECT')
110
+ end
111
+ end
112
+ end
@@ -0,0 +1,17 @@
1
+ # encoding: utf-8
2
+
3
+ $LOAD_PATH << ::File.expand_path('../../lib', __FILE__)
4
+
5
+ require 'simplecov'
6
+ SimpleCov.command_name 'rspec'
7
+ SimpleCov.start
8
+
9
+ # Pull in all of the gems including those in the `test` group
10
+ require 'bundler'
11
+ Bundler.require :default, :test, :development
12
+
13
+ # Loading support files
14
+ Dir.glob(::File.expand_path('../support/*.rb', __FILE__)).each { |f| require_relative f }
15
+
16
+ # Avoid writing "describe LocalPac::MyClass do [..]" but "describe MyClass do [..]"
17
+ include ProxyPacRb
@@ -0,0 +1,17 @@
1
+ # encoding: utf-8
2
+ require 'fedux_org/stdlib/environment'
3
+
4
+ module ProxyPacRb
5
+ module SpecHelper
6
+ module Environment
7
+ include FeduxOrg::Stdlib::Environment
8
+ alias_method :with_environment, :isolated_environment
9
+ end
10
+ end
11
+ end
12
+
13
+ # encoding: utf-8
14
+ RSpec.configure do |c|
15
+ c.include ProxyPacRb::SpecHelper::Environment
16
+ end
17
+
@@ -0,0 +1,20 @@
1
+ # encoding: utf-8
2
+ require 'fedux_org/stdlib/filesystem'
3
+
4
+ module ProxyPacRb
5
+ module SpecHelper
6
+ module Filesystem
7
+ include FeduxOrg::Stdlib::Filesystem
8
+
9
+ def root_directory
10
+ ::File.expand_path('../../../', __FILE__)
11
+ end
12
+ end
13
+ end
14
+ end
15
+
16
+ # encoding: utf-8
17
+ RSpec.configure do |c|
18
+ c.include ProxyPacRb::SpecHelper::Filesystem
19
+ c.before(:each) { cleanup_working_directory }
20
+ end
@@ -0,0 +1,2 @@
1
+ # encoding: utf-8
2
+ require 'active_support/core_ext/kernel/reporting'
@@ -0,0 +1,6 @@
1
+ # encoding: utf-8
2
+ RSpec.configure do |c|
3
+ c.filter_run_including :focus => true
4
+ c.run_all_when_everything_filtered = true
5
+ c.treat_symbols_as_metadata_keys_with_true_values = true
6
+ end
@@ -0,0 +1,2 @@
1
+ # encoding: utf-8
2
+ require 'active_support/core_ext/string/strip'
metadata ADDED
@@ -0,0 +1,94 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: proxy_pac_rb
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Dennis Günnewig
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2014-03-07 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: ! 'This gem uses a JavaScript runtime to evaulate a proxy auto-config
15
+ file the same way a browser does to determine what proxy (if
16
+
17
+ any at all) should a program use to connect to a server. You must install on of
18
+ the supported JavaScript runtimes:
19
+
20
+ therubyracer, therubyrhino, johnson or mustang.
21
+
22
+ '
23
+ email:
24
+ - dg1@vrnetze.de
25
+ executables:
26
+ - parsepac
27
+ extensions: []
28
+ extra_rdoc_files: []
29
+ files:
30
+ - .gitignore
31
+ - Gemfile
32
+ - LICENSE.md
33
+ - README.md
34
+ - Rakefile
35
+ - bin/parsepac
36
+ - files/sample.pac
37
+ - lib/proxy_pac_rb.rb
38
+ - lib/proxy_pac_rb/exceptions.rb
39
+ - lib/proxy_pac_rb/file.rb
40
+ - lib/proxy_pac_rb/functions.rb
41
+ - lib/proxy_pac_rb/runtimes.rb
42
+ - lib/proxy_pac_rb/runtimes/rubyracer.rb
43
+ - lib/proxy_pac_rb/runtimes/rubyrhino.rb
44
+ - lib/proxy_pac_rb/version.rb
45
+ - proxy_pac_rb.gemspec
46
+ - spec/proxy_pac_rb/functions_spec.rb
47
+ - spec/proxy_pac_rb_spec.rb
48
+ - spec/spec_helper.rb
49
+ - spec/support/environment.rb
50
+ - spec/support/filesystem.rb
51
+ - spec/support/reporting.rb
52
+ - spec/support/rspec.rb
53
+ - spec/support/string.rb
54
+ homepage: https://github.com/dg-vrnetze/ruby_pac_rb
55
+ licenses:
56
+ - MIT
57
+ post_install_message:
58
+ rdoc_options: []
59
+ require_paths:
60
+ - lib
61
+ required_ruby_version: !ruby/object:Gem::Requirement
62
+ none: false
63
+ requirements:
64
+ - - ! '>='
65
+ - !ruby/object:Gem::Version
66
+ version: '0'
67
+ segments:
68
+ - 0
69
+ hash: 3395524059172055841
70
+ required_rubygems_version: !ruby/object:Gem::Requirement
71
+ none: false
72
+ requirements:
73
+ - - ! '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ segments:
77
+ - 0
78
+ hash: 3395524059172055841
79
+ requirements: []
80
+ rubyforge_project:
81
+ rubygems_version: 1.8.23
82
+ signing_key:
83
+ specification_version: 3
84
+ summary: gem to parse proxy auto-config files.
85
+ test_files:
86
+ - spec/proxy_pac_rb/functions_spec.rb
87
+ - spec/proxy_pac_rb_spec.rb
88
+ - spec/spec_helper.rb
89
+ - spec/support/environment.rb
90
+ - spec/support/filesystem.rb
91
+ - spec/support/reporting.rb
92
+ - spec/support/rspec.rb
93
+ - spec/support/string.rb
94
+ has_rdoc: