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
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)}, )
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)})