def doFilter(self, request: Request, response: Response, chain: FilterChain): try: chain.doFilter(request, response) except Exception: response.status = 500 response.body = "An error occurred while handling this request." self.LOGGER.error(traceback.format_exc())
def doFilter(self, request: Request, response: Response, chain: FilterChain): try: chain.doFilter(request, response) except Exception as e: response.status = 500 response.body = "{}\n{}".format(e.__class__.__name__, traceback.format_exc()) self.LOGGER.error(traceback.format_exc())
def doFilter(self, request: Request, response: Response, chain: FilterChain): if request.headers['Content-Type'] == 'application/json' and len(request.body) > 0: request.body = json.loads(request.body) chain.doFilter(request, response) if isinstance(response.body, dict) or isinstance(response.body, list): response.body = json.dumps(response.body) response.headers['Content-Type'] = 'application/json'
def invoke(self, request: Request) -> Response: origin = request.headers['Origin'] if self.should_allow(origin): response = Response(200, self.cors_headers, "") else: response = Response(400, self.cors_headers, "") if 'Vary' not in response.headers and response.headers[ALLOW_ORIGIN_HEADER] != '*': response.headers['Vary'] = 'Origin' return response
def doFilter(self, request: Request, response: Response, chain: FilterChain): try: chain.doFilter(request, response) except Exception as e: exception_mapper = Stream(self.exception_mappers).firstMatch( lambda mapper: mapper.handles(e)) if exception_mapper.isPresent(): response.copy(exception_mapper.get().create_response(e)) else: raise e
def doFilter(self, request: Request, response: Response, chain: FilterChain): chain.doFilter(request, response) if isinstance(response.body, RenderedView): rendered_view = response.body template_text = self.view_template_repository.get_template(rendered_view.view_file) template_parameters = rendered_view.data if self.deserializer.is_deserializable_type(rendered_view.data.__class__): template_parameters = self.serializer.serialize(rendered_view.data) response.body = Template(template_text).render(**template_parameters) response.headers['Content-Type'] = "text/html"
def test_givenMatchingExceptionMapper_whenHandlingException_thenReturnTheCreatedHttpResponse( self): created_response = Response(200, {"foo": "bar"}, "body") self.exceptionMapperMock.handles.return_value = True self.exceptionMapperMock.create_response.return_value = created_response self.filterChainMock.doFilter.side_effect = AnException() returned_response = Response.empty() self.filter.doFilter(None, returned_response, self.filterChainMock) self.assertEqual(created_response.headers, returned_response.headers) self.assertEqual(created_response.body, returned_response.body) self.assertEqual(created_response.status, returned_response.status)
def doFilter(self, request: Request, response: Response): if len(self.filters) == 0: gotten_response = None for invoker in self.route_handler_factory.create_route_handlers( request): try: gotten_response = invoker.invoke(request) except IncorrectResourceParametersException: continue if gotten_response is None: raise IncorrectResourceParametersException() response.copy(gotten_response) else: self.filters[0].doFilter(request, response, self.getNextChain())
def test_shouldInjectCorsHeadersInResponse(self): response = Response.empty() self.filter.doFilter(self.request, response, self.filter_chain_mock) self.cors_handler_mock.inject_cors_headers.assert_called_with( self.request.path, response.headers)
def doFilter(self, request: Request, response: Response, chain: FilterChain): chain.doFilter(request, response) if self.registry.is_annotated( response.body.__class__, Serializable) or type( response.body) in TYPES_TO_BE_SERIALIZED: response.body = self.serializer.serialize(response.body)
def invoke(self, request: Request) -> Response: try: method = types.MethodType(self.route_registration.routeFunction, self.get_resource_instance()) parameters = self.parameter_selector_chain.get_parameters(request, method) function_return = method(*parameters) except MissingRouteInvocationArgument: raise IncorrectResourceParametersException() if isinstance(function_return, Response): return function_return return Response(200, {}, function_return)
def test_givenATemplatedResponse_whenApplyingFilter_thenTheTemplateIsProcessedByJinja2( self): a_templated_response = Response( 200, {}, RenderedView("test.html", {"foo": "bar"})) self.deserializerMock.is_deserializable_type.return_value = False self.viewTemplateRepositoryMock.get_template.return_value = A_TEMPLATE self.templateFilter.doFilter(A_REQUEST, a_templated_response, self.filterChainMock) self.assertEqual("bar", a_templated_response.body)
def test_givenATemplatedResponse_whenApplyingFilter_thenContentTypeIsSetToTextHtml( self): a_templated_response = Response( 200, {}, RenderedView("test.html", {"foo": "bar"})) self.viewTemplateRepositoryMock.get_template.return_value = A_TEMPLATE self.templateFilter.doFilter(A_REQUEST, a_templated_response, self.filterChainMock) self.assertEqual("text/html", a_templated_response.headers['Content-Type'])
def test_givenAResponseWhichShouldNotBeTemplated_whenApplyingFilter_thenDoNothing( self): returned_response = Response.empty() self.templateFilter.doFilter(A_REQUEST, returned_response, self.filterChainMock) self.assertEqual(A_RESPONSE.headers.items(), returned_response.headers.items()) self.assertEqual(A_RESPONSE.body, returned_response.body) self.assertEqual(A_RESPONSE.status, returned_response.status)
def handle_partial_content_request( self, request: Request, filepath: str, *, max_block_size: int = 2000000, content_type="application/octet-stream") -> Response: if request.headers['Range']: total_filesize = os.path.getsize(filepath) start, end = self._parse_range_string(request.headers['Range'], max_block_size, total_filesize) return Response( 206, { "Content-Type": content_type, "Accept-Ranges": "bytes", "Content-Range": f"bytes {start}-{end-1}/{total_filesize}" }, self._read_partial_file(filepath, start, end)) return Response(200, {"Content-Type": content_type}, self._read_whole_file(filepath))
def test_givenADto_whenApplyingFilter_thenDtoIsSerializedToDictionaryBeforeRenderingTheTemplate( self): A_DTO = object() a_templated_response = Response(200, {}, RenderedView("test.html", A_DTO)) self.serializerMock.serialize.return_value = {"foo": "bar"} self.viewTemplateRepositoryMock.get_template.return_value = A_TEMPLATE self.templateFilter.doFilter(A_REQUEST, a_templated_response, self.filterChainMock) self.assertEqual("bar", a_templated_response.body)
def post(self, request: Request) -> Response: filename = os.path.join(self.temp_dir, str(uuid.uuid4())) + ".pdf" new_filename = os.path.join(self.temp_dir, str(uuid.uuid4())) + ".pdf" with open(filename, 'wb') as f: f.write(request.body) subprocess.call( ("""pdfnup --nup 2x2 """ + filename + """ --papersize {8.5in,11in} -o """ + new_filename).split(" ")) with open(new_filename, 'rb') as f: body = f.read() return Response(200, {}, body)
def post_file(self, request: Request) -> Response: filename = self.temporary_file_factory.generate_temporary_pdf_filepath( ) dpi = 400 if "HTTP_DPI" in request.headers.keys(): dpi = int(request.headers["HTTP_DPI"]) with open(filename, 'wb') as f: f.write(request.body) new_filename = self.conversion_service.convert(filename, dpi) with open(new_filename, 'rb') as f: body = f.read() return Response(200, {}, body)
def route(self, env, start_response): request = self.request_factory.build_request(env) filter_chain = self.filter_chain_factory.create_filter_chain(request) response = Response.empty() filter_chain.doFilter(request, response) start_response( self.http_status_resolver.get_status_code(response.status), [x for x in response.headers.items()]) if isinstance(response.body, str): return [response.body.encode('utf-8')] else: return [response.body]
def post_file(self, request: Request) -> Response: filename = os.path.join(self.temp_dir, str(uuid.uuid4())) + ".pdf" new_filename = os.path.join(self.temp_dir, str(uuid.uuid4())) + ".pdf" dpi = 100 if "HTTP_DPI" in request.headers.keys(): dpi = int(request.headers["HTTP_DPI"]) with open(filename, 'wb') as f: f.write(request.body) subprocess.call( f"""convert -density {dpi} -negate {filename} {new_filename} """. split(" ")[:-1]) with open(new_filename, 'rb') as f: body = f.read() return Response(200, {}, body)
import unittest from unittest import mock from jivago.wsgi.filter.filter import Filter from jivago.wsgi.filter.filter_chain import FilterChain from jivago.wsgi.invocation.incorrect_resource_parameters_exception import IncorrectResourceParametersException from jivago.wsgi.invocation.resource_invoker import ResourceInvoker from jivago.wsgi.invocation.route_handler_factory import RouteHandlerFactory from jivago.wsgi.request.request import Request from jivago.wsgi.request.response import Response A_REQUEST = Request('GET', "/path", {}, "", "") A_RESPONSE = Response.empty() class FilterChainTest(unittest.TestCase): def setUp(self): self.resourceInvokerFactoryMock: RouteHandlerFactory = mock.create_autospec( RouteHandlerFactory) self.resourceInvokerMock: ResourceInvoker = mock.create_autospec( ResourceInvoker) self.filterMock: Filter = mock.create_autospec(Filter) self.secondFilterMock: Filter = mock.create_autospec(Filter) self.filterChain = FilterChain( [self.filterMock, self.secondFilterMock], self.resourceInvokerFactoryMock) self.resourceInvokerFactoryMock.create_route_handlers.return_value = [ self.resourceInvokerMock ] def test_givenEmptyFilterChain_whenApplyingFilterChain_thenInvokeResourceInvocator(
def get_album_artwork(self, album_id: PathParam[str]) -> Response: artwork = self.artwork_repository.get_artwork(UUID(album_id)) return Response(200, {'Content-Type': artwork.mime_type}, artwork.data)
def create_response(self, exception: Exception) -> Response: return Response(405, {}, {"message": "Method not allowed"})
def create_response(self, exception: Exception) -> Response: return Response(400, {}, {"message": "Missing CORS rule."})
class ResourceClass(object): has_been_called = False the_response = Response(402, {}, "a response") @GET def a_method(self): ResourceClass.has_been_called = True return "hello" @GET @Path("/request") def a_method_which_requires_a_request(self, request: Request) -> Response: assert isinstance(request, Request) return self.the_response @POST @Path("/dictionary") def a_method_which_requires_a_dictionary(self, body: dict) -> Response: assert isinstance(body, dict) assert body == BODY return self.the_response @POST @Path("/dto") def a_method_which_requires_a_dto(self, body: A_Dto) -> Response: assert isinstance(body, A_Dto) assert body.name == DTO_BODY['name'] return self.the_response @POST @Path("/dto-no-param") def a_method_which_requires_a_dto_without_a_constructor( self, body: ADtoWithoutAnExplicitConstructor) -> Response: assert isinstance(body, ADtoWithoutAnExplicitConstructor) assert body.name == DTO_BODY['name'] assert body.a_dummy_function( ) == False # assert function does not get overwritten return self.the_response @GET @Path("/return-dto") def returns_a_dto(self) -> A_Dto: return A_Dto("a_name") @GET @Path("/path-param/{name}") def with_path_param(self, name: PathParam[str]) -> str: assert isinstance(name, str) return name @GET @Path("/numeric-param/{number}") def with_numeric_path_param(self, number: PathParam[int]) -> int: assert isinstance(number, int) return number @GET @Path("/query-param") def with_query_param(self, name: QueryParam[str]) -> str: assert isinstance(name, str) return name @GET @Path("/overloaded") def overloaded_param(self, name: QueryParam[str]) -> int: return 5 OVERLOADED_RETURN = 6 @GET @Path("/overloaded") def overloaded_without_name_parameter(self, query: QueryParam[str]) -> int: return self.OVERLOADED_RETURN @GET @Path("/nullable-query") def nullable_query(self, query: OptionalQueryParam[str]) -> Optional[str]: return query @GET @Path("/error") def raises_error(self) -> str: raise AnException @GET @Path("/headers") def get_with_headers(self, headers: Headers) -> list: return headers.items()
def serve_file(self) -> Response: with open(self.filepath, 'rb') as f: return Response(200, {}, f.read())
def doFilter(self, request: Request, response: Response, chain: FilterChain): chain.doFilter(request, response) response.headers['X-Powered-By'] = f"Jivago {jivago.__version__}"
def doFilter(self, request: Request, response: Response, chain: FilterChain): chain.doFilter(request, response) if isinstance(response.body, StreamingResponseBody): response.headers["Transfer-Encoding"] = "chunked"
def preflight(self): headers = Headers() headers['Access-Control-Allow-Methods'] = "POST, GET, OPTIONS, DELETE" headers['Access-Control-Allow-Headers'] = '*' return Response(200, headers, "")
def create_response(self, exception: Exception) -> Response: return Response(404, {}, {"message": "Resource Not Found"})