Ejemplo n.º 1
0
        def inner(request, *args, **kwargs):
            # Compute values (if any) for the requested resource.
            def get_last_modified():
                if last_modified_func:
                    dt = last_modified_func(request, *args, **kwargs)
                    if dt:
                        return timegm(dt.utctimetuple())

            # The value from etag_func() could be quoted or unquoted.
            res_etag = etag_func(request, *args, **
                                 kwargs) if etag_func else None
            res_etag = quote_etag(res_etag) if res_etag is not None else None
            res_last_modified = get_last_modified()

            response = get_conditional_response(
                request,
                etag=res_etag,
                last_modified=res_last_modified,
            )

            if response is None:
                response = func(request, *args, **kwargs)

            # Set relevant headers on the response if they don't already exist
            # and if the request method is safe.
            if request.method in ('GET', 'HEAD'):
                if res_last_modified and not response.has_header(
                        'Last-Modified'):
                    response['Last-Modified'] = http_date(res_last_modified)
                if res_etag:
                    response.setdefault('ETag', res_etag)

            return response
Ejemplo n.º 2
0
 def process_response(self, request, response):
     """
     If request.session was modified, or if the configuration is to save the
     session every time, save the changes and set a session cookie or delete
     the session cookie if the session has been emptied.
     """
     try:
         accessed = request.session.accessed
         modified = request.session.modified
         empty = request.session.is_empty()
     except AttributeError:
         pass
     else:
         # First check if we need to delete this cookie.
         # The session should be deleted only if the session is entirely empty
         if settings.SESSION_COOKIE_NAME in request.COOKIES and empty:
             response.delete_cookie(
                 settings.SESSION_COOKIE_NAME,
                 path=settings.SESSION_COOKIE_PATH,
                 domain=settings.SESSION_COOKIE_DOMAIN,
             )
         else:
             if accessed:
                 patch_vary_headers(response, ('Cookie', ))
             if (modified
                     or settings.SESSION_SAVE_EVERY_REQUEST) and not empty:
                 if request.session.get_expire_at_browser_close():
                     max_age = None
                     expires = None
                 else:
                     max_age = request.session.get_expiry_age()
                     expires_time = time.time() + max_age
                     expires = http_date(expires_time)
                 # Save the session data and refresh the client cookie.
                 # Skip session save for 500 responses, refs #3881.
                 if response.status_code != 500:
                     try:
                         request.session.save()
                     except UpdateError:
                         raise SuspiciousOperation(
                             "The request's session was deleted before the "
                             "request completed. The user may have logged "
                             "out in a concurrent request, for example.")
                     response.set_cookie(
                         settings.SESSION_COOKIE_NAME,
                         request.session.session_key,
                         max_age=max_age,
                         expires=expires,
                         domain=settings.SESSION_COOKIE_DOMAIN,
                         path=settings.SESSION_COOKIE_PATH,
                         secure=settings.SESSION_COOKIE_SECURE or None,
                         httponly=settings.SESSION_COOKIE_HTTPONLY or None,
                         samesite=settings.SESSION_COOKIE_SAMESITE,
                     )
     return response
Ejemplo n.º 3
0
    def set_cookie(self,
                   key,
                   value='',
                   max_age=None,
                   expires=None,
                   path='/',
                   domain=None,
                   secure=False,
                   httponly=False,
                   samesite=None):
        """
        Set a cookie.

        ``expires`` can be:
        - a string in the correct format,
        - a naive ``datetime.datetime`` object in UTC,
        - an aware ``datetime.datetime`` object in any time zone.
        If it is a ``datetime.datetime`` object then calculate ``max_age``.
        """
        self.cookies[key] = value
        if expires is not None:
            if isinstance(expires, datetime.datetime):
                if timezone.is_aware(expires):
                    expires = timezone.make_naive(expires, timezone.utc)
                delta = expires - expires.utcnow()
                # Add one second so the date matches exactly (a fraction of
                # time gets lost between converting to a timedelta and
                # then the date string).
                delta = delta + datetime.timedelta(seconds=1)
                # Just set max_age - the max_age logic will set expires.
                expires = None
                max_age = max(0, delta.days * 86400 + delta.seconds)
            else:
                self.cookies[key]['expires'] = expires
        else:
            self.cookies[key]['expires'] = ''
        if max_age is not None:
            self.cookies[key]['max-age'] = max_age
            # IE requires expires, so set it if hasn't been already.
            if not expires:
                self.cookies[key]['expires'] = http_date(time.time() + max_age)
        if path is not None:
            self.cookies[key]['path'] = path
        if domain is not None:
            self.cookies[key]['domain'] = domain
        if secure:
            self.cookies[key]['secure'] = True
        if httponly:
            self.cookies[key]['httponly'] = True
        if samesite:
            if samesite.lower() not in ('lax', 'strict'):
                raise ValueError('samesite must be "lax" or "strict".')
            self.cookies[key]['samesite'] = samesite
Ejemplo n.º 4
0
 def __call__(self, request, *args, **kwargs):
     try:
         obj = self.get_object(request, *args, **kwargs)
     except ObjectDoesNotExist:
         raise Http404('Feed object does not exist.')
     feedgen = self.get_feed(obj, request)
     response = HttpResponse(content_type=feedgen.content_type)
     if hasattr(self, 'item_pubdate') or hasattr(self, 'item_updateddate'):
         # if item_pubdate or item_updateddate is defined for the feed, set
         # header so as ConditionalGetMiddleware is able to send 304 NOT MODIFIED
         response['Last-Modified'] = http_date(
             timegm(feedgen.latest_post_date().utctimetuple()))
     feedgen.write(response, 'utf-8')
     return response
Ejemplo n.º 5
0
def sitemap(request,
            sitemaps,
            section=None,
            template_name='sitemap.xml',
            content_type='application/xml'):

    req_protocol = request.scheme
    req_site = get_current_site(request)

    if section is not None:
        if section not in sitemaps:
            raise Http404("No sitemap available for section: %r" % section)
        maps = [sitemaps[section]]
    else:
        maps = sitemaps.values()
    page = request.GET.get("p", 1)

    lastmod = None
    all_sites_lastmod = True
    urls = []
    for site in maps:
        try:
            if callable(site):
                site = site()
            urls.extend(
                site.get_urls(page=page, site=req_site, protocol=req_protocol))
            if all_sites_lastmod:
                site_lastmod = getattr(site, 'latest_lastmod', None)
                if site_lastmod is not None:
                    site_lastmod = (site_lastmod.utctimetuple() if isinstance(
                        site_lastmod, datetime.datetime) else
                                    site_lastmod.timetuple())
                    lastmod = site_lastmod if lastmod is None else max(
                        lastmod, site_lastmod)
                else:
                    all_sites_lastmod = False
        except EmptyPage:
            raise Http404("Page %s empty" % page)
        except PageNotAnInteger:
            raise Http404("No page '%s'" % page)
    response = TemplateResponse(request,
                                template_name, {'urlset': urls},
                                content_type=content_type)
    if all_sites_lastmod and lastmod is not None:
        # if lastmod is defined for all sites, set header so as
        # ConditionalGetMiddleware is able to send 304 NOT MODIFIED
        response['Last-Modified'] = http_date(timegm(lastmod))
    return response
Ejemplo n.º 6
0
def patch_response_headers(response, cache_timeout=None):
    """
    Add HTTP caching headers to the given HttpResponse: Expires and
    Cache-Control.

    Each header is only added if it isn't already set.

    cache_timeout is in seconds. The CACHE_MIDDLEWARE_SECONDS setting is used
    by default.
    """
    if cache_timeout is None:
        cache_timeout = settings.CACHE_MIDDLEWARE_SECONDS
    if cache_timeout < 0:
        cache_timeout = 0  # Can't have max-age negative
    if not response.has_header('Expires'):
        response['Expires'] = http_date(time.time() + cache_timeout)
    patch_cache_control(response, max_age=cache_timeout)
Ejemplo n.º 7
0
def serve(request, path, document_root=None, show_indexes=False):
    """
    Serve static files below a given point in the directory structure.

    To use, put a URL pattern such as::

        from server.views.static import serve

        url(r'^(?P<path>.*)$', serve, {'document_root': '/path/to/my/files/'})

    in your URLconf. You must provide the ``document_root`` param. You may
    also set ``show_indexes`` to ``True`` if you'd like to serve a basic index
    of the directory.  This index view will use the template hardcoded below,
    but if you'd like to override it, you can create a template called
    ``static/directory_index.html``.
    """
    path = posixpath.normpath(path).lstrip('/')
    fullpath = Path(safe_join(document_root, path))
    if fullpath.is_dir():
        if show_indexes:
            return directory_index(path, fullpath)
        raise Http404(_("Directory indexes are not allowed here."))
    if not fullpath.exists():
        raise Http404(_('"%(path)s" does not exist') % {'path': fullpath})
    # Respect the If-Modified-Since header.
    statobj = fullpath.stat()
    if not was_modified_since(request.META.get('HTTP_IF_MODIFIED_SINCE'),
                              statobj.st_mtime, statobj.st_size):
        return HttpResponseNotModified()
    content_type, encoding = mimetypes.guess_type(str(fullpath))
    content_type = content_type or 'application/octet-stream'
    response = FileResponse(fullpath.open('rb'), content_type=content_type)
    response["Last-Modified"] = http_date(statobj.st_mtime)
    if encoding:
        response["Content-Encoding"] = encoding
    return response