def _request_handler()

in samcli/local/apigw/local_apigw_service.py [0:0]


    def _request_handler(self, **kwargs):
        """
        We handle all requests to the host:port. The general flow of handling a request is as follows

        * Fetch request from the Flask Global state. This is where Flask places the request and is per thread so
          multiple requests are still handled correctly
        * Find the Lambda function to invoke by doing a look up based on the request.endpoint and method
        * If we don't find the function, we will throw a 502 (just like the 404 and 405 responses we get
          from Flask.
        * Since we found a Lambda function to invoke, we construct the Lambda Event from the request
        * Then Invoke the Lambda function (docker container)
        * We then transform the response or errors we get from the Invoke and return the data back to
          the caller

        Parameters
        ----------
        kwargs dict
            Keyword Args that are passed to the function from Flask. This happens when we have path parameters

        Returns
        -------
        Response object
        """

        route: Route = self._get_current_route(request)

        request_origin = request.headers.get("Origin")
        cors_headers = Cors.cors_to_headers(self.api.cors, request_origin, route.event_type)

        lambda_authorizer = route.authorizer_object

        # payloadFormatVersion can only support 2 values: "1.0" and "2.0"
        # so we want to do strict validation to make sure it has proper value if provided
        # https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-develop-integrations-lambda.html
        if route.payload_format_version not in [None, "1.0", "2.0"]:
            raise PayloadFormatVersionValidateException(
                f'{route.payload_format_version} is not a valid value. PayloadFormatVersion must be "1.0" or "2.0"'
            )

        method, endpoint = self.get_request_methods_endpoints(request)
        if method == "OPTIONS" and self.api.cors:
            headers = Headers(cors_headers)
            return self.service_response("", headers, 200)

        # check for LambdaAuthorizer since that is the only authorizer we currently support
        if isinstance(lambda_authorizer, LambdaAuthorizer) and not self._valid_identity_sources(request, route):
            return ServiceErrorResponses.missing_lambda_auth_identity_sources()

        try:
            route_lambda_event = self._generate_lambda_event(request, route, method, endpoint)
            auth_lambda_event = None

            if lambda_authorizer:
                auth_lambda_event = self._generate_lambda_authorizer_event(request, route, lambda_authorizer)
        except UnicodeDecodeError as error:
            LOG.error("UnicodeDecodeError while processing HTTP request: %s", error)
            return ServiceErrorResponses.lambda_failure_response()

        lambda_authorizer_exception = None
        try:
            auth_service_error = None

            if lambda_authorizer:
                self._invoke_parse_lambda_authorizer(lambda_authorizer, auth_lambda_event, route_lambda_event, route)
        except AuthorizerUnauthorizedRequest as ex:
            auth_service_error = ServiceErrorResponses.lambda_authorizer_unauthorized()
            lambda_authorizer_exception = ex
        except InvalidLambdaAuthorizerResponse as ex:
            auth_service_error = ServiceErrorResponses.lambda_failure_response()
            lambda_authorizer_exception = ex
        except FunctionNotFound as ex:
            lambda_authorizer_exception = ex

            LOG.warning(
                "Failed to find a Function to invoke a Lambda authorizer, verify that "
                "this Function is defined and exists locally in the template."
            )
        except Exception as ex:
            # re-raise the catch all exception after we track it in our telemetry
            lambda_authorizer_exception = ex
            raise ex
        finally:
            exception_name = type(lambda_authorizer_exception).__name__ if lambda_authorizer_exception else None

            EventTracker.track_event(
                event_name=EventName.USED_FEATURE.value,
                event_value=UsedFeature.INVOKED_CUSTOM_LAMBDA_AUTHORIZERS.value,
                session_id=self._click_session_id,
                exception_name=exception_name,
            )

            if lambda_authorizer_exception:
                LOG.error("Lambda authorizer failed to invoke successfully: %s", str(lambda_authorizer_exception))

            if auth_service_error:
                # Return the Flask service error if there is one, since these are the only exceptions
                # we are anticipating from the authorizer, anything else indicates a local issue.
                #
                # Note that returning within a finally block will have the effect of swallowing
                # any reraised exceptions.
                return auth_service_error

        endpoint_service_error = None
        try:
            # invoke the route's Lambda function
            lambda_response = self._invoke_lambda_function(route.function_name, route_lambda_event)
        except FunctionNotFound:
            endpoint_service_error = ServiceErrorResponses.lambda_not_found_response()
        except UnsupportedInlineCodeError:
            endpoint_service_error = ServiceErrorResponses.not_implemented_locally(
                "Inline code is not supported for sam local commands. Please write your code in a separate file."
            )
        except LambdaResponseParseException:
            endpoint_service_error = ServiceErrorResponses.lambda_body_failure_response()
        except DockerContainerCreationFailedException as ex:
            endpoint_service_error = ServiceErrorResponses.container_creation_failed(ex.message)
        except MissingFunctionNameException as ex:
            endpoint_service_error = ServiceErrorResponses.lambda_failure_response(
                f"Failed to execute endpoint. Got an invalid function name ({str(ex)})",
            )

        if endpoint_service_error:
            return endpoint_service_error

        try:
            if route.event_type == Route.HTTP and (
                not route.payload_format_version or route.payload_format_version == "2.0"
            ):
                (status_code, headers, body) = self._parse_v2_payload_format_lambda_output(
                    lambda_response, self.api.binary_media_types, request
                )
            else:
                (status_code, headers, body) = self._parse_v1_payload_format_lambda_output(
                    lambda_response, self.api.binary_media_types, request, route.event_type
                )
        except LambdaResponseParseException as ex:
            LOG.error("Invalid lambda response received: %s", ex)
            return ServiceErrorResponses.lambda_failure_response()

        # Add CORS headers to the response
        headers.update(cors_headers)

        return self.service_response(body, headers, status_code)