Repository: getmoto/moto

Issue:
S3 get_bucket_location returns us-east-1 rather than None
In AWS, us-east-1 is the default region and as such, things behave a little bit differently there:

* When a bucket is in us-east-1, it returns a `LocationConstraint` equal to **None**. moto returns **us-east-1**

```
In [9]: s3_cli.get_bucket_location(Bucket='pix4d-development-us-east-1-assets-drop-zone')
Out[9]:
{'ResponseMetadata': {'RequestId': 'D6CC81F0D293872E',
  'HostId': 'LCf3LHvjW0lpzZ81YTsZYdU33hwqr3HeBm8pDvxEUArDwEZwA/zY38L84S9u8isM8bO3UcXH9H0=',
  'HTTPStatusCode': 200,
  'HTTPHeaders': {'x-amz-id-2': 'LCf3LHvjW0lpzZ81YTsZYdU33hwqr3HeBm8pDvxEUArDwEZwA/zY38L84S9u8isM8bO3UcXH9H0=',
   'x-amz-request-id': 'D6CC81F0D293872E',
   'date': 'Tue, 20 Nov 2018 07:17:41 GMT',
   'content-type': 'application/xml',
   'transfer-encoding': 'chunked',
   'server': 'AmazonS3'},
  'RetryAttempts': 0},
 'LocationConstraint': None}
```


* Creating a bucket with `CreateBucketConfiguration={'LocationConstraint': 'us-east-1'}` should actually raise an error. Moto allows it.

```
In [7]: s3_cli.create_bucket(Bucket='pix4d-test-gba2', CreateBucketConfiguration={'LocationConstraint': 'us-east-1'})
...
ClientError: An error occurred (InvalidLocationConstraint) when calling the CreateBucket operation: The specified location-constraint is not valid
```

(this issue is somewhat related to #971)


Discussion:
I might take a crack at fixing it later today (no promises though :( )

Resolving patch:
diff --git a/moto/s3/responses.py b/moto/s3/responses.py
--- a/moto/s3/responses.py
+++ b/moto/s3/responses.py
@@ -193,7 +193,13 @@ def _bucket_response_get(self, bucket_name, querystring, headers):
         elif 'location' in querystring:
             bucket = self.backend.get_bucket(bucket_name)
             template = self.response_template(S3_BUCKET_LOCATION)
-            return template.render(location=bucket.location)
+
+            location = bucket.location
+            # us-east-1 is different - returns a None location
+            if location == DEFAULT_REGION_NAME:
+                location = None
+
+            return template.render(location=location)
         elif 'lifecycle' in querystring:
             bucket = self.backend.get_bucket(bucket_name)
             if not bucket.rules:
@@ -432,8 +438,19 @@ def _bucket_response_put(self, request, body, region_name, bucket_name, querystr
 
         else:
             if body:
+                # us-east-1, the default AWS region behaves a bit differently
+                # - you should not use it as a location constraint --> it fails
+                # - querying the location constraint returns None
                 try:
-                    region_name = xmltodict.parse(body)['CreateBucketConfiguration']['LocationConstraint']
+                    forced_region = xmltodict.parse(body)['CreateBucketConfiguration']['LocationConstraint']
+
+                    if forced_region == DEFAULT_REGION_NAME:
+                        raise S3ClientError(
+                            'InvalidLocationConstraint',
+                            'The specified location-constraint is not valid'
+                        )
+                    else:
+                        region_name = forced_region
                 except KeyError:
                     pass
 
@@ -1176,7 +1193,7 @@ def _key_response_post(self, request, body, bucket_name, query, key_name, header
 </Error>"""
 
 S3_BUCKET_LOCATION = """<?xml version="1.0" encoding="UTF-8"?>
-<LocationConstraint xmlns="http://s3.amazonaws.com/doc/2006-03-01/">{{ location }}</LocationConstraint>"""
+<LocationConstraint xmlns="http://s3.amazonaws.com/doc/2006-03-01/">{% if location != None %}{{ location }}{% endif %}</LocationConstraint>"""
 
 S3_BUCKET_LIFECYCLE_CONFIGURATION = """<?xml version="1.0" encoding="UTF-8"?>
 <LifecycleConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">


Test patch:
diff --git a/tests/test_s3/test_s3.py b/tests/test_s3/test_s3.py
--- a/tests/test_s3/test_s3.py
+++ b/tests/test_s3/test_s3.py
@@ -977,6 +977,15 @@ def test_bucket_location():
     bucket.get_location().should.equal("us-west-2")
 
 
+@mock_s3_deprecated
+def test_bucket_location_us_east_1():
+    cli = boto3.client('s3')
+    bucket_name = 'mybucket'
+    # No LocationConstraint ==> us-east-1
+    cli.create_bucket(Bucket=bucket_name)
+    cli.get_bucket_location(Bucket=bucket_name)['LocationConstraint'].should.equal(None)
+
+
 @mock_s3_deprecated
 def test_ranged_get():
     conn = boto.connect_s3()
@@ -1300,6 +1309,16 @@ def test_bucket_create_duplicate():
     exc.exception.response['Error']['Code'].should.equal('BucketAlreadyExists')
 
 
+@mock_s3
+def test_bucket_create_force_us_east_1():
+    s3 = boto3.resource('s3', region_name='us-east-1')
+    with assert_raises(ClientError) as exc:
+        s3.create_bucket(Bucket="blah", CreateBucketConfiguration={
+            'LocationConstraint': 'us-east-1',
+        })
+    exc.exception.response['Error']['Code'].should.equal('InvalidLocationConstraint')
+
+
 @mock_s3
 def test_boto3_bucket_create_eu_central():
     s3 = boto3.resource('s3', region_name='eu-central-1')