proxy_pac_rb 0.0.2

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 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: