From cc45c7fbd0bdb1d6635e2f4e2f8d1b85fc72ef2a Mon Sep 17 00:00:00 2001
From: Yousong Zhou <yszhou4tech@gmail.com>
Date: Fri, 30 Jan 2015 21:07:11 +0800
Subject: [PATCH 3/5] testenv: fix http_server.py with Response and
 Authentication.

 * testenv/exc/server_error.py, testenv/server/http/http_server.py:

    Current behaviour is that whenever Response rule was encountered, server
    would respond with the specified code, then end the whole response
    without checking the presence of file content in fileSys.

    This patch tries to

     - Introducce AuthError to distinguish from general ServerError.
     - Try writing file content for GET request even if there is a Response
       rule present.
---
 testenv/exc/server_error.py        |  3 +++
 testenv/server/http/http_server.py | 33 +++++++++++++++++----------------
 2 files changed, 20 insertions(+), 16 deletions(-)

diff --git a/testenv/exc/server_error.py b/testenv/exc/server_error.py
index b8a37ce..fad239b 100644
--- a/testenv/exc/server_error.py
+++ b/testenv/exc/server_error.py
@@ -5,3 +5,6 @@ class ServerError (Exception):
 
     def __init__ (self, err_message):
         self.err_message = err_message
+
+class AuthError (ServerError):
+    pass
diff --git a/testenv/server/http/http_server.py b/testenv/server/http/http_server.py
index 9630efa..99f1d14 100644
--- a/testenv/server/http/http_server.py
+++ b/testenv/server/http/http_server.py
@@ -1,5 +1,5 @@
 from http.server import HTTPServer, BaseHTTPRequestHandler
-from exc.server_error import ServerError
+from exc.server_error import ServerError, AuthError
 from socketserver import BaseServer
 from posixpath import basename, splitext
 from base64 import b64encode
@@ -274,18 +274,16 @@ class _Handler (BaseHTTPRequestHandler):
             self.user = auth_rule.auth_user
             self.passw = auth_rule.auth_pass
             params = self.parse_auth_header (auth_header)
-            pass_auth = True
             if self.user != params['username'] or \
-               self.nonce != params['nonce'] or \
-               self.opaque != params['opaque']:
-                pass_auth = False
+                    self.nonce != params['nonce'] or \
+                    self.opaque != params['opaque']:
+                return False
             req_attribs = ['username', 'realm', 'nonce', 'uri', 'response']
             for attrib in req_attribs:
                 if attrib not in params:
-                    pass_auth = False
+                    return False
             if not self.check_response (params):
-                pass_auth = False
-            return pass_auth
+                return False
 
     def authorize_both (self, auth_header, auth_rule):
         return False
@@ -296,11 +294,11 @@ class _Handler (BaseHTTPRequestHandler):
     def Authentication (self, auth_rule):
         try:
             self.handle_auth (auth_rule)
-        except ServerError as se:
+        except AuthError as se:
             self.send_response (401, "Authorization Required")
             self.send_challenge (auth_rule.auth_type)
             self.finish_headers ()
-            raise ServerError (se.__str__())
+            raise se
 
     def handle_auth (self, auth_rule):
         is_auth = True
@@ -314,11 +312,11 @@ class _Handler (BaseHTTPRequestHandler):
             assert hasattr (self, "authorize_" + auth_type)
             is_auth = getattr (self, "authorize_" + auth_type) (auth_header, auth_rule)
         except AssertionError:
-            raise ServerError ("Authentication Mechanism " + auth_type + " not supported")
+            raise AuthError ("Authentication Mechanism " + auth_type + " not supported")
         except AttributeError as ae:
-            raise ServerError (ae.__str__())
+            raise AuthError (ae.__str__())
         if is_auth is False:
-            raise ServerError ("Unable to Authenticate")
+            raise AuthError ("Unable to Authenticate")
 
 
     def ExpectHeader (self, header_obj):
@@ -363,6 +361,8 @@ class _Handler (BaseHTTPRequestHandler):
         if path in self.server.fileSys:
             self.rules = self.server.server_configs.get (path)
 
+            content = self.server.fileSys.get (path)
+            content_length = len (content)
             for rule_name in self.rules:
                 try:
                     assert hasattr (self, rule_name)
@@ -371,12 +371,13 @@ class _Handler (BaseHTTPRequestHandler):
                     msg = "Rule " + rule_name + " not defined"
                     self.send_error (500, msg)
                     return (None, None)
+                except AuthError as ae:
+                    print (ae.__str__())
+                    return (None, None)
                 except ServerError as se:
                     print (se.__str__())
-                    return (None, None)
+                    return (content, None)
 
-            content = self.server.fileSys.get (path)
-            content_length = len (content)
             try:
                 self.range_begin = self.parse_range_header (
                     self.headers.get ("Range"), content_length)
-- 
2.2.1

