mirror of
https://github.com/minio/minio.git
synced 2025-01-11 15:03:22 -05:00
api/PostPolicy: Allow location header fully qualified URL (#4926)
req.Host is used to construct the final object location. Fixes #4910
This commit is contained in:
parent
c3ff402fcb
commit
4cadb33da2
@ -275,9 +275,25 @@ func getLocation(r *http.Request) string {
|
|||||||
return path.Clean(r.URL.Path) // Clean any trailing slashes.
|
return path.Clean(r.URL.Path) // Clean any trailing slashes.
|
||||||
}
|
}
|
||||||
|
|
||||||
// getObjectLocation gets the relative URL for an object
|
// returns "https" if the tls boolean is true, "http" otherwise.
|
||||||
func getObjectLocation(bucketName string, key string) string {
|
func getURLScheme(tls bool) string {
|
||||||
return "/" + bucketName + "/" + key
|
if tls {
|
||||||
|
return httpsScheme
|
||||||
|
}
|
||||||
|
return httpScheme
|
||||||
|
}
|
||||||
|
|
||||||
|
// getObjectLocation gets the fully qualified URL of an object.
|
||||||
|
func getObjectLocation(host, proto, bucket, object string) string {
|
||||||
|
if proto == "" {
|
||||||
|
proto = getURLScheme(globalIsSSL)
|
||||||
|
}
|
||||||
|
u := url.URL{
|
||||||
|
Host: host,
|
||||||
|
Path: path.Join(slashSeparator, bucket, object),
|
||||||
|
Scheme: proto,
|
||||||
|
}
|
||||||
|
return u.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
// generates ListBucketsResponse from array of BucketInfo which can be
|
// generates ListBucketsResponse from array of BucketInfo which can be
|
||||||
|
74
cmd/api-response_test.go
Normal file
74
cmd/api-response_test.go
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
/*
|
||||||
|
* Minio Cloud Storage, (C) 2017 Minio, Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Tests object location.
|
||||||
|
func TestObjectLocation(t *testing.T) {
|
||||||
|
testCases := []struct {
|
||||||
|
host, proto, bucket, object string
|
||||||
|
expectedLocation string
|
||||||
|
}{
|
||||||
|
// Server binding to localhost IP with https.
|
||||||
|
{
|
||||||
|
host: "127.0.0.1:9000",
|
||||||
|
proto: httpsScheme,
|
||||||
|
bucket: "testbucket1",
|
||||||
|
object: "test/1.txt",
|
||||||
|
expectedLocation: "https://127.0.0.1:9000/testbucket1/test/1.txt",
|
||||||
|
},
|
||||||
|
// Server binding to fqdn.
|
||||||
|
{
|
||||||
|
host: "s3.mybucket.org",
|
||||||
|
proto: httpScheme,
|
||||||
|
bucket: "mybucket",
|
||||||
|
object: "test/1.txt",
|
||||||
|
expectedLocation: "http://s3.mybucket.org/mybucket/test/1.txt",
|
||||||
|
},
|
||||||
|
// Server binding to fqdn.
|
||||||
|
{
|
||||||
|
host: "mys3.mybucket.org",
|
||||||
|
proto: "",
|
||||||
|
bucket: "mybucket",
|
||||||
|
object: "test/1.txt",
|
||||||
|
expectedLocation: "http://mys3.mybucket.org/mybucket/test/1.txt",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for i, testCase := range testCases {
|
||||||
|
gotLocation := getObjectLocation(testCase.host, testCase.proto, testCase.bucket, testCase.object)
|
||||||
|
if testCase.expectedLocation != gotLocation {
|
||||||
|
t.Errorf("Test %d: expected %s, got %s", i+1, testCase.expectedLocation, gotLocation)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tests getURLScheme function behavior.
|
||||||
|
func TestGetURLScheme(t *testing.T) {
|
||||||
|
tls := false
|
||||||
|
gotScheme := getURLScheme(tls)
|
||||||
|
if gotScheme != httpScheme {
|
||||||
|
t.Errorf("Expected %s, got %s", httpScheme, gotScheme)
|
||||||
|
}
|
||||||
|
tls = true
|
||||||
|
gotScheme = getURLScheme(tls)
|
||||||
|
if gotScheme != httpsScheme {
|
||||||
|
t.Errorf("Expected %s, got %s", httpsScheme, gotScheme)
|
||||||
|
}
|
||||||
|
}
|
@ -569,8 +569,10 @@ func (api objectAPIHandlers) PostPolicyBucketHandler(w http.ResponseWriter, r *h
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
port := r.Header.Get("X-Forward-Proto")
|
||||||
|
location := getObjectLocation(r.Host, port, bucket, object)
|
||||||
w.Header().Set("ETag", `"`+objInfo.ETag+`"`)
|
w.Header().Set("ETag", `"`+objInfo.ETag+`"`)
|
||||||
w.Header().Set("Location", getObjectLocation(bucket, object))
|
w.Header().Set("Location", location)
|
||||||
|
|
||||||
// Get host and port from Request.RemoteAddr.
|
// Get host and port from Request.RemoteAddr.
|
||||||
host, port, err := net.SplitHostPort(r.RemoteAddr)
|
host, port, err := net.SplitHostPort(r.RemoteAddr)
|
||||||
@ -603,7 +605,7 @@ func (api objectAPIHandlers) PostPolicyBucketHandler(w http.ResponseWriter, r *h
|
|||||||
Bucket: objInfo.Bucket,
|
Bucket: objInfo.Bucket,
|
||||||
Key: objInfo.Name,
|
Key: objInfo.Name,
|
||||||
ETag: `"` + objInfo.ETag + `"`,
|
ETag: `"` + objInfo.ETag + `"`,
|
||||||
Location: getObjectLocation(objInfo.Bucket, objInfo.Name),
|
Location: location,
|
||||||
})
|
})
|
||||||
writeResponse(w, http.StatusCreated, resp, "application/xml")
|
writeResponse(w, http.StatusCreated, resp, "application/xml")
|
||||||
case "200":
|
case "200":
|
||||||
|
@ -101,12 +101,7 @@ func newNotificationEvent(event eventData) NotificationEvent {
|
|||||||
host = localIP4.ToSlice()[0]
|
host = localIP4.ToSlice()[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
scheme := httpScheme
|
return fmt.Sprintf("%s://%s:%s", getURLScheme(globalIsSSL), host, globalMinioPort)
|
||||||
if globalIsSSL {
|
|
||||||
scheme = httpsScheme
|
|
||||||
}
|
|
||||||
|
|
||||||
return fmt.Sprintf("%s://%s:%s", scheme, host, globalMinioPort)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fetch the region.
|
// Fetch the region.
|
||||||
|
@ -175,13 +175,8 @@ func getAPIEndpoints(serverAddr string) (apiEndpoints []string) {
|
|||||||
ipList = []string{host}
|
ipList = []string{host}
|
||||||
}
|
}
|
||||||
|
|
||||||
scheme := httpScheme
|
|
||||||
if globalIsSSL {
|
|
||||||
scheme = httpsScheme
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, ip := range ipList {
|
for _, ip := range ipList {
|
||||||
apiEndpoints = append(apiEndpoints, fmt.Sprintf("%s://%s:%s", scheme, ip, port))
|
apiEndpoints = append(apiEndpoints, fmt.Sprintf("%s://%s:%s", getURLScheme(globalIsSSL), ip, port))
|
||||||
}
|
}
|
||||||
|
|
||||||
return apiEndpoints
|
return apiEndpoints
|
||||||
|
Loading…
Reference in New Issue
Block a user