def range(self): try: value = self.env['HTTP_RANGE'] if '=' in value: unit, sep, req_range = value.partition('=') else: msg = "The value must be prefixed with a range unit, e.g. 'bytes='" raise errors.HTTPInvalidHeader(msg, 'Range') except KeyError: return None if ',' in req_range: msg = 'The value must be a continuous range.' raise errors.HTTPInvalidHeader(msg, 'Range') try: first, sep, last = req_range.partition('-') if not sep: raise ValueError() if first: return (int(first), int(last or -1)) elif last: return (-int(last), -1) else: msg = 'The range offsets are missing.' raise errors.HTTPInvalidHeader(msg, 'Range') except ValueError: href = 'http://goo.gl/zZ6Ey' href_text = 'HTTP/1.1 Range Requests' msg = ('It must be a range formatted according to RFC 7233.') raise errors.HTTPInvalidHeader(msg, 'Range', href=href, href_text=href_text)
def content_length(self): try: value = self.env['CONTENT_LENGTH'] except KeyError: return None # NOTE(kgriffs): Normalize an empty value to behave as if # the header were not included; wsgiref, at least, inserts # an empty CONTENT_LENGTH value if the request does not # set the header. Gunicorn and uWSGI do not do this, but # others might if they are trying to match wsgiref's # behavior too closely. if not value: return None try: value_as_int = int(value) except ValueError: msg = 'The value of the header must be a number.' raise errors.HTTPInvalidHeader(msg, 'Content-Length') if value_as_int < 0: msg = 'The value of the header must be a positive number.' raise errors.HTTPInvalidHeader(msg, 'Content-Length') return value_as_int
def _deserialize_form( self, stream, content_type, content_length, form_cls=MultipartForm ): if not form_cls: raise NotImplementedError _, options = cgi.parse_header(content_type) try: boundary = options['boundary'] except KeyError: raise errors.HTTPInvalidHeader( 'No boundary specifier found in {!r}'.format(content_type), 'Content-Type', ) # NOTE(vytas): RFC 2046, section 5.1. # If a boundary delimiter line appears to end with white space, the # white space must be presumed to have been added by a gateway, and # must be deleted. boundary = boundary.rstrip() # NOTE(vytas): RFC 2046, section 5.1. # The boundary parameter consists of 1 to 70 characters from a set of # characters known to be very robust through mail gateways, and NOT # ending with white space. if not 1 <= len(boundary) <= 70: raise errors.HTTPInvalidHeader( 'The boundary parameter must consist of 1 to 70 characters', 'Content-Type', ) return form_cls(stream, boundary.encode(), content_length, self.parse_options)
def content_length(self): try: value = self._asgi_headers[b'content-length'] except KeyError: return None try: # PERF(vytas): int() also works with a bytestring argument. value_as_int = int(value) except ValueError: # PERF(vytas): Check for an empty value in the except clause, # because we do not expect ASGI servers to inject any headers # that the client did not provide. # NOTE(kgriffs): Normalize an empty value to behave as if # the header were not included; wsgiref, at least, inserts # an empty CONTENT_LENGTH value if the request does not # set the header. Gunicorn and uWSGI do not do this, but # others might if they are trying to match wsgiref's # behavior too closely. if not value: return None msg = 'The value of the header must be a number.' raise errors.HTTPInvalidHeader(msg, 'Content-Length') if value_as_int < 0: msg = 'The value of the header must be a positive number.' raise errors.HTTPInvalidHeader(msg, 'Content-Length') return value_as_int
def get_header_as_datetime(self, header, required=False, obs_date=False): """Return an HTTP header with HTTP-Date values as a datetime. Args: name (str): Header name, case-insensitive (e.g., 'Date') required (bool, optional): Set to ``True`` to raise ``HTTPBadRequest`` instead of returning gracefully when the header is not found (default ``False``). obs_date (bool, optional): Support obs-date formats according to RFC 7231, e.g.: "Sunday, 06-Nov-94 08:49:37 GMT" (default ``False``). Returns: datetime: The value of the specified header if it exists, or ``None`` if the header is not found and is not required. Raises: HTTPBadRequest: The header was not found in the request, but it was required. HttpInvalidHeader: The header contained a malformed/invalid value. """ try: http_date = self.get_header(header, required=required) return util.http_date_to_dt(http_date, obs_date=obs_date) except TypeError: # When the header does not exist and isn't required return None except ValueError: msg = ('It must be formatted according to RFC 7231, ' 'Section 7.1.1.1') raise errors.HTTPInvalidHeader(msg, header)
def range_unit(self): try: value = self.env['HTTP_RANGE'] if '=' in value: unit, sep, req_range = value.partition('=') return unit else: msg = "The value must be prefixed with a range unit, e.g. 'bytes='" raise errors.HTTPInvalidHeader(msg, 'Range') except KeyError: return None