pacproxy 0.0.6 → 0.0.7

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b4024d37226f9d4c70c55a9279e6a0ffa89b33ab
4
- data.tar.gz: 6d13403957afc8ca4e5d467f43885430cd7c5ef2
3
+ metadata.gz: a592de5e8ef2da33cd52d19f4ca3360a6204cbdf
4
+ data.tar.gz: 00e5f8e3243b2f608c40f82df2afb7d90529debd
5
5
  SHA512:
6
- metadata.gz: a8dd7e83efc77dcc421ae35318e0eaf755c4cf5eb8f28688509c8b0d94676c2b1472c4a2f3a17f5e789d59d381bd2db848ca970f70abb015f170dc7438a21714
7
- data.tar.gz: 4e38c95852f2dd9e534412272d443de7a3912f47299021cf9688081c167b3437371a2c93491abdc716629a7824cd47a32861df76784bc9fb2fcd97d5302be937
6
+ metadata.gz: 504b321afecb58a6b42a985df6057ec628c84ad19e8dd8a16fa81262a84a33865e6b2aa5d3432c87b905c8d48e662b3e50b08ad6929d937dc8bcbc050ff38fc7
7
+ data.tar.gz: 9422b0603fa43f68ac991f32ca19114ef9d7e0214405799fb94b11340d033f7f95fa14f40e3463292e97d980150426e1dcd7e17589618294d0f87675b513389c
data/.gitignore CHANGED
@@ -25,6 +25,7 @@ build/
25
25
  /.bundle/
26
26
  /lib/bundler/man/
27
27
  /vendor/
28
+ /lib/pacproxy/runtimes/node/node_modules/
28
29
 
29
30
  # for a library or gem, you might want to ignore these files since the code is
30
31
  # intended to run in multiple environments; otherwise, check them in:
@@ -37,3 +38,6 @@ Gemfile.lock
37
38
 
38
39
  # for log files
39
40
  *.log
41
+
42
+ # for backup files
43
+ *.bak
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format documentation
@@ -0,0 +1,7 @@
1
+ # Avoid methods longer than 10 lines of code
2
+ MethodLength:
3
+ Enabled: false
4
+
5
+ # Avoid classes longer than 100 lines of code
6
+ ClassLength:
7
+ Enabled: false
@@ -1,5 +1,15 @@
1
1
  language: ruby
2
+ cache: bundler
3
+
4
+ before_install:
5
+ - 'test Node = "$PACPROXY_RUNTIME" && sudo apt-get update || true'
6
+ - 'test Node = "$PACPROXY_RUNTIME" && sudo apt-get install node || true'
7
+ - 'test Node = "$PACPROXY_RUNTIME" && (cd lib/pacproxy/runtimes/node ; npm install) || true'
2
8
 
3
9
  rvm:
4
10
  - 2.0.0
5
- - 2.1.2
11
+ - 2.1.4
12
+
13
+ env:
14
+ - PACPROXY_RUNTIME=Node
15
+ - PACPROXY_RUNTIME=
data/README.md CHANGED
@@ -1,27 +1,23 @@
1
- # Pacproxy
1
+ # Pacproxy [![Build Status](https://travis-ci.org/otahi/pacproxy.png?branch=master)](https://travis-ci.org/otahi/pacproxy)[![Coverage Status](https://coveralls.io/repos/otahi/pacproxy/badge.png?branch=master)](https://coveralls.io/r/otahi/pacproxy?branch=master)[![Code Climate](https://codeclimate.com/github/otahi/pacproxy.png)](https://codeclimate.com/github/otahi/pacproxy)[![Gem Version](https://badge.fury.io/rb/pacproxy.png)](http://badge.fury.io/rb/pacproxy)
2
2
 
3
- Pacproxy provides http/https proxy routed by proxy.pac.
4
-
5
- [![Build Status](https://travis-ci.org/otahi/pacproxy.png?branch=master)](https://travis-ci.org/otahi/pacproxy)
6
- [![Coverage Status](https://coveralls.io/repos/otahi/pacproxy/badge.png?branch=master)](https://coveralls.io/r/otahi/pacproxy?branch=master)
7
- [![Code Climate](https://codeclimate.com/github/otahi/pacproxy.png)](https://codeclimate.com/github/otahi/pacproxy)
8
- [![Gem Version](https://badge.fury.io/rb/pacproxy.png)](http://badge.fury.io/rb/pacproxy)
3
+ Pacproxy provides an http/https proxy server which does proxy access according with a local/remote proxy.pac.
4
+ If your user agent is behind of the corporate proxy server and it does not recognize proxy.pac,
5
+ Proxypac transfers both your Internet and Intranet access correctly.
9
6
 
10
7
  ## Usage
11
8
 
12
- $ bundle exec pacproxy
13
-
14
- or
9
+ You can run pacproxy with specified proxy.pac location, running port and so on.
15
10
 
16
- $ bundle exec pacproxy -c pacproxy.yml
11
+ $ bundle exec pacproxy -P http://sample.org/proxy.pac -p 3128
17
12
 
18
13
  or
19
14
 
20
- $ bundle exec pacproxy -P proxy.pac -p 3128
15
+ $ bundle exec pacproxy -P /opt/pacproxy/sample-proxy.pac -p 3128
21
16
 
22
17
  or
23
18
 
24
- $ bundle exec pacproxy -P http://sample.org/proxy.pac -p 3128
19
+ $ bundle exec pacproxy -c pacproxy.yml
20
+
25
21
 
26
22
  ## Configuration
27
23
 
@@ -37,9 +33,13 @@ Configurable items:
37
33
  - access log
38
34
 
39
35
  ## Installation
36
+ You can select Ruby javascript runtimes or Node.js
40
37
 
41
- Add this line to your application's Gemfile, for example:
38
+ ### With a Ruby javascript runtime
39
+ Puts these lines on Gemfile, for example:
42
40
 
41
+ source 'https://rubygems.org'
42
+
43
43
  gem 'pacproxy'
44
44
  gem 'therubyracer'
45
45
 
@@ -47,16 +47,29 @@ And then execute:
47
47
 
48
48
  $ bundle
49
49
 
50
+ ### With Node.js
51
+ Install node.js runtime before this installation.
52
+ Puts these lines on Gemfile, for example:
53
+
54
+ source 'https://rubygems.org'
55
+
56
+ gem 'pacproxy'
57
+
58
+ And then execute:
59
+
60
+ $ bundle
61
+ $ bundle exec pacproxy --npminstall
62
+
50
63
  ## Requirements
51
64
 
52
65
  Before or After installing the `pacproxy` gem,
53
- you need to install a JavaScript runtime. Compatible runtimes include
54
- (see [pac](https://github.com/samuelkadolph/ruby-pac/blob/master/README.md)):
66
+ you need to install a JavaScript runtime.:
55
67
 
56
68
  * [therubyracer](https://rubygems.org/gems/therubyracer) Google V8 embedded within Ruby
57
69
  * [therubyrhino](https://rubygems.org/gems/therubyrhino/) Mozilla Rhino embedded within JRuby
58
70
  * [johnson](https://rubygems.org/gems/johnson/) Mozilla SpiderMonkey embedded within Ruby 1.8
59
71
  * [mustang](https://rubygems.org/gems/mustang/) Mustang V8 embedded within Ruby
72
+ * [Node.js](http://nodejs.org/) Node.js runtime
60
73
 
61
74
  ## Contributing
62
75
 
@@ -25,6 +25,16 @@ OptionParser.new do |o|
25
25
  o.on('-P PROXYPAC', String, 'specify proxy.pac location') do |pac|
26
26
  config.merge!('pac_file' => { 'location' => pac })
27
27
  end
28
+ o.on('--npminstall', 'install node libraries') do
29
+ fail 'No npm found!' unless Pacproxy::Util.which('npm')
30
+
31
+ node_dir = File.join([File.dirname(__FILE__)] +
32
+ %w(.. lib pacproxy runtimes node))
33
+ FileUtils.cd(node_dir) do
34
+ system('npm install')
35
+ end
36
+ exit
37
+ end
28
38
  o.on('-h', 'show this help') do
29
39
  puts o
30
40
  exit
@@ -1,4 +1,5 @@
1
1
  require 'pacproxy/version'
2
+ require 'pacproxy/util'
2
3
  require 'pacproxy/loggable'
3
4
  require 'pacproxy/pacproxy'
4
5
  require 'pacproxy/pac_file'
@@ -6,6 +7,8 @@ require 'pacproxy/general_logger'
6
7
  require 'pacproxy/access_logger'
7
8
  require 'pacproxy/config'
8
9
 
10
+ require 'pacproxy/runtime'
11
+
9
12
  # Pacproxy provides http/https proxy routed with proxy.pac.
10
13
  module Pacproxy
11
14
  end
@@ -1,5 +1,4 @@
1
1
  require 'pacproxy'
2
- require 'pac'
3
2
  require 'uri'
4
3
  require 'thread'
5
4
 
@@ -8,42 +7,39 @@ module Pacproxy
8
7
  class PacFile
9
8
  include Loggable
10
9
 
11
- @js_lock = Mutex.new
12
- class << self
13
- attr_reader :js_lock
10
+ def initialize(file_location, update_interval = 1800)
11
+ begin
12
+ require 'pac'
13
+ rescue RuntimeUnavailable
14
+ info('No javascript runtime found for pac')
15
+ end
16
+ @file_location = file_location
17
+ @update_interval = update_interval
18
+ @runtime = Runtime.new
19
+ begin_update
14
20
  end
15
21
 
16
- def initialize(file_location, update_interval = 1800)
17
- @pac = nil
18
- begin_update(file_location, update_interval)
22
+ def shutdown
23
+ @runtime.shutdown
19
24
  end
20
25
 
21
26
  def find(uri)
22
- return 'DIRECT' unless @pac
23
- PacFile.js_lock.synchronize do
24
- @pac.find(uri)
25
- end
27
+ return 'DIRECT' unless @runtime
28
+ @runtime.find(uri)
26
29
  end
27
30
 
28
31
  private
29
32
 
30
- def begin_update(file_location, update_interval)
33
+ def begin_update
31
34
  is_updated = false
32
35
  Thread.new do
33
36
  loop do
34
- update(file_location)
37
+ @runtime.update(@file_location)
35
38
  is_updated = true
36
- sleep(update_interval)
39
+ sleep(@update_interval)
37
40
  end
38
41
  end
39
42
  sleep 0.01 until is_updated
40
43
  end
41
-
42
- def update(file_location)
43
- tmp = PAC.load(file_location)
44
- @pac = tmp if @pac.nil? || @pac.source != tmp.source
45
- rescue => e
46
- error("#{file_location} update error: #{e}")
47
- end
48
44
  end
49
45
  end
@@ -9,12 +9,18 @@ module Pacproxy
9
9
 
10
10
  def initialize(config = {}, default = WEBrick::Config::HTTP)
11
11
  super({ Port: config['port'], Logger: general_logger }, default)
12
+ @auth = config['auth']
12
13
  return unless config['pac_file'] && config['pac_file']['location']
13
14
 
14
15
  @pac = PacFile.new(config['pac_file']['location'],
15
16
  config['pac_file']['update_interval'])
16
17
  end
17
18
 
19
+ def shutdown
20
+ @pac.shutdown
21
+ super
22
+ end
23
+
18
24
  def proxy_uri(req, res)
19
25
  super(req, res)
20
26
  return unless @pac
@@ -27,16 +33,18 @@ module Pacproxy
27
33
  def create_proxy_uri(proxy, header)
28
34
  return nil unless proxy
29
35
  return URI.parse("http://#{proxy}") unless
30
- header.key?('proxy-authorization')
31
-
32
- auth = header['proxy-authorization'][0]
33
- pattern = /basic (\S+)/i
34
- basic_auth = pattern.match(auth)[1]
35
- header.delete('proxy-authorization')
36
-
37
- return URI.parse("http://#{proxy}") unless basic_auth
36
+ @auth || header.key?('proxy-authorization')
37
+
38
+ if @auth
39
+ basic_auth = "#{@auth['user']}:#{@auth['password']}"
40
+ elsif header.key?('proxy-authorization')
41
+ auth = header['proxy-authorization'][0]
42
+ pattern = /basic (\S+)/i
43
+ basic_auth = pattern.match(auth)[1].unpack('m').first
44
+ header.delete('proxy-authorization')
45
+ end
38
46
 
39
- URI.parse("http://#{basic_auth.unpack('m').first}@#{proxy}")
47
+ URI.parse("http://#{basic_auth}@#{proxy}")
40
48
  end
41
49
 
42
50
  # This method is mainly from WEBrick::HTTPProxyServer.
@@ -0,0 +1,40 @@
1
+ require 'pacproxy'
2
+ require 'pacproxy/runtimes/node/node'
3
+ require 'pacproxy/runtimes/pac/pac'
4
+
5
+ module Pacproxy
6
+ # Pacproxy::Runtime represet runtime
7
+ class Runtime
8
+ include Loggable
9
+
10
+ def initialize
11
+ @runtime = autodetect
12
+ end
13
+
14
+ def shutdown
15
+ @runtime.shutdown
16
+ end
17
+
18
+ def find(url)
19
+ @runtime.find(url)
20
+ end
21
+
22
+ def update(file_location)
23
+ @runtime.update(file_location)
24
+ end
25
+
26
+ private
27
+
28
+ def autodetect
29
+ name = ENV['PACPROXY_RUNTIME']
30
+ return Runtimes::Node.runtime if name || /Node/ =~ name
31
+
32
+ ENV['JS_RUNTIME'] = name
33
+ return Runtimes::Pac.runtime if Runtimes::Pac.runtime
34
+ return Runtimes::Node.runtime if Runtimes::Node.runtime
35
+
36
+ fail(RuntimeUnavailable,
37
+ 'No runtime supporting proxy.pac')
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,27 @@
1
+ require 'pacproxy'
2
+
3
+ module Pacproxy
4
+ module Runtimes
5
+ # Pacproxy::Runtimes::Basee represet basic runtime
6
+ class Base
7
+ include Loggable
8
+
9
+ attr_reader :source
10
+
11
+ def self.runtime
12
+ end
13
+
14
+ def initialize
15
+ end
16
+
17
+ def shutdown
18
+ end
19
+
20
+ def update(_file_location)
21
+ end
22
+
23
+ def find(_url)
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,18 @@
1
+ var dnode = require('dnode');
2
+ var pac = require('pac-resolver');
3
+ var source;
4
+
5
+ process.on('uncaughtException', function(err){});
6
+
7
+ var server = dnode({
8
+ find : function(source, uri, host, cb) {
9
+ var FindProxyForURL = pac(source);
10
+ FindProxyForURL(uri, host, function (err, res) {
11
+ if (err) res = "DIRECT";
12
+ cb(res);
13
+ });
14
+ }
15
+ });
16
+
17
+ var port = process.argv[2];
18
+ server.listen(port);
@@ -0,0 +1,138 @@
1
+ require 'pacproxy'
2
+ require 'pacproxy/runtimes/base'
3
+
4
+ require 'open-uri'
5
+ require 'dnode'
6
+ require 'thread'
7
+ require 'os'
8
+
9
+ module Pacproxy
10
+ module Runtimes
11
+ # Pacproxy::Runtimes::Node represet node js runtime
12
+ class Node < Base
13
+ include Loggable
14
+
15
+ TIMEOUT_JS_CALL = 0.5
16
+ TIMEOUT_JS_SERVER = 5
17
+ attr_reader :source
18
+
19
+ def self.runtime
20
+ if Util.which('node').nil?
21
+ error('No PAC supported runtime')
22
+ fail(RuntimeUnavailable,
23
+ 'No PAC supported runtime')
24
+ end
25
+ new
26
+ end
27
+
28
+ def initialize
29
+ js = File.join(File.dirname(__FILE__), 'find.js')
30
+
31
+ retries = 3
32
+ begin
33
+ Timeout.timeout(TIMEOUT_JS_SERVER) do
34
+ server = TCPServer.new('127.0.0.1', 0)
35
+ @port = server.addr[1]
36
+ server.close
37
+ if OS.windows?
38
+ @server_pid = start_server
39
+ else
40
+ @server_pid = fork { exec('node', js, @port.to_s) }
41
+ Process.detach(@server_pid)
42
+ end
43
+ sleep 0.01 until port_open?
44
+ end
45
+ rescue Timeout::Error
46
+ shutdown
47
+ if retries > 0
48
+ retries -= 1
49
+ lwarn('Timeout. Initialize Node.js server.')
50
+ retry
51
+ else
52
+ error('Gave up to retry Initialize Node.js server.')
53
+ raise 'Gave up to retry Initialize Node.js server.'
54
+ end
55
+ end
56
+ end
57
+
58
+ def shutdown
59
+ if OS.windows?
60
+ stop_server(@server_pid)
61
+ else
62
+ Process.kill(:INT, @server_pid)
63
+ end
64
+ end
65
+
66
+ def update(file_location)
67
+ @source = open(file_location, proxy: false).read
68
+ rescue
69
+ @source = nil
70
+ end
71
+
72
+ def find(url)
73
+ return 'DIRECT' unless @source
74
+ uri = URI.parse(url)
75
+ call_find(uri)
76
+ end
77
+
78
+ private
79
+
80
+ def port_open?
81
+ Timeout.timeout(TIMEOUT_JS_CALL) do
82
+ begin
83
+ TCPSocket.new('127.0.0.1', @port).close
84
+ return true
85
+ rescue Errno::ECONNREFUSED, Errno::EHOSTUNREACH
86
+ return false
87
+ end
88
+ end
89
+ rescue Timeout::Error
90
+ false
91
+ end
92
+
93
+ def call_find(uri, retries = 3)
94
+ proxy = nil
95
+ begin
96
+ thread = Thread.new do
97
+ DNode.new.connect('127.0.0.1', @port) do |remote|
98
+ remote.find(@source, uri, uri.host,
99
+ proc do |p|
100
+ proxy = p
101
+ EM.stop
102
+ end)
103
+ end
104
+ end
105
+ thread.join(TIMEOUT_JS_CALL)
106
+ proxy
107
+ rescue Timeout::Error
108
+ if retries > 0
109
+ retries -= 1
110
+ lwarn('Timeout. Retring call_find.')
111
+ retry
112
+ else
113
+ error('Gave up Retry call_find.')
114
+ nil
115
+ end
116
+ end
117
+ end
118
+
119
+ def rand_string
120
+ (0...16).map { ('a'..'z').to_a[rand(26)] }.join
121
+ end
122
+
123
+ def start_server
124
+ require 'win32/process'
125
+ Process.create(
126
+ app_name: Util.which('node'),
127
+ creation_flags: Process::DETACHED_PROCESS
128
+ )
129
+ end
130
+
131
+ def stop_server(server_info)
132
+ require 'win32/process'
133
+ return unless server_info || server_info.respond_to?(:process_id)
134
+ Process.kill('ExitProcess', [server_info.process_id])
135
+ end
136
+ end
137
+ end
138
+ end
@@ -0,0 +1,15 @@
1
+ {
2
+ "name": "pacproxy",
3
+ "description": "A proxy server works with proxy.pac",
4
+ "repository": {
5
+ "type": "git",
6
+ "url": "https://github.com/otahi/pacproxy.git"
7
+ },
8
+ "dependencies": {
9
+ "dnode": "^1.2.0",
10
+ "pac-resolver": "^1.2.2"
11
+ },
12
+ "author": "Hiroshi OTA",
13
+ "license": "MIT",
14
+ "readme": "See: https://github.com/otahi/pacproxy"
15
+ }
@@ -0,0 +1,40 @@
1
+ require 'pacproxy'
2
+ require 'pacproxy/runtimes/base'
3
+
4
+ require 'open-uri'
5
+ require 'thread'
6
+
7
+ module Pacproxy
8
+ module Runtimes
9
+ # Pacproxy::Runtimes::Pac represent Pac
10
+ class Pac < Base
11
+ include Loggable
12
+
13
+ attr_reader :source
14
+
15
+ @js_lock = Mutex.new
16
+ class << self
17
+ attr_reader :js_lock
18
+ end
19
+
20
+ def self.runtime
21
+ PAC.runtime
22
+ new
23
+ end
24
+
25
+ def find(url)
26
+ return 'DIRECT' unless @pac
27
+ Pac.js_lock.synchronize do
28
+ @pac.find(url)
29
+ end
30
+ end
31
+
32
+ def update(file_location)
33
+ tmp = PAC.load(file_location)
34
+ @pac = tmp if @pac.nil? || @pac.source != tmp.source
35
+ rescue => e
36
+ error("#{file_location} update error: #{e}")
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,17 @@
1
+ require 'pacproxy'
2
+
3
+ module Pacproxy
4
+ # Pacproxy::PacUtil is utility
5
+ class Util
6
+ def self.which(cmd)
7
+ exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
8
+ ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
9
+ exts.each do |ext|
10
+ exe = File.join(path, "#{cmd}#{ext}")
11
+ return exe if File.executable?(exe) && !File.directory?(exe)
12
+ end
13
+ end
14
+ nil
15
+ end
16
+ end
17
+ end
@@ -1,4 +1,4 @@
1
1
  # Pacproxy provides http/https proxy routed with proxy.pac.
2
2
  module Pacproxy
3
- VERSION = '0.0.6'
3
+ VERSION = '0.0.7'
4
4
  end
Binary file
@@ -19,6 +19,9 @@ Gem::Specification.new do |spec|
19
19
  spec.require_paths = ["lib"]
20
20
 
21
21
  spec.add_dependency 'pac', '~> 1.0.0'
22
+ spec.add_dependency 'dnode', '~> 0.0.2'
23
+ spec.add_dependency 'os', '~> 0.9.6'
24
+ spec.add_dependency 'win32-process', '~> 0.7.4'
22
25
 
23
26
  spec.add_development_dependency 'bundler', '~> 1.6'
24
27
  spec.add_development_dependency 'rspec', '~> 3.0.0'
@@ -19,6 +19,16 @@ pac_file:
19
19
  # eg. update_interval: 1800
20
20
  update_interval: 1800
21
21
 
22
+ # upstream proxy authorization related items
23
+ # auth > user: [string]
24
+ # user name for upstream proxy server
25
+ # auth > password: [string]
26
+ # password for upstream proxy server
27
+ # eg.
28
+ # auth:
29
+ # user: user100
30
+ # password: abcd1234
31
+
22
32
  # general log related items
23
33
  general_log:
24
34
  # general_log > location: [string]
@@ -1,24 +1,29 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Pacproxy::PacFile do
4
+ after(:each) do
5
+ @pac_file.shutdown
6
+ end
7
+
4
8
  describe 'PacFile#find' do
5
9
  it 'returns proxyurl in pac file' do
6
- pac_file = Pacproxy::PacFile.new('spec/all_proxy.pac')
7
- expect(pac_file.find('http://sample.org/')).to eq('PROXY localhost:13081')
10
+ @pac_file = Pacproxy::PacFile.new('spec/all_proxy.pac')
11
+ expect(@pac_file.find('http://sample.org/')).to eq('PROXY localhost:13081')
8
12
  end
9
13
  it 'returns DIRECT when no pac file' do
10
- pac_file = Pacproxy::PacFile.new('')
11
- expect(pac_file.find('http://sample.org/')).to eq('DIRECT')
14
+ @pac_file = Pacproxy::PacFile.new('')
15
+ expect(@pac_file.find('http://sample.org/')).to eq('DIRECT')
12
16
  end
13
17
  end
14
18
  describe 'PacFile#update' do
15
19
  it 'has same pac file if no change' do
16
- pac_file = Pacproxy::PacFile.new('spec/all_proxy.pac', 0.01)
17
- expect(pac_file).to receive(:update).at_least(2).times
20
+ @pac_file = Pacproxy::PacFile.new('spec/all_proxy.pac', 0.01)
21
+ expect(@pac_file.instance_variable_get('@runtime'))
22
+ .to receive(:update).at_least(2).times
18
23
 
19
- first_pac = pac_file.instance_variable_get(:@pac)
24
+ first_pac = @pac_file.instance_variable_get(:@pac)
20
25
  sleep 0.2
21
- second_pac = pac_file.instance_variable_get(:@pac)
26
+ second_pac = @pac_file.instance_variable_get(:@pac)
22
27
  expect(second_pac).to eq(first_pac)
23
28
  end
24
29
  end
@@ -152,6 +152,32 @@ describe Pacproxy do
152
152
  expect(res.status).to eq(200)
153
153
  end
154
154
 
155
+ it 'transfer request with overridden auth to server via parent proxy' do
156
+ auth = nil
157
+ proxy_proc = proc do |req, _resp|
158
+ auth = req.header['proxy-authorization']
159
+ end
160
+
161
+ pc = @proxy_server.instance_variable_get('@config')
162
+ @proxy_server.instance_variable_set('@config',
163
+ pc.merge(ProxyAuthProc: proxy_proc))
164
+
165
+ c = Pacproxy::Config.instance.config
166
+ c['port'] = 13_128
167
+ c['pac_file']['location'] = 'spec/partial_proxy.pac'
168
+ c['auth'] = { 'user' => 'user01', 'password' => 'pass01' }
169
+
170
+ @pacproxy_server = Pacproxy::Pacproxy.new(c)
171
+ Thread.new { @pacproxy_server.start }
172
+ wait_server_status(@pacproxy_server, :Running)
173
+
174
+ c = HTTPClient.new('http://127.0.0.1:13128')
175
+ res = c.get('http://127.0.0.1:13080/')
176
+ expect(res.status).to eq(200)
177
+ expect(auth)
178
+ .to eq([%Q(Basic #{['user01:pass01'].pack('m').delete("\n")})])
179
+ end
180
+
155
181
  it 'respond 407 when upstrem proxy respond 407 on http' do
156
182
  proxy_proc = proc do |_req, resp|
157
183
  resp.header.merge!('Proxy-Authenticate' => "Basic realm=\"proxy\"")
@@ -0,0 +1,15 @@
1
+ require 'spec_helper'
2
+
3
+ describe Pacproxy::Runtime do
4
+
5
+ after(:each) do
6
+ @runtime.shutdown
7
+ end
8
+
9
+ describe 'Runtime#new' do
10
+ it 'returns Pacproxy::Runtime' do
11
+ @runtime = Pacproxy::Runtime.new
12
+ expect(@runtime).to be_kind_of(Pacproxy::Runtime)
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,14 @@
1
+ require 'spec_helper'
2
+
3
+ describe Pacproxy::Util do
4
+ describe 'Util#which' do
5
+ it 'return "/bin/sh" when "sh" is given' do
6
+ l = Pacproxy::Util.which('sh')
7
+ expect(l).to eq('/bin/sh')
8
+ end
9
+ it 'return nil when "unknown command" is given' do
10
+ l = Pacproxy::Util.which('unknown command')
11
+ expect(l).to be_nil
12
+ end
13
+ end
14
+ end
metadata CHANGED
@@ -1,97 +1,139 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pacproxy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.6
4
+ version: 0.0.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - OTA Hiroshi
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-09-16 00:00:00.000000000 Z
11
+ date: 2014-11-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: pac
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ~>
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
19
  version: 1.0.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ~>
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: 1.0.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: dnode
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 0.0.2
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 0.0.2
41
+ - !ruby/object:Gem::Dependency
42
+ name: os
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 0.9.6
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 0.9.6
55
+ - !ruby/object:Gem::Dependency
56
+ name: win32-process
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 0.7.4
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 0.7.4
27
69
  - !ruby/object:Gem::Dependency
28
70
  name: bundler
29
71
  requirement: !ruby/object:Gem::Requirement
30
72
  requirements:
31
- - - ~>
73
+ - - "~>"
32
74
  - !ruby/object:Gem::Version
33
75
  version: '1.6'
34
76
  type: :development
35
77
  prerelease: false
36
78
  version_requirements: !ruby/object:Gem::Requirement
37
79
  requirements:
38
- - - ~>
80
+ - - "~>"
39
81
  - !ruby/object:Gem::Version
40
82
  version: '1.6'
41
83
  - !ruby/object:Gem::Dependency
42
84
  name: rspec
43
85
  requirement: !ruby/object:Gem::Requirement
44
86
  requirements:
45
- - - ~>
87
+ - - "~>"
46
88
  - !ruby/object:Gem::Version
47
89
  version: 3.0.0
48
90
  type: :development
49
91
  prerelease: false
50
92
  version_requirements: !ruby/object:Gem::Requirement
51
93
  requirements:
52
- - - ~>
94
+ - - "~>"
53
95
  - !ruby/object:Gem::Version
54
96
  version: 3.0.0
55
97
  - !ruby/object:Gem::Dependency
56
98
  name: rake
57
99
  requirement: !ruby/object:Gem::Requirement
58
100
  requirements:
59
- - - ~>
101
+ - - "~>"
60
102
  - !ruby/object:Gem::Version
61
103
  version: 10.3.2
62
104
  type: :development
63
105
  prerelease: false
64
106
  version_requirements: !ruby/object:Gem::Requirement
65
107
  requirements:
66
- - - ~>
108
+ - - "~>"
67
109
  - !ruby/object:Gem::Version
68
110
  version: 10.3.2
69
111
  - !ruby/object:Gem::Dependency
70
112
  name: httpclient
71
113
  requirement: !ruby/object:Gem::Requirement
72
114
  requirements:
73
- - - ~>
115
+ - - "~>"
74
116
  - !ruby/object:Gem::Version
75
117
  version: 2.4.0
76
118
  type: :development
77
119
  prerelease: false
78
120
  version_requirements: !ruby/object:Gem::Requirement
79
121
  requirements:
80
- - - ~>
122
+ - - "~>"
81
123
  - !ruby/object:Gem::Version
82
124
  version: 2.4.0
83
125
  - !ruby/object:Gem::Dependency
84
126
  name: therubyracer
85
127
  requirement: !ruby/object:Gem::Requirement
86
128
  requirements:
87
- - - ~>
129
+ - - "~>"
88
130
  - !ruby/object:Gem::Version
89
131
  version: 0.12.1
90
132
  type: :development
91
133
  prerelease: false
92
134
  version_requirements: !ruby/object:Gem::Requirement
93
135
  requirements:
94
- - - ~>
136
+ - - "~>"
95
137
  - !ruby/object:Gem::Version
96
138
  version: 0.12.1
97
139
  - !ruby/object:Gem::Dependency
@@ -112,28 +154,28 @@ dependencies:
112
154
  name: coveralls
113
155
  requirement: !ruby/object:Gem::Requirement
114
156
  requirements:
115
- - - ~>
157
+ - - "~>"
116
158
  - !ruby/object:Gem::Version
117
159
  version: '0.7'
118
160
  type: :development
119
161
  prerelease: false
120
162
  version_requirements: !ruby/object:Gem::Requirement
121
163
  requirements:
122
- - - ~>
164
+ - - "~>"
123
165
  - !ruby/object:Gem::Version
124
166
  version: '0.7'
125
167
  - !ruby/object:Gem::Dependency
126
168
  name: byebug
127
169
  requirement: !ruby/object:Gem::Requirement
128
170
  requirements:
129
- - - ~>
171
+ - - "~>"
130
172
  - !ruby/object:Gem::Version
131
173
  version: 3.4.0
132
174
  type: :development
133
175
  prerelease: false
134
176
  version_requirements: !ruby/object:Gem::Requirement
135
177
  requirements:
136
- - - ~>
178
+ - - "~>"
137
179
  - !ruby/object:Gem::Version
138
180
  version: 3.4.0
139
181
  description: A proxy server works with proxy.pac
@@ -144,8 +186,10 @@ executables:
144
186
  extensions: []
145
187
  extra_rdoc_files: []
146
188
  files:
147
- - .gitignore
148
- - .travis.yml
189
+ - ".gitignore"
190
+ - ".rspec"
191
+ - ".rubocop.yml"
192
+ - ".travis.yml"
149
193
  - Gemfile
150
194
  - LICENSE
151
195
  - README.md
@@ -158,7 +202,15 @@ files:
158
202
  - lib/pacproxy/loggable.rb
159
203
  - lib/pacproxy/pac_file.rb
160
204
  - lib/pacproxy/pacproxy.rb
205
+ - lib/pacproxy/runtime.rb
206
+ - lib/pacproxy/runtimes/base.rb
207
+ - lib/pacproxy/runtimes/node/find.js
208
+ - lib/pacproxy/runtimes/node/node.rb
209
+ - lib/pacproxy/runtimes/node/package.json
210
+ - lib/pacproxy/runtimes/pac/pac.rb
211
+ - lib/pacproxy/util.rb
161
212
  - lib/pacproxy/version.rb
213
+ - model/pacproxy.asta
162
214
  - pacproxy.gemspec
163
215
  - pacproxy.yml
164
216
  - pacproxy/.gitignore
@@ -171,7 +223,9 @@ files:
171
223
  - spec/pac_file_spec.rb
172
224
  - spec/pacproxy_spec.rb
173
225
  - spec/partial_proxy.pac
226
+ - spec/runtime_spec.rb
174
227
  - spec/spec_helper.rb
228
+ - spec/util_spec.rb
175
229
  homepage: https://github.com/otahi/pacproxy
176
230
  licenses:
177
231
  - MIT
@@ -182,17 +236,17 @@ require_paths:
182
236
  - lib
183
237
  required_ruby_version: !ruby/object:Gem::Requirement
184
238
  requirements:
185
- - - '>='
239
+ - - ">="
186
240
  - !ruby/object:Gem::Version
187
241
  version: '0'
188
242
  required_rubygems_version: !ruby/object:Gem::Requirement
189
243
  requirements:
190
- - - '>='
244
+ - - ">="
191
245
  - !ruby/object:Gem::Version
192
246
  version: '0'
193
247
  requirements: []
194
248
  rubyforge_project:
195
- rubygems_version: 2.0.14
249
+ rubygems_version: 2.2.2
196
250
  signing_key:
197
251
  specification_version: 4
198
252
  summary: A proxy server works with proxy.pac
@@ -205,4 +259,6 @@ test_files:
205
259
  - spec/pac_file_spec.rb
206
260
  - spec/pacproxy_spec.rb
207
261
  - spec/partial_proxy.pac
262
+ - spec/runtime_spec.rb
208
263
  - spec/spec_helper.rb
264
+ - spec/util_spec.rb