From 377ae13e8fd5a4bf45dd28784d2ff8401df28fa8 Mon Sep 17 00:00:00 2001
From: Michael Hanselmann <hansmi@google.com>
Date: Tue, 21 Feb 2012 18:23:37 +0100
Subject: [PATCH] http.server: Move error message formatting to handler class

Like before this patch moves more functionality from the actual server
class into a separate handler class. At the same time the function is
changed to return both content-type and body instead of relying on a
class attribute.

Signed-off-by: Michael Hanselmann <hansmi@google.com>
Reviewed-by: Guido Trotter <ultrotter@google.com>
---
 lib/http/server.py | 40 ++++++++++++++++++++--------------------
 lib/server/rapi.py | 33 +++++++++++++--------------------
 2 files changed, 33 insertions(+), 40 deletions(-)

diff --git a/lib/http/server.py b/lib/http/server.py
index 8e9a638da..25e792806 100644
--- a/lib/http/server.py
+++ b/lib/http/server.py
@@ -265,10 +265,6 @@ class HttpServerRequestExecutor(object):
   # Most web servers default to HTTP 0.9, i.e. don't send a status line.
   default_request_version = http.HTTP_0_9
 
-  # Error message settings
-  error_message_format = DEFAULT_ERROR_MESSAGE
-  error_content_type = DEFAULT_ERROR_CONTENT_TYPE
-
   responses = BaseHTTPServer.BaseHTTPRequestHandler.responses
 
   # Timeouts in seconds for socket layer
@@ -420,26 +416,18 @@ class HttpServerRequestExecutor(object):
       "explain": longmsg,
       }
 
-    self.response_msg.start_line.code = err.code
+    (content_type, body) = self.handler.FormatErrorMessage(values)
+
+    headers = {
+      http.HTTP_CONTENT_TYPE: content_type,
+      }
 
-    headers = {}
     if err.headers:
       headers.update(err.headers)
-    headers[http.HTTP_CONTENT_TYPE] = self.error_content_type
-    self.response_msg.headers = headers
-
-    self.response_msg.body = self._FormatErrorMessage(values)
-
-  def _FormatErrorMessage(self, values):
-    """Formats the body of an error message.
-
-    @type values: dict
-    @param values: dictionary with keys code, message and explain.
-    @rtype: string
-    @return: the body of the message
 
-    """
-    return self.error_message_format % values
+    self.response_msg.start_line.code = err.code
+    self.response_msg.headers = headers
+    self.response_msg.body = body
 
 
 class HttpServer(http.HttpBase, asyncore.dispatcher):
@@ -592,3 +580,15 @@ class HttpServerHandler(object):
 
     """
     raise NotImplementedError()
+
+  @staticmethod
+  def FormatErrorMessage(values):
+    """Formats the body of an error message.
+
+    @type values: dict
+    @param values: dictionary with keys C{code}, C{message} and C{explain}.
+    @rtype: tuple; (string, string)
+    @return: Content-type and response body
+
+    """
+    return (DEFAULT_ERROR_CONTENT_TYPE, DEFAULT_ERROR_MESSAGE % values)
diff --git a/lib/server/rapi.py b/lib/server/rapi.py
index b19571198..2bc0dc4f8 100644
--- a/lib/server/rapi.py
+++ b/lib/server/rapi.py
@@ -64,24 +64,6 @@ class RemoteApiRequestContext(object):
     self.body_data = None
 
 
-class JsonErrorRequestExecutor(http.server.HttpServerRequestExecutor):
-  """Custom Request Executor class that formats HTTP errors in JSON.
-
-  """
-  error_content_type = http.HTTP_APP_JSON
-
-  def _FormatErrorMessage(self, values):
-    """Formats the body of an error message.
-
-    @type values: dict
-    @param values: dictionary with keys code, message and explain.
-    @rtype: string
-    @return: the body of the message
-
-    """
-    return serializer.DumpJson(values)
-
-
 class RemoteApiHandler(http.auth.HttpServerRequestAuthentication,
                        http.server.HttpServerHandler):
   """REST Request Handler Class.
@@ -127,6 +109,18 @@ class RemoteApiHandler(http.auth.HttpServerRequestAuthentication,
 
     return True
 
+  @staticmethod
+  def FormatErrorMessage(values):
+    """Formats the body of an error message.
+
+    @type values: dict
+    @param values: dictionary with keys C{code}, C{message} and C{explain}.
+    @rtype: tuple; (string, string)
+    @return: Content-type and response body
+
+    """
+    return (http.HTTP_APP_JSON, serializer.DumpJson(values))
+
   def _GetRequestContext(self, req):
     """Returns the context for a request.
 
@@ -319,8 +313,7 @@ def PrepRapi(options, _):
 
   server = \
     http.server.HttpServer(mainloop, options.bind_address, options.port,
-      handler, ssl_params=options.ssl_params, ssl_verify_peer=False,
-      request_executor_class=JsonErrorRequestExecutor)
+      handler, ssl_params=options.ssl_params, ssl_verify_peer=False)
   server.Start()
 
   return (mainloop, server)
-- 
GitLab