Source

django-rest-api / rest_api / middleware.py

The default branch has multiple heads

Full commit
import logging
from auth import _authenticate, _masquerade
from django.contrib.auth.models import AnonymousUser
from django.conf import settings

import datetime
import time
import sys
import hashlib

from timezones.utils import adjust_datetime_to_timezone

import serializers

class HttpAuthMiddleware(object):
    """
    Use HTTP Authorization to log in to django site.

    If you use the FORCE_HTTP_AUTH=True in your settings.py, then ONLY
    Http Auth will be used, if you don't then either http auth or 
    django's session-based auth will be used.

    If you provide a HTTP_AUTH_REALM in your settings, that will be used as
    the realm for the challenge.
    """

    def process_request(self, request):
        if isinstance(request.user, AnonymousUser):
            # We may return an HttpResponse, if we are not authenticated
            return _authenticate(request)


class MasqueradeAsUserMiddleware(object):
    """
    Allows a superuser to appear to the system to be another user,
    but still logs in the API logs as the superuser.
    """
    
    def process_request(self, request):
        _masquerade(request)

class SerializationMiddleware(object):
    """
    """
    def process_request(self, request):
        """
        Deserialize raw_post_data according to Content-Type
        """
        request.data = serializers.deserialize(request)
        
    
    # def process_response(self, request, response):
    #     """
    #     Serialize attached objects into the HTTP Response
    #     """
    #     return response


class ContentHashMiddleware(object):
    def process_response(self, request, response):
        response['Content-Hash'] = hashlib.md5(response.content).hexdigest()
        try:
            response.content.seek(0)
        except:
            pass
        return response

class HttpLoggingMiddleware(object):
    def process_response(self, request, response):
        if hasattr(request, '_start_time'):
            time_spent = time.time() - request._start_time
        else:
            time_spent = '-'
        
        if hasattr(request, 'data'):
            data = request.data
        else:
            data = ''
        
        status = int(response.status_code)
        
        if status >= 400:
            # Log as a warning object if we got a server error.
            exc_info = sys.exc_info()
            if exc_info == (None, None, None):
                try:
                    if isinstance(response, Exception):
                        raise response
                    raise Exception(response.content)
                except:
                    exc_info = sys.exc_info()
                    try:
                        response.content.seek(0)
                    except:
                        pass
            
            logger = logging.getLogger('django.request').warning
            if status in (401, 403, 409):
                logger = logging.getLogger('django.request').debug
            if status >= 500:
                logger = logging.getLogger('django.request').error
            
            logger("%s %s [%s]" % (
                request.method, request.get_full_path(), response.status_code
            ), exc_info=exc_info, extra={
                'request':request,
                'url': request.build_absolute_uri(),
                'data':{
                    'username': request.user.username,
                    'data': data,
                    'response': response.content,
                }
            })
            try:
                response.content.seek(0)
            except:
                pass
            
        if isinstance(time_spent, float) and not request.path.startswith('/admin/'):
            # Log as a warning if we took too long.
            if time_spent > getattr(settings, 'WARN_IF_TIME_EXCEEDS', 2) and not (request.get_full_path() in getattr(settings, 'IGNORE_LONG_REQUEST_TIME_URLS', [])):
                logging.getLogger('django.request').warn("Request took too long", extra={
                    'request':request,
                    'url':request.build_absolute_uri() + ' ' + str(time_spent),
                    'data':{
                        'time':time_spent,
                        'username':request.user.username,
                        'data':data,
                        'response':response.content,
                        'status':response.status_code,
                    }
                })
                try:
                    response.content.seek(0)
                except:
                    pass
                
        if not request.path.startswith('/sentry/'):
            logging.getLogger('django.request').info(
                "%s %s %s [%s] \"%s %s %s\" %s %s %s" % (
                    request.META.get('REMOTE_ADDR'),
                    '-',
                    '-',
                    adjust_datetime_to_timezone(datetime.datetime.now(), settings.TIME_ZONE, getattr(settings, 'ADMIN_TIME_ZONE', settings.TIME_ZONE)).strftime("%d/%b/%Y %H:%M:%S"),
                    request.method,
                    request.get_full_path(),
                    "HTTP/1.1",
                    response.status_code,
                    len(response.content) or '-',
                    time_spent,
            ))
            try:
                response.content.seek(0)
            except:
                pass
        
        try:
            response.content.seek(0)
        except:
            pass
            
        return response
        
    def process_request(self, request):
        request._start_time = time.time()