diff options
author | vitalyr@chromium.org <vitalyr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-06-07 09:00:47 +0000 |
---|---|---|
committer | vitalyr@chromium.org <vitalyr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-06-07 09:00:47 +0000 |
commit | 7a158cc250768c944236b31042aa06d55757f72f (patch) | |
tree | c5396866aac95255801bfa07c404ce78f5375048 /tools/playback_benchmark/proxy_handler.py | |
parent | 1d21e4402d5f87766399afb56b20964af3f8a64e (diff) | |
download | chromium_src-7a158cc250768c944236b31042aa06d55757f72f.zip chromium_src-7a158cc250768c944236b31042aa06d55757f72f.tar.gz chromium_src-7a158cc250768c944236b31042aa06d55757f72f.tar.bz2 |
Landing for Pavel Podivilov (podivilov@chromium.org).
Playback benchmark scripts.
Original review: http://codereview.chromium.org/1515006/show
BUG=none
TEST=none
TBR=podivilov
Review URL: http://codereview.chromium.org/2626002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@49041 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'tools/playback_benchmark/proxy_handler.py')
-rw-r--r-- | tools/playback_benchmark/proxy_handler.py | 123 |
1 files changed, 123 insertions, 0 deletions
diff --git a/tools/playback_benchmark/proxy_handler.py b/tools/playback_benchmark/proxy_handler.py new file mode 100644 index 0000000..05da078 --- /dev/null +++ b/tools/playback_benchmark/proxy_handler.py @@ -0,0 +1,123 @@ +#!/usr/bin/env python +# +# Copyright 2010 Google Inc. All Rights Reserved. + +"""HTTP proxy request handler with SSL support. + + RequestHandler: Utility class for parsing HTTP requests. + ProxyHandler: HTTP proxy handler. +""" + +import BaseHTTPServer +import cgi +import OpenSSL +import os +import socket +import SocketServer +import sys +import traceback +import urlparse + + +class RequestHandler(BaseHTTPServer.BaseHTTPRequestHandler): + """Class for reading HTTP requests and writing HTTP responses""" + + protocol_version = "HTTP/1.1" + request_version = protocol_version + + class HTTPRequestException(Exception): pass + + def __init__(self, rfile, wfile, server): + self.rfile = rfile + self.wfile = wfile + self.server = server + + def ReadRequest(self): + "Reads and parses single HTTP request from self.rfile" + + self.raw_requestline = self.rfile.readline() + if not self.raw_requestline: + self.close_connection = 1 + raise HTTPRequestException('failed to read request line') + if not self.parse_request(): + raise HTTPRequestException('failed to parse request') + self.headers = dict(self.headers) + self.body = None + if 'content-length' in self.headers: + self.body = self.rfile.read(int(self.headers['content-length'])) + + def log_message(self, format, *args): + pass + + +class ProxyHandler(BaseHTTPServer.BaseHTTPRequestHandler): + "Request handler class for proxy server" + + server_version = "PlaybackProxy/0.0.1" + protocol_version = "HTTP/1.1" + + def do_CONNECT(self): + "Handles CONNECT HTTP request" + + server = self.path.split(':')[0] + certificate_file = os.path.join(self.certificate_directory, server) + if not os.path.isfile(certificate_file): + sys.stderr.write('request to connect %s is ignored\n' % server) + self.send_response(501) + self.send_header('Proxy-agent', self.version_string()) + self.end_headers() + return + + # Send confirmation to browser. + self.send_response(200, 'Connection established') + self.send_header('Proxy-agent', self.version_string()) + self.end_headers() + + # Create SSL context. + context = OpenSSL.SSL.Context(OpenSSL.SSL.SSLv23_METHOD) + context.use_privatekey_file(certificate_file) + context.use_certificate_file(certificate_file) + + # Create and initialize SSL connection atop of tcp socket. + ssl_connection = OpenSSL.SSL.Connection(context, self.connection) + ssl_connection.set_accept_state() + ssl_connection.do_handshake() + ssl_rfile = socket._fileobject(ssl_connection, "rb", self.rbufsize) + ssl_wfile = socket._fileobject(ssl_connection, "wb", self.wbufsize) + + # Handle http requests coming from ssl_connection. + handler = RequestHandler(ssl_rfile, ssl_wfile, self.path) + try: + handler.close_connection = 1 + while True: + handler.ReadRequest() + self.driver.ProcessRequest(handler) + if handler.close_connection: break + except (OpenSSL.SSL.SysCallError, OpenSSL.SSL.ZeroReturnError): + pass + finally: + self.close_connection = 1 + + def do_GET(self): + self.driver.ProcessRequest(self) + + def do_POST(self): + if 'content-length' in self.headers: + self.body = self.rfile.read(int(self.headers['content-length'])) + self.driver.ProcessRequest(self) + + def log_message(self, format, *args): + sys.stdout.write((format % args) + '\n') + + +class ThreadingHTTPServer (SocketServer.ThreadingMixIn, + BaseHTTPServer.HTTPServer): + pass + + +def CreateServer(driver, port, certificate_directory=None): + if not certificate_directory: + certificate_directory = os.path.join(os.getcwd(), 'certificates') + ProxyHandler.driver = driver + ProxyHandler.certificate_directory = certificate_directory + return ThreadingHTTPServer(('', port), ProxyHandler) |