示例#1
0
文件: request.py 项目: xzflin/falcon
    def _wrap_stream(self):  # pragma nocover
        try:
            content_length = self.content_length or 0

        except HTTPInvalidHeader:
            # NOTE(kgriffs): The content-length header was specified,
            # but it had an invalid value. Assume no content.
            content_length = 0

        self.stream = helpers.Body(self.stream, content_length)
示例#2
0
文件: request.py 项目: shniu/falcon
    def _wrap_stream(self):  # pragma nocover
        try:
            # NOTE(kgriffs): We can only add the wrapper if the
            # content-length header was provided.
            if self.content_length is not None:
                self.stream = helpers.Body(self.stream, self.content_length)

        except HTTPInvalidHeader:
            # NOTE(kgriffs): The content-length header was specified,
            # but it had an invalid value.
            pass
示例#3
0
文件: request.py 项目: lumberj/falcon
    def _wrap_stream(self):
        try:
            content_length = self.content_length or 0

        # NOTE(kgriffs): This branch is indeed covered in test_wsgi.py
        # even though coverage isn't able to detect it.
        except errors.HTTPInvalidHeader:  # pragma: no cover
            # NOTE(kgriffs): The content-length header was specified,
            # but it had an invalid value. Assume no content.
            content_length = 0

        self.stream = helpers.Body(self.stream, content_length)
示例#4
0
    def __init__(self, env):
        """Initialize attributes based on a WSGI environment dict

        Note: Request is not meant to be instantiated directory by responders.

        Args:
            env: A WSGI environment dict passed in from the server. See also
                the PEP-3333 spec.

        """
        self.env = env

        self._wsgierrors = env['wsgi.errors']
        self.stream = env['wsgi.input']
        self.method = env['REQUEST_METHOD']

        # Normalize path
        path = env['PATH_INFO']
        if path:
            if len(path) != 1 and path.endswith('/'):
                self.path = path[:-1]
            else:
                self.path = path
        else:
            self.path = '/'

        # QUERY_STRING isn't required to be in env, so let's check
        # PERF: if...in is faster than using env.get(...)
        if 'QUERY_STRING' in env:
            self.query_string = env['QUERY_STRING']
        else:
            self.query_string = ''

        # PERF: Don't parse it if we don't have to!
        if self.query_string:
            self._params = helpers.parse_query_string(self.query_string)
        else:
            self._params = {}

        self._headers = helpers.parse_headers(env)

        # NOTE(kgriffs): Wrap wsgi.input if needed to make read() more robust,
        # normalizing semantics between, e.g., gunicorn and wsgiref.
        if isinstance(self.stream, NativeStream):  # pragma: nocover
            # NOTE(kgriffs): coverage can't detect that this *is* actually
            # covered since the test that does so uses multiprocessing.
            self.stream = helpers.Body(self.stream, self.content_length)
示例#5
0
    def test_body_stream_wrapper(self):
        data = testing.rand_string(SIZE_1_KB / 2, SIZE_1_KB)
        expected_body = data.encode('utf-8')
        expected_len = len(expected_body)

        # NOTE(kgriffs): Append newline char to each line
        # to match readlines behavior
        expected_lines = [(line + '\n').encode('utf-8')
                          for line in data.split('\n')]

        # NOTE(kgriffs): Remove trailing newline to simulate
        # what readlines does
        expected_lines[-1] = expected_lines[-1][:-1]

        stream = io.BytesIO(expected_body)
        body = request_helpers.Body(stream, expected_len)
        self.assertEquals(body.read(), expected_body)

        stream = io.BytesIO(expected_body)
        body = request_helpers.Body(stream, expected_len)
        self.assertEquals(body.read(2), expected_body[0:2])

        stream = io.BytesIO(expected_body)
        body = request_helpers.Body(stream, expected_len)
        self.assertEquals(body.read(expected_len + 1), expected_body)

        stream = io.BytesIO(expected_body)
        body = request_helpers.Body(stream, expected_len)
        self.assertEquals(body.readline(), expected_lines[0])

        stream = io.BytesIO(expected_body)
        body = request_helpers.Body(stream, expected_len)
        self.assertEquals(body.readlines(), expected_lines)

        stream = io.BytesIO(expected_body)
        body = request_helpers.Body(stream, expected_len)
        self.assertEquals(next(body), expected_lines[0])

        stream = io.BytesIO(expected_body)
        body = request_helpers.Body(stream, expected_len)
        for i, line in enumerate(body):
            self.assertEquals(line, expected_lines[i])
示例#6
0
    def test_body_stream_wrapper(self):
        data = testing.rand_string(SIZE_1_KB / 2, SIZE_1_KB)
        expected_body = data.encode('utf-8')
        expected_len = len(expected_body)

        # NOTE(kgriffs): Append newline char to each line
        # to match readlines behavior
        expected_lines = [(line + '\n').encode('utf-8')
                          for line in data.split('\n')]

        # NOTE(kgriffs): Remove trailing newline to simulate
        # what readlines does
        expected_lines[-1] = expected_lines[-1][:-1]

        stream = io.BytesIO(expected_body)
        body = request_helpers.Body(stream, expected_len)
        assert body.read() == expected_body

        stream = io.BytesIO(expected_body)
        body = request_helpers.Body(stream, expected_len)
        assert body.read(2) == expected_body[0:2]

        stream = io.BytesIO(expected_body)
        body = request_helpers.Body(stream, expected_len)
        assert body.read(expected_len + 1) == expected_body

        # NOTE(kgriffs): Test that reading past the end does not
        # hang, but returns the empty string.
        stream = io.BytesIO(expected_body)
        body = request_helpers.Body(stream, expected_len)
        for i in range(expected_len + 1):
            expected_value = expected_body[i:i + 1] if i < expected_len else b''
            assert body.read(1) == expected_value

        stream = io.BytesIO(expected_body)
        body = request_helpers.Body(stream, expected_len)
        assert body.readline() == expected_lines[0]

        stream = io.BytesIO(expected_body)
        body = request_helpers.Body(stream, expected_len)
        assert body.readline(-1) == expected_lines[0]

        stream = io.BytesIO(expected_body)
        body = request_helpers.Body(stream, expected_len)
        assert body.readline(expected_len + 1) == expected_lines[0]

        stream = io.BytesIO(expected_body)
        body = request_helpers.Body(stream, expected_len)
        assert body.readlines() == expected_lines

        stream = io.BytesIO(expected_body)
        body = request_helpers.Body(stream, expected_len)
        assert body.readlines(-1) == expected_lines

        stream = io.BytesIO(expected_body)
        body = request_helpers.Body(stream, expected_len)
        assert body.readlines(expected_len + 1) == expected_lines

        stream = io.BytesIO(expected_body)
        body = request_helpers.Body(stream, expected_len)
        assert next(body) == expected_lines[0]

        stream = io.BytesIO(expected_body)
        body = request_helpers.Body(stream, expected_len)
        for i, line in enumerate(body):
            assert line == expected_lines[i]
示例#7
0
    def __init__(self, env):
        self.env = env

        if self.context_type is None:
            # Literal syntax is more efficient than using dict()
            self.context = {}
        else:
            # pylint will detect this as not-callable because it only sees the
            # declaration of None, not whatever type a subclass may have set.
            self.context = self.context_type()  # pylint: disable=not-callable

        self._wsgierrors = env['wsgi.errors']
        self.stream = env['wsgi.input']
        self.method = env['REQUEST_METHOD']

        # Normalize path
        path = env['PATH_INFO']
        if path:
            if len(path) != 1 and path.endswith('/'):
                self.path = path[:-1]
            else:
                self.path = path
        else:
            self.path = '/'

        # QUERY_STRING isn't required to be in env, so let's check
        # PERF: if...in is faster than using env.get(...)
        if 'QUERY_STRING' in env and env['QUERY_STRING']:

            # TODO(kgriffs): Should this escape individual values instead
            # of the entire string? The way it is now, this:
            #
            #   x=ab%2Bcd%3D42%2C9
            #
            # becomes this:
            #
            #   x=ab+cd=42,9
            #
            self.query_string = uri.decode(env['QUERY_STRING'])

        else:
            self.query_string = six.text_type()

        # PERF: Don't parse it if we don't have to!
        if self.query_string:
            self._params = uri.parse_query_string(self.query_string)
        else:
            self._params = {}

        helpers.normalize_headers(env)
        self._cached_headers = {}

        self._cached_uri = None
        self._cached_relative_uri = None

        self.content_type = self._get_header_by_wsgi_name('HTTP_CONTENT_TYPE')

        # NOTE(kgriffs): Wrap wsgi.input if needed to make read() more robust,
        # normalizing semantics between, e.g., gunicorn and wsgiref.
        if isinstance(self.stream, NativeStream):  # pragma: nocover
            # NOTE(kgriffs): coverage can't detect that this *is* actually
            # covered since the test that does so uses multiprocessing.
            self.stream = helpers.Body(self.stream, self.content_length)

        # PERF(kgriffs): Technically, we should spend a few more
        # cycles and parse the content type for real, but
        # this heuristic will work virtually all the time.
        if (self.content_type
                and 'application/x-www-form-urlencoded' in self.content_type):

            # NOTE(kgriffs): This assumes self.stream has been patched
            # above in the case of wsgiref, so that self.content_length
            # is not needed. Normally we just avoid accessing
            # self.content_length, because it is a little expensive
            # to call. We could cache self.content_length, but the
            # overhead to do that won't usually be helpful, since
            # content length will only ever be read once per
            # request in most cases.
            body = self.stream.read()
            body = body.decode('ascii')

            extra_params = uri.parse_query_string(uri.decode(body))
            self._params.update(extra_params)
示例#8
0
    def __init__(self, env):
        """Initialize attributes based on a WSGI environment dict

        Note: Request is not meant to be instantiated directory by responders.

        Args:
            env: A WSGI environment dict passed in from the server. See also
                the PEP-3333 spec.

        """
        self.env = env

        self._wsgierrors = env['wsgi.errors']
        self.stream = env['wsgi.input']
        self.method = env['REQUEST_METHOD']

        # Normalize path
        path = env['PATH_INFO']
        if path:
            if len(path) != 1 and path.endswith('/'):
                self.path = path[:-1]
            else:
                self.path = path
        else:
            self.path = '/'

        # QUERY_STRING isn't required to be in env, so let's check
        # PERF: if...in is faster than using env.get(...)
        if 'QUERY_STRING' in env and env['QUERY_STRING']:

            # TODO(kgriffs): Should this escape individual values instead
            # of the entire string? The way it is now, this:
            #
            #   x=ab%2Bcd%3D42%2C9
            #
            # becomes this:
            #
            #   x=ab+cd=42,9
            #
            self.query_string = uri.decode(env['QUERY_STRING'])

        else:
            self.query_string = six.text_type()

        # PERF: Don't parse it if we don't have to!
        if self.query_string:
            self._params = uri.parse_query_string(self.query_string)
        else:
            self._params = {}

        helpers.normalize_headers(env)
        self._cached_headers = {}

        self._cached_uri = None
        self._cached_relative_uri = None

        # NOTE(kgriffs): Wrap wsgi.input if needed to make read() more robust,
        # normalizing semantics between, e.g., gunicorn and wsgiref.
        if isinstance(self.stream, NativeStream):  # pragma: nocover
            # NOTE(kgriffs): coverage can't detect that this *is* actually
            # covered since the test that does so uses multiprocessing.
            self.stream = helpers.Body(self.stream, self.content_length)