Changeset 169
- Timestamp:
- 07/18/05 01:30:26 (3 years ago)
- Files:
-
- django/trunk/django/core/extensions.py (modified) (1 diff)
- django/trunk/django/core/handler.py (modified) (1 diff)
- django/trunk/django/core/handlers (added)
- django/trunk/django/core/handlers/__init__.py (added)
- django/trunk/django/core/handlers/modpython.py (added)
- django/trunk/django/core/handlers/wsgi.py (added)
- django/trunk/django/utils/httpwrappers.py (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
django/trunk/django/core/extensions.py
r167 r169 1 "Specialized Context and ModPythonRequest classes for Django. Use these!" 1 # Specialized template classes for Django, decoupled from the basic template system. 2 2 3 3 from django.core.template import Context 4 from django.utils.httpwrappers import ModPythonRequest5 4 from django.conf.settings import DEBUG, INTERNAL_IPS 6 from pprint import pformat7 5 8 6 class DjangoContext(Context): django/trunk/django/core/handler.py
r168 r169 1 import os 2 from django.utils import httpwrappers 1 # This module is DEPRECATED! 2 # 3 # You should no longer be pointing your mod_python configuration 4 # at "django.core.handler". 5 # 6 # Use "django.core.handlers.modpython" instead. 3 7 4 # NOTE: do *not* import settings (or any module which eventually imports 5 # settings) until after ModPythonHandler has been called; otherwise os.environ 6 # won't be set up correctly (with respect to settings). 7 8 class ModPythonHandler: 9 10 def __init__(self): 11 self._request_middleware = self._view_middleware = self._response_middleware = None 12 13 def __call__(self, req): 14 # mod_python fakes the environ, and thus doesn't process SetEnv. This fixes that 15 os.environ.update(req.subprocess_env) 16 17 # now that the environ works we can see the correct settings, so imports 18 # that use settings now can work 19 from django.conf import settings 20 from django.core import db 21 from django.utils.httpwrappers import ModPythonRequest 22 23 # if we need to set up middleware, now that settings works we can do it now. 24 if self._request_middleware is None: 25 self.load_middleware() 26 27 try: 28 request = ModPythonRequest(req) 29 response = self.get_response(req.uri, request) 30 finally: 31 db.db.close() 32 33 # Apply response middleware 34 for middleware_method in self._response_middleware: 35 response = middleware_method(request, response) 36 37 # Convert our custom HttpResponse object back into the mod_python req. 38 httpwrappers.populate_apache_request(response, req) 39 return 0 # mod_python.apache.OK 40 41 def load_middleware(self): 42 """ 43 Populate middleware lists from settings.MIDDLEWARE_CLASSES. 44 45 Must be called after the environment is fixed (see __call__). 46 """ 47 from django.conf import settings 48 from django.core import exceptions 49 self._request_middleware = [] 50 self._view_middleware = [] 51 self._response_middleware = [] 52 for middleware_path in settings.MIDDLEWARE_CLASSES: 53 dot = middleware_path.rindex('.') 54 mw_module, mw_classname = middleware_path[:dot], middleware_path[dot+1:] 55 try: 56 mod = __import__(mw_module, '', '', ['']) 57 except ImportError, e: 58 raise exceptions.ImproperlyConfigured, 'Error importing middleware %s: "%s"' % (mw_module, e) 59 try: 60 mw_class = getattr(mod, mw_classname) 61 except AttributeError: 62 raise exceptions.ImproperlyConfigured, 'Middleware module "%s" does not define a "%s" class' % (mw_module, mw_classname) 63 64 try: 65 mw_instance = mw_class() 66 except exceptions.MiddlewareNotUsed: 67 continue 68 69 if hasattr(mw_instance, 'process_request'): 70 self._request_middleware.append(mw_instance.process_request) 71 if hasattr(mw_instance, 'process_view'): 72 self._view_middleware.append(mw_instance.process_view) 73 if hasattr(mw_instance, 'process_response'): 74 self._response_middleware.insert(0, mw_instance.process_response) 75 76 def get_response(self, path, request): 77 "Returns an HttpResponse object for the given HttpRequest" 78 from django.core import db, exceptions, urlresolvers 79 from django.core.mail import mail_admins 80 from django.conf.settings import DEBUG, INTERNAL_IPS, ROOT_URLCONF 81 82 # Apply request middleware 83 for middleware_method in self._request_middleware: 84 response = middleware_method(request) 85 if response: 86 return response 87 88 conf_module = __import__(ROOT_URLCONF, '', '', ['']) 89 resolver = urlresolvers.RegexURLResolver(conf_module.urlpatterns) 90 try: 91 callback, param_dict = resolver.resolve(path) 92 # Apply view middleware 93 for middleware_method in self._view_middleware: 94 response = middleware_method(request, callback, param_dict) 95 if response: 96 return response 97 return callback(request, **param_dict) 98 except exceptions.Http404: 99 if DEBUG: 100 return self.get_technical_error_response(is404=True) 101 else: 102 resolver = urlresolvers.Error404Resolver(conf_module.handler404) 103 callback, param_dict = resolver.resolve() 104 return callback(request, **param_dict) 105 except db.DatabaseError: 106 db.db.rollback() 107 if DEBUG: 108 return self.get_technical_error_response() 109 else: 110 subject = 'Database error (%s IP)' % (request.META['REMOTE_ADDR'] in INTERNAL_IPS and 'internal' or 'EXTERNAL') 111 message = "%s\n\n%s" % (self._get_traceback(), request) 112 mail_admins(subject, message, fail_silently=True) 113 return self.get_friendly_error_response(request, conf_module) 114 except exceptions.PermissionDenied: 115 return httpwrappers.HttpResponseForbidden('<h1>Permission denied</h1>') 116 except: # Handle everything else, including SuspiciousOperation, etc. 117 if DEBUG: 118 return self.get_technical_error_response() 119 else: 120 subject = 'Coding error (%s IP)' % (request.META['REMOTE_ADDR'] in INTERNAL_IPS and 'internal' or 'EXTERNAL') 121 message = "%s\n\n%s" % (self._get_traceback(), request) 122 mail_admins(subject, message, fail_silently=True) 123 return self.get_friendly_error_response(request, conf_module) 124 125 def get_friendly_error_response(self, request, conf_module): 126 """ 127 Returns an HttpResponse that displays a PUBLIC error message for a 128 fundamental database or coding error. 129 """ 130 from django.core import urlresolvers 131 resolver = urlresolvers.Error404Resolver(conf_module.handler500) 132 callback, param_dict = resolver.resolve() 133 return callback(request, **param_dict) 134 135 def get_technical_error_response(self, is404=False): 136 """ 137 Returns an HttpResponse that displays a TECHNICAL error message for a 138 fundamental database or coding error. 139 """ 140 error_string = "<pre>There's been an error:\n\n%s</pre>" % self._get_traceback() 141 responseClass = is404 and httpwrappers.HttpResponseNotFound or httpwrappers.HttpResponseServerError 142 return responseClass(error_string) 143 144 def _get_traceback(self): 145 "Helper function to return the traceback as a string" 146 import sys, traceback 147 return '\n'.join(traceback.format_exception(*sys.exc_info())) 8 from django.core.handlers.modpython import ModPythonHandler 148 9 149 10 def handler(req): django/trunk/django/utils/httpwrappers.py
r167 r169 24 24 def get_full_path(self): 25 25 return '' 26 27 class ModPythonRequest(HttpRequest):28 def __init__(self, req):29 self._req = req30 self.path = req.uri31 32 def __repr__(self):33 return '<ModPythonRequest\npath:%s,\nGET:%s,\nPOST:%s,\nCOOKIES:%s,\nMETA:%s,\nuser:%s>' % \34 (self.path, pformat(self.GET), pformat(self.POST), pformat(self.COOKIES),35 pformat(self.META), pformat(self.user))36 37 def get_full_path(self):38 return '%s%s' % (self.path, self._req.args and ('?' + self._req.args) or '')39 40 def _load_post_and_files(self):41 "Populates self._post and self._files"42 if self._req.headers_in.has_key('content-type') and self._req.headers_in['content-type'].startswith('multipart'):43 self._post, self._files = parse_file_upload(self._req.headers_in, self._req.read())44 else:45 self._post, self._files = QueryDict(self._req.read()), datastructures.MultiValueDict()46 47 def _get_request(self):48 if not hasattr(self, '_request'):49 self._request = datastructures.MergeDict(self.POST, self.GET)50 return self._request51 52 def _get_get(self):53 if not hasattr(self, '_get'):54 self._get = QueryDict(self._req.args)55 return self._get56 57 def _set_get(self, get):58 self._get = get59 60 def _get_post(self):61 if not hasattr(self, '_post'):62 self._load_post_and_files()63 return self._post64 65 def _set_post(self, post):66 self._post = post67 68 def _get_cookies(self):69 if not hasattr(self, '_cookies'):70 self._cookies = parse_cookie(self._req.headers_in.get('cookie', ''))71 return self._cookies72 73 def _set_cookies(self, cookies):74 self._cookies = cookies75 76 def _get_files(self):77 if not hasattr(self, '_files'):78 self._load_post_and_files()79 return self._files80 81 def _get_meta(self):82 "Lazy loader that returns self.META dictionary"83 if not hasattr(self, '_meta'):84 self._meta = {85 'AUTH_TYPE': self._req.ap_auth_type,86 'CONTENT_LENGTH': self._req.clength, # This may be wrong87 'CONTENT_TYPE': self._req.content_type, # This may be wrong88 'GATEWAY_INTERFACE': 'CGI/1.1',89 'PATH_INFO': self._req.path_info,90 'PATH_TRANSLATED': None, # Not supported91 'QUERY_STRING': self._req.args,92 'REMOTE_ADDR': self._req.connection.remote_ip,93 'REMOTE_HOST': None, # DNS lookups not supported94 'REMOTE_IDENT': self._req.connection.remote_logname,95 'REMOTE_USER': self._req.user,96 'REQUEST_METHOD': self._req.method,97 'SCRIPT_NAME': None, # Not supported98 'SERVER_NAME': self._req.server.server_hostname,99 'SERVER_PORT': self._req.server.port,100 'SERVER_PROTOCOL': self._req.protocol,101 'SERVER_SOFTWARE': 'mod_python'102 }103 for key, value in self._req.headers_in.items():104 key = 'HTTP_' + key.upper().replace('-', '_')105 self._meta[key] = value106 return self._meta107 108 def _load_session_and_user(self):109 from django.models.auth import sessions110 from django.conf.settings import AUTH_SESSION_COOKIE111 session_cookie = self.COOKIES.get(AUTH_SESSION_COOKIE, '')112 try:113 self._session = sessions.get_session_from_cookie(session_cookie)114 self._user = self._session.get_user()115 except sessions.SessionDoesNotExist:116 from django.parts.auth import anonymoususers117 self._session = None118 self._user = anonymoususers.AnonymousUser()119 120 def _get_session(self):121 if not hasattr(self, '_session'):122 self._load_session_and_user()123 return self._session124 125 def _set_session(self, session):126 self._session = session127 128 def _get_user(self):129 if not hasattr(self, '_user'):130 self._load_session_and_user()131 return self._user132 133 def _set_user(self, user):134 self._user = user135 136 GET = property(_get_get, _set_get)137 POST = property(_get_post, _set_post)138 COOKIES = property(_get_cookies, _set_cookies)139 FILES = property(_get_files)140 META = property(_get_meta)141 REQUEST = property(_get_request)142 session = property(_get_session, _set_session)143 user = property(_get_user, _set_user)144 26 145 27 def parse_file_upload(header_dict, post_data): … … 337 219 HttpResponse.__init__(self, content, mimetype) 338 220 self.status_code = 500 339 340 def populate_apache_request(http_response, mod_python_req):341 "Populates the mod_python request object with an HttpResponse"342 mod_python_req.content_type = http_response['Content-Type'] or DEFAULT_MIME_TYPE343 del http_response['Content-Type']344 if http_response.cookies:345 mod_python_req.headers_out['Set-Cookie'] = http_response.cookies.output(header='')346 for key, value in http_response.headers.items():347 mod_python_req.headers_out[key] = value348 mod_python_req.status = http_response.status_code349 mod_python_req.write(http_response.get_content_as_string('utf-8'))
