def _headers__get(self): """ The headers in a dictionary-like object """ if self._headers is None: self._headers = HeaderDict.view_list(self.headerlist) return self._headers
def start_mime_update(status, response_headers, exc_info=None): ext = os.path.splitext(environ["SCRIPT_NAME"])[1].lower()[1:] header_dict = HeaderDict.view_list(response_headers) if ext in self.MIME_MAPPINGS: header_dict["Content-Type"] = self.MIME_MAPPINGS[ext] new_status, headers = self._maybe_parse_headers_file(path_info) if new_status: status = new_status # HeaderDict.update() doesn't do what we need here. for k, v in headers.iteritems(): header_dict[k] = v return start_response(status, response_headers, exc_info)
def conditional_response_app(self, environ, start_response): """ Like the normal __call__ interface, but checks conditional headers: * If-Modified-Since (304 Not Modified; only on GET, HEAD) * If-None-Match (304 Not Modified; only on GET, HEAD) * Range (406 Partial Content; only on GET, HEAD) """ req = self.RequestClass(environ) status304 = False headerlist = self._abs_headerlist(environ) if req.method in self._safe_methods: if req.if_modified_since and self.last_modified and self.last_modified <= req.if_modified_since: status304 = True if req.if_none_match and self.etag: ## FIXME: should a weak match be okay? if self.etag in req.if_none_match: status304 = True else: # Even if If-Modified-Since matched, if ETag doesn't then reject it status304 = False if status304: remove_headers = ['content-length', 'content-type'] headerlist = filter( lambda (k, v): HeaderDict.normalize(k) not in remove_headers, headerlist) start_response('304 Not Modified', headerlist) return EmptyResponse(self.app_iter) if req.method == 'HEAD': start_response(self.status, headerlist) return EmptyResponse(self.app_iter) # FIXME: we should handle HEAD requests with Range if (req.range and req.if_range.match_response(self) and self.content_range is None and req.method == 'GET' and self.status_int == 200 and self.content_length is not None): content_range = req.range.content_range(self.content_length) # FIXME: we should support If-Range if content_range is None: iter_close(self.app_iter) # FIXME: we should use exc.HTTPRequestRangeNotSatisfiable # and let it generate the response body in correct content-type error_resp = Response( status_int=416, headers=list(headerlist), content_range=ContentRange(None, None, self.content_length), ) error_resp.body = "Requested range not satisfiable: %s" % req.range error_resp.content_type = 'text/plain' #error_resp.content_length = None return error_resp(environ, start_response) else: app_iter = self.app_iter_range(content_range.start, content_range.stop) if app_iter is not None: partial_resp = Response( status='206 Partial Content', headers=list(headerlist), content_range=content_range, app_iter=app_iter, ) # this should be guaranteed by Range.range_for_length(length) assert content_range.start is not None partial_resp.content_length = content_range.stop - content_range.start return partial_resp(environ, start_response) start_response(self.status, headerlist) return self.app_iter
def conditional_response_app(self, environ, start_response): """ Like the normal __call__ interface, but checks conditional headers: * If-Modified-Since (304 Not Modified; only on GET, HEAD) * If-None-Match (304 Not Modified; only on GET, HEAD) * Range (406 Partial Content; only on GET, HEAD) """ req = self.RequestClass(environ) status304 = False headerlist = self._abs_headerlist(environ) if req.method in self._safe_methods: if req.if_modified_since and self.last_modified and self.last_modified <= req.if_modified_since: status304 = True if req.if_none_match and self.etag: ## FIXME: should a weak match be okay? if self.etag in req.if_none_match: status304 = True else: # Even if If-Modified-Since matched, if ETag doesn't then reject it status304 = False if status304: remove_headers = ['content-length', 'content-type'] headerlist = filter( lambda (k,v): HeaderDict.normalize(k) not in remove_headers, headerlist ) start_response('304 Not Modified', headerlist) return EmptyResponse(self.app_iter) if req.method == 'HEAD': start_response(self.status, headerlist) return EmptyResponse(self.app_iter) # FIXME: we should handle HEAD requests with Range if (req.range and req.if_range.match_response(self) and self.content_range is None and req.method == 'GET' and self.status_int == 200 and self.content_length is not None ): content_range = req.range.content_range(self.content_length) # FIXME: we should support If-Range if content_range is None: iter_close(self.app_iter) # FIXME: we should use exc.HTTPRequestRangeNotSatisfiable # and let it generate the response body in correct content-type error_resp = Response( status_int=416, headers=list(headerlist), content_range = ContentRange(None, None, self.content_length), ) error_resp.body = "Requested range not satisfiable: %s" % req.range error_resp.content_type = 'text/plain' #error_resp.content_length = None return error_resp(environ, start_response) else: app_iter = self.app_iter_range(content_range.start, content_range.stop) if app_iter is not None: partial_resp = Response( status = '206 Partial Content', headers=list(headerlist), content_range=content_range, app_iter=app_iter, ) # this should be guaranteed by Range.range_for_length(length) assert content_range.start is not None partial_resp.content_length = content_range.stop - content_range.start return partial_resp(environ, start_response) start_response(self.status, headerlist) return self.app_iter