From 040c2cd8cc241d80e8878be12f2f6cf004a0d9da Mon Sep 17 00:00:00 2001 From: mfranke <2mf@users.noreply.github.com> Date: Thu, 24 Nov 2016 02:05:34 +0100 Subject: [PATCH] Fix s3bucketpath handling for IP based requests (#765) * check HTTP header for IPv4 or IPv6 addresses and default to path based S3 * improved IPv4 and IPv6 checking with optional ports * typo --- moto/s3/responses.py | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/moto/s3/responses.py b/moto/s3/responses.py index b07b50fa6..b441b9ac5 100644 --- a/moto/s3/responses.py +++ b/moto/s3/responses.py @@ -4,6 +4,8 @@ import re import six from six.moves.urllib.parse import parse_qs, urlparse + +import socket import xmltodict from moto.core.responses import _TemplateEnvironmentMixin @@ -44,10 +46,29 @@ class ResponseObject(_TemplateEnvironmentMixin): def subdomain_based_buckets(self, request): host = request.headers.get('host', request.headers.get('Host')) - if host.startswith("localhost"): + + if not host or host.startswith("localhost"): # For localhost, default to path-based buckets return False + match = re.match(r'^([^\[\]:]+)(:\d+)?$', host) + if match: + try: + socket.inet_pton(socket.AF_INET, match.groups()[0]) + # For IPv4, default to path-based buckets + return False + except socket.error: + pass + + match = re.match(r'^\[(.+)\](:\d+)?$', host) + if match: + try: + socket.inet_pton(socket.AF_INET6, match.groups()[0]) + # For IPv6, default to path-based buckets + return False + except socket.error: + pass + path_based = (host == 's3.amazonaws.com' or re.match(r"s3[\.\-]([^.]*)\.amazonaws\.com", host)) return not path_based