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