Browse files

seperated proxy management from web management app

  • Loading branch information...
1 parent c8873d0 commit c422d06fbe023e7f5d2f43ffccd77943a6d44bde @dereke committed Dec 12, 2011
Showing with 222 additions and 162 deletions.
  1. +8 −7 Gemfile.lock
  2. +1 −0 Rakefile
  3. +2 −1 lib/proxy-server.rb
  4. +75 −0 lib/proxy/proxy_app.rb
  5. +27 −68 lib/proxy/proxy_manager.rb
  6. +1 −1 proxy-server.gemspec
  7. +99 −0 spec/proxy/proxy_app_spec.rb
  8. +9 −85 spec/proxy/proxy_manager_spec.rb
View
15 Gemfile.lock
@@ -1,7 +1,7 @@
PATH
remote: .
specs:
- proxy-server (0.0.6)
+ proxy-server (0.0.7)
em-http-request
em-synchrony
goliath (= 0.9.2)
@@ -28,7 +28,7 @@ GEM
eventmachine
em-synchrony (1.0.0)
eventmachine (>= 1.0.0.beta.1)
- eventmachine (1.0.0.beta.4.1-x86-mingw32)
+ eventmachine (1.0.0.beta.4)
goliath (0.9.2)
async-rack
em-synchrony (>= 0.3.0.beta.1)
@@ -40,14 +40,14 @@ GEM
rack (>= 1.2.2)
rack-contrib
rack-respond_to
- http_parser.rb (0.5.3-x86-mingw32)
+ http_parser.rb (0.5.3)
http_router (0.8.11)
rack (>= 1.0.0)
url_mount (~> 0.2.1)
- httpclient (2.2.3)
- json (1.6.1)
+ httpclient (2.2.4)
+ json (1.6.3)
log4r (1.1.9)
- multi_json (1.0.3)
+ multi_json (1.0.4)
rack (1.3.5)
rack-accept-media-types (0.9)
rack-contrib (1.1.0)
@@ -82,11 +82,12 @@ GEM
tilt (1.3.3)
url_mount (0.2.1)
rack
- webmock (1.7.6)
+ webmock (1.7.8)
addressable (~> 2.2, > 2.2.5)
crack (>= 0.1.7)
PLATFORMS
+ ruby
x86-mingw32
DEPENDENCIES
View
1 Rakefile
@@ -9,6 +9,7 @@ task :coverage do
SimpleCov.start do
add_group "lib", "lib"
+ add_filter 'spec'
end
SimpleCov.start
RSpec::Core::Runner.run %w[spec]
View
3 lib/proxy-server.rb
@@ -1,2 +1,3 @@
require_relative './proxy/proxy_server'
-require_relative './proxy/proxy_manager'
+require_relative './proxy/proxy_manager'
+require_relative './proxy/proxy_app'
View
75 lib/proxy/proxy_app.rb
@@ -0,0 +1,75 @@
+require 'sinatra/base'
+require 'json'
+
+class ProxyApp < Sinatra::Base
+ disable :show_exceptions
+
+ def initialize(proxy_manager = ProxyManager.new)
+ @proxy_manager = proxy_manager
+ super
+ end
+
+ get '/proxies' do
+ @proxy_manager.proxies.to_json
+ end
+
+ post '/proxies' do
+ proxy_uri = @proxy_manager.new_proxy
+
+ options = {
+ :port => proxy_uri.port
+ }
+
+ options[:proxy] = params[:proxy] if params[:proxy]
+ @proxy_manager.start_proxy(options)
+
+ {
+ :url => proxy_uri.to_s,
+ :port => proxy_uri.port
+ }.to_json
+ end
+
+ delete '/proxies' do
+ @proxy_manager.delete_proxies
+ end
+
+ delete '/proxies/:port' do |port|
+ @proxy_manager.stop_proxy port.to_i
+ end
+
+ post '/proxies/:port/reset' do |port|
+ proxy_server = @proxy_manager.get_proxy(port.to_i)
+ proxy_server.reset
+ end
+
+ post '/proxies/:port/requests' do |port|
+ proxy_server = @proxy_manager.get_proxy(port.to_i)
+ proxy_server.track_request(params[:track])
+ end
+
+ get '/proxies/:port/requests' do |port|
+ proxy_server = @proxy_manager.get_proxy(port.to_i)
+ proxy_server.requests.to_json
+ end
+
+ post '/proxies/:port/requests/substitute' do |port|
+ proxy_server = @proxy_manager.get_proxy(port.to_i)
+ options = {}
+ options[:body] = params[:body] if params[:body]
+ options[:url] = params[:url] if params[:url]
+ proxy_server.substitute_request(params[:pattern], options)
+ end
+
+ class << self
+ def start(options = {})
+ require 'thin'
+ server = ::Thin::Server.new(
+ '0.0.0.0',
+ options.fetch(:port, 4985),
+ ProxyApp.new
+ )
+
+ server.start
+ end
+ end
+end
View
95 lib/proxy/proxy_manager.rb
@@ -1,67 +1,14 @@
require_relative './proxy_server'
require_relative './port_prober'
-require 'sinatra/base'
-require 'json'
-class ProxyManager < Sinatra::Base
+class ProxyManager
START_PORT = 5000
attr_reader :running_proxy_servers, :assigned_proxy_ports
- disable :show_exceptions
- def initialize()
+ def initialize
@running_proxy_servers = {}
@assigned_proxy_ports = []
- super
- end
-
- get '/proxies' do
- assigned_proxy_ports.to_json
- end
-
- post '/proxies' do
- new_proxy_port = find_proxy_port
- assigned_proxy_ports << new_proxy_port
-
- options = {
- :port => new_proxy_port
- }
-
- options[:proxy] = params[:proxy] if params[:proxy]
- start_proxy(options)
-
- {:port => new_proxy_port}.to_json
- end
-
- delete '/proxies' do
- assigned_proxy_ports.clear
- end
-
- delete '/proxies/:port' do |port|
- stop_proxy port.to_i
- end
-
- post '/proxies/:port/reset' do |port|
- proxy_server = get_proxy(port.to_i)
- proxy_server.reset
- end
-
- post '/proxies/:port/requests' do |port|
- proxy_server = get_proxy(port.to_i)
- proxy_server.track_request(params[:track])
- end
-
- get '/proxies/:port/requests' do |port|
- proxy_server = get_proxy(port.to_i)
- proxy_server.requests.to_json
- end
-
- post '/proxies/:port/requests/substitute' do |port|
- proxy_server = get_proxy(port.to_i)
- options = {}
- options[:body] = params[:body] if params[:body]
- options[:url] = params[:url] if params[:url]
- proxy_server.substitute_request(params[:pattern], options)
end
def get_proxy(port)
@@ -74,27 +21,39 @@ def stop_proxy(port)
running_proxy_servers.delete proxy_server
end
+ def delete_proxies
+ assigned_proxy_ports.clear
+ end
+
+ def proxies
+ assigned_proxy_ports
+ end
+
def start_proxy(options)
proxy_server = ProxyServer.new(options)
proxy_server.start
running_proxy_servers[options[:port]] = proxy_server
end
- def find_proxy_port
- new_proxy_port = (assigned_proxy_ports.max || ProxyManager::START_PORT) + 1
- PortProber.above(new_proxy_port)
- end
+ def new_proxy
+ port = find_proxy_port
+ assigned_proxy_ports << port
+ URI.parse("http://#{proxy_host_address}:#{port}")
+ end
- class << self
- def start(options = {})
- require 'thin'
- server = ::Thin::Server.new(
- '0.0.0.0',
- options.fetch(:port, 4985),
- ProxyManager.new
- )
+ def proxy_host_address
+ orig, Socket.do_not_reverse_lookup = Socket.do_not_reverse_lookup, true # turn off reverse DNS resolution temporarily
- server.start
+ UDPSocket.open do |s|
+ s.connect '64.233.187.99', 1
+ s.addr.last
end
+ ensure
+ Socket.do_not_reverse_lookup = orig
+ end
+
+ def find_proxy_port
+ new_proxy_port = (assigned_proxy_ports.max || ProxyManager::START_PORT) + 1
+ PortProber.above(new_proxy_port)
end
end
View
2 proxy-server.gemspec
@@ -2,7 +2,7 @@ $LOAD_PATH.unshift File.expand_path("../lib", __FILE__)
Gem::Specification.new do |s|
s.name = 'proxy-server'
- s.version = '0.0.6'
+ s.version = '0.0.7'
s.authors = ["Derek Ekins"]
s.description = 'Proxy server'
s.summary = "proxy-server-#{s.version}"
View
99 spec/proxy/proxy_app_spec.rb
@@ -0,0 +1,99 @@
+require_relative '../spec_helper'
+require_relative '../../lib/proxy/proxy_app'
+require_relative '../../lib/proxy/proxy_manager'
+require 'rack/test'
+require 'webmock/rspec'
+
+describe ProxyApp do
+ include Rack::Test::Methods
+
+ before do
+ @proxy_server = mock('ProxyServer')
+ @proxy_manager = ProxyManager.new
+ @proxy_manager.stub(:start_proxy).with(anything()).and_return(@proxy_server)
+ @proxy_manager.stub(:get_proxy).with(anything()).and_return(@proxy_server)
+ end
+
+ let(:app) { ProxyApp.new(@proxy_manager) }
+
+ it "should create a new proxy" do
+ @proxy_manager.should_receive(:new_proxy).and_return(URI('http://localhost:4000'))
+ response = post '/proxies'
+ proxy = JSON.parse(response.body)
+ proxy['port'].should == 4000
+ proxy['url'].should == "http://localhost:4000"
+ end
+
+ it "should create a new proxy with an upstream proxy when asked to" do
+ @proxy_manager.should_receive(:start_proxy).with(hash_including(:proxy => 'http://my_proxy:80'))
+ response = post '/proxies', {:proxy => 'http://my_proxy:80'}
+ end
+
+ it "should tell me about all the proxies that have been created" do
+ @proxy_manager.should_receive(:find_proxy_port).and_return(4000)
+
+ post '/proxies'
+ response = get '/proxies'
+ JSON.parse(response.body).should == [4000]
+ end
+
+ it "should remove all proxies when asked" do
+ post '/proxies'
+ delete '/proxies'
+
+ response = get '/proxies'
+ JSON.parse(response.body).should == []
+ end
+
+ it "should remove a proxy when asked to" do
+ running_proxy_port = JSON.parse(post('/proxies').body)['port']
+ ProxyManager.any_instance.should_receive(:stop_proxy).with(running_proxy_port)
+
+ response = delete "/proxies/#{running_proxy_port}"
+
+ response.status.should == 200
+ end
+
+ it "should assign new proxy ports when more than one is asked for" do
+ first_expected_proxy = 100
+ second_expected_proxy = 101
+ available_proxy_ports = [first_expected_proxy, second_expected_proxy]
+ ProxyManager.any_instance.stub(:find_proxy_port).and_return { available_proxy_ports.shift }
+
+ first_response = post '/proxies'
+ second_response = post '/proxies'
+
+ JSON.parse(first_response.body)['port'].should == first_expected_proxy
+ JSON.parse(second_response.body)['port'].should == second_expected_proxy
+ end
+
+ it "ads a given url to a list of them to track" do
+ track_url = 'public/.*.js'
+
+ @proxy_server.should_receive(:track_request).with(track_url)
+ post "/proxies/1111/requests", {:track => track_url}
+ end
+
+ it "ads a given url to a list of them to track" do
+ @proxy_server.stub!(:requests).and_return(['request 1', 'request 2'])
+ response = get "/proxies/1111/requests"
+ requests = JSON.parse(response.body)
+ requests.should include('request 1')
+ requests.should include('request 2')
+ end
+
+ it "can substitute a request with another body" do
+ @proxy_server.should_receive(:substitute_request).with('*.js', :body => 'alert(1);')
+ post "/proxies/1111/requests/substitute", {:pattern => '*.js', :body => 'alert(1);'}
+ end
+
+ it "can substitute a request with another url" do
+ @proxy_server.should_receive(:substitute_request).with('*.js', :url => 'http://example.com/test.js')
+ post "/proxies/1111/requests/substitute", {:pattern => '*.js', :url => 'http://example.com/test.js'}
+ end
+
+ it "can reset the configuration of a proxy" do
+ @proxy_server.should_receive(:reset)
+ post "/proxies/1111/reset"
+ end
+end
View
94 spec/proxy/proxy_manager_spec.rb
@@ -1,96 +1,20 @@
require_relative '../spec_helper'
require_relative '../../lib/proxy/proxy_manager'
require 'rack/test'
-require 'webmock/rspec'
describe ProxyManager do
- include Rack::Test::Methods
+ it "creates a new proxy" do
+ pm = ProxyManager.new
- before do
- @proxy_server = mock('ProxyServer')
- ProxyManager.any_instance.stub(:start_proxy).with(anything()).and_return(@proxy_server)
- ProxyManager.any_instance.stub(:get_proxy).with(anything()).and_return(@proxy_server)
- end
-
- let(:app) { ProxyManager.new }
-
- it "should create a new proxy when I ask for one" do
- ProxyManager.any_instance.should_receive(:find_proxy_port).and_return(4000)
- response = post '/proxies'
- proxy = JSON.parse(response.body)
- proxy.should == {'port' => 4000}
- end
-
- it "should create a new proxy with an upstream proxy when asked to" do
- ProxyManager.any_instance.should_receive(:start_proxy).with(hash_including(:proxy => 'http://my_proxy:80'))
- response = post '/proxies', {:proxy => 'http://my_proxy:80'}
- end
-
- it "should tell me about all the proxies that have been created" do
- ProxyManager.any_instance.should_receive(:find_proxy_port).and_return(4000)
-
- post '/proxies'
- response = get '/proxies'
- JSON.parse(response.body).should == [4000]
- end
-
- it "should remove all proxies when asked" do
- post '/proxies'
- delete '/proxies'
-
- response = get '/proxies'
- JSON.parse(response.body).should == []
- end
-
- it "should remove a proxy when asked to" do
- running_proxy_port = JSON.parse(post('/proxies').body)['port']
- ProxyManager.any_instance.should_receive(:stop_proxy).with(running_proxy_port)
-
- response = delete "/proxies/#{running_proxy_port}"
-
- response.status.should == 200
- end
-
- it "should assign new proxy ports when more than one is asked for" do
- first_expected_proxy = 100
- second_expected_proxy = 101
- available_proxy_ports = [first_expected_proxy, second_expected_proxy]
- ProxyManager.any_instance.stub(:find_proxy_port).and_return { available_proxy_ports.shift }
-
- first_response = post '/proxies'
- second_response = post '/proxies'
-
- JSON.parse(first_response.body)['port'].should == first_expected_proxy
- JSON.parse(second_response.body)['port'].should == second_expected_proxy
- end
-
- it "ads a given url to a list of them to track" do
- track_url = 'public/.*.js'
-
- @proxy_server.should_receive(:track_request).with(track_url)
- post "/proxies/1111/requests", {:track => track_url}
- end
-
- it "ads a given url to a list of them to track" do
- @proxy_server.stub!(:requests).and_return(['request 1', 'request 2'])
- response = get "/proxies/1111/requests"
- requests = JSON.parse(response.body)
- requests.should include('request 1')
- requests.should include('request 2')
- end
-
- it "can substitute a request with another body" do
- @proxy_server.should_receive(:substitute_request).with('*.js', :body => 'alert(1);')
- post "/proxies/1111/requests/substitute", {:pattern => '*.js', :body => 'alert(1);'}
- end
+ pm.should_receive(:find_proxy_port).and_return(4000)
+ pm.should_receive(:proxy_host_address).and_return('127.0.0.1')
- it "can substitute a request with another url" do
- @proxy_server.should_receive(:substitute_request).with('*.js', :url => 'http://example.com/test.js')
- post "/proxies/1111/requests/substitute", {:pattern => '*.js', :url => 'http://example.com/test.js'}
+ pm.new_proxy.should == URI.parse("http://127.0.0.1:4000")
end
- it "can reset the configuration of a proxy" do
- @proxy_server.should_receive(:reset)
- post "/proxies/1111/reset"
+ it "finds the address of this machine" do
+ expected_address = `ifconfig`.scan(/inet addr:(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}) Bcast:/)[0][0]
+ pm = ProxyManager.new
+ pm.proxy_host_address.should == expected_address
end
end

0 comments on commit c422d06

Please sign in to comment.