Created
October 20, 2018 00:29
-
-
Save DylanLacey/d04eafab9cd5bb0ace4b6c2928109231 to your computer and use it in GitHub Desktop.
A POC for redirecting traffic from one Sauce Connect proxy to multiple upstream proxies
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Capybara.register_driver :remote do |app| | |
capabilities = { | |
browserName: "Chrome", | |
platform: "Windows 10", | |
version: "60" | |
}# {Put your Sauce Labs Desired Capabilities here as a hash} | |
capabilities[:name] = scenario.full_description # Give the Sauce Labs test a decent name | |
client = Selenium::WebDriver::Remote::Http::Default.new | |
client.open_timeout = 1500 # Optional; Deals with long session start times | |
server_url = "https://#{ENV['SAUCE_USERNAME']}:#{ENV['SAUCE_ACCESS_KEY']}" +'@ondemand.saucelabs.com:443/wd/hub' | |
proxy = { | |
proxyType: "manual", | |
sslProxy: "#{Billy.proxy.host}:#{Billy.proxy.port}", | |
httpProxy: "#{Billy.proxy.host}:#{Billy.proxy.port}" | |
} | |
driver = SauceCapybara::Driver.new( | |
app, | |
browser: :remote, | |
url: server_url, | |
desired_capabilities: capabilities, | |
http_client: client | |
) | |
server_uri = URI('http://localhost:4567/mapping') | |
res = Net::HTTP.post_form(server_uri, 'job' => driver.browser.session_id, 'port' => Billy.proxy.port) | |
driver | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require "sinatra" | |
require "thread" | |
require 'webrick/httpproxy' | |
require_relative 'web_marble' | |
require_relative 'port_map' | |
class WebrickPortProxy | |
def initialize map, proxy | |
@port_map = map | |
@proxy = WEBrick::HTTPProxyServer.new(:Port => 8004, :ProxyURI => proxy) | |
@proxy.port_map = @port_map | |
end | |
trap 'INT' do @proxy.shutdown end | |
trap 'TERM' do @proxy.shutdown end | |
def start | |
# puts "Starting Proxy" | |
begin | |
@proxy.start | |
rescue => e | |
puts "ERROR in thread" | |
puts e | |
puts "#{caller}" | |
end | |
# puts "Proxy Started" | |
end | |
end | |
semaphore = Mutex.new | |
port_map = PortMap.new semaphore | |
proxyURI = URI.parse "http://localhost:1111" | |
Thread.new do | |
begin | |
proxy = WebrickPortProxy.new port_map, proxyURI | |
proxy.start | |
# puts "Control Returned" | |
rescue => e | |
# puts "Thread issue" | |
puts e | |
end | |
end | |
get '/mapping' do | |
template = "<h1>Job/Port Map</h1>" | |
template += "<table><tr><th>Job ID</th><th>Puffing Billy Port</th></tr>" | |
port_map.each_port do |id, port| | |
template += "<tr><td>#{id}</td><td>#{port}</td></tr>" | |
end | |
template += "</table></br></br>" | |
template += "<b>Total Rows:</b> #{port_map.size}" | |
template | |
end | |
post '/mapping' do | |
# puts "Storing a map between #{params['job']} and #{params['port']}" | |
port_map.add(params['job'], params['port']) | |
end | |
delete '/mapping' do | |
port_map.remove params['job'] | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require "thread" | |
class PortMap | |
def initialize semaphore | |
@map = {} | |
@semaphore = semaphore | |
end | |
def find_port job_id | |
port = nil | |
@semaphore.synchronize { port = @map[job_id.to_sym] } | |
port | |
end | |
def add job_id, port | |
@semaphore.synchronize { @map[job_id.to_sym] = port } | |
end | |
def remove job_id | |
@semaphore.synchronize { @map.delete job_id } | |
end | |
def sizes | |
@semaphore.synchronize { @map.size } | |
end | |
def each_port &block | |
@semaphore.synchronize do | |
@map.each_pair { |k, v| yield k, v } | |
end | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class WEBrick::HTTPProxyServer | |
def proxy_uri(req, res) | |
proxy = @config[:ProxyURI].dup | |
job_id = req.header['x-sl-job-id'] | |
if job_id && !job_id.empty? | |
puts "Checking port map #{@port_map}" | |
redirect_port = @port_map.find_port(job_id) | |
puts "Redirecting traffic for #{job_id} to port #{redirect_port}" | |
proxy.port = redirect_port | |
return proxy | |
end | |
# puts "This was not matched; Returning nil" | |
# should return upstream proxy server's URI | |
return nil | |
end | |
attr_accessor :port_map | |
def port_map= pmap | |
@port_map = pmap | |
end | |
def port_map | |
@port_map | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment