pacproxy 0.0.5 → 0.0.6

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: eda757cf693b406eb8f4502a3e85b2b0e326b95d
4
- data.tar.gz: d8ed42f024dfebcccf979f4e05e5c2df8eb0d8ea
3
+ metadata.gz: b4024d37226f9d4c70c55a9279e6a0ffa89b33ab
4
+ data.tar.gz: 6d13403957afc8ca4e5d467f43885430cd7c5ef2
5
5
  SHA512:
6
- metadata.gz: fb5e9a2dcfdbea5c337df0142e049081a9f718bdefe59ef3c62979aca90cf38c19ff9dd1c944858eb193c52a53818043046de28be0e8fa740297b2d13818e979
7
- data.tar.gz: 706eb4bebce43f55c59572d1afb6f55c6292305adbafe3a3660bdee0cfe11546040805188c90ae25ce6784be925bbe0c72f52a2eff2c9b1f95b1a204e67ed14a
6
+ metadata.gz: a8dd7e83efc77dcc421ae35318e0eaf755c4cf5eb8f28688509c8b0d94676c2b1472c4a2f3a17f5e789d59d381bd2db848ca970f70abb015f170dc7438a21714
7
+ data.tar.gz: 4e38c95852f2dd9e534412272d443de7a3912f47299021cf9688081c167b3437371a2c93491abdc716629a7824cd47a32861df76784bc9fb2fcd97d5302be937
data/README.md CHANGED
@@ -7,16 +7,35 @@ Pacproxy provides http/https proxy routed by proxy.pac.
7
7
  [![Code Climate](https://codeclimate.com/github/otahi/pacproxy.png)](https://codeclimate.com/github/otahi/pacproxy)
8
8
  [![Gem Version](https://badge.fury.io/rb/pacproxy.png)](http://badge.fury.io/rb/pacproxy)
9
9
 
10
- **:warning: Now Pacproxy is early stage, so it might have big change.**
11
-
12
10
  ## Usage
13
11
 
12
+ $ bundle exec pacproxy
13
+
14
+ or
15
+
16
+ $ bundle exec pacproxy -c pacproxy.yml
17
+
18
+ or
19
+
14
20
  $ bundle exec pacproxy -P proxy.pac -p 3128
15
21
 
16
22
  or
17
23
 
18
24
  $ bundle exec pacproxy -P http://sample.org/proxy.pac -p 3128
19
25
 
26
+ ## Configuration
27
+
28
+ You can configure pacproxy by a file which you specified with `-c` option.
29
+ The default configuration file is `pacproxy.yml`([sample](./pacproxy.yml))
30
+ in the current working directory.
31
+
32
+ Configurable items:
33
+ - daemonize
34
+ - port
35
+ - pac file
36
+ - general log
37
+ - access log
38
+
20
39
  ## Installation
21
40
 
22
41
  Add this line to your application's Gemfile, for example:
data/bin/pacproxy CHANGED
@@ -4,32 +4,46 @@ require 'pacproxy'
4
4
  require 'optparse'
5
5
  require 'logger'
6
6
 
7
- port = 3128
8
- proxy_pac = nil
9
- daemonize = false
10
- log_file = 'pacproxy.log'
7
+ config_file = nil
8
+ config = Pacproxy::Config.instance.config
11
9
 
12
10
  OptionParser.new do |o|
13
- o.on('-d', 'daemonize') { daemonize = true }
14
- o.on('-l LOGFILE', String, "specify log file. default: #{log_file}") { |l| log_file = l }
15
- o.on('-p PORT', Integer,"specify listening port. default: #{port}") { |p| port = p }
16
- o.on('-P PROXYPAC', String, 'specify proxy.pac location') { |pac| proxy_pac = pac }
17
- o.on('-h', 'show this help') { puts o; exit }
11
+ o.on('-c CONFIGFILE', String,
12
+ "specify config file. default: #{config_file}") do |f|
13
+ config_file = f
14
+ config = Pacproxy::Config.instance.update(config_file).config
15
+ end
16
+ o.on('-d', 'daemonize') { config.merge!('daemonize' => true) }
17
+ o.on('-l LOGFILE', String,
18
+ "specify log file. default: #{config['log_file']}") do |l|
19
+ config.merge!('log_file' => l)
20
+ end
21
+ o.on('-p PORT', Integer,
22
+ "specify listening port. default: #{config['port']}") do |p|
23
+ config.merge!('port' => p)
24
+ end
25
+ o.on('-P PROXYPAC', String, 'specify proxy.pac location') do |pac|
26
+ config.merge!('pac_file' => { 'location' => pac })
27
+ end
28
+ o.on('-h', 'show this help') do
29
+ puts o
30
+ exit
31
+ end
18
32
  o.parse!
19
33
  end
20
34
 
21
- logger = Logger.new(log_file, 'weekly')
22
- logger.level = Logger::DEBUG
23
-
24
- s = Pacproxy::Pacproxy.new(Port: port,
25
- Proxypac: proxy_pac,
26
- Logger: logger)
35
+ s = Pacproxy::Pacproxy.new(config)
27
36
 
28
37
  Signal.trap('INT') do
29
38
  s.shutdown
30
39
  end
31
40
 
32
- if daemonize
41
+ if config['daemonize']
42
+ # To use executed directory as the current directory
43
+ # The current directory is changed when daemonized to '/'
44
+ Pacproxy::GeneralLogger.instance
45
+ Pacproxy::AccessLogger.instance
46
+
33
47
  WEBrick::Daemon.start { s.start }
34
48
  else
35
49
  s.start
@@ -10,14 +10,23 @@ module Pacproxy
10
10
  attr_accessor :logger
11
11
 
12
12
  def initialize
13
- @logger = Logger.new('proxy_access.log', 7, 10 * 1024 * 1024)
13
+ c = Config.instance.config['access_log']
14
14
  @format = WEBrick::AccessLog::COMMON_LOG_FORMAT
15
+ return @logger = nil unless c
16
+
17
+ @format = c['format'] if c['format']
18
+
19
+ location = c['location'] ? c['location'] : STDOUT
20
+ shift_age = c['shift_age'] ? c['shift_age'] : 0
21
+ shift_size = c['shift_size'] ? c['shift_size'] : 1_048_576
22
+ @logger = Logger.new(location, shift_age, shift_size)
15
23
  end
16
24
 
17
25
  def accesslog(req, res)
18
26
  params = setup_params(req, res)
19
- logger << WEBrick::AccessLog.format(@format, params)
20
- logger << "\n"
27
+ return unless @logger
28
+ @logger << WEBrick::AccessLog.format(@format, params)
29
+ @logger << "\n"
21
30
  end
22
31
 
23
32
  private
@@ -0,0 +1,33 @@
1
+ require 'pacproxy'
2
+ require 'yaml'
3
+
4
+ module Pacproxy
5
+ # Pacproxy::Config represent configuration for Pacproxy
6
+ class Config
7
+ include Singleton
8
+ DEFAULT_CONFIG = {
9
+ 'daemonize' => false,
10
+ 'port' => 3128,
11
+ 'pac_file' => { 'location' => nil },
12
+ 'general_log' => { 'location' => 'pacproxy.log' }
13
+ }
14
+
15
+ attr_reader :config
16
+
17
+ def initialize
18
+ @config = DEFAULT_CONFIG
19
+ self
20
+ end
21
+
22
+ def update(yaml_file = 'pacproxy.yml')
23
+ @config.merge!(read_config(yaml_file))
24
+ self
25
+ end
26
+
27
+ def read_config(yaml_file)
28
+ return {} unless yaml_file
29
+ return {} unless File.exist?(yaml_file)
30
+ YAML.load(File.read(yaml_file))
31
+ end
32
+ end
33
+ end
@@ -9,7 +9,14 @@ module Pacproxy
9
9
  attr_accessor :logger
10
10
 
11
11
  def initialize
12
- @logger = Logger.new('pacproxy.log', 7, 10 * 1024 * 1024)
12
+ c = Config.instance.config['general_log']
13
+ return @logger = nil unless c
14
+
15
+ location = c['location'] ? c['location'] : STDOUT
16
+ shift_age = c['shift_age'] ? c['shift_age'] : 0
17
+ shift_size = c['shift_size'] ? c['shift_size'] : 1_048_576
18
+ @logger = Logger.new(location, shift_age, shift_size)
19
+ @logger.level = c['log_level'] ? Logger.const_get(c['log_level']) : Logger::ERROR
13
20
  @logger.progname = 'pacproxy'
14
21
  end
15
22
  end
@@ -13,27 +13,27 @@ module Pacproxy
13
13
  end
14
14
 
15
15
  def debug(message)
16
- general_logger.debug(message)
16
+ general_logger.debug(message) if general_logger
17
17
  end
18
18
 
19
19
  def info(message)
20
- general_logger.info(message)
20
+ general_logger.info(message) if general_logger
21
21
  end
22
22
 
23
23
  def lwarn(message)
24
- general_logger.warn(message)
24
+ general_logger.warn(message) if general_logger
25
25
  end
26
26
 
27
27
  def error(message)
28
- general_logger.error(message)
28
+ general_logger.error(message) if general_logger
29
29
  end
30
30
 
31
31
  def fatal(message)
32
- general_logger.fatal(message)
32
+ general_logger.fatal(message) if general_logger
33
33
  end
34
34
 
35
35
  def accesslog(req, res)
36
- access_logger.accesslog(req, res)
36
+ access_logger.accesslog(req, res) if access_logger
37
37
  end
38
38
  end
39
39
  end
@@ -1,10 +1,18 @@
1
1
  require 'pacproxy'
2
2
  require 'pac'
3
3
  require 'uri'
4
+ require 'thread'
4
5
 
5
6
  module Pacproxy
6
7
  # Pacproxy::PacFile represent proxy.pac file
7
8
  class PacFile
9
+ include Loggable
10
+
11
+ @js_lock = Mutex.new
12
+ class << self
13
+ attr_reader :js_lock
14
+ end
15
+
8
16
  def initialize(file_location, update_interval = 1800)
9
17
  @pac = nil
10
18
  begin_update(file_location, update_interval)
@@ -12,7 +20,9 @@ module Pacproxy
12
20
 
13
21
  def find(uri)
14
22
  return 'DIRECT' unless @pac
15
- @pac.find(uri)
23
+ PacFile.js_lock.synchronize do
24
+ @pac.find(uri)
25
+ end
16
26
  end
17
27
 
18
28
  private
@@ -32,9 +42,8 @@ module Pacproxy
32
42
  def update(file_location)
33
43
  tmp = PAC.load(file_location)
34
44
  @pac = tmp if @pac.nil? || @pac.source != tmp.source
35
- rescue
36
- # log
37
- puts "#{file_location} update error"
45
+ rescue => e
46
+ error("#{file_location} update error: #{e}")
38
47
  end
39
48
  end
40
49
  end
@@ -4,13 +4,15 @@ require 'uri'
4
4
 
5
5
  module Pacproxy
6
6
  # Pacproxy::Pacproxy represent http/https proxy server
7
- class Pacproxy < WEBrick::HTTPProxyServer
7
+ class Pacproxy < WEBrick::HTTPProxyServer # rubocop:disable ClassLength
8
8
  include Loggable
9
9
 
10
10
  def initialize(config = {}, default = WEBrick::Config::HTTP)
11
- config[:Logger] = general_logger
12
- super(config, default)
13
- @pac = PacFile.new(config[:Proxypac])
11
+ super({ Port: config['port'], Logger: general_logger }, default)
12
+ return unless config['pac_file'] && config['pac_file']['location']
13
+
14
+ @pac = PacFile.new(config['pac_file']['location'],
15
+ config['pac_file']['update_interval'])
14
16
  end
15
17
 
16
18
  def proxy_uri(req, res)
@@ -37,6 +39,94 @@ module Pacproxy
37
39
  URI.parse("http://#{basic_auth.unpack('m').first}@#{proxy}")
38
40
  end
39
41
 
42
+ # This method is mainly from WEBrick::HTTPProxyServer.
43
+ # To allow upstream proxy authentication,
44
+ # it operate 407 response from an upstream proxy.
45
+ # see: https://github.com/ruby/ruby/blob/trunk/lib/webrick/httpproxy.rb
46
+ # rubocop:disable all
47
+ def do_CONNECT(req, res)
48
+ # Proxy Authentication
49
+ proxy_auth(req, res)
50
+
51
+ ua = Thread.current[:WEBrickSocket] # User-Agent
52
+ raise WEBrick::HTTPStatus::InternalServerError,
53
+ "[BUG] cannot get socket" unless ua
54
+
55
+ host, port = req.unparsed_uri.split(":", 2)
56
+ # Proxy authentication for upstream proxy server
57
+ if proxy = proxy_uri(req, res)
58
+ proxy_request_line = "CONNECT #{host}:#{port} HTTP/1.0"
59
+ if proxy.userinfo
60
+ credentials = "Basic " + [proxy.userinfo].pack("m").delete("\n")
61
+ end
62
+ host, port = proxy.host, proxy.port
63
+ end
64
+
65
+ begin
66
+ @logger.debug("CONNECT: upstream proxy is `#{host}:#{port}'.")
67
+ os = TCPSocket.new(host, port) # origin server
68
+
69
+ if proxy
70
+ @logger.debug("CONNECT: sending a Request-Line")
71
+ os << proxy_request_line << WEBrick::CRLF
72
+ @logger.debug("CONNECT: > #{proxy_request_line}")
73
+ if credentials
74
+ @logger.debug("CONNECT: sending a credentials")
75
+ os << "Proxy-Authorization: " << credentials << WEBrick::CRLF
76
+ end
77
+ os << WEBrick::CRLF
78
+ proxy_status_line = os.gets(WEBrick::LF)
79
+ @logger.debug("CONNECT: read a Status-Line form the upstream server")
80
+ @logger.debug("CONNECT: < #{proxy_status_line}")
81
+ if /^HTTP\/\d+\.\d+\s+(?<st>200|407)\s*/ =~ proxy_status_line
82
+ res.status = st.to_i
83
+ while line = os.gets(WEBrick::LF)
84
+ res.header['Proxy-Authenticate'] =
85
+ line.split(':')[1] if /Proxy-Authenticate/i =~ line
86
+ break if /\A(#{WEBrick::CRLF}|#{WEBrick::LF})\z/om =~ line
87
+ end
88
+ else
89
+ raise WEBrick::HTTPStatus::BadGateway
90
+ end
91
+ end
92
+ @logger.debug("CONNECT #{host}:#{port}: succeeded")
93
+ rescue => ex
94
+ @logger.debug("CONNECT #{host}:#{port}: failed `#{ex.message}'")
95
+ res.set_error(ex)
96
+ raise WEBrick::HTTPStatus::EOFError
97
+ ensure
98
+ if handler = @config[:ProxyContentHandler]
99
+ handler.call(req, res)
100
+ end
101
+ res.send_response(ua)
102
+ access_log(@config, req, res)
103
+
104
+ # Should clear request-line not to send the response twice.
105
+ # see: HTTPServer#run
106
+ req.parse(WEBrick::NullReader) rescue nil
107
+ end
108
+
109
+ begin
110
+ while fds = IO::select([ua, os])
111
+ if fds[0].member?(ua)
112
+ buf = ua.sysread(1024);
113
+ @logger.debug("CONNECT: #{buf.bytesize} byte from User-Agent")
114
+ os.syswrite(buf)
115
+ elsif fds[0].member?(os)
116
+ buf = os.sysread(1024);
117
+ @logger.debug("CONNECT: #{buf.bytesize} byte from #{host}:#{port}")
118
+ ua.syswrite(buf)
119
+ end
120
+ end
121
+ rescue
122
+ os.close
123
+ @logger.debug("CONNECT #{host}:#{port}: closed")
124
+ end
125
+
126
+ raise WEBrick::HTTPStatus::EOFError
127
+ end
128
+ # rubocop:enable all
129
+
40
130
  def proxy_auth(req, res)
41
131
  @config[:ProxyAuthProc].call(req, res) if @config[:ProxyAuthProc]
42
132
  end
@@ -61,6 +151,25 @@ module Pacproxy
61
151
  end
62
152
  end
63
153
 
154
+ # This method is mainly from WEBrick::HTTPProxyServer.
155
+ # proxy-authenticate can be transferred from a upstream proxy server
156
+ # to a client
157
+ # see: https://github.com/ruby/ruby/blob/trunk/lib/webrick/httpproxy.rb
158
+ HOP_BY_HOP = %w( connection keep-alive upgrade
159
+ proxy-authorization te trailers transfer-encoding )
160
+ SHOULD_NOT_TRANSFER = %w( set-cookie proxy-connection )
161
+ def choose_header(src, dst)
162
+ connections = split_field(src['connection'])
163
+ src.each do |key, value|
164
+ key = key.downcase
165
+ next if HOP_BY_HOP.member?(key) || # RFC2616: 13.5.1
166
+ connections.member?(key) || # RFC2616: 14.10
167
+ SHOULD_NOT_TRANSFER.member?(key) # pragmatics
168
+
169
+ dst[key] = value
170
+ end
171
+ end
172
+
64
173
  def perform_proxy_request(req, res)
65
174
  super
66
175
  accesslog(req, res)
@@ -1,4 +1,4 @@
1
1
  # Pacproxy provides http/https proxy routed with proxy.pac.
2
2
  module Pacproxy
3
- VERSION = '0.0.5'
3
+ VERSION = '0.0.6'
4
4
  end
data/lib/pacproxy.rb CHANGED
@@ -4,6 +4,7 @@ require 'pacproxy/pacproxy'
4
4
  require 'pacproxy/pac_file'
5
5
  require 'pacproxy/general_logger'
6
6
  require 'pacproxy/access_logger'
7
+ require 'pacproxy/config'
7
8
 
8
9
  # Pacproxy provides http/https proxy routed with proxy.pac.
9
10
  module Pacproxy
data/pacproxy.gemspec CHANGED
@@ -28,4 +28,5 @@ Gem::Specification.new do |spec|
28
28
 
29
29
  spec.add_development_dependency 'rubocop', '0.24.1'
30
30
  spec.add_development_dependency 'coveralls', '~> 0.7'
31
+ spec.add_development_dependency 'byebug', '~> 3.4.0'
31
32
  end
data/pacproxy.yml ADDED
@@ -0,0 +1,59 @@
1
+ # pacproxy conifguration
2
+
3
+ # daemonize: [boolean]
4
+ # eg. daemonize: true
5
+ daemonize: true
6
+
7
+ # port: [integer]
8
+ # eg. port: 3128
9
+ port: 3128
10
+
11
+ # pac_file related items
12
+ pac_file:
13
+ # pac_file > location: [string]
14
+ # absolute path is preferred
15
+ # eg. location: /opt/pacproxy/proxy.pac
16
+ # eg. location: http://example.com/proxy.pac
17
+ location: proxy.pac
18
+ # pac_file > update_interval(seconds): [integer]
19
+ # eg. update_interval: 1800
20
+ update_interval: 1800
21
+
22
+ # general log related items
23
+ general_log:
24
+ # general_log > location: [string]
25
+ # absolute path is preferred
26
+ # eg. location: /var/log/pacproxy.log
27
+ location: pacproxy.log
28
+ # general_log > log_level: [string]
29
+ # DEBUG/INFO/WARN/ERROR/FATAL
30
+ # see: http://ruby-doc.org/stdlib-2.1.2/libdoc/logger/rdoc/Logger.html
31
+ # eg. log_level: ERROR
32
+ log_level: ERROR
33
+ # general_log > log_rotate related items
34
+ log_rotate:
35
+ # general_log > log_rotate > shift_age: [integer/string]
36
+ # see: http://ruby-doc.org/stdlib-2.1.2/libdoc/logger/rdoc/Logger.html
37
+ shift_age: 7
38
+ # general_log > log_rotate > shift_size: [integer]
39
+ # see: http://ruby-doc.org/stdlib-2.1.2/libdoc/logger/rdoc/Logger.html
40
+ shift_size: 10485760 #10 * 1024 * 1024
41
+
42
+ # access log related items
43
+ access_log:
44
+ # access_log > location: [string]
45
+ # absolute path is preferred
46
+ # eg. location: /var/log/proxy_access.log
47
+ location: proxy_access.log
48
+ # access_log > format: [string]
49
+ # eg. format: "%h %l %u %t \"%r\" %s %b"
50
+ # see: http://httpd.apache.org/docs/current/en/mod/mod_log_config.html
51
+ format: "%h %l %u %t \"%r\" %s %b"
52
+ # access_log > log_rotate related items
53
+ log_rotate:
54
+ # access_log > log_rotate > shift_age: [integer/string]
55
+ # see: http://ruby-doc.org/stdlib-2.1.2/libdoc/logger/rdoc/Logger.html
56
+ shift_age: 7
57
+ # access_log > log_rotate > shift_size: [integer]
58
+ # see: http://ruby-doc.org/stdlib-2.1.2/libdoc/logger/rdoc/Logger.html
59
+ shift_size: 10485760 #10 * 1024 * 1024
data/proxy.pac CHANGED
@@ -1,3 +1,3 @@
1
1
  function FindProxyForURL(url, host) {
2
- return "PROXY localhost:3128;
2
+ return "DIRECT";
3
3
  }
@@ -3,6 +3,8 @@ require 'spec_helper'
3
3
  describe Pacproxy::AccessLogger do
4
4
  describe 'accesslog' do
5
5
  it 'write Apache common log format' do
6
+ Pacproxy::Config.instance.update('pacproxy.yml')
7
+
6
8
  log = Pacproxy::AccessLogger.instance
7
9
  log.logger = ''
8
10
  now = Time.now
@@ -0,0 +1,13 @@
1
+ require 'spec_helper'
2
+
3
+ describe Pacproxy::Config do
4
+ it 'store values from specified yaml file' do
5
+ c = Pacproxy::Config.instance.update('pacproxy.yml')
6
+
7
+ expect(c.config['daemonize']).to eq(true)
8
+ expect(c.config['port']).to eq(3128)
9
+ expect(c.config['pac_file']['location']).to eq('proxy.pac')
10
+ expect(c.config['general_log']['location']).to eq('pacproxy.log')
11
+ expect(c.config['access_log']['log_rotate']['shift_age']).to eq(7)
12
+ end
13
+ end
@@ -52,9 +52,10 @@ describe Pacproxy do
52
52
  end
53
53
 
54
54
  it 'transfer request to server directly' do
55
- @pacproxy_server =
56
- Pacproxy::Pacproxy.new(Port: 13_128,
57
- Proxypac: 'spec/all_direct.pac')
55
+ c = Pacproxy::Config.instance.config
56
+ c['port'] = 13_128
57
+ c['pac_file']['location'] = 'spec/all_direct.pac'
58
+ @pacproxy_server = Pacproxy::Pacproxy.new(c)
58
59
  Thread.new { @pacproxy_server.start }
59
60
  wait_server_status(@pacproxy_server, :Running)
60
61
 
@@ -67,9 +68,10 @@ describe Pacproxy do
67
68
  end
68
69
 
69
70
  it 'transfer request to server directly via HTTPS' do
70
- @pacproxy_server =
71
- Pacproxy::Pacproxy.new(Port: 13_128,
72
- Proxypac: 'spec/all_direct.pac')
71
+ c = Pacproxy::Config.instance.config
72
+ c['port'] = 13_128
73
+ c['pac_file']['location'] = 'spec/all_direct.pac'
74
+ @pacproxy_server = Pacproxy::Pacproxy.new(c)
73
75
  Thread.new { @pacproxy_server.start }
74
76
  wait_server_status(@pacproxy_server, :Running)
75
77
 
@@ -83,9 +85,10 @@ describe Pacproxy do
83
85
  end
84
86
 
85
87
  it 'transfer request to server directly with PUT method' do
86
- @pacproxy_server =
87
- Pacproxy::Pacproxy.new(Port: 13_128,
88
- Proxypac: 'spec/all_direct.pac')
88
+ c = Pacproxy::Config.instance.config
89
+ c['port'] = 13_128
90
+ c['pac_file']['location'] = 'spec/all_direct.pac'
91
+ @pacproxy_server = Pacproxy::Pacproxy.new(c)
89
92
  Thread.new { @pacproxy_server.start }
90
93
  wait_server_status(@pacproxy_server, :Running)
91
94
 
@@ -98,9 +101,10 @@ describe Pacproxy do
98
101
  end
99
102
 
100
103
  it 'transfer request to server via parent proxy' do
101
- @pacproxy_server =
102
- Pacproxy::Pacproxy.new(Port: 13_128,
103
- Proxypac: 'spec/all_proxy.pac')
104
+ c = Pacproxy::Config.instance.config
105
+ c['port'] = 13_128
106
+ c['pac_file']['location'] = 'spec/all_direct.pac'
107
+ @pacproxy_server = Pacproxy::Pacproxy.new(c)
104
108
  Thread.new { @pacproxy_server.start }
105
109
  wait_server_status(@pacproxy_server, :Running)
106
110
 
@@ -113,9 +117,10 @@ describe Pacproxy do
113
117
  end
114
118
 
115
119
  it 'transfer request to server via parent proxy partially' do
116
- @pacproxy_server =
117
- Pacproxy::Pacproxy.new(Port: 13_128,
118
- Proxypac: 'spec/partial_proxy.pac')
120
+ c = Pacproxy::Config.instance.config
121
+ c['port'] = 13_128
122
+ c['pac_file']['location'] = 'spec/partial_proxy.pac'
123
+ @pacproxy_server = Pacproxy::Pacproxy.new(c)
119
124
  Thread.new { @pacproxy_server.start }
120
125
  wait_server_status(@pacproxy_server, :Running)
121
126
 
@@ -128,9 +133,10 @@ describe Pacproxy do
128
133
  end
129
134
 
130
135
  it 'transfer request with auth to server via parent proxy' do
131
- @pacproxy_server =
132
- Pacproxy::Pacproxy.new(Port: 13_128,
133
- Proxypac: 'spec/all_proxy.pac')
136
+ c = Pacproxy::Config.instance.config
137
+ c['port'] = 13_128
138
+ c['pac_file']['location'] = 'spec/all_proxy.pac'
139
+ @pacproxy_server = Pacproxy::Pacproxy.new(c)
134
140
 
135
141
  Thread.new { @pacproxy_server.start }
136
142
  wait_server_status(@pacproxy_server, :Running)
@@ -140,11 +146,60 @@ describe Pacproxy do
140
146
  %Q(Basic #{['user01:pass01'].pack('m').delete("\n")})
141
147
  }
142
148
  }
143
- p header: header
144
149
  res = c.get('http://127.0.0.1:13080/', header)
145
150
  expect(res.status).to eq(200)
146
151
  res = c.get('http://127.0.0.1:13080/noproxy/', header)
147
152
  expect(res.status).to eq(200)
148
153
  end
154
+
155
+ it 'respond 407 when upstrem proxy respond 407 on http' do
156
+ proxy_proc = proc do |_req, resp|
157
+ resp.header.merge!('Proxy-Authenticate' => "Basic realm=\"proxy\"")
158
+ fail WEBrick::HTTPStatus::ProxyAuthenticationRequired
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
+ c = Pacproxy::Config.instance.config
165
+ c['port'] = 13_128
166
+ c['pac_file']['location'] = 'spec/all_proxy.pac'
167
+ @pacproxy_server = Pacproxy::Pacproxy.new(c)
168
+
169
+ Thread.new { @pacproxy_server.start }
170
+ wait_server_status(@pacproxy_server, :Running)
171
+
172
+ c = HTTPClient.new('http://127.0.0.1:13128')
173
+ res = c.get('http://127.0.0.1:13080/')
174
+ expect(res.status).to eq(407)
175
+ expect(res.header['Proxy-Authenticate']).to eq(["Basic realm=\"proxy\""])
176
+ end
177
+
178
+ it 'respond 407 when upstrem proxy respond 407 on https' do
179
+ proxy_proc = proc do |_req, resp|
180
+ resp.header.merge!('Proxy-Authenticate' => "Basic realm=\"proxy\"")
181
+ fail WEBrick::HTTPStatus::ProxyAuthenticationRequired
182
+ end
183
+
184
+ pc = @proxy_server.instance_variable_get('@config')
185
+ @proxy_server.instance_variable_set('@config',
186
+ pc.merge(ProxyAuthProc: proxy_proc))
187
+ c = Pacproxy::Config.instance.config
188
+ c['port'] = 13_128
189
+ c['pac_file']['location'] = 'spec/all_proxy.pac'
190
+ @pacproxy_server = Pacproxy::Pacproxy.new(c)
191
+
192
+ Thread.new { @pacproxy_server.start }
193
+ wait_server_status(@pacproxy_server, :Running)
194
+
195
+ c = HTTPClient.new('http://127.0.0.1:13128')
196
+ begin
197
+ c.get('https://127.0.0.1:13080/')
198
+ rescue => e
199
+ expect(e.res.status).to eq(407)
200
+ expect(e.res.header['Proxy-Authenticate'])
201
+ .to eq(["Basic realm=\"proxy\""])
202
+ end
203
+ end
149
204
  end
150
205
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pacproxy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5
4
+ version: 0.0.6
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-08-26 00:00:00.000000000 Z
11
+ date: 2014-09-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: pac
@@ -122,6 +122,20 @@ dependencies:
122
122
  - - ~>
123
123
  - !ruby/object:Gem::Version
124
124
  version: '0.7'
125
+ - !ruby/object:Gem::Dependency
126
+ name: byebug
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ~>
130
+ - !ruby/object:Gem::Version
131
+ version: 3.4.0
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ~>
137
+ - !ruby/object:Gem::Version
138
+ version: 3.4.0
125
139
  description: A proxy server works with proxy.pac
126
140
  email:
127
141
  - ota_h@nifty.com
@@ -139,17 +153,20 @@ files:
139
153
  - bin/pacproxy
140
154
  - lib/pacproxy.rb
141
155
  - lib/pacproxy/access_logger.rb
156
+ - lib/pacproxy/config.rb
142
157
  - lib/pacproxy/general_logger.rb
143
158
  - lib/pacproxy/loggable.rb
144
159
  - lib/pacproxy/pac_file.rb
145
160
  - lib/pacproxy/pacproxy.rb
146
161
  - lib/pacproxy/version.rb
147
162
  - pacproxy.gemspec
163
+ - pacproxy.yml
148
164
  - pacproxy/.gitignore
149
165
  - proxy.pac
150
166
  - spec/access_logger_spec.rb
151
167
  - spec/all_direct.pac
152
168
  - spec/all_proxy.pac
169
+ - spec/config_spec.rb
153
170
  - spec/loggable_spec.rb
154
171
  - spec/pac_file_spec.rb
155
172
  - spec/pacproxy_spec.rb
@@ -183,6 +200,7 @@ test_files:
183
200
  - spec/access_logger_spec.rb
184
201
  - spec/all_direct.pac
185
202
  - spec/all_proxy.pac
203
+ - spec/config_spec.rb
186
204
  - spec/loggable_spec.rb
187
205
  - spec/pac_file_spec.rb
188
206
  - spec/pacproxy_spec.rb