def test_app_missing(self): env = testing.create_environ() del env['SCRIPT_NAME'] req = Request(env) assert req.app == ''
def test_uri_http_1_0(self): # ======================================================= # HTTP, 80 # ======================================================= req = Request( testing.create_environ(protocol='HTTP/1.0', app=self.app, port=80, path='/hello', query_string=self.qs, headers=self.headers)) uri = ('http://' + testing.DEFAULT_HOST + self.app + self.relative_uri) self.assertEqual(req.uri, uri) # ======================================================= # HTTP, 80 # ======================================================= req = Request( testing.create_environ(protocol='HTTP/1.0', app=self.app, port=8080, path='/hello', query_string=self.qs, headers=self.headers)) uri = ('http://' + testing.DEFAULT_HOST + ':8080' + self.app + self.relative_uri) self.assertEqual(req.uri, uri) # ======================================================= # HTTP, 80 # ======================================================= req = Request( testing.create_environ(protocol='HTTP/1.0', scheme='https', app=self.app, port=443, path='/hello', query_string=self.qs, headers=self.headers)) uri = ('https://' + testing.DEFAULT_HOST + self.app + self.relative_uri) self.assertEqual(req.uri, uri) # ======================================================= # HTTP, 80 # ======================================================= req = Request( testing.create_environ(protocol='HTTP/1.0', scheme='https', app=self.app, port=22, path='/hello', query_string=self.qs, headers=self.headers)) uri = ('https://' + testing.DEFAULT_HOST + ':22' + self.app + self.relative_uri) self.assertEqual(req.uri, uri)
def test_bogus_content_length_neg(self): headers = {'content-length': '-1'} req = Request(testing.create_environ(headers=headers)) self.assertRaises(falcon.HTTPBadRequest, lambda: req.content_length)
def test_date_missing(self, attr): req = Request(testing.create_environ()) self.assertIs(getattr(req, attr), None)
def test_empty_path(self): self.req = Request(testing.create_environ(path='')) self.assertEqual(self.req.path, '/')
def test_date_missing(self): req = Request(testing.create_environ()) self.assertIs(req.date, None)
def test_range_invalid(self): headers = {'Range': 'bytes=10240'} req = Request(testing.create_environ(headers=headers)) self.assertRaises(falcon.HTTPBadRequest, lambda: req.range) headers = {'Range': 'bytes=-'} expected_desc = ('The value provided for the Range header is ' 'invalid. The range offsets are missing.') self._test_error_details(headers, 'range', falcon.HTTPInvalidHeader, 'Invalid header value', expected_desc) headers = {'Range': 'bytes=--'} req = Request(testing.create_environ(headers=headers)) self.assertRaises(falcon.HTTPBadRequest, lambda: req.range) headers = {'Range': 'bytes=-3-'} req = Request(testing.create_environ(headers=headers)) self.assertRaises(falcon.HTTPBadRequest, lambda: req.range) headers = {'Range': 'bytes=-3-4'} req = Request(testing.create_environ(headers=headers)) self.assertRaises(falcon.HTTPBadRequest, lambda: req.range) headers = {'Range': 'bytes=3-3-4'} req = Request(testing.create_environ(headers=headers)) self.assertRaises(falcon.HTTPBadRequest, lambda: req.range) headers = {'Range': 'bytes=3-3-'} req = Request(testing.create_environ(headers=headers)) self.assertRaises(falcon.HTTPBadRequest, lambda: req.range) headers = {'Range': 'bytes=3-3- '} req = Request(testing.create_environ(headers=headers)) self.assertRaises(falcon.HTTPBadRequest, lambda: req.range) headers = {'Range': 'bytes=fizbit'} req = Request(testing.create_environ(headers=headers)) self.assertRaises(falcon.HTTPBadRequest, lambda: req.range) headers = {'Range': 'bytes=a-'} req = Request(testing.create_environ(headers=headers)) self.assertRaises(falcon.HTTPBadRequest, lambda: req.range) headers = {'Range': 'bytes=a-3'} req = Request(testing.create_environ(headers=headers)) self.assertRaises(falcon.HTTPBadRequest, lambda: req.range) headers = {'Range': 'bytes=-b'} req = Request(testing.create_environ(headers=headers)) self.assertRaises(falcon.HTTPBadRequest, lambda: req.range) headers = {'Range': 'bytes=3-b'} req = Request(testing.create_environ(headers=headers)) self.assertRaises(falcon.HTTPBadRequest, lambda: req.range) headers = {'Range': 'bytes=x-y'} expected_desc = ('The value provided for the Range header is ' 'invalid. It must be a range formatted ' 'according to RFC 7233.') self._test_error_details(headers, 'range', falcon.HTTPInvalidHeader, 'Invalid header value', expected_desc) headers = {'Range': 'bytes=0-0,-1'} expected_desc = ('The value provided for the Range ' 'header is invalid. The value must be a ' 'continuous range.') self._test_error_details(headers, 'range', falcon.HTTPInvalidHeader, 'Invalid header value', expected_desc) headers = {'Range': '10-'} expected_desc = ('The value provided for the Range ' 'header is invalid. The value must be ' "prefixed with a range unit, e.g. 'bytes='") self._test_error_details(headers, 'range', falcon.HTTPInvalidHeader, 'Invalid header value', expected_desc)
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
def test_default_request_context(self): env = testing.create_environ() req = Request(env) self.assertIsInstance(req.context, dict)
def test_remote_addr_missing(self): env = testing.create_environ(host='example.com', path='/access_route') del env['REMOTE_ADDR'] req = Request(env) self.assertEqual(req.access_route, [])
def test_multipart_file_upload(): """Ensure that multipart input format works as intended""" file1_path = os.path.dirname( os.path.abspath(__file__)) + '/../logo/banner.jpg' file2_path = os.path.dirname( os.path.abspath(__file__)) + '/../logo/banner.xcf' file3_path = os.path.dirname( os.path.abspath(__file__)) + '/../logo/logo.svg' file4_path = os.path.dirname( os.path.abspath(__file__)) + '/../logo/mstile-150x150.png' file5_path = os.path.dirname( os.path.abspath(__file__)) + '/../logo/mstile-310x310.png' file1 = open(file1_path, 'rb') file2 = open(file2_path, 'rb') file3 = open(file3_path, 'rb') file4 = open(file4_path, 'rb') file5 = open(file5_path, 'rb') text_fields = { 'name': 'John Doe', 'foo': ['baz', 'bar', 'baz1', 'bar1'], 'file1': 'John Doe', 'file4': ['baz', 'bar', 'baz1', 'bar1'], 'blank_field': '' } file_fields = [('file1', file1), ('multifile', file2), ('multifile', file3), ('multifile', b''), ('file4', file4), ('file5', file5), ('enptyFileField', b'')] prepared_request = requests.Request(method='POST', url='http://localhost/', data=text_fields, files=file_fields).prepare() file1.seek(0) file1_content = file1.read() file2.seek(0) file2_content = file2.read() file3.seek(0) file3_content = file3.read() file4.seek(0) file4_content = file4.read() file5.seek(0) file5_content = file5.read() req = Request( testing.create_environ(host='example.com', path='/languages', app='backoffice', headers=prepared_request.headers, body=prepared_request.body, method='POST')) assertFileUpload(req.files['file1'], file1_content, file1_path) assert isinstance(req.files['multifile'], list) and len( req.files['multifile']) == 2 k = 0 multifile_data = [{ 'content': file2_content, 'path': file2_path }, { 'content': file3_content, 'path': file3_path }] for fileStream in req.files['multifile']: assertFileUpload(fileStream, multifile_data[k]['content'], multifile_data[k]['path']) k = k + 1 assertFileUpload(req.files['file4'], file4_content, file4_path) assertFileUpload(req.files['file5'], file5_content, file5_path, '/var') assert req.form_data == text_fields file1.close() file2.close() file3.close() file4.close() file5.close()
def test_remote_addr(self): req = Request( testing.create_environ(host='example.com', path='/access_route')) self.assertEqual(req.access_route, ['127.0.0.1'])
def test_x_real_ip(self): req = Request( testing.create_environ(host='example.com', path='/access_route', headers={'X-Real-IP': '2001:db8:cafe::17'})) self.assertEqual(req.access_route, ['2001:db8:cafe::17'])
def test_date_invalid(self): headers = {'date': 'Thu, 04 Apr 2013'} req = Request(testing.create_environ(headers=headers)) self.assertRaises(falcon.HTTPBadRequest, lambda: req.date)
def test_range_invalid(self): headers = {'Range': '10240'} req = Request(testing.create_environ(headers=headers)) self.assertRaises(falcon.HTTPBadRequest, lambda: req.range) headers = {'Range': '-'} expected_desc = ('The value provided for the Range header is ' 'invalid. The byte offsets are missing.') self._test_error_details(headers, 'range', falcon.HTTPInvalidHeader, 'Invalid header value', expected_desc) headers = {'Range': '--'} req = Request(testing.create_environ(headers=headers)) self.assertRaises(falcon.HTTPBadRequest, lambda: req.range) headers = {'Range': '-3-'} req = Request(testing.create_environ(headers=headers)) self.assertRaises(falcon.HTTPBadRequest, lambda: req.range) headers = {'Range': '-3-4'} req = Request(testing.create_environ(headers=headers)) self.assertRaises(falcon.HTTPBadRequest, lambda: req.range) headers = {'Range': '3-3-4'} req = Request(testing.create_environ(headers=headers)) self.assertRaises(falcon.HTTPBadRequest, lambda: req.range) headers = {'Range': '3-3-'} req = Request(testing.create_environ(headers=headers)) self.assertRaises(falcon.HTTPBadRequest, lambda: req.range) headers = {'Range': '3-3- '} req = Request(testing.create_environ(headers=headers)) self.assertRaises(falcon.HTTPBadRequest, lambda: req.range) headers = {'Range': 'fizbit'} req = Request(testing.create_environ(headers=headers)) self.assertRaises(falcon.HTTPBadRequest, lambda: req.range) headers = {'Range': 'a-'} req = Request(testing.create_environ(headers=headers)) self.assertRaises(falcon.HTTPBadRequest, lambda: req.range) headers = {'Range': 'a-3'} req = Request(testing.create_environ(headers=headers)) self.assertRaises(falcon.HTTPBadRequest, lambda: req.range) headers = {'Range': '-b'} req = Request(testing.create_environ(headers=headers)) self.assertRaises(falcon.HTTPBadRequest, lambda: req.range) headers = {'Range': '3-b'} req = Request(testing.create_environ(headers=headers)) self.assertRaises(falcon.HTTPBadRequest, lambda: req.range) headers = {'Range': 'x-y'} expected_desc = ('The value provided for the Range header is ' 'invalid. It must be a byte range formatted ' 'according to RFC 2616.') self._test_error_details(headers, 'range', falcon.HTTPInvalidHeader, 'Invalid header value', expected_desc) headers = {'Range': 'bytes=0-0,-1'} expected_desc = ('The value provided for the Range ' 'header is invalid. The value must be a ' 'continuous byte range.') self._test_error_details(headers, 'range', falcon.HTTPInvalidHeader, 'Invalid header value', expected_desc)
def test_missing_attribute_header(self): req = Request(testing.create_environ()) assert req.range is None req = Request(testing.create_environ()) assert req.content_length is None
def test_date(self): date = datetime.datetime(2013, 4, 4, 5, 19, 18) headers = {'date': 'Thu, 04 Apr 2013 05:19:18 GMT'} req = Request(testing.create_environ(headers=headers)) self.assertEqual(req.date, date)
def test_date_missing(self, attr): req = Request(testing.create_environ()) assert getattr(req, attr) is None
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'))
def test_method(self): assert self.req.method == 'GET' self.req = Request(testing.create_environ(path='', method='HEAD')) assert self.req.method == 'HEAD'
def test_missing_attribute_header(self): req = Request(testing.create_environ()) self.assertEqual(req.range, None) req = Request(testing.create_environ()) self.assertEqual(req.content_length, None)
def test_empty_path(self): self.req = Request(testing.create_environ(path='')) assert self.req.path == '/'
def test_method(self): self.assertEqual(self.req.method, 'GET') self.req = Request(testing.create_environ(path='', method='HEAD')) self.assertEqual(self.req.method, 'HEAD')
def test_app_present(self): req = Request(testing.create_environ(app='/moving-pictures')) assert req.app == '/moving-pictures'
def _test_header_expected_value(self, name, value, attr, expected_value): headers = {name: value} req = Request(testing.create_environ(headers=headers)) self.assertEqual(getattr(req, attr), expected_value)
def test_app_blank(self): req = Request(testing.create_environ(app='')) assert req.app == ''
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.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/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'))
def test_range_invalid(self): headers = {'Range': '10240'} req = Request(testing.create_environ(headers=headers)) self.assertRaises(falcon.HTTPBadRequest, lambda: req.range) headers = {'Range': '-'} req = Request(testing.create_environ(headers=headers)) self.assertRaises(falcon.HTTPBadRequest, lambda: req.range) headers = {'Range': '--'} req = Request(testing.create_environ(headers=headers)) self.assertRaises(falcon.HTTPBadRequest, lambda: req.range) headers = {'Range': '-3-'} req = Request(testing.create_environ(headers=headers)) self.assertRaises(falcon.HTTPBadRequest, lambda: req.range) headers = {'Range': '-3-4'} req = Request(testing.create_environ(headers=headers)) self.assertRaises(falcon.HTTPBadRequest, lambda: req.range) headers = {'Range': '3-3-4'} req = Request(testing.create_environ(headers=headers)) self.assertRaises(falcon.HTTPBadRequest, lambda: req.range) headers = {'Range': '3-3-'} req = Request(testing.create_environ(headers=headers)) self.assertRaises(falcon.HTTPBadRequest, lambda: req.range) headers = {'Range': '3-3- '} req = Request(testing.create_environ(headers=headers)) self.assertRaises(falcon.HTTPBadRequest, lambda: req.range) headers = {'Range': 'fizbit'} req = Request(testing.create_environ(headers=headers)) self.assertRaises(falcon.HTTPBadRequest, lambda: req.range) headers = {'Range': 'a-'} req = Request(testing.create_environ(headers=headers)) self.assertRaises(falcon.HTTPBadRequest, lambda: req.range) headers = {'Range': 'a-3'} req = Request(testing.create_environ(headers=headers)) self.assertRaises(falcon.HTTPBadRequest, lambda: req.range) headers = {'Range': '-b'} req = Request(testing.create_environ(headers=headers)) self.assertRaises(falcon.HTTPBadRequest, lambda: req.range) headers = {'Range': '3-b'} req = Request(testing.create_environ(headers=headers)) self.assertRaises(falcon.HTTPBadRequest, lambda: req.range) headers = {'Range': 'x-y'} req = Request(testing.create_environ(headers=headers)) self.assertRaises(falcon.HTTPBadRequest, lambda: req.range) headers = {'Range': 'bytes=0-0,-1'} req = Request(testing.create_environ(headers=headers)) self.assertRaises(falcon.HTTPBadRequest, lambda: req.range)