/
handler-utils.go
143 lines (131 loc) · 4.03 KB
/
handler-utils.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
/*
* Minio Cloud Storage, (C) 2015, 2016 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 s3
import (
"io"
"io/ioutil"
"mime/multipart"
"net/http"
"strings"
. "github.com/opensds/multi-cloud/api/pkg/s3/datatype"
. "github.com/opensds/multi-cloud/s3/error"
"github.com/opensds/multi-cloud/s3/pkg/helper"
)
// validates location constraint from the request body.
// the location value in the request body should match the Region in serverConfig.
// other values of location are not accepted.
// make bucket fails in such cases.
func isValidLocationConstraint(reqBody io.Reader) (err error) {
var region = helper.CONFIG.Region
var locationConstraint CreateBucketLocationConfiguration
e := xmlDecoder(reqBody, &locationConstraint)
if e != nil {
if e == io.EOF {
// Failed due to empty request body. The location will be set to
// default value from the serverConfig
err = nil
} else {
// Failed due to malformed configuration.
err = ErrMalformedXML
}
} else {
// Region obtained from the body.
// It should be equal to Region in serverConfig.
// Else ErrInvalidRegion returned.
// For empty value location will be to set to default value from the serverConfig.
if locationConstraint.Location != "" && region != locationConstraint.Location {
err = ErrInvalidRegion
}
}
return err
}
// Supported headers that needs to be extracted.
var supportedHeaders = []string{
"cache-control",
"content-disposition",
"content-encoding",
"content-language",
"content-type",
"expires",
"website-redirect-location",
// Add more supported headers here
}
// extractMetadataFromHeader extracts metadata from HTTP header.
func extractMetadataFromHeader(header http.Header) map[string]string {
metadata := make(map[string]string)
// Save standard supported headers.
for _, supportedHeader := range supportedHeaders {
if h := header.Get(http.CanonicalHeaderKey(supportedHeader)); h != "" {
metadata[supportedHeader] = h
}
}
// Go through all other headers for any additional headers that needs to be saved.
for key := range header {
if strings.HasPrefix(strings.ToLower(key), "x-amz-meta-") {
metadata[key] = header.Get(key)
}
}
// Return.
return metadata
}
// Suffix matcher string matches suffix in a platform specific way.
// For example on windows since its case insensitive we are supposed
// to do case insensitive checks.
func hasSuffix(s string, suffix string) bool {
return strings.HasSuffix(s, suffix)
}
func extractHTTPFormValues(reader *multipart.Reader) (filePartReader io.Reader,
formValues map[string]string, err error) {
formValues = make(map[string]string)
for {
var part *multipart.Part
part, err = reader.NextPart()
if err == io.EOF {
err = nil
break
}
if err != nil {
return nil, nil, err
}
if part.FormName() != "file" {
var buffer []byte
buffer, err = ioutil.ReadAll(part)
if err != nil {
return nil, nil, err
}
formValues[http.CanonicalHeaderKey(part.FormName())] = string(buffer)
} else {
// "All variables within the form are expanded prior to validating
// the POST policy"
fileName := part.FileName()
objectKey, ok := formValues["Key"]
if !ok {
return nil, nil, ErrMissingFields
}
if strings.Contains(objectKey, "${filename}") {
formValues["Key"] = strings.Replace(objectKey, "${filename}", fileName, -1)
}
filePartReader = part
// "The file or content must be the last field in the form.
// Any fields below it are ignored."
break
}
}
if filePartReader == nil {
err = ErrEmptyEntity
}
return
}