def __call__(self, environ, start_response): # sanitize the path for non unix systems cleaned_path = environ.get('PATH_INFO', '').strip('/') for sep in os.sep, os.altsep: if sep and sep != '/': cleaned_path = cleaned_path.replace(sep, '/') path = '/'.join([''] + [x for x in cleaned_path.split('/') if x and x != '..']) file_loader = None for search_path, loader in self.exports.iteritems(): if search_path == path: real_filename, file_loader = loader(None) if file_loader is not None: break if not search_path.endswith('/'): search_path += '/' if path.startswith(search_path): real_filename, file_loader = loader(path[len(search_path):]) if file_loader is not None: break if file_loader is None or not self.is_allowed(real_filename): return self.app(environ, start_response) guessed_type = mimetypes.guess_type(real_filename) mime_type = guessed_type[0] or self.fallback_mimetype f, mtime, file_size = file_loader() headers = [('Date', http_date())] if self.cache: timeout = self.cache_timeout etag = self.generate_etag(mtime, file_size, real_filename) headers += [ ('Etag', '"%s"' % etag), ('Cache-Control', 'max-age=%d, public' % timeout) ] if not is_resource_modified(environ, etag, last_modified=mtime): f.close() start_response('304 Not Modified', headers) return [] headers.append(('Expires', http_date(time() + timeout))) else: headers.append(('Cache-Control', 'public')) headers.extend(( ('Content-Type', mime_type), ('Content-Length', str(file_size)), ('Last-Modified', http_date(mtime)) )) start_response('200 OK', headers) return wrap_file(environ, f)
def make_conditional(self, request_or_environ): """Make the response conditional to the request. This method works best if an etag was defined for the response already. The `add_etag` method can be used to do that. If called without etag just the date header is set. This does nothing if the request method in the request or enviorn is anything but GET or HEAD. It does not remove the body of the response because that's something the `__call__` function does for us automatically. Returns self so that you can do ``return resp.make_conditional(req)`` but modifies the object in-place. """ environ = getattr(request_or_environ, 'environ', request_or_environ) if environ['REQUEST_METHOD'] not in ('GET', 'HEAD'): return self.headers['Date'] = http_date() if 'content-length' in self.headers: self.headers['Content-Length'] = len(self.data) if not is_resource_modified(environ, self.headers.get('etag'), None, self.headers.get('last-modified')): self.status_code = 304 return self
def __call__(self, environ, start_response): # sanitize the path for non unix systems cleaned_path = environ.get('PATH_INFO', '').strip('/') for sep in os.sep, os.altsep: if sep and sep != '/': cleaned_path = cleaned_path.replace(sep, '/') path = '/'.join( [''] + [x for x in cleaned_path.split('/') if x and x != '..']) file_loader = None for search_path, loader in self.exports.iteritems(): if search_path == path: real_filename, file_loader = loader(None) if file_loader is not None: break if not search_path.endswith('/'): search_path += '/' if path.startswith(search_path): real_filename, file_loader = loader(path[len(search_path):]) if file_loader is not None: break if file_loader is None or not self.is_allowed(real_filename): return self.app(environ, start_response) guessed_type = mimetypes.guess_type(real_filename) mime_type = guessed_type[0] or self.fallback_mimetype f, mtime, file_size = file_loader() headers = [('Date', http_date())] if self.cache: timeout = self.cache_timeout etag = self.generate_etag(mtime, file_size, real_filename) headers += [('Etag', '"%s"' % etag), ('Cache-Control', 'max-age=%d, public' % timeout)] if not is_resource_modified(environ, etag, last_modified=mtime): f.close() start_response('304 Not Modified', headers) return [] headers.append(('Expires', http_date(time() + timeout))) else: headers.append(('Cache-Control', 'public')) headers.extend( (('Content-Type', mime_type), ('Content-Length', str(file_size)), ('Last-Modified', http_date(mtime)))) start_response('200 OK', headers) return wrap_file(environ, f)
def make_conditional(self, request_or_environ): environ = _get_environ(request_or_environ) if environ['REQUEST_METHOD'] in ('GET', 'HEAD'): self.headers['Date'] = http_date() if 'content-length' in self.headers: self.headers['Content-Length'] = len(self.data) if not is_resource_modified(environ, self.headers.get('etag'), None, self.headers.get('last-modified')): self.status_code = 304 return self
def make_conditional(self, request_or_environ): environ = _get_environ(request_or_environ) if environ["REQUEST_METHOD"] in ("GET", "HEAD"): self.headers["Date"] = http_date() if "content-length" in self.headers: self.headers["Content-Length"] = len(self.data) if not is_resource_modified(environ, self.headers.get("etag"), None, self.headers.get("last-modified")): self.status_code = 304 return self
def __call__(self, environ, start_response): # sanitize the path for non unix systems cleaned_path = environ.get("PATH_INFO", "").strip("/") for sep in os.sep, os.altsep: if sep and sep != "/": cleaned_path = cleaned_path.replace(sep, "/") path = "/".join([""] + [x for x in cleaned_path.split("/") if x and x != ".."]) file_loader = None for search_path, loader in self.exports.iteritems(): if search_path == path: real_filename, file_loader = loader(None) if file_loader is not None: break if not search_path.endswith("/"): search_path += "/" if path.startswith(search_path): real_filename, file_loader = loader(path[len(search_path) :]) if file_loader is not None: break if file_loader is None or not self.is_allowed(real_filename): return self.app(environ, start_response) guessed_type = mimetypes.guess_type(real_filename) mime_type = guessed_type[0] or self.fallback_mimetype f, mtime, file_size = file_loader() headers = [("Date", http_date())] if self.cache: timeout = self.cache_timeout etag = self.generate_etag(mtime, file_size, real_filename) headers += [("Etag", '"%s"' % etag), ("Cache-Control", "max-age=%d, public" % timeout)] if not is_resource_modified(environ, etag, last_modified=mtime): f.close() start_response("304 Not Modified", headers) return [] headers.append(("Expires", http_date(time() + timeout))) else: headers.append(("Cache-Control", "public")) headers.extend( (("Content-Type", mime_type), ("Content-Length", str(file_size)), ("Last-Modified", http_date(mtime))) ) start_response("200 OK", headers) return wrap_file(environ, f)
def _set_retry_after(self, value): if value is None: if 'retry-after' in self.headers: del self.headers['retry-after'] return elif isinstance(value, datetime): value = http_date(value) else: value = str(value) self.headers['Retry-After'] = value
def _set_retry_after(self, value): if value is None: if "retry-after" in self.headers: del self.headers["retry-after"] return if isinstance(value, datetime): value = http_date(value) else: value = str(value) self.headers["Retry-After"] = value
def _set_retry_after(self, value): if value is None: if 'retry-after' in self.headers: del self.headers['retry-after'] return if isinstance(value, datetime): value = http_date(value) else: value = str(value) self.headers['Retry-After'] = value
def test_remove_entity_headers(): """Entity header removing function""" now = http_date() headers1 = [('Date', now), ('Content-Type', 'text/html'), ('Content-Length', '0')] headers2 = Headers(headers1) remove_entity_headers(headers1) assert headers1 == [('Date', now)] remove_entity_headers(headers2) assert headers2 == Headers([('Date', now)])
def request_redirect(response): """To be passed into the fwerks module to handle mis-matched paths. We define the general 'redirect' handler here for easy access to other tools in this module. This function is designed to be passed to the FWerks application constructor function in `request.py`. `response` A pre-constructed response object. """ # There is no need to format a nice redirect response, since # browsers will automatically redirect response = set_common_headers(response) # Expire in 4 weeks. response.headers['Expires'] = http_date(time.time() + (86400 * 28)) response.headers['Cache-Control'] = 'public, max-age=%d' % (86400 * 28) response.headers['Connection'] = 'close' return response
def test_is_resource_modified(): """Test is_resource_modified alone""" env = create_environ() # ignore POST env['REQUEST_METHOD'] = 'POST' assert not is_resource_modified(env, etag='testing') env['REQUEST_METHOD'] = 'GET' # etagify from data assert_raises(TypeError, is_resource_modified, env, data='42', etag='23') env['HTTP_IF_NONE_MATCH'] = generate_etag('awesome') assert not is_resource_modified(env, data='awesome') env['HTTP_IF_MODIFIED_SINCE'] = http_date(datetime(2008, 1, 1, 12, 30)) assert not is_resource_modified(env, last_modified=datetime(2008, 1, 1, 12, 00)) assert is_resource_modified(env, last_modified=datetime(2008, 1, 1, 13, 00))
def make_conditional(self, request_or_environ): """ Make the response conditional to the request. This method works best if an etag was defined for the response already. The `add_etag` method can be used to do that. If called without etag just the date header is set. This does nothing if the request method in the request or enviorn is anything but GET. """ if environ['REQUEST_METHOD'] not in ('GET', 'HEAD'): return environ = getattr(request_or_environ, 'environ', request_or_environ) self.headers['Date'] = http_date() if 'etag' in self.headers: if_none_match = environ.get('HTTP_IF_NONE_MATCH') last_modified = self.headers.get('last-modified') if_modified_since = environ.get('HTTP_IF_MODIFIED_SINCE') # we only set the status code because the request object removes # contents for 304 responses automatically on `__call__` if if_none_match and if_none_match == self.headers['etag'] or \ if_modified_since == last_modified: self.status_code = 304