Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / third_party / webpagereplay / httpproxy.py
index 2946da8..89f6d8d 100644 (file)
@@ -20,6 +20,7 @@ import logging
 import os
 import proxyshaper
 import re
+import socket
 import SocketServer
 import ssl
 import subprocess
@@ -145,51 +146,55 @@ class HttpArchiveHandler(BaseHTTPServer.BaseHTTPRequestHandler):
       logging.error('Error sending response for %s%s: %s',
                     self.headers['host'], self.path, e)
 
-  def _manage_request_count(fn):
-    """Keep track of the current number active requests.
+  def handle_one_request(self):
+    """Handle a single HTTP request."""
+    try:
+      self.raw_requestline = self.rfile.readline(65537)
+      self.do_parse_and_handle_one_request()
+    except socket.timeout, e:
+      # A read or a write timed out.  Discard this connection
+      self.log_error("Request timed out: %r", e)
+      self.close_connection = 1
+      return
+
+  def do_parse_and_handle_one_request(self):
+    start_time = time.time()
+    self.server.num_active_requests += 1
+    request = None
+    try:
+      if len(self.raw_requestline) > 65536:
+        self.requestline = ''
+        self.request_version = ''
+        self.command = ''
+        self.send_error(414)
+        return
+      if not self.raw_requestline:
+        self.close_connection = 1
+        return
+      if not self.parse_request():
+        # An error code has been sent, just exit
+        return
 
-    This is used for traffic shaping. The request and response are
-    wrapped separately because no single BaseHTTPRequestHandler
-    function handles an entire active request.
-    BaseHTTPRequestHandler.process_one_request() does not work because
-    when one request finishes it is called again to wait for another
-    request -- and another request may never arrive.
-    """
-    def wrapped(self, *args, **kwargs):
-      self.server.num_active_requests += 1
       try:
-        return fn(self, *args, **kwargs)
+        request = self.get_archived_http_request()
+        if request is None:
+          self.send_error(500)
+          return
+        response = self.server.custom_handlers.handle(request)
+        if not response:
+          response = self.server.http_archive_fetch(request)
+        if response:
+          self.send_archived_http_response(response)
+        else:
+          self.send_error(404)
       finally:
-        self.server.num_active_requests -= 1
-    return wrapped
-
-  @_manage_request_count
-  def parse_request(self):
-    return BaseHTTPServer.BaseHTTPRequestHandler.parse_request(self)
-
-  def do_POST(self):
-    self.do_GET()
-
-  def do_HEAD(self):
-    self.do_GET()
-
-  @_manage_request_count
-  def do_GET(self):
-    start_time = time.time()
-    request = self.get_archived_http_request()
-    if request is None:
-      self.send_error(500)
-      return
-    response = self.server.custom_handlers.handle(request)
-    if not response:
-      response = self.server.http_archive_fetch(request)
-    if response:
-      self.send_archived_http_response(response)
+        self.wfile.flush()  # Actually send the response if not already done.
+    finally:
       request_time_ms = (time.time() - start_time) * 1000.0;
-      logging.debug('Served: %s (%dms)', request, request_time_ms)
+      if request:
+        logging.debug('Served: %s (%dms)', request, request_time_ms)
       self.server.total_request_time += request_time_ms
-    else:
-      self.send_error(404)
+      self.server.num_active_requests -= 1
 
   def send_error(self, status, body=None):
     """Override the default send error with a version that doesn't unnecessarily