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 = self._get_current_route(request)
        cors_headers = Cors.cors_to_headers(self.api.cors)

        # 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)

        try:
            # TODO: Rewrite the logic below to use version 2.0 when an invalid value is provided
            # the Lambda Event 2.0 is only used for the HTTP API gateway with defined payload format version equal 2.0
            # or none, as the default value to be used is 2.0
            # https://docs.aws.amazon.com/apigatewayv2/latest/api-reference/apis-apiid-integrations.html#apis-apiid-integrations-prop-createintegrationinput-payloadformatversion
            if route.event_type == Route.HTTP and route.payload_format_version in [None, "2.0"]:
                apigw_endpoint = PathConverter.convert_path_to_api_gateway(endpoint)
                route_key = self._v2_route_key(method, apigw_endpoint, route.is_default_route)
                event = self._construct_v_2_0_event_http(
                    request,
                    self.port,
                    self.api.binary_media_types,
                    self.api.stage_name,
                    self.api.stage_variables,
                    route_key,
                )
            elif route.event_type == Route.API:
                # The OperationName is only sent to the Lambda Function from API Gateway V1(Rest API).
                event = self._construct_v_1_0_event(
                    request,
                    self.port,
                    self.api.binary_media_types,
                    self.api.stage_name,
                    self.api.stage_variables,
                    route.operation_name,
                )
            else:
                # For Http Apis with payload version 1.0, API Gateway never sends the OperationName.
                event = self._construct_v_1_0_event(
                    request,
                    self.port,
                    self.api.binary_media_types,
                    self.api.stage_name,
                    self.api.stage_variables,
                    None,
                )
        except UnicodeDecodeError:
            return ServiceErrorResponses.lambda_failure_response()

        stdout_stream = io.BytesIO()
        stdout_stream_writer = StreamWriter(stdout_stream, auto_flush=True)

        try:
            self.lambda_runner.invoke(route.function_name, event, stdout=stdout_stream_writer, stderr=self.stderr)
        except FunctionNotFound:
            return ServiceErrorResponses.lambda_not_found_response()

        lambda_response, lambda_logs, _ = LambdaOutputParser.get_lambda_output(stdout_stream)

        if self.stderr and lambda_logs:
            # Write the logs to stderr if available.
            self.stderr.write(lambda_logs)

        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()

        return self.service_response(body, headers, status_code)