We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
mock_s3 gives "ConnectionError: Connection refused..." error when Key used in put_object call contains leading forward slash
This is very specific situation, however the behavior of moto in this situation doesn't match what happens when you use the actual boto3 connecting to AWS.

The situation is if you have a Key for a S3 object that you are putting into a S3 bucket that has a leading forward slash ("/").

So if your Key is "/abc" and you try putting an object into a S3 bucket with the key as follows:

```
def do_something():
  my_bucket = boto3.resource('s3', region_name='us-west-2').Bucket('my_bucket')
  my_bucket.put_object(Key='/abc', Body='ABCD')
```

If you run this snippet of code (along with required imports and so on), then an object with the key "/abc" will be placed in the bucket with the content specified.

When you view this on the AWS Console, it will seem a bit strange because at the "root" level of the S3 bucket, you'll find a "folder" with no name. Upon clicking this no-named folder, you'll see an object named "abc" with the content specified. So this is the expected behavior when boto3 is being used without moto.

When moto is used in a similar situation, lets say as follows:

```
@moto_s3
def do_something_moto()
  conn = botot3.resource('s3', region_name='us-west-2')
  conn.create_bucket(Bucket='my_bucket')
  bucket.put_object(Key='/abc', Body='ABCD')
```

If you run this code, you will get an error with a traceback ending with:

`ConnectionError: Connection refused: PUT https://foobar.s3.us-west-2.amazonaws.com//abc`

If you remove the leading forward slash from the Key in the put_object call:

`bucket.put_object(Key='abc', Body='ABCD')`

Then this code will run without an error. As pointed out above when using the boto3 without moto, a Key with a leading forward slash is a valid key and should not cause an error. This is really an edge case, but I think moto should be made to handle this situation correctly.

As for versions of boto3 and moto being used:
boto3: 1.7.19
moto: 1.3.3

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `moto/server.py`
Content:
```
1 from __future__ import unicode_literals
2 
3 import argparse
4 import json
5 import re
6 import sys
7 from threading import Lock
8 
9 import six
10 from flask import Flask
11 from flask.testing import FlaskClient
12 
13 from six.moves.urllib.parse import urlencode
14 from werkzeug.routing import BaseConverter
15 from werkzeug.serving import run_simple
16 
17 from moto.backends import BACKENDS
18 from moto.core.utils import convert_flask_to_httpretty_response
19 
20 
21 HTTP_METHODS = ["GET", "POST", "PUT", "DELETE", "HEAD", "PATCH"]
22 
23 
24 DEFAULT_SERVICE_REGION = ('s3', 'us-east-1')
25 
26 # Map of unsigned calls to service-region as per AWS API docs
27 # https://docs.aws.amazon.com/cognito/latest/developerguide/resource-permissions.html#amazon-cognito-signed-versus-unsigned-apis
28 UNSIGNED_REQUESTS = {
29     'AWSCognitoIdentityService': ('cognito-identity', 'us-east-1'),
30     'AWSCognitoIdentityProviderService': ('cognito-idp', 'us-east-1'),
31 }
32 
33 
34 class DomainDispatcherApplication(object):
35     """
36     Dispatch requests to different applications based on the "Host:" header
37     value. We'll match the host header value with the url_bases of each backend.
38     """
39 
40     def __init__(self, create_app, service=None):
41         self.create_app = create_app
42         self.lock = Lock()
43         self.app_instances = {}
44         self.service = service
45 
46     def get_backend_for_host(self, host):
47         if host == 'moto_api':
48             return host
49 
50         if self.service:
51             return self.service
52 
53         if host in BACKENDS:
54             return host
55 
56         for backend_name, backend in BACKENDS.items():
57             for url_base in list(backend.values())[0].url_bases:
58                 if re.match(url_base, 'http://%s' % host):
59                     return backend_name
60 
61     def infer_service_region_host(self, environ):
62         auth = environ.get('HTTP_AUTHORIZATION')
63         if auth:
64             # Signed request
65             # Parse auth header to find service assuming a SigV4 request
66             # https://docs.aws.amazon.com/general/latest/gr/sigv4-signed-request-examples.html
67             # ['Credential=sdffdsa', '20170220', 'us-east-1', 'sns', 'aws4_request']
68             try:
69                 credential_scope = auth.split(",")[0].split()[1]
70                 _, _, region, service, _ = credential_scope.split("/")
71             except ValueError:
72                 # Signature format does not match, this is exceptional and we can't
73                 # infer a service-region. A reduced set of services still use
74                 # the deprecated SigV2, ergo prefer S3 as most likely default.
75                 # https://docs.aws.amazon.com/general/latest/gr/signature-version-2.html
76                 service, region = DEFAULT_SERVICE_REGION
77         else:
78             # Unsigned request
79             target = environ.get('HTTP_X_AMZ_TARGET')
80             if target:
81                 service, _ = target.split('.', 1)
82                 service, region = UNSIGNED_REQUESTS.get(service, DEFAULT_SERVICE_REGION)
83             else:
84                 # S3 is the last resort when the target is also unknown
85                 service, region = DEFAULT_SERVICE_REGION
86 
87         if service == 'dynamodb':
88             if environ['HTTP_X_AMZ_TARGET'].startswith('DynamoDBStreams'):
89                 host = 'dynamodbstreams'
90             else:
91                 dynamo_api_version = environ['HTTP_X_AMZ_TARGET'].split("_")[1].split(".")[0]
92                 # If Newer API version, use dynamodb2
93                 if dynamo_api_version > "20111205":
94                     host = "dynamodb2"
95         else:
96             host = "{service}.{region}.amazonaws.com".format(
97                 service=service, region=region)
98 
99         return host
100 
101     def get_application(self, environ):
102         path_info = environ.get('PATH_INFO', '')
103 
104         # The URL path might contain non-ASCII text, for instance unicode S3 bucket names
105         if six.PY2 and isinstance(path_info, str):
106             path_info = six.u(path_info)
107         if six.PY3 and isinstance(path_info, six.binary_type):
108             path_info = path_info.decode('utf-8')
109 
110         if path_info.startswith("/moto-api") or path_info == "/favicon.ico":
111             host = "moto_api"
112         elif path_info.startswith("/latest/meta-data/"):
113             host = "instance_metadata"
114         else:
115             host = environ['HTTP_HOST'].split(':')[0]
116 
117         with self.lock:
118             backend = self.get_backend_for_host(host)
119             if not backend:
120                 # No regular backend found; try parsing other headers
121                 host = self.infer_service_region_host(environ)
122                 backend = self.get_backend_for_host(host)
123 
124             app = self.app_instances.get(backend, None)
125             if app is None:
126                 app = self.create_app(backend)
127                 self.app_instances[backend] = app
128             return app
129 
130     def __call__(self, environ, start_response):
131         backend_app = self.get_application(environ)
132         return backend_app(environ, start_response)
133 
134 
135 class RegexConverter(BaseConverter):
136     # http://werkzeug.pocoo.org/docs/routing/#custom-converters
137 
138     def __init__(self, url_map, *items):
139         super(RegexConverter, self).__init__(url_map)
140         self.regex = items[0]
141 
142 
143 class AWSTestHelper(FlaskClient):
144 
145     def action_data(self, action_name, **kwargs):
146         """
147         Method calls resource with action_name and returns data of response.
148         """
149         opts = {"Action": action_name}
150         opts.update(kwargs)
151         res = self.get("/?{0}".format(urlencode(opts)),
152                        headers={"Host": "{0}.us-east-1.amazonaws.com".format(self.application.service)})
153         return res.data.decode("utf-8")
154 
155     def action_json(self, action_name, **kwargs):
156         """
157         Method calls resource with action_name and returns object obtained via
158         deserialization of output.
159         """
160         return json.loads(self.action_data(action_name, **kwargs))
161 
162 
163 def create_backend_app(service):
164     from werkzeug.routing import Map
165 
166     # Create the backend_app
167     backend_app = Flask(__name__)
168     backend_app.debug = True
169     backend_app.service = service
170 
171     # Reset view functions to reset the app
172     backend_app.view_functions = {}
173     backend_app.url_map = Map()
174     backend_app.url_map.converters['regex'] = RegexConverter
175     backend = list(BACKENDS[service].values())[0]
176     for url_path, handler in backend.flask_paths.items():
177         if handler.__name__ == 'dispatch':
178             endpoint = '{0}.dispatch'.format(handler.__self__.__name__)
179         else:
180             endpoint = None
181 
182         original_endpoint = endpoint
183         index = 2
184         while endpoint in backend_app.view_functions:
185             # HACK: Sometimes we map the same view to multiple url_paths. Flask
186             # requries us to have different names.
187             endpoint = original_endpoint + str(index)
188             index += 1
189 
190         backend_app.add_url_rule(
191             url_path,
192             endpoint=endpoint,
193             methods=HTTP_METHODS,
194             view_func=convert_flask_to_httpretty_response(handler),
195             strict_slashes=False,
196         )
197 
198     backend_app.test_client_class = AWSTestHelper
199     return backend_app
200 
201 
202 def main(argv=sys.argv[1:]):
203     parser = argparse.ArgumentParser()
204 
205     # Keep this for backwards compat
206     parser.add_argument(
207         "service",
208         type=str,
209         nargs='?',  # http://stackoverflow.com/a/4480202/731592
210         default=None)
211     parser.add_argument(
212         '-H', '--host', type=str,
213         help='Which host to bind',
214         default='127.0.0.1')
215     parser.add_argument(
216         '-p', '--port', type=int,
217         help='Port number to use for connection',
218         default=5000)
219     parser.add_argument(
220         '-r', '--reload',
221         action='store_true',
222         help='Reload server on a file change',
223         default=False
224     )
225     parser.add_argument(
226         '-s', '--ssl',
227         action='store_true',
228         help='Enable SSL encrypted connection with auto-generated certificate (use https://... URL)',
229         default=False
230     )
231     parser.add_argument(
232         '-c', '--ssl-cert', type=str,
233         help='Path to SSL certificate',
234         default=None)
235     parser.add_argument(
236         '-k', '--ssl-key', type=str,
237         help='Path to SSL private key',
238         default=None)
239 
240     args = parser.parse_args(argv)
241 
242     # Wrap the main application
243     main_app = DomainDispatcherApplication(
244         create_backend_app, service=args.service)
245     main_app.debug = True
246 
247     ssl_context = None
248     if args.ssl_key and args.ssl_cert:
249         ssl_context = (args.ssl_cert, args.ssl_key)
250     elif args.ssl:
251         ssl_context = 'adhoc'
252 
253     run_simple(args.host, args.port, main_app,
254                threaded=True, use_reloader=args.reload,
255                ssl_context=ssl_context)
256 
257 
258 if __name__ == '__main__':
259     main()
260
```

Path: `moto/s3/urls.py`
Content:
```
1 from __future__ import unicode_literals
2 
3 from .responses import S3ResponseInstance
4 
5 url_bases = [
6     "https?://s3(.*).amazonaws.com",
7     r"https?://(?P<bucket_name>[a-zA-Z0-9\-_.]*)\.?s3(.*).amazonaws.com"
8 ]
9 
10 url_paths = {
11     # subdomain bucket
12     '{0}/$': S3ResponseInstance.bucket_response,
13 
14     # subdomain key of path-based bucket
15     '{0}/(?P<key_or_bucket_name>[^/]+)/?$': S3ResponseInstance.ambiguous_response,
16     # path-based bucket + key
17     '{0}/(?P<bucket_name_path>[^/]+)/(?P<key_name>.+)': S3ResponseInstance.key_response,
18 }
19
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/moto/s3/urls.py b/moto/s3/urls.py
--- a/moto/s3/urls.py
+++ b/moto/s3/urls.py
@@ -15,4 +15,6 @@
     '{0}/(?P<key_or_bucket_name>[^/]+)/?$': S3ResponseInstance.ambiguous_response,
     # path-based bucket + key
     '{0}/(?P<bucket_name_path>[^/]+)/(?P<key_name>.+)': S3ResponseInstance.key_response,
+    # subdomain bucket + key with empty first part of path
+    '{0}//(?P<key_name>.*)$': S3ResponseInstance.key_response,
 }
diff --git a/moto/server.py b/moto/server.py
--- a/moto/server.py
+++ b/moto/server.py
@@ -174,10 +174,11 @@
     backend_app.url_map.converters['regex'] = RegexConverter
     backend = list(BACKENDS[service].values())[0]
     for url_path, handler in backend.flask_paths.items():
+        view_func = convert_flask_to_httpretty_response(handler)
         if handler.__name__ == 'dispatch':
             endpoint = '{0}.dispatch'.format(handler.__self__.__name__)
         else:
-            endpoint = None
+            endpoint = view_func.__name__
 
         original_endpoint = endpoint
         index = 2
@@ -191,7 +192,7 @@
             url_path,
             endpoint=endpoint,
             methods=HTTP_METHODS,
-            view_func=convert_flask_to_httpretty_response(handler),
+            view_func=view_func,
             strict_slashes=False,
         )

{"golden_diff": "diff --git a/moto/s3/urls.py b/moto/s3/urls.py\n--- a/moto/s3/urls.py\n+++ b/moto/s3/urls.py\n@@ -15,4 +15,6 @@\n     '{0}/(?P<key_or_bucket_name>[^/]+)/?$': S3ResponseInstance.ambiguous_response,\n     # path-based bucket + key\n     '{0}/(?P<bucket_name_path>[^/]+)/(?P<key_name>.+)': S3ResponseInstance.key_response,\n+    # subdomain bucket + key with empty first part of path\n+    '{0}//(?P<key_name>.*)$': S3ResponseInstance.key_response,\n }\ndiff --git a/moto/server.py b/moto/server.py\n--- a/moto/server.py\n+++ b/moto/server.py\n@@ -174,10 +174,11 @@\n     backend_app.url_map.converters['regex'] = RegexConverter\n     backend = list(BACKENDS[service].values())[0]\n     for url_path, handler in backend.flask_paths.items():\n+        view_func = convert_flask_to_httpretty_response(handler)\n         if handler.__name__ == 'dispatch':\n             endpoint = '{0}.dispatch'.format(handler.__self__.__name__)\n         else:\n-            endpoint = None\n+            endpoint = view_func.__name__\n \n         original_endpoint = endpoint\n         index = 2\n@@ -191,7 +192,7 @@\n             url_path,\n             endpoint=endpoint,\n             methods=HTTP_METHODS,\n-            view_func=convert_flask_to_httpretty_response(handler),\n+            view_func=view_func,\n             strict_slashes=False,\n         )\n", "issue": "mock_s3 gives \"ConnectionError: Connection refused...\" error when Key used in put_object call contains leading forward slash\nThis is very specific situation, however the behavior of moto in this situation doesn't match what happens when you use the actual boto3 connecting to AWS.\r\n\r\nThe situation is if you have a Key for a S3 object that you are putting into a S3 bucket that has a leading forward slash (\"/\").\r\n\r\nSo if your Key is \"/abc\" and you try putting an object into a S3 bucket with the key as follows:\r\n\r\n```\r\ndef do_something():\r\n  my_bucket = boto3.resource('s3', region_name='us-west-2').Bucket('my_bucket')\r\n  my_bucket.put_object(Key='/abc', Body='ABCD')\r\n```\r\n\r\nIf you run this snippet of code (along with required imports and so on), then an object with the key \"/abc\" will be placed in the bucket with the content specified.\r\n\r\nWhen you view this on the AWS Console, it will seem a bit strange because at the \"root\" level of the S3 bucket, you'll find a \"folder\" with no name. Upon clicking this no-named folder, you'll see an object named \"abc\" with the content specified. So this is the expected behavior when boto3 is being used without moto.\r\n\r\nWhen moto is used in a similar situation, lets say as follows:\r\n\r\n```\r\n@moto_s3\r\ndef do_something_moto()\r\n  conn = botot3.resource('s3', region_name='us-west-2')\r\n  conn.create_bucket(Bucket='my_bucket')\r\n  bucket.put_object(Key='/abc', Body='ABCD')\r\n```\r\n\r\nIf you run this code, you will get an error with a traceback ending with:\r\n\r\n`ConnectionError: Connection refused: PUT https://foobar.s3.us-west-2.amazonaws.com//abc`\r\n\r\nIf you remove the leading forward slash from the Key in the put_object call:\r\n\r\n`bucket.put_object(Key='abc', Body='ABCD')`\r\n\r\nThen this code will run without an error. As pointed out above when using the boto3 without moto, a Key with a leading forward slash is a valid key and should not cause an error. This is really an edge case, but I think moto should be made to handle this situation correctly.\r\n\r\nAs for versions of boto3 and moto being used:\r\nboto3: 1.7.19\r\nmoto: 1.3.3\n", "before_files": [{"content": "from __future__ import unicode_literals\n\nimport argparse\nimport json\nimport re\nimport sys\nfrom threading import Lock\n\nimport six\nfrom flask import Flask\nfrom flask.testing import FlaskClient\n\nfrom six.moves.urllib.parse import urlencode\nfrom werkzeug.routing import BaseConverter\nfrom werkzeug.serving import run_simple\n\nfrom moto.backends import BACKENDS\nfrom moto.core.utils import convert_flask_to_httpretty_response\n\n\nHTTP_METHODS = [\"GET\", \"POST\", \"PUT\", \"DELETE\", \"HEAD\", \"PATCH\"]\n\n\nDEFAULT_SERVICE_REGION = ('s3', 'us-east-1')\n\n# Map of unsigned calls to service-region as per AWS API docs\n# https://docs.aws.amazon.com/cognito/latest/developerguide/resource-permissions.html#amazon-cognito-signed-versus-unsigned-apis\nUNSIGNED_REQUESTS = {\n    'AWSCognitoIdentityService': ('cognito-identity', 'us-east-1'),\n    'AWSCognitoIdentityProviderService': ('cognito-idp', 'us-east-1'),\n}\n\n\nclass DomainDispatcherApplication(object):\n    \"\"\"\n    Dispatch requests to different applications based on the \"Host:\" header\n    value. We'll match the host header value with the url_bases of each backend.\n    \"\"\"\n\n    def __init__(self, create_app, service=None):\n        self.create_app = create_app\n        self.lock = Lock()\n        self.app_instances = {}\n        self.service = service\n\n    def get_backend_for_host(self, host):\n        if host == 'moto_api':\n            return host\n\n        if self.service:\n            return self.service\n\n        if host in BACKENDS:\n            return host\n\n        for backend_name, backend in BACKENDS.items():\n            for url_base in list(backend.values())[0].url_bases:\n                if re.match(url_base, 'http://%s' % host):\n                    return backend_name\n\n    def infer_service_region_host(self, environ):\n        auth = environ.get('HTTP_AUTHORIZATION')\n        if auth:\n            # Signed request\n            # Parse auth header to find service assuming a SigV4 request\n            # https://docs.aws.amazon.com/general/latest/gr/sigv4-signed-request-examples.html\n            # ['Credential=sdffdsa', '20170220', 'us-east-1', 'sns', 'aws4_request']\n            try:\n                credential_scope = auth.split(\",\")[0].split()[1]\n                _, _, region, service, _ = credential_scope.split(\"/\")\n            except ValueError:\n                # Signature format does not match, this is exceptional and we can't\n                # infer a service-region. A reduced set of services still use\n                # the deprecated SigV2, ergo prefer S3 as most likely default.\n                # https://docs.aws.amazon.com/general/latest/gr/signature-version-2.html\n                service, region = DEFAULT_SERVICE_REGION\n        else:\n            # Unsigned request\n            target = environ.get('HTTP_X_AMZ_TARGET')\n            if target:\n                service, _ = target.split('.', 1)\n                service, region = UNSIGNED_REQUESTS.get(service, DEFAULT_SERVICE_REGION)\n            else:\n                # S3 is the last resort when the target is also unknown\n                service, region = DEFAULT_SERVICE_REGION\n\n        if service == 'dynamodb':\n            if environ['HTTP_X_AMZ_TARGET'].startswith('DynamoDBStreams'):\n                host = 'dynamodbstreams'\n            else:\n                dynamo_api_version = environ['HTTP_X_AMZ_TARGET'].split(\"_\")[1].split(\".\")[0]\n                # If Newer API version, use dynamodb2\n                if dynamo_api_version > \"20111205\":\n                    host = \"dynamodb2\"\n        else:\n            host = \"{service}.{region}.amazonaws.com\".format(\n                service=service, region=region)\n\n        return host\n\n    def get_application(self, environ):\n        path_info = environ.get('PATH_INFO', '')\n\n        # The URL path might contain non-ASCII text, for instance unicode S3 bucket names\n        if six.PY2 and isinstance(path_info, str):\n            path_info = six.u(path_info)\n        if six.PY3 and isinstance(path_info, six.binary_type):\n            path_info = path_info.decode('utf-8')\n\n        if path_info.startswith(\"/moto-api\") or path_info == \"/favicon.ico\":\n            host = \"moto_api\"\n        elif path_info.startswith(\"/latest/meta-data/\"):\n            host = \"instance_metadata\"\n        else:\n            host = environ['HTTP_HOST'].split(':')[0]\n\n        with self.lock:\n            backend = self.get_backend_for_host(host)\n            if not backend:\n                # No regular backend found; try parsing other headers\n                host = self.infer_service_region_host(environ)\n                backend = self.get_backend_for_host(host)\n\n            app = self.app_instances.get(backend, None)\n            if app is None:\n                app = self.create_app(backend)\n                self.app_instances[backend] = app\n            return app\n\n    def __call__(self, environ, start_response):\n        backend_app = self.get_application(environ)\n        return backend_app(environ, start_response)\n\n\nclass RegexConverter(BaseConverter):\n    # http://werkzeug.pocoo.org/docs/routing/#custom-converters\n\n    def __init__(self, url_map, *items):\n        super(RegexConverter, self).__init__(url_map)\n        self.regex = items[0]\n\n\nclass AWSTestHelper(FlaskClient):\n\n    def action_data(self, action_name, **kwargs):\n        \"\"\"\n        Method calls resource with action_name and returns data of response.\n        \"\"\"\n        opts = {\"Action\": action_name}\n        opts.update(kwargs)\n        res = self.get(\"/?{0}\".format(urlencode(opts)),\n                       headers={\"Host\": \"{0}.us-east-1.amazonaws.com\".format(self.application.service)})\n        return res.data.decode(\"utf-8\")\n\n    def action_json(self, action_name, **kwargs):\n        \"\"\"\n        Method calls resource with action_name and returns object obtained via\n        deserialization of output.\n        \"\"\"\n        return json.loads(self.action_data(action_name, **kwargs))\n\n\ndef create_backend_app(service):\n    from werkzeug.routing import Map\n\n    # Create the backend_app\n    backend_app = Flask(__name__)\n    backend_app.debug = True\n    backend_app.service = service\n\n    # Reset view functions to reset the app\n    backend_app.view_functions = {}\n    backend_app.url_map = Map()\n    backend_app.url_map.converters['regex'] = RegexConverter\n    backend = list(BACKENDS[service].values())[0]\n    for url_path, handler in backend.flask_paths.items():\n        if handler.__name__ == 'dispatch':\n            endpoint = '{0}.dispatch'.format(handler.__self__.__name__)\n        else:\n            endpoint = None\n\n        original_endpoint = endpoint\n        index = 2\n        while endpoint in backend_app.view_functions:\n            # HACK: Sometimes we map the same view to multiple url_paths. Flask\n            # requries us to have different names.\n            endpoint = original_endpoint + str(index)\n            index += 1\n\n        backend_app.add_url_rule(\n            url_path,\n            endpoint=endpoint,\n            methods=HTTP_METHODS,\n            view_func=convert_flask_to_httpretty_response(handler),\n            strict_slashes=False,\n        )\n\n    backend_app.test_client_class = AWSTestHelper\n    return backend_app\n\n\ndef main(argv=sys.argv[1:]):\n    parser = argparse.ArgumentParser()\n\n    # Keep this for backwards compat\n    parser.add_argument(\n        \"service\",\n        type=str,\n        nargs='?',  # http://stackoverflow.com/a/4480202/731592\n        default=None)\n    parser.add_argument(\n        '-H', '--host', type=str,\n        help='Which host to bind',\n        default='127.0.0.1')\n    parser.add_argument(\n        '-p', '--port', type=int,\n        help='Port number to use for connection',\n        default=5000)\n    parser.add_argument(\n        '-r', '--reload',\n        action='store_true',\n        help='Reload server on a file change',\n        default=False\n    )\n    parser.add_argument(\n        '-s', '--ssl',\n        action='store_true',\n        help='Enable SSL encrypted connection with auto-generated certificate (use https://... URL)',\n        default=False\n    )\n    parser.add_argument(\n        '-c', '--ssl-cert', type=str,\n        help='Path to SSL certificate',\n        default=None)\n    parser.add_argument(\n        '-k', '--ssl-key', type=str,\n        help='Path to SSL private key',\n        default=None)\n\n    args = parser.parse_args(argv)\n\n    # Wrap the main application\n    main_app = DomainDispatcherApplication(\n        create_backend_app, service=args.service)\n    main_app.debug = True\n\n    ssl_context = None\n    if args.ssl_key and args.ssl_cert:\n        ssl_context = (args.ssl_cert, args.ssl_key)\n    elif args.ssl:\n        ssl_context = 'adhoc'\n\n    run_simple(args.host, args.port, main_app,\n               threaded=True, use_reloader=args.reload,\n               ssl_context=ssl_context)\n\n\nif __name__ == '__main__':\n    main()\n", "path": "moto/server.py"}, {"content": "from __future__ import unicode_literals\n\nfrom .responses import S3ResponseInstance\n\nurl_bases = [\n    \"https?://s3(.*).amazonaws.com\",\n    r\"https?://(?P<bucket_name>[a-zA-Z0-9\\-_.]*)\\.?s3(.*).amazonaws.com\"\n]\n\nurl_paths = {\n    # subdomain bucket\n    '{0}/$': S3ResponseInstance.bucket_response,\n\n    # subdomain key of path-based bucket\n    '{0}/(?P<key_or_bucket_name>[^/]+)/?$': S3ResponseInstance.ambiguous_response,\n    # path-based bucket + key\n    '{0}/(?P<bucket_name_path>[^/]+)/(?P<key_name>.+)': S3ResponseInstance.key_response,\n}\n", "path": "moto/s3/urls.py"}], "after_files": [{"content": "from __future__ import unicode_literals\n\nimport argparse\nimport json\nimport re\nimport sys\nfrom threading import Lock\n\nimport six\nfrom flask import Flask\nfrom flask.testing import FlaskClient\n\nfrom six.moves.urllib.parse import urlencode\nfrom werkzeug.routing import BaseConverter\nfrom werkzeug.serving import run_simple\n\nfrom moto.backends import BACKENDS\nfrom moto.core.utils import convert_flask_to_httpretty_response\n\n\nHTTP_METHODS = [\"GET\", \"POST\", \"PUT\", \"DELETE\", \"HEAD\", \"PATCH\"]\n\n\nDEFAULT_SERVICE_REGION = ('s3', 'us-east-1')\n\n# Map of unsigned calls to service-region as per AWS API docs\n# https://docs.aws.amazon.com/cognito/latest/developerguide/resource-permissions.html#amazon-cognito-signed-versus-unsigned-apis\nUNSIGNED_REQUESTS = {\n    'AWSCognitoIdentityService': ('cognito-identity', 'us-east-1'),\n    'AWSCognitoIdentityProviderService': ('cognito-idp', 'us-east-1'),\n}\n\n\nclass DomainDispatcherApplication(object):\n    \"\"\"\n    Dispatch requests to different applications based on the \"Host:\" header\n    value. We'll match the host header value with the url_bases of each backend.\n    \"\"\"\n\n    def __init__(self, create_app, service=None):\n        self.create_app = create_app\n        self.lock = Lock()\n        self.app_instances = {}\n        self.service = service\n\n    def get_backend_for_host(self, host):\n        if host == 'moto_api':\n            return host\n\n        if self.service:\n            return self.service\n\n        if host in BACKENDS:\n            return host\n\n        for backend_name, backend in BACKENDS.items():\n            for url_base in list(backend.values())[0].url_bases:\n                if re.match(url_base, 'http://%s' % host):\n                    return backend_name\n\n    def infer_service_region_host(self, environ):\n        auth = environ.get('HTTP_AUTHORIZATION')\n        if auth:\n            # Signed request\n            # Parse auth header to find service assuming a SigV4 request\n            # https://docs.aws.amazon.com/general/latest/gr/sigv4-signed-request-examples.html\n            # ['Credential=sdffdsa', '20170220', 'us-east-1', 'sns', 'aws4_request']\n            try:\n                credential_scope = auth.split(\",\")[0].split()[1]\n                _, _, region, service, _ = credential_scope.split(\"/\")\n            except ValueError:\n                # Signature format does not match, this is exceptional and we can't\n                # infer a service-region. A reduced set of services still use\n                # the deprecated SigV2, ergo prefer S3 as most likely default.\n                # https://docs.aws.amazon.com/general/latest/gr/signature-version-2.html\n                service, region = DEFAULT_SERVICE_REGION\n        else:\n            # Unsigned request\n            target = environ.get('HTTP_X_AMZ_TARGET')\n            if target:\n                service, _ = target.split('.', 1)\n                service, region = UNSIGNED_REQUESTS.get(service, DEFAULT_SERVICE_REGION)\n            else:\n                # S3 is the last resort when the target is also unknown\n                service, region = DEFAULT_SERVICE_REGION\n\n        if service == 'dynamodb':\n            if environ['HTTP_X_AMZ_TARGET'].startswith('DynamoDBStreams'):\n                host = 'dynamodbstreams'\n            else:\n                dynamo_api_version = environ['HTTP_X_AMZ_TARGET'].split(\"_\")[1].split(\".\")[0]\n                # If Newer API version, use dynamodb2\n                if dynamo_api_version > \"20111205\":\n                    host = \"dynamodb2\"\n        else:\n            host = \"{service}.{region}.amazonaws.com\".format(\n                service=service, region=region)\n\n        return host\n\n    def get_application(self, environ):\n        path_info = environ.get('PATH_INFO', '')\n\n        # The URL path might contain non-ASCII text, for instance unicode S3 bucket names\n        if six.PY2 and isinstance(path_info, str):\n            path_info = six.u(path_info)\n        if six.PY3 and isinstance(path_info, six.binary_type):\n            path_info = path_info.decode('utf-8')\n\n        if path_info.startswith(\"/moto-api\") or path_info == \"/favicon.ico\":\n            host = \"moto_api\"\n        elif path_info.startswith(\"/latest/meta-data/\"):\n            host = \"instance_metadata\"\n        else:\n            host = environ['HTTP_HOST'].split(':')[0]\n\n        with self.lock:\n            backend = self.get_backend_for_host(host)\n            if not backend:\n                # No regular backend found; try parsing other headers\n                host = self.infer_service_region_host(environ)\n                backend = self.get_backend_for_host(host)\n\n            app = self.app_instances.get(backend, None)\n            if app is None:\n                app = self.create_app(backend)\n                self.app_instances[backend] = app\n            return app\n\n    def __call__(self, environ, start_response):\n        backend_app = self.get_application(environ)\n        return backend_app(environ, start_response)\n\n\nclass RegexConverter(BaseConverter):\n    # http://werkzeug.pocoo.org/docs/routing/#custom-converters\n\n    def __init__(self, url_map, *items):\n        super(RegexConverter, self).__init__(url_map)\n        self.regex = items[0]\n\n\nclass AWSTestHelper(FlaskClient):\n\n    def action_data(self, action_name, **kwargs):\n        \"\"\"\n        Method calls resource with action_name and returns data of response.\n        \"\"\"\n        opts = {\"Action\": action_name}\n        opts.update(kwargs)\n        res = self.get(\"/?{0}\".format(urlencode(opts)),\n                       headers={\"Host\": \"{0}.us-east-1.amazonaws.com\".format(self.application.service)})\n        return res.data.decode(\"utf-8\")\n\n    def action_json(self, action_name, **kwargs):\n        \"\"\"\n        Method calls resource with action_name and returns object obtained via\n        deserialization of output.\n        \"\"\"\n        return json.loads(self.action_data(action_name, **kwargs))\n\n\ndef create_backend_app(service):\n    from werkzeug.routing import Map\n\n    # Create the backend_app\n    backend_app = Flask(__name__)\n    backend_app.debug = True\n    backend_app.service = service\n\n    # Reset view functions to reset the app\n    backend_app.view_functions = {}\n    backend_app.url_map = Map()\n    backend_app.url_map.converters['regex'] = RegexConverter\n    backend = list(BACKENDS[service].values())[0]\n    for url_path, handler in backend.flask_paths.items():\n        view_func = convert_flask_to_httpretty_response(handler)\n        if handler.__name__ == 'dispatch':\n            endpoint = '{0}.dispatch'.format(handler.__self__.__name__)\n        else:\n            endpoint = view_func.__name__\n\n        original_endpoint = endpoint\n        index = 2\n        while endpoint in backend_app.view_functions:\n            # HACK: Sometimes we map the same view to multiple url_paths. Flask\n            # requries us to have different names.\n            endpoint = original_endpoint + str(index)\n            index += 1\n\n        backend_app.add_url_rule(\n            url_path,\n            endpoint=endpoint,\n            methods=HTTP_METHODS,\n            view_func=view_func,\n            strict_slashes=False,\n        )\n\n    backend_app.test_client_class = AWSTestHelper\n    return backend_app\n\n\ndef main(argv=sys.argv[1:]):\n    parser = argparse.ArgumentParser()\n\n    # Keep this for backwards compat\n    parser.add_argument(\n        \"service\",\n        type=str,\n        nargs='?',  # http://stackoverflow.com/a/4480202/731592\n        default=None)\n    parser.add_argument(\n        '-H', '--host', type=str,\n        help='Which host to bind',\n        default='127.0.0.1')\n    parser.add_argument(\n        '-p', '--port', type=int,\n        help='Port number to use for connection',\n        default=5000)\n    parser.add_argument(\n        '-r', '--reload',\n        action='store_true',\n        help='Reload server on a file change',\n        default=False\n    )\n    parser.add_argument(\n        '-s', '--ssl',\n        action='store_true',\n        help='Enable SSL encrypted connection with auto-generated certificate (use https://... URL)',\n        default=False\n    )\n    parser.add_argument(\n        '-c', '--ssl-cert', type=str,\n        help='Path to SSL certificate',\n        default=None)\n    parser.add_argument(\n        '-k', '--ssl-key', type=str,\n        help='Path to SSL private key',\n        default=None)\n\n    args = parser.parse_args(argv)\n\n    # Wrap the main application\n    main_app = DomainDispatcherApplication(\n        create_backend_app, service=args.service)\n    main_app.debug = True\n\n    ssl_context = None\n    if args.ssl_key and args.ssl_cert:\n        ssl_context = (args.ssl_cert, args.ssl_key)\n    elif args.ssl:\n        ssl_context = 'adhoc'\n\n    run_simple(args.host, args.port, main_app,\n               threaded=True, use_reloader=args.reload,\n               ssl_context=ssl_context)\n\n\nif __name__ == '__main__':\n    main()\n", "path": "moto/server.py"}, {"content": "from __future__ import unicode_literals\n\nfrom .responses import S3ResponseInstance\n\nurl_bases = [\n    \"https?://s3(.*).amazonaws.com\",\n    r\"https?://(?P<bucket_name>[a-zA-Z0-9\\-_.]*)\\.?s3(.*).amazonaws.com\"\n]\n\nurl_paths = {\n    # subdomain bucket\n    '{0}/$': S3ResponseInstance.bucket_response,\n\n    # subdomain key of path-based bucket\n    '{0}/(?P<key_or_bucket_name>[^/]+)/?$': S3ResponseInstance.ambiguous_response,\n    # path-based bucket + key\n    '{0}/(?P<bucket_name_path>[^/]+)/(?P<key_name>.+)': S3ResponseInstance.key_response,\n    # subdomain bucket + key with empty first part of path\n    '{0}//(?P<key_name>.*)$': S3ResponseInstance.key_response,\n}\n", "path": "moto/s3/urls.py"}]}