Beispiel #1
0
    def fetch(self, environ):
        if environ.get('REQUEST_METHOD', 'GET') not in self.allowed_methods:
            return

        request_headers = list(parse_headers(environ))

        # if a Cache-Control/Pragma: no-cache header is in the request,
        # and if honor_shift_reload is true, we don't serve it from cache
        if self.honor_shift_reload:
            if self._check_no_cache(request_headers, environ):
                return
        # we don't try to serve range requests up from the cache
        if header_value(request_headers, 'Range'):
            return
        # we don't try to serve conditional requests up from cache
        for conditional in ('If-Modified-Since', 'If-None-Match',
                            'If-Match'):  # XXX other conditionals?
            if header_value(request_headers, conditional):
                return

        url = construct_url(environ)
        entries = self.storage.fetch(url)

        if entries:
            matching = self._discriminate(entries, request_headers, environ)
            if not matching:
                return

            now = time.time()

            discrims, expires, status, response_headers, body, extras = matching
            if expires > now:
                return status, response_headers, body
Beispiel #2
0
    def fetch(self, environ):
        if environ.get('REQUEST_METHOD', 'GET') not in self.allowed_methods:
            return

        request_headers = list(parse_headers(environ))

        # if a Cache-Control/Pragma: no-cache header is in the request,
        # and if honor_shift_reload is true, we don't serve it from cache
        if self.honor_shift_reload:
            if self._check_no_cache(request_headers, environ):
                return
        # we don't try to serve range requests up from the cache
        if header_value(request_headers, 'Range'):
            return
        # we don't try to serve conditional requests up from cache
        for conditional in ('If-Modified-Since', 'If-None-Match',
                            'If-Match'):  # XXX other conditionals?
            if header_value(request_headers, conditional):
                return

        url = construct_url(environ)
        entries = self.storage.fetch(url)

        if entries:
            matching = self._discriminate(entries, request_headers, environ)
            if not matching:
                return

            now = time.time()
        
            discrims, expires, status, response_headers, body, extras = matching
            if expires > now:
                return status, response_headers, body
Beispiel #3
0
    def store(self, status, response_headers, environ):
        request_headers = list(parse_headers(environ))

        # abort if we shouldn't store this response
        request_method = environ.get('REQUEST_METHOD', 'GET')
        if request_method not in self.allowed_methods:
            return
        if not (status.startswith('200') or status.startswith('203')):
            return
        if environ['wsgi.url_scheme'] == 'https':
            if not self.store_https_responses:
                return
        if self._check_no_cache(response_headers, environ):
            return
        cc_header = header_value(response_headers, 'Cache-Control')
        if cc_header:
            cc_parts = parse_cache_control_header(cc_header)
            try:
                if int(cc_parts.get('max-age', '0')) == 0:
                    return
            except ValueError:
                return

        # if we didn't abort due to any condition above, store the response
        vary_header_names = []
        vary = header_value(response_headers, 'Vary')
        if vary is not None:
            vary_header_names.extend(
                [ x.strip().lower() for x in vary.split(',') ])
        if self.always_vary_on_headers:
            vary_header_names.extend(list(self.always_vary_on_headers))

        if '*' in vary_header_names:
            return

        discriminators = Discriminators(request_headers, environ, 
            vary_header_names, self.always_vary_on_environ)
        headers = endtoend(response_headers)
        url = construct_url(environ)

        # Response headers won't have a date if we aren't proxying to
        # another http server on our right hand side.
        date = header_value(response_headers, 'Date')
        if date is None:
            date = time.time()
        else:
            date = calendar.timegm(parsedate_tz(date))

        expires = self._expires(date, response_headers)

        # XXX purge?

        return self.storage.store(
            url,
            discriminators,
            expires,
            status,
            headers,
            )
Beispiel #4
0
    def store(self, status, response_headers, environ):
        request_headers = list(parse_headers(environ))

        # abort if we shouldn't store this response
        request_method = environ.get('REQUEST_METHOD', 'GET')
        if request_method not in self.allowed_methods:
            return
        if not (status.startswith('200') or status.startswith('203')):
            return
        if environ['wsgi.url_scheme'] == 'https':
            if not self.store_https_responses:
                return
        if self._check_no_cache(response_headers, environ):
            return
        cc_header = header_value(response_headers, 'Cache-Control')
        if cc_header:
            cc_parts = parse_cache_control_header(cc_header)
            try:
                if int(cc_parts.get('max-age', '0')) == 0:
                    return
            except ValueError:
                return

        # if we didn't abort due to any condition above, store the response
        vary_header_names = []
        vary = header_value(response_headers, 'Vary')
        if vary is not None:
            vary_header_names.extend(
                [x.strip().lower() for x in vary.split(',')])
        if self.always_vary_on_headers:
            vary_header_names.extend(list(self.always_vary_on_headers))

        if '*' in vary_header_names:
            return

        discriminators = []
        for header_name in vary_header_names:
            value = header_value(request_headers, header_name)
            if value is not None:
                discriminators.append(('vary', (header_name, value)))
        for varname in self.always_vary_on_environ:
            value = environ.get(varname)
            if value is not None:
                discriminators.append(('env', (varname, value)))

        discriminators = tuple(sorted(discriminators))
        headers = endtoend(response_headers)
        url = construct_url(environ)

        # Response headers won't have a date if we aren't proxying to
        # another http server on our right hand side.
        date = header_value(response_headers, 'Date')
        if date is None:
            date = time.time()
        else:
            date = calendar.timegm(parsedate_tz(date))

        expires = self._expires(date, response_headers)

        # XXX purge?

        return self.storage.store(
            url,
            discriminators,
            expires,
            status,
            headers,
        )
Beispiel #5
0
 def headers(self):
     return dict(parse_headers(self.environ))
 def headers( self ):
     return dict( parse_headers( self.environ ) )