Example #1
0
    def test_client_accepts(self):
        headers = {'Accept': 'application/xml'}
        req = Request(testing.create_environ(headers=headers))
        self.assertTrue(req.client_accepts('application/xml'))

        headers = {'Accept': '*/*'}
        req = Request(testing.create_environ(headers=headers))
        self.assertTrue(req.client_accepts('application/xml'))

        headers = {'Accept': 'application/json'}
        req = Request(testing.create_environ(headers=headers))
        self.assertFalse(req.client_accepts('application/xml'))

        headers = {'Accept': 'application/xm'}
        req = Request(testing.create_environ(headers=headers))
        self.assertFalse(req.client_accepts('application/xml'))
Example #2
0
    def __call__(self, env, start_response):
        """WSGI "app" method

        Makes instances of API callable by any WSGI server. See also PEP 333.

        Args:
            env: A WSGI environment dictionary
            start_response: A WSGI helper method for setting status and headers
                on a response.

        """

        req = Request(env)
        resp = Response()

        responder, params, na_responder = self._get_responder(
            req.path, req.method)

        try:
            responder(req, resp, **params)

        except HTTPError as ex:
            resp.status = ex.status
            if ex.headers is not None:
                resp.set_headers(ex.headers)

            if req.client_accepts('application/json'):
                resp.body = ex.json()

        #
        # Set status and headers
        #
        use_body = not helpers.should_ignore_body(resp.status, req.method)
        if use_body:
            helpers.set_content_length(resp)
            body = helpers.get_body(resp)
        else:
            # Default: return an empty body
            body = []

        # Set content type if needed
        use_content_type = (body or
                            req.method == 'HEAD' or
                            resp.status == HTTP_416)

        if use_content_type:
            media_type = self._media_type
        else:
            media_type = None

        headers = resp._wsgi_headers(media_type)

        # Return the response per the WSGI spec
        start_response(resp.status, headers)
        return body
Example #3
0
 def test_client_accepts_bogus(self):
     headers = {'Accept': '~'}
     req = Request(testing.create_environ(headers=headers))
     self.assertFalse(req.client_accepts('text/plain'))
     self.assertFalse(req.client_accepts('application/json'))
Example #4
0
    def test_client_accepts(self):
        headers = {'Accept': 'application/xml'}
        req = Request(testing.create_environ(headers=headers))
        self.assertTrue(req.client_accepts('application/xml'))

        headers = {'Accept': '*/*'}
        req = Request(testing.create_environ(headers=headers))
        self.assertTrue(req.client_accepts('application/xml'))
        self.assertTrue(req.client_accepts('application/json'))
        self.assertTrue(req.client_accepts('application/x-msgpack'))

        headers = {'Accept': 'application/x-msgpack'}
        req = Request(testing.create_environ(headers=headers))
        self.assertFalse(req.client_accepts('application/xml'))
        self.assertFalse(req.client_accepts('application/json'))
        self.assertTrue(req.client_accepts('application/x-msgpack'))

        headers = {}  # NOTE(kgriffs): Equivalent to '*/*' per RFC
        req = Request(testing.create_environ(headers=headers))
        self.assertTrue(req.client_accepts('application/xml'))

        headers = {'Accept': 'application/json'}
        req = Request(testing.create_environ(headers=headers))
        self.assertFalse(req.client_accepts('application/xml'))

        headers = {'Accept': 'application/x-msgpack'}
        req = Request(testing.create_environ(headers=headers))
        self.assertTrue(req.client_accepts('application/x-msgpack'))

        headers = {'Accept': 'application/xm'}
        req = Request(testing.create_environ(headers=headers))
        self.assertFalse(req.client_accepts('application/xml'))

        headers = {'Accept': 'application/*'}
        req = Request(testing.create_environ(headers=headers))
        self.assertTrue(req.client_accepts('application/json'))
        self.assertTrue(req.client_accepts('application/xml'))
        self.assertTrue(req.client_accepts('application/x-msgpack'))

        headers = {'Accept': 'text/*'}
        req = Request(testing.create_environ(headers=headers))
        self.assertTrue(req.client_accepts('text/plain'))
        self.assertTrue(req.client_accepts('text/csv'))
        self.assertFalse(req.client_accepts('application/xhtml+xml'))

        headers = {'Accept': 'text/*, application/xhtml+xml; q=0.0'}
        req = Request(testing.create_environ(headers=headers))
        self.assertTrue(req.client_accepts('text/plain'))
        self.assertTrue(req.client_accepts('text/csv'))
        self.assertFalse(req.client_accepts('application/xhtml+xml'))

        headers = {'Accept': 'text/*; q=0.1, application/xhtml+xml; q=0.5'}
        req = Request(testing.create_environ(headers=headers))
        self.assertTrue(req.client_accepts('text/plain'))
        self.assertTrue(req.client_accepts('application/xhtml+xml'))

        headers = {'Accept': 'text/*,         application/*'}
        req = Request(testing.create_environ(headers=headers))
        self.assertTrue(req.client_accepts('text/plain'))
        self.assertTrue(req.client_accepts('application/xml'))
        self.assertTrue(req.client_accepts('application/json'))
        self.assertTrue(req.client_accepts('application/x-msgpack'))

        headers = {'Accept': 'text/*,application/*'}
        req = Request(testing.create_environ(headers=headers))
        self.assertTrue(req.client_accepts('text/plain'))
        self.assertTrue(req.client_accepts('application/xml'))
        self.assertTrue(req.client_accepts('application/json'))
        self.assertTrue(req.client_accepts('application/x-msgpack'))
Example #5
0
    def test_client_accepts(self):
        headers = {'Accept': 'application/xml'}
        req = Request(testing.create_environ(headers=headers))
        self.assertTrue(req.client_accepts('application/xml'))

        headers = {'Accept': '*/*'}
        req = Request(testing.create_environ(headers=headers))
        self.assertTrue(req.client_accepts('application/xml'))

        headers = {}  # NOTE(kgriffs): Equivalent to '*/*' per RFC
        req = Request(testing.create_environ(headers=headers))
        self.assertTrue(req.client_accepts('application/xml'))

        headers = {'Accept': 'application/json'}
        req = Request(testing.create_environ(headers=headers))
        self.assertFalse(req.client_accepts('application/xml'))

        headers = {'Accept': 'application/xm'}
        req = Request(testing.create_environ(headers=headers))
        self.assertFalse(req.client_accepts('application/xml'))

        headers = {'Accept': 'application/*'}
        req = Request(testing.create_environ(headers=headers))
        self.assertTrue(req.client_accepts('application/json'))
        self.assertTrue(req.client_accepts('application/xml'))

        headers = {'Accept': 'text/*'}
        req = Request(testing.create_environ(headers=headers))
        self.assertTrue(req.client_accepts('text/plain'))
        self.assertTrue(req.client_accepts('text/csv'))
        self.assertFalse(req.client_accepts('application/xhtml+xml'))

        headers = {'Accept': 'text/*, application/xhtml+xml; q=0.0'}
        req = Request(testing.create_environ(headers=headers))
        self.assertTrue(req.client_accepts('text/plain'))
        self.assertTrue(req.client_accepts('text/csv'))
        self.assertTrue(req.client_accepts('application/xhtml+xml'))

        headers = {'Accept': 'text/*; q=0.1, application/xhtml+xml; q=0.5'}
        req = Request(testing.create_environ(headers=headers))
        self.assertTrue(req.client_accepts('text/plain'))

        headers = {'Accept': 'text/*,         application/*'}
        req = Request(testing.create_environ(headers=headers))
        self.assertTrue(req.client_accepts('text/plain'))
        self.assertTrue(req.client_accepts('application/json'))

        headers = {'Accept': 'text/*,application/*'}
        req = Request(testing.create_environ(headers=headers))
        self.assertTrue(req.client_accepts('text/plain'))
        self.assertTrue(req.client_accepts('application/json'))
Example #6
0
 def test_client_accepts_bogus(self):
     headers = {'Accept': '~'}
     req = Request(testing.create_environ(headers=headers))
     self.assertFalse(req.client_accepts('text/plain'))
     self.assertFalse(req.client_accepts('application/json'))
Example #7
0
    def __call__(self, env, start_response):
        """WSGI "app" method

        Makes instances of API callable by any WSGI server. See also PEP 333.

        Args:
            env: A WSGI environment dictionary
            start_response: A WSGI helper method for setting status and headers
                on a response.

        """

        req = Request(env)
        resp = Response()

        responder, params, na_responder = self._get_responder(
            req.path, req.method)

        try:
            responder(req, resp, **params)

        except HTTPError as ex:
            resp.status = ex.status
            if ex.headers is not None:
                resp.set_headers(ex.headers)

            if req.client_accepts('application/json'):
                resp.body = ex.json()

        except TypeError as ex:
            # NOTE(kgriffs): Get the stack trace up here since we can just
            # use this convenience function which graps the last raised
            # exception context.
            stack_trace = traceback.format_exc()

            # See if the method doesn't support the given route's params, to
            # support assigning multiple routes to the same resource.
            try:
                argspec = responder.wrapped_argspec
            except AttributeError:
                argspec = inspect.getargspec(responder)

            # First three args should be (self, req, resp)
            if argspec.args[0] == 'self':
                offset = 3
            else:
                offset = 2

            args_needed = set(argspec.args[offset:])
            args_given = set(params.keys())

            # Reset the response
            resp = Response()

            # Does the responder require more or fewer args than given?
            if args_needed != args_given:
                req.log_error('A responder method could not be found with the '
                              'correct arguments.')
                na_responder(req, resp)
            else:
                # Error caused by something else
                req.log_error('A responder method (on_*) raised TypeError. %s'
                              % stack_trace)
                falcon.responders.internal_server_error(req, resp)

        #
        # Set status and headers
        #
        use_body = not helpers.should_ignore_body(resp.status, req.method)
        if use_body:
            helpers.set_content_length(resp)
            body = helpers.get_body(resp)
        else:
            # Default: return an empty body
            body = []

        # Set content type if needed
        use_content_type = (body or
                            req.method == 'HEAD' or
                            resp.status == HTTP_416)

        if use_content_type:
            media_type = self._media_type
        else:
            media_type = None

        headers = resp._wsgi_headers(media_type)

        # Return the response per the WSGI spec
        start_response(resp.status, headers)
        return body
Example #8
0
    def __call__(self, env, start_response):
        """WSGI "app" method

        Makes instances of API callable by any WSGI server. See also PEP 333.

        Args:
            env: A WSGI environment dictionary
            start_response: A WSGI helper method for setting status and
                headers on a response.

        """

        req = Request(env)
        resp = Response()

        responder, params = self._get_responder(
            req.path, req.method)

        try:
            # NOTE(kgriffs): Using an inner try..except in order to
            # address the case when err_handler raises HTTPError.
            #
            # NOTE(kgriffs): Coverage is giving false negatives,
            # so disabled on relevant lines. All paths are tested
            # afaict.
            try:
                responder(req, resp, **params)  # pragma: no cover
            except Exception as ex:
                for err_type, err_handler in self._error_handlers:
                    if isinstance(ex, err_type):
                        err_handler(ex, req, resp, params)
                        break  # pragma: no cover

                else:
                    # PERF(kgriffs): This will propagate HTTPError to
                    # the handler below. It makes handling HTTPError
                    # less efficient, but that is OK since error cases
                    # don't need to be as fast as the happy path, and
                    # indeed, should perhaps be slower to create
                    # backpressure on clients that are issuing bad
                    # requests.
                    raise

        except HTTPError as ex:
            resp.status = ex.status
            if ex.headers is not None:
                resp.set_headers(ex.headers)

            if req.client_accepts('application/json'):
                resp.body = ex.json()

        #
        # Set status and headers
        #
        use_body = not helpers.should_ignore_body(resp.status, req.method)
        if use_body:
            helpers.set_content_length(resp)
            body = helpers.get_body(resp)
        else:
            # Default: return an empty body
            body = []

        # Set content type if needed
        use_content_type = (body or
                            req.method == 'HEAD' or
                            resp.status == HTTP_416)

        if use_content_type:
            media_type = self._media_type
        else:
            media_type = None

        headers = resp._wsgi_headers(media_type)

        # Return the response per the WSGI spec
        start_response(resp.status, headers)
        return body
Example #9
0
    def __call__(self, env, start_response):
        """WSGI "app" method

        Makes instances of API callable by any WSGI server. See also PEP 333.

        Args:
            env: A WSGI environment dictionary
            start_response: A WSGI helper method for setting status and headers
                on a response.

        """

        req = Request(env)
        resp = Response()

        responder, params, na_responder = self._get_responder(
            req.path, req.method)

        try:
            responder(req, resp, **params)

        except HTTPError as ex:
            resp.status = ex.status
            if ex.headers is not None:
                resp.set_headers(ex.headers)

            if req.client_accepts('application/json'):
                resp.body = ex.json()

        except TypeError as ex:
            # NOTE(kgriffs): Get the stack trace up here since we can just
            # use this convenience function which graps the last raised
            # exception context.
            stack_trace = traceback.format_exc()

            # See if the method doesn't support the given route's params, to
            # support assigning multiple routes to the same resource.
            try:
                argspec = responder.wrapped_argspec
            except AttributeError:
                argspec = inspect.getargspec(responder)

            # First three args should be (self, req, resp)
            if argspec.args[0] == 'self':
                offset = 3
            else:
                offset = 2

            args_needed = set(argspec.args[offset:])
            args_given = set(params.keys())

            # Reset the response
            resp = Response()

            # Does the responder require more or fewer args than given?
            if args_needed != args_given:
                req.log_error('A responder method could not be found with the '
                              'correct arguments.')
                na_responder(req, resp)
            else:
                # Error caused by something else
                req.log_error(
                    'A responder method (on_*) raised TypeError. %s' %
                    stack_trace)
                falcon.responders.internal_server_error(req, resp)

        #
        # Set status and headers
        #
        use_body = not helpers.should_ignore_body(resp.status, req.method)
        if use_body:
            helpers.set_content_length(resp)
            body = helpers.get_body(resp)
        else:
            # Default: return an empty body
            body = []

        # Set content type if needed
        use_content_type = (body or req.method == 'HEAD'
                            or resp.status == HTTP_416)

        if use_content_type:
            media_type = self._media_type
        else:
            media_type = None

        headers = resp._wsgi_headers(media_type)

        # Return the response per the WSGI spec
        start_response(resp.status, headers)
        return body
Example #10
0
    def __call__(self, env, start_response):
        """WSGI "app" method

        Makes instances of API callable by any WSGI server. See also PEP 333.

        Args:
            env: A WSGI environment dictionary
            start_response: A WSGI helper method for setting status and
                headers on a response.

        """

        req = Request(env)
        resp = Response()

        responder, params = self._get_responder(
            req.path, req.method)

        try:
            # NOTE(kgriffs): Using an inner try..except in order to
            # address the case when err_handler raises HTTPError.
            #
            # NOTE(kgriffs): Coverage is giving false negatives,
            # so disabled on relevant lines. All paths are tested
            # afaict.
            try:
                responder(req, resp, **params)  # pragma: no cover
            except Exception as ex:
                for err_type, err_handler in self._error_handlers:
                    if isinstance(ex, err_type):
                        err_handler(ex, req, resp, params)
                        break  # pragma: no cover

                else:
                    # PERF(kgriffs): This will propagate HTTPError to
                    # the handler below. It makes handling HTTPError
                    # less efficient, but that is OK since error cases
                    # don't need to be as fast as the happy path, and
                    # indeed, should perhaps be slower to create
                    # backpressure on clients that are issuing bad
                    # requests.
                    raise

        except HTTPError as ex:
            resp.status = ex.status
            if ex.headers is not None:
                resp.set_headers(ex.headers)

            if req.client_accepts('application/json'):
                resp.body = ex.json()

        #
        # Set status and headers
        #
        use_body = not helpers.should_ignore_body(resp.status, req.method)
        if use_body:
            helpers.set_content_length(resp)
            body = helpers.get_body(resp)
        else:
            # Default: return an empty body
            body = []

        # Set content type if needed
        use_content_type = (body or
                            req.method == 'HEAD' or
                            resp.status == HTTP_416)

        if use_content_type:
            media_type = self._media_type
        else:
            media_type = None

        headers = resp._wsgi_headers(media_type)

        # Return the response per the WSGI spec
        start_response(resp.status, headers)
        return body