proxy-server 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.
- data/.gitignore +4 -4
- data/Gemfile +1 -1
- data/Gemfile.lock +8 -7
- data/Rakefile +20 -19
- data/examples/proxy_in_process.rb +22 -22
- data/lib/proxy-server.rb +3 -2
- data/lib/proxy/port_prober.rb +15 -15
- data/lib/proxy/proxy_app.rb +75 -0
- data/lib/proxy/proxy_manager.rb +58 -99
- data/lib/proxy/proxy_server.rb +122 -122
- data/proxy-server.gemspec +35 -35
- data/spec/proxy/proxy_app_spec.rb +99 -0
- data/spec/proxy/proxy_manager_spec.rb +19 -95
- data/spec/proxy/proxy_server_spec.rb +119 -119
- data/spec/spec_helper.rb +8 -8
- metadata +30 -28
data/.gitignore
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
.idea
|
2
|
-
.bundle
|
3
|
-
coverage
|
4
|
-
pkg
|
1
|
+
.idea
|
2
|
+
.bundle
|
3
|
+
coverage
|
4
|
+
pkg
|
data/Gemfile
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
source :rubygems
|
1
|
+
source :rubygems
|
2
2
|
gemspec
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
proxy-server (0.0.
|
4
|
+
proxy-server (0.0.7)
|
5
5
|
em-http-request
|
6
6
|
em-synchrony
|
7
7
|
goliath (= 0.9.2)
|
@@ -28,7 +28,7 @@ GEM
|
|
28
28
|
eventmachine
|
29
29
|
em-synchrony (1.0.0)
|
30
30
|
eventmachine (>= 1.0.0.beta.1)
|
31
|
-
eventmachine (1.0.0.beta.4
|
31
|
+
eventmachine (1.0.0.beta.4)
|
32
32
|
goliath (0.9.2)
|
33
33
|
async-rack
|
34
34
|
em-synchrony (>= 0.3.0.beta.1)
|
@@ -40,14 +40,14 @@ GEM
|
|
40
40
|
rack (>= 1.2.2)
|
41
41
|
rack-contrib
|
42
42
|
rack-respond_to
|
43
|
-
http_parser.rb (0.5.3
|
43
|
+
http_parser.rb (0.5.3)
|
44
44
|
http_router (0.8.11)
|
45
45
|
rack (>= 1.0.0)
|
46
46
|
url_mount (~> 0.2.1)
|
47
|
-
httpclient (2.2.
|
48
|
-
json (1.6.
|
47
|
+
httpclient (2.2.4)
|
48
|
+
json (1.6.3)
|
49
49
|
log4r (1.1.9)
|
50
|
-
multi_json (1.0.
|
50
|
+
multi_json (1.0.4)
|
51
51
|
rack (1.3.5)
|
52
52
|
rack-accept-media-types (0.9)
|
53
53
|
rack-contrib (1.1.0)
|
@@ -82,11 +82,12 @@ GEM
|
|
82
82
|
tilt (1.3.3)
|
83
83
|
url_mount (0.2.1)
|
84
84
|
rack
|
85
|
-
webmock (1.7.
|
85
|
+
webmock (1.7.8)
|
86
86
|
addressable (~> 2.2, > 2.2.5)
|
87
87
|
crack (>= 0.1.7)
|
88
88
|
|
89
89
|
PLATFORMS
|
90
|
+
ruby
|
90
91
|
x86-mingw32
|
91
92
|
|
92
93
|
DEPENDENCIES
|
data/Rakefile
CHANGED
@@ -1,19 +1,20 @@
|
|
1
|
-
require 'rubygems'
|
2
|
-
require 'bundler'
|
3
|
-
require 'rspec/core/rake_task'
|
4
|
-
Bundler::GemHelper.install_tasks
|
5
|
-
|
6
|
-
task :coverage do
|
7
|
-
require 'simplecov'
|
8
|
-
require 'rspec/core'
|
9
|
-
|
10
|
-
SimpleCov.start do
|
11
|
-
add_group "lib", "lib"
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler'
|
3
|
+
require 'rspec/core/rake_task'
|
4
|
+
Bundler::GemHelper.install_tasks
|
5
|
+
|
6
|
+
task :coverage do
|
7
|
+
require 'simplecov'
|
8
|
+
require 'rspec/core'
|
9
|
+
|
10
|
+
SimpleCov.start do
|
11
|
+
add_group "lib", "lib"
|
12
|
+
add_filter 'spec'
|
13
|
+
end
|
14
|
+
SimpleCov.start
|
15
|
+
RSpec::Core::Runner.run %w[spec]
|
16
|
+
end
|
17
|
+
|
18
|
+
|
19
|
+
require 'rake/clean'
|
20
|
+
CLEAN.include %w(**/*.{log,pyc,rbc,tgz} doc)
|
@@ -1,22 +1,22 @@
|
|
1
|
-
require '../lib/proxy-server'
|
2
|
-
require 'rest_client' # you will need to install this via gem install rest-client / bundler etc
|
3
|
-
require 'httpclient'
|
4
|
-
require 'json'
|
5
|
-
|
6
|
-
Thread.abort_on_exception=true
|
7
|
-
Thread.new do
|
8
|
-
ProxyManager.start :port => 4983
|
9
|
-
end
|
10
|
-
|
11
|
-
until_proxy_is_running = 3
|
12
|
-
sleep until_proxy_is_running # need to implement the ability to wait for the proxy to be running
|
13
|
-
|
14
|
-
proxy = JSON.parse(RestClient.post 'http://localhost:4983/proxies', {})
|
15
|
-
|
16
|
-
RestClient.post "http://localhost:4983/proxies/#{proxy['port']}/requests", {:track => 'google.com'}
|
17
|
-
|
18
|
-
client = HTTPClient.new :proxy => "http://localhost:#{proxy['port']}"
|
19
|
-
client.get 'http://www.google.com'
|
20
|
-
client.get 'http://github.com'
|
21
|
-
|
22
|
-
p JSON.parse(HTTPClient.get("http://localhost:4983/proxies/#{proxy['port']}/requests").body)
|
1
|
+
require '../lib/proxy-server'
|
2
|
+
require 'rest_client' # you will need to install this via gem install rest-client / bundler etc
|
3
|
+
require 'httpclient'
|
4
|
+
require 'json'
|
5
|
+
|
6
|
+
Thread.abort_on_exception=true
|
7
|
+
Thread.new do
|
8
|
+
ProxyManager.start :port => 4983
|
9
|
+
end
|
10
|
+
|
11
|
+
until_proxy_is_running = 3
|
12
|
+
sleep until_proxy_is_running # need to implement the ability to wait for the proxy to be running
|
13
|
+
|
14
|
+
proxy = JSON.parse(RestClient.post 'http://localhost:4983/proxies', {})
|
15
|
+
|
16
|
+
RestClient.post "http://localhost:4983/proxies/#{proxy['port']}/requests", {:track => 'google.com'}
|
17
|
+
|
18
|
+
client = HTTPClient.new :proxy => "http://localhost:#{proxy['port']}"
|
19
|
+
client.get 'http://www.google.com'
|
20
|
+
client.get 'http://github.com'
|
21
|
+
|
22
|
+
p JSON.parse(HTTPClient.get("http://localhost:4983/proxies/#{proxy['port']}/requests").body)
|
data/lib/proxy-server.rb
CHANGED
@@ -1,2 +1,3 @@
|
|
1
|
-
require_relative './proxy/proxy_server'
|
2
|
-
require_relative './proxy/proxy_manager'
|
1
|
+
require_relative './proxy/proxy_server'
|
2
|
+
require_relative './proxy/proxy_manager'
|
3
|
+
require_relative './proxy/proxy_app'
|
data/lib/proxy/port_prober.rb
CHANGED
@@ -1,15 +1,15 @@
|
|
1
|
-
# lovingly reused from selenium-webdriver
|
2
|
-
|
3
|
-
class PortProber
|
4
|
-
def self.above(port)
|
5
|
-
port += 1 until free? port
|
6
|
-
port
|
7
|
-
end
|
8
|
-
|
9
|
-
def self.free?(port)
|
10
|
-
TCPServer.new('localhost', port).close
|
11
|
-
true
|
12
|
-
rescue SocketError, Errno::EADDRINUSE
|
13
|
-
false
|
14
|
-
end
|
15
|
-
end
|
1
|
+
# lovingly reused from selenium-webdriver
|
2
|
+
|
3
|
+
class PortProber
|
4
|
+
def self.above(port)
|
5
|
+
port += 1 until free? port
|
6
|
+
port
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.free?(port)
|
10
|
+
TCPServer.new('localhost', port).close
|
11
|
+
true
|
12
|
+
rescue SocketError, Errno::EADDRINUSE
|
13
|
+
false
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'sinatra/base'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
class ProxyApp < Sinatra::Base
|
5
|
+
disable :show_exceptions
|
6
|
+
|
7
|
+
def initialize(proxy_manager = ProxyManager.new)
|
8
|
+
@proxy_manager = proxy_manager
|
9
|
+
super
|
10
|
+
end
|
11
|
+
|
12
|
+
get '/proxies' do
|
13
|
+
@proxy_manager.proxies.to_json
|
14
|
+
end
|
15
|
+
|
16
|
+
post '/proxies' do
|
17
|
+
proxy_uri = @proxy_manager.new_proxy
|
18
|
+
|
19
|
+
options = {
|
20
|
+
:port => proxy_uri.port
|
21
|
+
}
|
22
|
+
|
23
|
+
options[:proxy] = params[:proxy] if params[:proxy]
|
24
|
+
@proxy_manager.start_proxy(options)
|
25
|
+
|
26
|
+
{
|
27
|
+
:url => proxy_uri.to_s,
|
28
|
+
:port => proxy_uri.port
|
29
|
+
}.to_json
|
30
|
+
end
|
31
|
+
|
32
|
+
delete '/proxies' do
|
33
|
+
@proxy_manager.delete_proxies
|
34
|
+
end
|
35
|
+
|
36
|
+
delete '/proxies/:port' do |port|
|
37
|
+
@proxy_manager.stop_proxy port.to_i
|
38
|
+
end
|
39
|
+
|
40
|
+
post '/proxies/:port/reset' do |port|
|
41
|
+
proxy_server = @proxy_manager.get_proxy(port.to_i)
|
42
|
+
proxy_server.reset
|
43
|
+
end
|
44
|
+
|
45
|
+
post '/proxies/:port/requests' do |port|
|
46
|
+
proxy_server = @proxy_manager.get_proxy(port.to_i)
|
47
|
+
proxy_server.track_request(params[:track])
|
48
|
+
end
|
49
|
+
|
50
|
+
get '/proxies/:port/requests' do |port|
|
51
|
+
proxy_server = @proxy_manager.get_proxy(port.to_i)
|
52
|
+
proxy_server.requests.to_json
|
53
|
+
end
|
54
|
+
|
55
|
+
post '/proxies/:port/requests/substitute' do |port|
|
56
|
+
proxy_server = @proxy_manager.get_proxy(port.to_i)
|
57
|
+
options = {}
|
58
|
+
options[:body] = params[:body] if params[:body]
|
59
|
+
options[:url] = params[:url] if params[:url]
|
60
|
+
proxy_server.substitute_request(params[:pattern], options)
|
61
|
+
end
|
62
|
+
|
63
|
+
class << self
|
64
|
+
def start(options = {})
|
65
|
+
require 'thin'
|
66
|
+
server = ::Thin::Server.new(
|
67
|
+
'0.0.0.0',
|
68
|
+
options.fetch(:port, 4985),
|
69
|
+
ProxyApp.new
|
70
|
+
)
|
71
|
+
|
72
|
+
server.start
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
data/lib/proxy/proxy_manager.rb
CHANGED
@@ -1,100 +1,59 @@
|
|
1
|
-
require_relative './proxy_server'
|
2
|
-
require_relative './port_prober'
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
end
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
end
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
post '/proxies/:port/requests/substitute' do |port|
|
60
|
-
proxy_server = get_proxy(port.to_i)
|
61
|
-
options = {}
|
62
|
-
options[:body] = params[:body] if params[:body]
|
63
|
-
options[:url] = params[:url] if params[:url]
|
64
|
-
proxy_server.substitute_request(params[:pattern], options)
|
65
|
-
end
|
66
|
-
|
67
|
-
def get_proxy(port)
|
68
|
-
running_proxy_servers[port]
|
69
|
-
end
|
70
|
-
|
71
|
-
def stop_proxy(port)
|
72
|
-
proxy_server = running_proxy_servers[port]
|
73
|
-
proxy_server.stop
|
74
|
-
running_proxy_servers.delete proxy_server
|
75
|
-
end
|
76
|
-
|
77
|
-
def start_proxy(options)
|
78
|
-
proxy_server = ProxyServer.new(options)
|
79
|
-
proxy_server.start
|
80
|
-
running_proxy_servers[options[:port]] = proxy_server
|
81
|
-
end
|
82
|
-
|
83
|
-
def find_proxy_port
|
84
|
-
new_proxy_port = (assigned_proxy_ports.max || ProxyManager::START_PORT) + 1
|
85
|
-
PortProber.above(new_proxy_port)
|
86
|
-
end
|
87
|
-
|
88
|
-
class << self
|
89
|
-
def start(options = {})
|
90
|
-
require 'thin'
|
91
|
-
server = ::Thin::Server.new(
|
92
|
-
'0.0.0.0',
|
93
|
-
options.fetch(:port, 4985),
|
94
|
-
ProxyManager.new
|
95
|
-
)
|
96
|
-
|
97
|
-
server.start
|
98
|
-
end
|
99
|
-
end
|
1
|
+
require_relative './proxy_server'
|
2
|
+
require_relative './port_prober'
|
3
|
+
|
4
|
+
class ProxyManager
|
5
|
+
START_PORT = 5000
|
6
|
+
|
7
|
+
attr_reader :running_proxy_servers, :assigned_proxy_ports
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
@running_proxy_servers = {}
|
11
|
+
@assigned_proxy_ports = []
|
12
|
+
end
|
13
|
+
|
14
|
+
def get_proxy(port)
|
15
|
+
running_proxy_servers[port]
|
16
|
+
end
|
17
|
+
|
18
|
+
def stop_proxy(port)
|
19
|
+
proxy_server = running_proxy_servers[port]
|
20
|
+
proxy_server.stop
|
21
|
+
running_proxy_servers.delete proxy_server
|
22
|
+
end
|
23
|
+
|
24
|
+
def delete_proxies
|
25
|
+
assigned_proxy_ports.clear
|
26
|
+
end
|
27
|
+
|
28
|
+
def proxies
|
29
|
+
assigned_proxy_ports
|
30
|
+
end
|
31
|
+
|
32
|
+
def start_proxy(options)
|
33
|
+
proxy_server = ProxyServer.new(options)
|
34
|
+
proxy_server.start
|
35
|
+
running_proxy_servers[options[:port]] = proxy_server
|
36
|
+
end
|
37
|
+
|
38
|
+
def new_proxy
|
39
|
+
port = find_proxy_port
|
40
|
+
assigned_proxy_ports << port
|
41
|
+
URI.parse("http://#{proxy_host_address}:#{port}")
|
42
|
+
end
|
43
|
+
|
44
|
+
def proxy_host_address
|
45
|
+
orig, Socket.do_not_reverse_lookup = Socket.do_not_reverse_lookup, true # turn off reverse DNS resolution temporarily
|
46
|
+
|
47
|
+
UDPSocket.open do |s|
|
48
|
+
s.connect '64.233.187.99', 1
|
49
|
+
s.addr.last
|
50
|
+
end
|
51
|
+
ensure
|
52
|
+
Socket.do_not_reverse_lookup = orig
|
53
|
+
end
|
54
|
+
|
55
|
+
def find_proxy_port
|
56
|
+
new_proxy_port = (assigned_proxy_ports.max || ProxyManager::START_PORT) + 1
|
57
|
+
PortProber.above(new_proxy_port)
|
58
|
+
end
|
100
59
|
end
|
data/lib/proxy/proxy_server.rb
CHANGED
@@ -1,122 +1,122 @@
|
|
1
|
-
require 'goliath/api'
|
2
|
-
require 'goliath/server'
|
3
|
-
require 'em-synchrony/em-http'
|
4
|
-
class ProxyServer < Goliath::API
|
5
|
-
attr_reader :upstream_proxy, :port
|
6
|
-
attr_reader :requests, :track_requests, :substitute_requests
|
7
|
-
DEFAULT_PORT = 8080
|
8
|
-
|
9
|
-
def initialize(options = {})
|
10
|
-
@upstream_proxy = URI.parse(options[:proxy]) if options[:proxy]
|
11
|
-
|
12
|
-
@port = options.fetch(:port, DEFAULT_PORT)
|
13
|
-
|
14
|
-
@substitute_requests = {}
|
15
|
-
@requests = []
|
16
|
-
@track_requests = []
|
17
|
-
end
|
18
|
-
|
19
|
-
def start
|
20
|
-
Thread.abort_on_exception = true
|
21
|
-
require 'log4r'
|
22
|
-
@proxy_thread = Thread.new do
|
23
|
-
Goliath.env = :development
|
24
|
-
server = Goliath::Server.new('0.0.0.0', self.port)
|
25
|
-
server.app = Goliath::Rack::Builder.build(self.class, self)
|
26
|
-
server.logger = Log4r::Logger.new 'proxy-server'
|
27
|
-
|
28
|
-
server.options = {
|
29
|
-
:daemonize => false,
|
30
|
-
:verbose => true,
|
31
|
-
:log_stdout => true,
|
32
|
-
:env => :development
|
33
|
-
}
|
34
|
-
server.start do
|
35
|
-
p "Proxy started"
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
def stop
|
41
|
-
Thread.kill @proxy_thread if @proxy_thread
|
42
|
-
end
|
43
|
-
|
44
|
-
def reset
|
45
|
-
@requests.clear
|
46
|
-
@track_requests.clear
|
47
|
-
@substitute_requests.clear
|
48
|
-
end
|
49
|
-
|
50
|
-
def response(env)
|
51
|
-
uri = get_uri env
|
52
|
-
track uri if tracking_enabled? uri
|
53
|
-
return substitute uri if has_substitute? uri
|
54
|
-
request_uri uri
|
55
|
-
end
|
56
|
-
|
57
|
-
def get_uri(env)
|
58
|
-
env['REQUEST_URI'] || "http://#{env['SERVER_NAME']}#{env['PATH_INFO']}#{env['QUERY_STRING'].length > 0 ? '?'+env['QUERY_STRING'] : ''}"
|
59
|
-
end
|
60
|
-
|
61
|
-
def request_uri(uri)
|
62
|
-
options = {
|
63
|
-
:redirects => 1
|
64
|
-
}
|
65
|
-
get_proxy(options)
|
66
|
-
client= EM::HttpRequest.new(uri, options)
|
67
|
-
request = client.get
|
68
|
-
[request.response_header.status, request.response_header, request.response]
|
69
|
-
end
|
70
|
-
|
71
|
-
def get_proxy(options)
|
72
|
-
options[:proxy] = {:type => 'http', :host => @upstream_proxy.host, :port => @upstream_proxy.port} if @upstream_proxy
|
73
|
-
end
|
74
|
-
|
75
|
-
def get_substituted_response(options)
|
76
|
-
if options[:body]
|
77
|
-
[200, {}, [options[:body]]]
|
78
|
-
elsif options[:url]
|
79
|
-
request_uri options[:url]
|
80
|
-
end
|
81
|
-
end
|
82
|
-
|
83
|
-
def substitute(uri)
|
84
|
-
@substitute_requests.each do |pattern, options|
|
85
|
-
if Regexp.new(pattern) =~ uri
|
86
|
-
return get_substituted_response(options)
|
87
|
-
end
|
88
|
-
end
|
89
|
-
nil
|
90
|
-
end
|
91
|
-
|
92
|
-
def has_substitute?(uri)
|
93
|
-
@substitute_requests.each do |pattern, options|
|
94
|
-
if Regexp.new(pattern) =~ uri
|
95
|
-
return true
|
96
|
-
end
|
97
|
-
end
|
98
|
-
false
|
99
|
-
end
|
100
|
-
|
101
|
-
def substitute_request(pattern, options)
|
102
|
-
@substitute_requests[pattern] = options
|
103
|
-
end
|
104
|
-
|
105
|
-
def track_request(pattern)
|
106
|
-
@track_requests << pattern
|
107
|
-
end
|
108
|
-
|
109
|
-
def track(uri)
|
110
|
-
@requests << uri
|
111
|
-
@track_requests.each do |pattern|
|
112
|
-
@requests << uri if Regexp.new(pattern) =~ uri
|
113
|
-
end
|
114
|
-
end
|
115
|
-
|
116
|
-
def tracking_enabled?(uri)
|
117
|
-
@track_requests.each do |pattern|
|
118
|
-
return true if Regexp.new(pattern) =~ uri
|
119
|
-
end
|
120
|
-
false
|
121
|
-
end
|
122
|
-
end
|
1
|
+
require 'goliath/api'
|
2
|
+
require 'goliath/server'
|
3
|
+
require 'em-synchrony/em-http'
|
4
|
+
class ProxyServer < Goliath::API
|
5
|
+
attr_reader :upstream_proxy, :port
|
6
|
+
attr_reader :requests, :track_requests, :substitute_requests
|
7
|
+
DEFAULT_PORT = 8080
|
8
|
+
|
9
|
+
def initialize(options = {})
|
10
|
+
@upstream_proxy = URI.parse(options[:proxy]) if options[:proxy]
|
11
|
+
|
12
|
+
@port = options.fetch(:port, DEFAULT_PORT)
|
13
|
+
|
14
|
+
@substitute_requests = {}
|
15
|
+
@requests = []
|
16
|
+
@track_requests = []
|
17
|
+
end
|
18
|
+
|
19
|
+
def start
|
20
|
+
Thread.abort_on_exception = true
|
21
|
+
require 'log4r'
|
22
|
+
@proxy_thread = Thread.new do
|
23
|
+
Goliath.env = :development
|
24
|
+
server = Goliath::Server.new('0.0.0.0', self.port)
|
25
|
+
server.app = Goliath::Rack::Builder.build(self.class, self)
|
26
|
+
server.logger = Log4r::Logger.new 'proxy-server'
|
27
|
+
|
28
|
+
server.options = {
|
29
|
+
:daemonize => false,
|
30
|
+
:verbose => true,
|
31
|
+
:log_stdout => true,
|
32
|
+
:env => :development
|
33
|
+
}
|
34
|
+
server.start do
|
35
|
+
p "Proxy started"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def stop
|
41
|
+
Thread.kill @proxy_thread if @proxy_thread
|
42
|
+
end
|
43
|
+
|
44
|
+
def reset
|
45
|
+
@requests.clear
|
46
|
+
@track_requests.clear
|
47
|
+
@substitute_requests.clear
|
48
|
+
end
|
49
|
+
|
50
|
+
def response(env)
|
51
|
+
uri = get_uri env
|
52
|
+
track uri if tracking_enabled? uri
|
53
|
+
return substitute uri if has_substitute? uri
|
54
|
+
request_uri uri
|
55
|
+
end
|
56
|
+
|
57
|
+
def get_uri(env)
|
58
|
+
env['REQUEST_URI'] || "http://#{env['SERVER_NAME']}#{env['PATH_INFO']}#{env['QUERY_STRING'].length > 0 ? '?'+env['QUERY_STRING'] : ''}"
|
59
|
+
end
|
60
|
+
|
61
|
+
def request_uri(uri)
|
62
|
+
options = {
|
63
|
+
:redirects => 1
|
64
|
+
}
|
65
|
+
get_proxy(options)
|
66
|
+
client= EM::HttpRequest.new(uri, options)
|
67
|
+
request = client.get
|
68
|
+
[request.response_header.status, request.response_header, request.response]
|
69
|
+
end
|
70
|
+
|
71
|
+
def get_proxy(options)
|
72
|
+
options[:proxy] = {:type => 'http', :host => @upstream_proxy.host, :port => @upstream_proxy.port} if @upstream_proxy
|
73
|
+
end
|
74
|
+
|
75
|
+
def get_substituted_response(options)
|
76
|
+
if options[:body]
|
77
|
+
[200, {}, [options[:body]]]
|
78
|
+
elsif options[:url]
|
79
|
+
request_uri options[:url]
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def substitute(uri)
|
84
|
+
@substitute_requests.each do |pattern, options|
|
85
|
+
if Regexp.new(pattern) =~ uri
|
86
|
+
return get_substituted_response(options)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
nil
|
90
|
+
end
|
91
|
+
|
92
|
+
def has_substitute?(uri)
|
93
|
+
@substitute_requests.each do |pattern, options|
|
94
|
+
if Regexp.new(pattern) =~ uri
|
95
|
+
return true
|
96
|
+
end
|
97
|
+
end
|
98
|
+
false
|
99
|
+
end
|
100
|
+
|
101
|
+
def substitute_request(pattern, options)
|
102
|
+
@substitute_requests[pattern] = options
|
103
|
+
end
|
104
|
+
|
105
|
+
def track_request(pattern)
|
106
|
+
@track_requests << pattern
|
107
|
+
end
|
108
|
+
|
109
|
+
def track(uri)
|
110
|
+
@requests << uri
|
111
|
+
@track_requests.each do |pattern|
|
112
|
+
@requests << uri if Regexp.new(pattern) =~ uri
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
def tracking_enabled?(uri)
|
117
|
+
@track_requests.each do |pattern|
|
118
|
+
return true if Regexp.new(pattern) =~ uri
|
119
|
+
end
|
120
|
+
false
|
121
|
+
end
|
122
|
+
end
|