changeset 4138:6bbc4beed793

Started with the HTTPContext (currently a reimplementation of request_wsgi with werkzeug)
author Florian Krupicka <florian.krupicka@googlemail.com>
date Thu, 29 May 2008 14:59:41 +0200
parents ac94a866f715
children e3893c082fe5
files MoinMoin/web/contexts.py MoinMoin/web/request.py MoinMoin/wsgiapp.py
diffstat 3 files changed, 118 insertions(+), 52 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MoinMoin/web/contexts.py	Thu May 29 14:59:41 2008 +0200
@@ -0,0 +1,102 @@
+# -*- coding: iso-8859-1 -*-
+"""
+    MoinMoin - Context objects which are passed thru instead of the classic
+               request objects. Currently contains legacy wrapper code for
+               a single request object.
+
+    @copyright: 2008-2008 MoinMoin:FlorianKrupicka
+    @license: GNU GPL, see COPYING for details.
+"""
+
+import re
+
+from werkzeug.utils import Headers
+
+from MoinMoin.request import RequestBase
+from MoinMoin.web.request import Request
+
+from MoinMoin import log
+logging = log.getLogger(__name__)
+
+STATUS_CODE_RE = re.compile('Status:\s*(\d{3,3})', re.IGNORECASE)
+
+class Context(object):
+    pass
+
+class HTTPContext(Context, RequestBase):
+    """ Lowermost context for MoinMoin.
+
+    Contains code related to manipulation of HTTP related data like:
+    * Headers
+    * Cookies
+    * GET/POST/PUT/etc data 
+    """
+    def __init__(self, environ):
+        self._wsgirequest = Request(environ)
+        self.__output = []
+        self.headers = Headers()
+
+        self.status = 200
+        self.failed = 0
+
+        self._setup_vars_from_std_env(environ)
+        RequestBase.__init__(self, {})
+
+    # implementation of methods expected by RequestBase
+    def _setup_args_from_cgi_form(self):
+        logging.warning("Form values requested as plain dict, "
+                        "consider using MultiDicts here")
+        return self._wsgirequest.form.to_dict(flat=False)
+
+    def read(self, n=None):
+        if n is None:
+            return self._wsgirequest.data
+        else:
+            return self._wsgirequest.input_stream.read(n)
+
+    def send_file(self, fileobj, bufsize=8192, do_flush=None):
+        self._sendfile = fileobj
+        self._send_bufsize = bufsize
+
+    def write(self, *data):
+        if len(data) > 1:
+            logging.warning("Some code still uses write with multiple arguments, "
+                            "consider changing this soon")
+        self.__output.extend(data)
+
+    def output(self):
+        return ''.join(self.__output)
+
+    def _emit_http_headers(self, headers):
+        print 'called', headers
+        st_header, other_headers = headers[0], headers[1:]
+        status = STATUS_CODE_RE.match(st_header)
+        status = int(status.groups()[0])
+        self.status = status
+        for header in other_headers:
+            key, value = header.split(':', 1)
+            self.headers.add(key, value)
+
+    def flush(self):
+        pass
+
+    def setup_args(self):
+        return self._wsgirequest.values.to_dict(flat=False)
+
+# mangle in logging of function calls
+
+def _logfunc(func):
+    def _decorated(*args, **kwargs):
+        logging.warning("Function '%s' called with '%r', '%r'. Consider if"
+                        "this is intended", func.__name__, args, kwargs)
+        return func(*args, **kwargs)
+    _decorated.__name__ = func.__name__
+    _decorated.__doc__ = func.__doc__
+    return _decorated
+
+from types import FunctionType
+
+for name, item in RequestBase.__dict__.items():
+    if isinstance(item, FunctionType):
+        setattr(RequestBase, name, _logfunc(item))
+del name, item, FunctionType, _logfunc
--- a/MoinMoin/web/request.py	Wed May 28 18:44:22 2008 +0200
+++ b/MoinMoin/web/request.py	Thu May 29 14:59:41 2008 +0200
@@ -6,52 +6,16 @@
     @license: GNU GPL, see COPYING for details.
 """
 
+import re
+
 from werkzeug import wrappers as werkzeug
 from werkzeug.utils import cached_property
 
-from MoinMoin.request import RequestBase
+from MoinMoin import config
 
 from MoinMoin import log
 logging = log.getLogger(__name__)
 
-class Request(werkzeug.Request, RequestBase):
-    def __init__(self, environ):
-        werkzeug.Request.__init__(self, environ)
-        RequestBase.__init__(self, {})
-
-    def __getattribute__(self, name):
-        logging.error("UR DOING IT WRONG! (attribute '%s' requested)", name)
-        return RequestBase.__getattribute__(self, name)
-
-    def __setattr__(self, name, value):
-        logging.error("UR DOING IT WRONG! (attribute '%s' changed to '%r')", name, value)
-        return RequestBase.__setattr__(self, name, value)
-
-    def __delattr__(self, name):
-        logging.error("UR DOING IT WRONG! (attribute '%s' deleted)", name)
-        return Request.__delattr__(self, name)        
-
-    def decodePagename(self, name):
-        return name
-
-    def request_uri(self):
-        answer = self.script_root + self.path
-        qs = self.query_string
-        if qs:
-            answer = answer + '?' + qs
-        return answer
-    request_uri = cached_property(request_uri)
-
-    def http_user_agent(self):
-        return str(self.user_agent)
-    http_user_agent = cached_property(http_user_agent)
-
-for moinname, werkname in [('path_info', 'path'),
-                           ('request_method', 'method')]:
-    method =  getattr(werkzeug.Request, werkname)
-    setattr(Request, moinname, method)
-del moinname, werkname
-        
-
-    
-
+class Request(werkzeug.Request):
+    charset = config.charset
+    encoding_errors = 'replace'
--- a/MoinMoin/wsgiapp.py	Wed May 28 18:44:22 2008 +0200
+++ b/MoinMoin/wsgiapp.py	Thu May 29 14:59:41 2008 +0200
@@ -3,23 +3,23 @@
     MoinMoin - WSGI application
 
 
-    @copyright: 2001-2003 Juergen Hermann <jh@web.de>,
-                2003-2006 MoinMoin:ThomasWaldmann,
+    @copyright: 2003-2008 MoinMoin:ThomasWaldmann,
                 2008-2008 MoinMoin:FlorianKrupicka
     @license: GNU GPL, see COPYING for details.
 """
-
+from werkzeug.utils import responder
 from werkzeug.wrappers import Response
-from werkzeug.debug import DebuggedApplication
 
-from MoinMoin.web.request import Request
+from MoinMoin.web.contexts import HTTPContext
 
+def application(environ, start_response):
+    request = HTTPContext(environ)
+    request.run()
 
-def application(request):
-    request.run()
     response = Response(status=request.status,
                         headers=request.headers)
-    if request._send_file is not None:
+
+    if getattr(request, '_send_file', None) is not None:
         # moin wants to send a file (e.g. AttachFile.do_get)
         def simple_wrapper(fileobj, bufsize):
             return iter(lambda: fileobj.read(bufsize), '')
@@ -27,7 +27,7 @@
         response.response = file_wrapper(request._send_file, request._send_bufsize)
     else:
         response.response = request.output()
+        print request.output()
     return response
 
-application = Request.application(application)
-application = DebuggedApplication(application)
+application = responder(application)