Exemple #1
0
 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
Exemple #2
0
 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
Exemple #3
0
        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)
Exemple #4
0
    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