|
15 | 15 | from localstack import config as localstack_config
|
16 | 16 | from localstack.aws.spec import load_service
|
17 | 17 | from localstack.config import external_service_url
|
18 |
| -from localstack.constants import AWS_REGION_US_EAST_1, DOCKER_IMAGE_NAME_PRO |
| 18 | +from localstack.constants import AWS_REGION_US_EAST_1, DOCKER_IMAGE_NAME_PRO, LOCALHOST_HOSTNAME |
19 | 19 | from localstack.http import Request
|
20 | 20 | from localstack.utils.aws.aws_responses import requests_response
|
21 | 21 | from localstack.utils.bootstrap import setup_logging
|
|
32 | 32 | from aws_replicator import config as repl_config
|
33 | 33 | from aws_replicator.client.utils import truncate_content
|
34 | 34 | from aws_replicator.config import HANDLER_PATH_PROXIES
|
| 35 | +from aws_replicator.shared.constants import HEADER_HOST_ORIGINAL |
35 | 36 | from aws_replicator.shared.models import AddProxyRequest, ProxyConfig
|
36 | 37 |
|
37 | 38 | from .http2_server import run_server
|
@@ -106,6 +107,7 @@ def proxy_request(self, request: Request, data: bytes) -> Response:
|
106 | 107 |
|
107 | 108 | # fix headers (e.g., "Host") and create client
|
108 | 109 | self._fix_headers(request, service_name)
|
| 110 | + self._fix_host_and_path(request, service_name) |
109 | 111 |
|
110 | 112 | # create request and request dict
|
111 | 113 | operation_model, aws_request, request_dict = self._parse_aws_request(
|
@@ -262,14 +264,24 @@ def _fix_headers(self, request: Request, service_name: str):
|
262 | 264 | host = request.headers.get("Host") or ""
|
263 | 265 | regex = r"^(https?://)?([0-9.]+|localhost)(:[0-9]+)?"
|
264 | 266 | if re.match(regex, host):
|
265 |
| - request.headers["Host"] = re.sub(regex, r"\1s3.localhost.localstack.cloud", host) |
| 267 | + request.headers["Host"] = re.sub(regex, rf"\1s3.{LOCALHOST_HOSTNAME}", host) |
266 | 268 | request.headers.pop("Content-Length", None)
|
267 | 269 | request.headers.pop("x-localstack-request-url", None)
|
268 | 270 | request.headers.pop("X-Forwarded-For", None)
|
269 | 271 | request.headers.pop("X-Localstack-Tgt-Api", None)
|
270 | 272 | request.headers.pop("X-Moto-Account-Id", None)
|
271 | 273 | request.headers.pop("Remote-Addr", None)
|
272 | 274 |
|
| 275 | + def _fix_host_and_path(self, request: Request, service_name: str): |
| 276 | + if service_name == "s3": |
| 277 | + # fix the path and Host header, to avoid bucket addressing issues |
| 278 | + host = request.headers.pop(HEADER_HOST_ORIGINAL, None) |
| 279 | + host = host or request.headers.get("Host") or "" |
| 280 | + match = re.match(rf"(.+)\.s3\.{LOCALHOST_HOSTNAME}", host) |
| 281 | + if match: |
| 282 | + # prepend the bucket name (extracted from the host) to the path of the request (path-based addressing) |
| 283 | + request.path = f"/{match.group(1)}{request.path}" |
| 284 | + |
273 | 285 | def _extract_region_and_service(self, headers) -> Optional[Tuple[str, str]]:
|
274 | 286 | auth_header = headers.pop("Authorization", "")
|
275 | 287 | parts = auth_header.split("Credential=", maxsplit=1)
|
|
0 commit comments