blob: 14dc974dbb30eccfb75146ac1eb844727e04883b [file] [log] [blame]
#!/usr/bin/env ruby
# iExploder Web Server (using webrick)
#
# Copyright 2010 Thomas Stromberg - All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
require 'cgi'
require 'webrick'
require 'optparse'
require './iexploder.rb'
include WEBrick
$INSTANCE = nil
$last_page_requested = [Time.now().to_i, 0]
# Main CGI - Pass requests to iexploder
class IEServlet < HTTPServlet::AbstractServlet
def do_GET(request, response)
ie = $INSTANCE.dup
ie.test_num = request.query['t'].to_i || 0
ie.subtest_data = request.query['s'] || nil
ie.random_mode = request.query['r']
ie.lookup_mode = request.query['l']
ie.claimed_browser = request.query['b'] || nil
ie.stop_num = request.query['x'] || nil
user_agent = request['User-agent'] || 'unknown'
raw_user_agent = user_agent.dup
# Shorten the user-agent displayed
user_agent.gsub!('Mozilla/5.0', '')
user_agent.gsub!('X11; ', '')
user_agent.gsub!('Macintosh; ', '')
user_agent.gsub!(' U;', '')
user_agent.gsub!(/^ +/, '')
user_agent.gsub!(' (KHTML, like Gecko)', '')
if user_agent =~ /Chrome/
user_agent.gsub!(/Safari\/[\d\.]+/, '')
end
ie.browser = user_agent
ie.setRandomSeed()
# If we are a dependency image, fiddle with the headers!
mime_type = request.query['m']
headers = []
if mime_type
for (key, value) in ie.buildHeaders(mime_type)
headers << "#{key}[#{value.length}]"
response[key] = value
end
response.body = ie.buildMediaFile(mime_type)
else
response['Content-Type'] = 'text/html'
response.body = ie.buildPage()
end
details = "?t=#{ie.test_num}"
if ie.subtest_data
details << "&s=#{ie.subtest_data}"
end
if ie.random_mode
details << "&r=1"
end
if ie.lookup_mode
details << "&l=#{ie.lookup_mode}"
end
if mime_type
details << "&m=#{mime_type}"
else
$last_page_requested = [Time.now().to_i, request.unparsed_uri, CGI.escape(user_agent)]
end
printf("%-45.45s %s\n", details, user_agent)
if headers.length > 0
printf("%-45.45s %s\n", "Headers for #{mime_type}:", headers.join(', '))
end
end
end
# Simple form
class IEForm < HTTPServlet::AbstractServlet
def do_GET(request, response)
response['Content-Type'] = 'text/html'
response.body = File.read("index.html")
end
end
class IELogo < HTTPServlet::AbstractServlet
def do_GET(request, response)
response['Content-Type'] = 'image/png'
response.body = File.read("media/bug.png")
end
end
class NoPage < HTTPServlet::AbstractServlet
def do_GET(request, response)
response.body = 'OHAI'
end
end
class LastPage < HTTPServlet::AbstractServlet
def do_GET(request, response)
response.body = $last_page_requested.join(' ')
end
end
def start_server(port, config_path, log_path)
puts "* iExploder #{$VERSION} is loading (config=#{config_path}, port=#{port})"
puts "=" * 80
$INSTANCE = IExploder.new(config_path)
warn_logger = Log.new($stderr, Log::WARN)
config = YAML::load(File.open(config_path))
if not log_path
log_path = config['access_log_path']
end
puts "- Setting up logging to #{log_path}"
access_log_stream = Log.new(log_path)
access_log = [[ access_log_stream, AccessLog::COMMON_LOG_FORMAT ]]
s = WEBrick::HTTPServer.new(:Port => port, :Logger => warn_logger, :AccessLog => access_log)
s.mount("/", IEForm)
s.mount("/favicon.ico", NoPage)
s.mount("/media/bug.png", IELogo)
s.mount("/iexploder.cgi", IEServlet)
s.mount("/last_page.cgi", LastPage)
['INT', 'TERM'].each {|signal| trap(signal) { puts "SERVER SHUTDOWN: #{signal}"; s.shutdown }}
puts "- iExploder is at http://127.0.0.1:#{port}"
s.start
puts ""
puts "Goodbye! Have a fantastic day."
end
if $0 == __FILE__
options = {
:port => 3100,
:config_path => 'config.yaml',
:log_path => nil
}
optparse = OptionParser.new do|opts|
opts.banner = "Usage: webserver.rb [options]"
opts.on( '-p', '--port NUM', 'Listen on TCP port NUM' ) { |port| options[:port] = port }
opts.on( '-c', '--config PATH', 'Use PATH for configuration file' ) { |path| options[:config_path] = path }
opts.on( '-l', '--log PATH', 'Use PATH for log file' ) { |path| options[:log_path] = path }
opts.on( '-h', '--help', 'Display this screen' ) { puts opts; exit }
end
optparse.parse!
start_server(options[:port], options[:config_path], options[:log_path])
end