#!/usr/bin/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