Skip to content

Instantly share code, notes, and snippets.

@andrew-carroll
Last active February 1, 2021 22:31
Show Gist options
  • Save andrew-carroll/3aaf406dfadc00ea3032 to your computer and use it in GitHub Desktop.
Save andrew-carroll/3aaf406dfadc00ea3032 to your computer and use it in GitHub Desktop.
Run Watir-Webdriver through a proxy to capture network traffic. Heavily inspired by https://web.archive.org/web/20110202071609/http://altentee.com/blogs/2008/httpwatch-a-free-alternative-using-ruby/
#!/usr/bin/env ruby
require 'watir-webdriver'
require 'webrick/httpproxy'
# USAGE: ./proxied_browser.rb server (port) [json]
# ./proxied_browser.rb browser (port)
class ProxiedBrowser < Watir::Browser
def initialize(port)
proxy = ['localhost',port].join(?:)
profile = Selenium::WebDriver::Firefox::Profile.new
profile.proxy = Selenium::WebDriver::Proxy.new(
http: proxy,
ftp: proxy,
ssl: proxy
)
super :firefox, profile: profile
end
end
class Proxy < WEBrick::HTTPProxyServer
def initialize(port)
options = {
Port: port,
AccessLog: [],
ProxyContentHandler: ->(req, res) do
if ARGV.include? 'json'
puts format_json(req, res)
puts "JSONSEPARATOR\n"
else
puts format_text(req, res)
end
end
}
super options
end
def self.start(port)
server = new(port)
trap("INT") { server.shutdown }
server.start
end
private
def format_json(req, res)
require 'oj'
hash = {
'request' => {
'request_line' => req.request_line.chomp,
'headers' => req.header
},
'response' => {
'headers' => res.header,
'body' => parse_body(res)
}
}
Oj.dump hash
end
def format_text(req, res)
puts "-" * 75
puts ">>> #{req.request_line.chomp}\n"
req.header.keys.each do |k|
puts "#{k.capitalize}: #{req.header[k]}"
end
puts "<<<"
puts res.status_line
res.header.keys.each do |k|
puts "#{k.capitalize}: #{res.header[k]}"
end
unless res.body.nil?
body = parse_body(res)
body.split("\n").each_with_index do |line, i|
puts "\n<<< #{i} #{line}"
end
end
end
def parse_body(res)
primitive_body = res.body
case res.header['content-encoding']
when 'gzip'
Zlib::GzipReader.new(StringIO.new(primitive_body), encoding: 'ASCII-8BIT').read
when 'deflate'
Zlib::Inflate.inflate(primitive_body)
else
primitive_body
end
end
end
unless ARGV.empty?
case ARGV[0]
when 'server' then Proxy.start(ARGV[1])
when 'browser'
begin
b = ProxiedBrowser.new(ARGV[1])
require 'pry'
pry
ensure
b.close
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment