pacproxy 0.0.6 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
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