Repository: minio/minio (language: go)

Issue:
CreateBucket using virtual host-style - incorrect header in response
When creating a bucket using virtual host-style addressing the response headers include `location=/` where it should be `location=/<bucket-name>` 

## Expected Behavior
`Response headers: {'Accept-Ranges': 'bytes', 'Content-Length': '0', 'Content-Security-Policy': 'block-all-mixed-content', 'Location': '/foobar', 'Server': 'MinIO', 'Strict-Transport-Security': 'max-age=31536000; includeSubDomains', 'Vary': 'Origin, Accept-Encoding', 'X-Amz-Bucket-Region': 'us-west-1', 'X-Amz-Id-2': 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', 'X-Amz-Request-Id': '1747FD0AE6009647', 'X-Content-Type-Options': 'nosniff', 'X-Xss-Protection': '1; mode=block', 'Date': 'Tue, 28 Feb 2023 12:33:29 GMT'}`

## Current Behavior
<!--- If describing a bug, tell us what happens instead of the expected behavior -->
` Response headers: {'Accept-Ranges': 'bytes', 'Content-Length': '0', 'Content-Security-Policy': 'block-all-mixed-content', 'Location': '/', 'Server': 'MinIO', 'Strict-Transport-Security': 'max-age=31536000; includeSubDomains', 'Vary': 'Origin, Accept-Encoding', 'X-Amz-Bucket-Region': 'us-west-1', 'X-Amz-Id-2': 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', 'X-Amz-Request-Id': '1747FCFC4831F19D', 'X-Content-Type-Options': 'nosniff', 'X-Xss-Protection': '1; mode=block', 'Date': 'Tue, 28 Feb 2023 12:32:26 GMT'}`
## Possible Solution
Instead of an obscure use of `getObjectLocation` just set the header to the correct value (`/<bucket>`).

## Steps to Reproduce (for bugs)
<!--- Provide a link to a live example, or an unambiguous set of steps to -->
<!--- reproduce this bug. Include code to reproduce, if relevant -->
<!--- and make sure you have followed https://github.com/minio/minio/tree/release/docs/debugging to capture relevant logs -->

1. Ensures MinIO is setup to use virtual host-style addressing (i.e. set `MINIO_DOMAIN`) 
2. Create a bucket using virtual host-style addressing (for example using `addressing-style = virtual` in aws config)
3. Check the response headers

## Context
Incompatible to AWS S3

## Regression
No

## Your Environment
* Version used (`minio --version`):
`RELEASE.2023-02-27T18-10-45Z`
* Server setup and configuration:
Setup using docker-compose:
```
  minio-server:
    image: quay.io/minio/minio:RELEASE.2023-02-27T18-10-45Z
    environment:
      MINIO_ROOT_USER: minioadmin00
      MINIO_ROOT_PASSWORD: minioadmin00
      MINIO_DOMAIN: 127-0-0-1.nip.io
    command:
      - server
      - /data
      - --address
      - ':9100'
      - --console-address
      - ':9190'
    ports:
      - '9100:9100'
      - '9190:9190'
```
* Operating System and version (`uname -a`):
`Darwin Hans-MBPro2021.local 21.6.0 Darwin Kernel Version 21.6.0: Wed Aug 10 14:28:23 PDT 2022; root:xnu-8020.141.5~2/RELEASE_ARM64_T6000 arm64`


Discussion / hints:
Note: using `https` I see another (also incorrect) behavior: 
`'Location': 'https://bucket-name.MINIO_DOMAIN'`
virtual host-style presumes https://bucket-name.MINIO_DOMAIN naming convention.
path style would produce https://MINIO_DOMAIN/bucket-name

Isn't it by definition?
https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateBucket.html

```
If the action is successful, the service sends back an HTTP 200 response.

The response returns the following HTTP headers.

Location

    A forward slash followed by the name of the bucket.
```
I think cited Amazon doc refers to a path-style. They deferred the deprecation of path-style naming.

Basically, Location header redirects the client to that location. In case of a virtual host-style naming the Location: /bucket-name would be incorrect destination to redirect to. Response code is 200, so there will be no redirection in either case, anyway.

https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Location
I don't think https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateBucket.html refers specifically to path-style, this is the first example:

## Sample request
```
            PUT / HTTP/1.1
            Host: colorpictures.s3.<Region>.amazonaws.com
            Content-Length: 0
            Date: Wed, 01 Mar  2006 12:00:00 GMT
            Authorization: authorization string
```
## Sample response
```
            HTTP/1.1 200 OK
            x-amz-id-2: YgIPIfBiKa2bj0KMg95r/0zo3emzU4dzsD4rcKCHQUAdQkf3ShJTOOpXUueF6QKo
            x-amz-request-id: 236A8905248E5A01
            Date: Wed, 01 Mar  2006 12:00:00 GMT
            Location: /colorpictures
            Content-Length: 0
            Connection: close
            Server: AmazonS3
```
Yes, I see this. Still, that particular response may work for Amazon as long as they support both naming schemes. How they will update their docs when they will stop, it's another issue.

Fix patch:
diff --git a/cmd/bucket-handlers.go b/cmd/bucket-handlers.go
index 27d1a8a280732..40f417aa189ec 100644
--- a/cmd/bucket-handlers.go
+++ b/cmd/bucket-handlers.go
@@ -796,8 +796,7 @@ func (api objectAPIHandlers) PutBucketHandler(w http.ResponseWriter, r *http.Req
 				globalNotificationSys.LoadBucketMetadata(GlobalContext, bucket)
 
 				// Make sure to add Location information here only for bucket
-				w.Header().Set(xhttp.Location,
-					getObjectLocation(r, globalDomainNames, bucket, ""))
+				w.Header().Set(xhttp.Location, pathJoin(SlashSeparator, bucket))
 
 				writeSuccessResponseHeadersOnly(w)
 
@@ -848,9 +847,7 @@ func (api objectAPIHandlers) PutBucketHandler(w http.ResponseWriter, r *http.Req
 	logger.LogIf(ctx, globalSiteReplicationSys.MakeBucketHook(ctx, bucket, opts))
 
 	// Make sure to add Location information here only for bucket
-	if cp := pathClean(r.URL.Path); cp != "" {
-		w.Header().Set(xhttp.Location, cp) // Clean any trailing slashes.
-	}
+	w.Header().Set(xhttp.Location, pathJoin(SlashSeparator, bucket))
 
 	writeSuccessResponseHeadersOnly(w)
 
@@ -1123,7 +1120,9 @@ func (api objectAPIHandlers) PostPolicyBucketHandler(w http.ResponseWriter, r *h
 		w.Header()[xhttp.AmzVersionID] = []string{objInfo.VersionID}
 	}
 
-	w.Header().Set(xhttp.Location, getObjectLocation(r, globalDomainNames, bucket, object))
+	if obj := getObjectLocation(r, globalDomainNames, bucket, object); obj != "" {
+		w.Header().Set(xhttp.Location, obj)
+	}
 
 	// Notify object created event.
 	defer sendEvent(eventArgs{


Test patch: