Ticket #3680: cache.control.on.syndication.code.only.diff

File cache.control.on.syndication.code.only.diff, 6.2 KB (added by jerf@…, 8 years ago)

a code only prototype of the cache system, for discussion purposes

  • django/contrib/syndication/views.py

     
    11from django.contrib.syndication import feeds
    22from django.http import HttpResponse, Http404
     3from django.middleware.http import response_304_if_cached
    34
    45def feed(request, url, feed_dict=None):
    56    if not feed_dict:
     
    1516    except KeyError:
    1617        raise Http404, "Slug %r isn't registered." % slug
    1718
     19    feed = f(slug, request.path)
     20
     21    response = HttpResponse()
     22
     23    # Give the feed a chance to pull cache control data from
     24    # somewhere without even retrieving the objects, like from a cache.
    1825    try:
    19         feedgen = f(slug, request.path).get_feed(param)
     26        etag, last_modified = feed.cache_control_from_bits(param)
     27        if etag:
     28            response['ETag'] = etag
     29        if last_modified:
     30            response['Last-Modified'] = last_modified.strftime('%a, %d %b %Y %H:%M:%S GMT')
     31
     32        if response_304_if_cached(request, response):
     33            return response
     34    except AttributeError:
     35        # No .cache_control_from_bits method
     36        pass
     37
     38    try:
     39        feedgen = feed.get_feed(param)
    2040    except feeds.FeedDoesNotExist:
    2141        raise Http404, "Invalid feed parameters. Slug %r is valid, but other parameters, or lack thereof, are not." % slug
    2242
    23     response = HttpResponse(mimetype=feedgen.mime_type)
     43    response.mimetype = feedgen.mime_type
     44
     45    # See if we can bail out before generating the text of the feed
     46    try:
     47        etag, last_modified = feed.cache_control(feed._raw_items)
     48        if etag:
     49            response['ETag'] = etag
     50        if last_modified:
     51            response['Last-Modified'] = last_modified.strftime('%a, %d %b %Y %H:%M:%S GMT')
     52
     53        if response_304_if_cached(request, response):
     54            return response
     55    except AttributeError:
     56        # no cache_control method
     57        raise
     58        pass
     59
     60    feed.process_items()
    2461    feedgen.write(response, 'utf-8')
    2562    return response
  • django/contrib/syndication/feeds.py

     
    2424        self.feed_url = feed_url
    2525        self.title_template_name = self.title_template or ('feeds/%s_title.html' % slug)
    2626        self.description_template_name = self.description_template or ('feeds/%s_description.html' % slug)
     27        self.__items = None
    2728
    2829    def item_link(self, item):
    2930        try:
     
    6465        else:
    6566            obj = None
    6667
    67         current_site = Site.objects.get_current()
     68        self.current_site = current_site = Site.objects.get_current()
    6869        link = self.__get_dynamic_attr('link', obj)
    6970        link = add_domain(current_site.domain, link)
    7071
     
    8182            feed_copyright = self.__get_dynamic_attr('feed_copyright', obj),
    8283        )
    8384
     85        self._raw_items = self.__get_dynamic_attr('items', obj)
     86        self.feed = feed
     87        return feed
     88
     89    def process_items(self):
     90        current_site = self.current_site
     91        feed = self.feed
     92
    8493        try:
    8594            title_tmp = loader.get_template(self.title_template_name)
    8695        except TemplateDoesNotExist:
     
    9099        except TemplateDoesNotExist:
    91100            description_tmp = Template('{{ obj }}')
    92101
    93         for item in self.__get_dynamic_attr('items', obj):
     102        for item in self._raw_items:
    94103            link = add_domain(current_site.domain, self.__get_dynamic_attr('item_link', item))
    95104            enc = None
    96105            enc_url = self.__get_dynamic_attr('item_enclosure_url', item)
  • django/middleware/http.py

     
    11import datetime
    22
     3def response_304_if_cached(request, response):
     4    """Given the etag and last_modified passed in, modifies the
     5    response inline to make it return a 304 if appropriate.
     6    Returns true if a cached response was created."""
     7    if response.has_header('ETag'):
     8        if_none_match = request.META.get('HTTP_IF_NONE_MATCH', None)
     9        if if_none_match == response['ETag']:
     10            response.status_code = 304
     11            response.content = ''
     12            response['Content-Length'] = '0'
     13            return True
     14
     15    if response.has_header('Last-Modified'):
     16        last_mod = response['Last-Modified']
     17        if_modified_since = request.META.get('HTTP_IF_MODIFIED_SINCE', None)
     18        if if_modified_since == response['Last-Modified']:
     19            response.status_code = 304
     20            response.content = ''
     21            response['Content-Length'] = '0'
     22            return True
     23
     24    if request.method == 'HEAD':
     25        response.content = ''
     26
     27    return False
     28
    329class ConditionalGetMiddleware(object):
    430    """
    531    Handles conditional GET operations. If the response has a ETag or
     
    1339    def process_response(self, request, response):
    1440        now = datetime.datetime.utcnow()
    1541        response['Date'] = now.strftime('%a, %d %b %Y %H:%M:%S GMT')
     42
    1643        if not response.has_header('Content-Length'):
    1744            response['Content-Length'] = str(len(response.content))
    1845
    19         if response.has_header('ETag'):
    20             if_none_match = request.META.get('HTTP_IF_NONE_MATCH', None)
    21             if if_none_match == response['ETag']:
    22                 response.status_code = 304
    23                 response.content = ''
    24                 response['Content-Length'] = '0'
    25 
    26         if response.has_header('Last-Modified'):
    27             last_mod = response['Last-Modified']
    28             if_modified_since = request.META.get('HTTP_IF_MODIFIED_SINCE', None)
    29             if if_modified_since == response['Last-Modified']:
    30                 response.status_code = 304
    31                 response.content = ''
    32                 response['Content-Length'] = '0'
    33 
    34         if request.method == 'HEAD':
    35             response.content = ''
    36 
     46        response_304_if_cached(request, response)
     47       
    3748        return response
    3849
    3950class SetRemoteAddrFromForwardedFor(object):
Back to Top