예제 #1
0
    def forward_request(self, method, path, data, headers):
        invocation_context = ApiInvocationContext(method, path, data, headers)

        forwarded_for = headers.get(HEADER_LOCALSTACK_EDGE_URL, "")
        if re.match(PATH_REGEX_USER_REQUEST,
                    path) or "execute-api" in forwarded_for:
            result = invoke_rest_api_from_request(invocation_context)
            if result is not None:
                return result

        data = data and json.loads(to_str(data))

        if re.match(PATH_REGEX_AUTHORIZERS, path):
            return handle_authorizers(method, path, data, headers)

        if re.match(PATH_REGEX_DOC_PARTS, path):
            return handle_documentation_parts(method, path, data, headers)

        if re.match(PATH_REGEX_VALIDATORS, path):
            return handle_validators(method, path, data, headers)

        if re.match(PATH_REGEX_RESPONSES, path):
            return handle_gateway_responses(method, path, data, headers)

        if re.match(PATH_REGEX_PATH_MAPPINGS, path):
            return handle_base_path_mappings(method, path, data, headers)

        if helpers.is_test_invoke_method(method, path):
            # if call is from test_invoke_api then use http_method to find the integration,
            #   as test_invoke_api makes a POST call to request the test invocation
            match = re.match(PATH_REGEX_TEST_INVOKE_API, path)
            invocation_context.method = match[3]
            if data:
                orig_data = data
                path_with_query_string = orig_data.get("pathWithQueryString",
                                                       None)
                if path_with_query_string:
                    invocation_context.path_with_query_string = path_with_query_string
                invocation_context.data = data.get("body")
                invocation_context.headers = orig_data.get("headers", {})
            result = invoke_rest_api_from_request(invocation_context)
            result = {
                "status": result.status_code,
                "body": to_str(result.content),
                "headers": dict(result.headers),
            }
            return result

        return True
예제 #2
0
    def return_response(self, method, path, data, headers, response):
        # fix backend issue (missing support for API documentation)
        if re.match(r"/restapis/[^/]+/documentation/versions", path):
            if response.status_code == 404:
                return requests_response({"position": "1", "items": []})

        # add missing implementations
        if response.status_code == 404:
            data = data and json.loads(to_str(data))
            result = None
            if path == "/account":
                result = handle_accounts(method, path, data, headers)
            elif path.startswith("/vpclinks"):
                result = handle_vpc_links(method, path, data, headers)
            elif re.match(PATH_REGEX_PATH_MAPPINGS, path):
                result = handle_base_path_mappings(method, path, data, headers)
            elif re.match(PATH_REGEX_CLIENT_CERTS, path):
                result = handle_client_certificates(method, path, data,
                                                    headers)

            if result is not None:
                response.status_code = 200
                aws_responses.set_response_content(
                    response, result, getattr(result, "headers", {}))

        # keep track of API regions for faster lookup later on
        if method == "POST" and path == "/restapis":
            content = json.loads(to_str(response.content))
            api_id = content["id"]
            region = aws_stack.extract_region_from_auth_header(headers)
            API_REGIONS[api_id] = region

        # publish event
        if method == "POST" and path == "/restapis":
            content = json.loads(to_str(response.content))
            event_publisher.fire_event(
                event_publisher.EVENT_APIGW_CREATE_API,
                payload={"a": event_publisher.get_hash(content["id"])},
            )
        api_regex = r"^/restapis/([a-zA-Z0-9\-]+)$"
        if method == "DELETE" and re.match(api_regex, path):
            api_id = re.sub(api_regex, r"\1", path)
            event_publisher.fire_event(
                event_publisher.EVENT_APIGW_DELETE_API,
                payload={"a": event_publisher.get_hash(api_id)},
            )
예제 #3
0
    def return_response(self, method, path, data, headers, response):
        # fix backend issue (missing support for API documentation)
        if re.match(r'/restapis/[^/]+/documentation/versions', path):
            if response.status_code == 404:
                return requests_response({'position': '1', 'items': []})

        # add missing implementations
        if response.status_code == 404:
            data = data and json.loads(to_str(data))
            result = None
            if path == '/account':
                result = handle_accounts(method, path, data, headers)
            elif path.startswith('/vpclinks'):
                result = handle_vpc_links(method, path, data, headers)
            elif re.match(PATH_REGEX_PATH_MAPPINGS, path):
                result = handle_base_path_mappings(method, path, data, headers)
            elif re.match(PATH_REGEX_CLIENT_CERTS, path):
                result = handle_client_certificates(method, path, data,
                                                    headers)

            if result is not None:
                response.status_code = 200
                aws_responses.set_response_content(
                    response, result, getattr(result, 'headers', {}))

        # publish event
        if method == 'POST' and path == '/restapis':
            content = json.loads(to_str(response.content))
            event_publisher.fire_event(
                event_publisher.EVENT_APIGW_CREATE_API,
                payload={'a': event_publisher.get_hash(content['id'])})
        api_regex = r'^/restapis/([a-zA-Z0-9\-]+)$'
        if method == 'DELETE' and re.match(api_regex, path):
            api_id = re.sub(api_regex, r'\1', path)
            event_publisher.fire_event(
                event_publisher.EVENT_APIGW_DELETE_API,
                payload={'a': event_publisher.get_hash(api_id)})