From 2a9c37ba26a810540a9ec88dd71a7311332bc015 Mon Sep 17 00:00:00 2001 From: Harshavardhana Date: Sun, 4 Oct 2015 00:27:49 -0700 Subject: [PATCH] Remove using HTTP responses in json reply always in application/xml --- server-api-bucket-handlers.go | 150 +++++++++++++-------------- server-api-contenttype.go | 56 ---------- server-api-generic-handlers.go | 37 ++----- server-api-headers.go | 40 ++----- server-api-object-handlers.go | 184 ++++++++++++++++----------------- server-api-response.go | 10 +- server-router.go | 1 - 7 files changed, 181 insertions(+), 297 deletions(-) delete mode 100644 server-api-contenttype.go diff --git a/server-api-bucket-handlers.go b/server-api-bucket-handlers.go index 2f25f751b..735f35bc5 100644 --- a/server-api-bucket-handlers.go +++ b/server-api-bucket-handlers.go @@ -25,7 +25,7 @@ import ( signv4 "github.com/minio/minio/pkg/signature" ) -func (api API) isValidOp(w http.ResponseWriter, req *http.Request, acceptsContentType contentType) bool { +func (api API) isValidOp(w http.ResponseWriter, req *http.Request) bool { vars := mux.Vars(req) bucket := vars["bucket"] @@ -34,13 +34,13 @@ func (api API) isValidOp(w http.ResponseWriter, req *http.Request, acceptsConten errorIf(err.Trace(), "GetBucketMetadata failed.", nil) switch err.ToGoError().(type) { case donut.BucketNotFound: - writeErrorResponse(w, req, NoSuchBucket, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, NoSuchBucket, req.URL.Path) return false case donut.BucketNameInvalid: - writeErrorResponse(w, req, InvalidBucketName, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, InvalidBucketName, req.URL.Path) return false default: - writeErrorResponse(w, req, InternalError, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, InternalError, req.URL.Path) return false } } @@ -48,13 +48,13 @@ func (api API) isValidOp(w http.ResponseWriter, req *http.Request, acceptsConten if bucketMetadata.ACL.IsPrivate() { return true //uncomment this when we have webcli - //writeErrorResponse(w, req, AccessDenied, acceptsContentType, req.URL.Path) + //writeErrorResponse(w, req, AccessDenied, req.URL.Path) //return false } if bucketMetadata.ACL.IsPublicRead() && req.Method == "PUT" { return true //uncomment this when we have webcli - //writeErrorResponse(w, req, AccessDenied, acceptsContentType, req.URL.Path) + //writeErrorResponse(w, req, AccessDenied, req.URL.Path) //return false } } @@ -78,14 +78,13 @@ func (api API) ListMultipartUploadsHandler(w http.ResponseWriter, req *http.Requ <-op.ProceedCh } - acceptsContentType := getContentType(req) - if !api.isValidOp(w, req, acceptsContentType) { + if !api.isValidOp(w, req) { return } resources := getBucketMultipartResources(req.URL.Query()) if resources.MaxUploads < 0 { - writeErrorResponse(w, req, InvalidMaxUploads, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, InvalidMaxUploads, req.URL.Path) return } if resources.MaxUploads == 0 { @@ -102,7 +101,7 @@ func (api API) ListMultipartUploadsHandler(w http.ResponseWriter, req *http.Requ signature, err = initSignatureV4(req) if err != nil { errorIf(err.Trace(), "Initializing signature v4 failed.", nil) - writeErrorResponse(w, req, InternalError, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, InternalError, req.URL.Path) return } } @@ -112,19 +111,19 @@ func (api API) ListMultipartUploadsHandler(w http.ResponseWriter, req *http.Requ errorIf(err.Trace(), "ListMultipartUploads failed.", nil) switch err.ToGoError().(type) { case signv4.DoesNotMatch: - writeErrorResponse(w, req, SignatureDoesNotMatch, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, SignatureDoesNotMatch, req.URL.Path) case donut.BucketNotFound: - writeErrorResponse(w, req, NoSuchBucket, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, NoSuchBucket, req.URL.Path) default: - writeErrorResponse(w, req, InternalError, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, InternalError, req.URL.Path) } return } // generate response response := generateListMultipartUploadsResponse(bucket, resources) - encodedSuccessResponse := encodeSuccessResponse(response, acceptsContentType) + encodedSuccessResponse := encodeSuccessResponse(response) // write headers - setCommonHeaders(w, getContentTypeString(acceptsContentType), len(encodedSuccessResponse)) + setCommonHeaders(w, len(encodedSuccessResponse)) // write body w.Write(encodedSuccessResponse) } @@ -145,8 +144,7 @@ func (api API) ListObjectsHandler(w http.ResponseWriter, req *http.Request) { <-op.ProceedCh } - acceptsContentType := getContentType(req) - if !api.isValidOp(w, req, acceptsContentType) { + if !api.isValidOp(w, req) { return } @@ -157,7 +155,7 @@ func (api API) ListObjectsHandler(w http.ResponseWriter, req *http.Request) { resources := getBucketResources(req.URL.Query()) if resources.Maxkeys < 0 { - writeErrorResponse(w, req, InvalidMaxKeys, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, InvalidMaxKeys, req.URL.Path) return } if resources.Maxkeys == 0 { @@ -174,7 +172,7 @@ func (api API) ListObjectsHandler(w http.ResponseWriter, req *http.Request) { signature, err = initSignatureV4(req) if err != nil { errorIf(err.Trace(), "Initializing signature v4 failed.", nil) - writeErrorResponse(w, req, InternalError, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, InternalError, req.URL.Path) return } } @@ -183,27 +181,27 @@ func (api API) ListObjectsHandler(w http.ResponseWriter, req *http.Request) { if err == nil { // generate response response := generateListObjectsResponse(bucket, objects, resources) - encodedSuccessResponse := encodeSuccessResponse(response, acceptsContentType) + encodedSuccessResponse := encodeSuccessResponse(response) // write headers - setCommonHeaders(w, getContentTypeString(acceptsContentType), len(encodedSuccessResponse)) + setCommonHeaders(w, len(encodedSuccessResponse)) // write body w.Write(encodedSuccessResponse) return } switch err.ToGoError().(type) { case signv4.DoesNotMatch: - writeErrorResponse(w, req, SignatureDoesNotMatch, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, SignatureDoesNotMatch, req.URL.Path) case donut.BucketNameInvalid: - writeErrorResponse(w, req, InvalidBucketName, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, InvalidBucketName, req.URL.Path) case donut.BucketNotFound: - writeErrorResponse(w, req, NoSuchBucket, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, NoSuchBucket, req.URL.Path) case donut.ObjectNotFound: - writeErrorResponse(w, req, NoSuchKey, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, NoSuchKey, req.URL.Path) case donut.ObjectNameInvalid: - writeErrorResponse(w, req, NoSuchKey, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, NoSuchKey, req.URL.Path) default: errorIf(err.Trace(), "ListObjects failed.", nil) - writeErrorResponse(w, req, InternalError, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, InternalError, req.URL.Path) } } @@ -221,11 +219,10 @@ func (api API) ListBucketsHandler(w http.ResponseWriter, req *http.Request) { <-op.ProceedCh } - acceptsContentType := getContentType(req) // uncomment this when we have webcli // without access key credentials one cannot list buckets // if _, err := StripAccessKeyID(req); err != nil { - // writeErrorResponse(w, req, AccessDenied, acceptsContentType, req.URL.Path) + // writeErrorResponse(w, req, AccessDenied, req.URL.Path) // return // } @@ -236,7 +233,7 @@ func (api API) ListBucketsHandler(w http.ResponseWriter, req *http.Request) { signature, err = initSignatureV4(req) if err != nil { errorIf(err.Trace(), "Initializing signature v4 failed.", nil) - writeErrorResponse(w, req, InternalError, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, InternalError, req.URL.Path) return } } @@ -245,19 +242,19 @@ func (api API) ListBucketsHandler(w http.ResponseWriter, req *http.Request) { if err == nil { // generate response response := generateListBucketsResponse(buckets) - encodedSuccessResponse := encodeSuccessResponse(response, acceptsContentType) + encodedSuccessResponse := encodeSuccessResponse(response) // write headers - setCommonHeaders(w, getContentTypeString(acceptsContentType), len(encodedSuccessResponse)) + setCommonHeaders(w, len(encodedSuccessResponse)) // write response w.Write(encodedSuccessResponse) return } switch err.ToGoError().(type) { case signv4.DoesNotMatch: - writeErrorResponse(w, req, SignatureDoesNotMatch, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, SignatureDoesNotMatch, req.URL.Path) default: errorIf(err.Trace(), "ListBuckets failed.", nil) - writeErrorResponse(w, req, InternalError, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, InternalError, req.URL.Path) } } @@ -274,11 +271,10 @@ func (api API) PutBucketHandler(w http.ResponseWriter, req *http.Request) { <-op.ProceedCh } - acceptsContentType := getContentType(req) // uncomment this when we have webcli // without access key credentials one cannot create a bucket // if _, err := StripAccessKeyID(req); err != nil { - // writeErrorResponse(w, req, AccessDenied, acceptsContentType, req.URL.Path) + // writeErrorResponse(w, req, AccessDenied, req.URL.Path) // return // } @@ -289,7 +285,7 @@ func (api API) PutBucketHandler(w http.ResponseWriter, req *http.Request) { // read from 'x-amz-acl' aclType := getACLType(req) if aclType == unsupportedACLType { - writeErrorResponse(w, req, NotImplemented, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, NotImplemented, req.URL.Path) return } @@ -303,7 +299,7 @@ func (api API) PutBucketHandler(w http.ResponseWriter, req *http.Request) { signature, err = initSignatureV4(req) if err != nil { errorIf(err.Trace(), "Initializing signature v4 failed.", nil) - writeErrorResponse(w, req, InternalError, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, InternalError, req.URL.Path) return } } @@ -313,7 +309,7 @@ func (api API) PutBucketHandler(w http.ResponseWriter, req *http.Request) { /// if Content-Length missing, deny the request size := req.Header.Get("Content-Length") if size == "" { - writeErrorResponse(w, req, MissingContentLength, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, MissingContentLength, req.URL.Path) return } } @@ -323,21 +319,21 @@ func (api API) PutBucketHandler(w http.ResponseWriter, req *http.Request) { errorIf(err.Trace(), "MakeBucket failed.", nil) switch err.ToGoError().(type) { case signv4.DoesNotMatch: - writeErrorResponse(w, req, SignatureDoesNotMatch, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, SignatureDoesNotMatch, req.URL.Path) case donut.TooManyBuckets: - writeErrorResponse(w, req, TooManyBuckets, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, TooManyBuckets, req.URL.Path) case donut.BucketNameInvalid: - writeErrorResponse(w, req, InvalidBucketName, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, InvalidBucketName, req.URL.Path) case donut.BucketExists: - writeErrorResponse(w, req, BucketAlreadyExists, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, BucketAlreadyExists, req.URL.Path) default: - writeErrorResponse(w, req, InternalError, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, InternalError, req.URL.Path) } return } // Make sure to add Location information here only for bucket w.Header().Set("Location", "/"+bucket) - writeSuccessResponse(w, acceptsContentType) + writeSuccessResponse(w) } // PostPolicyBucketHandler - POST policy @@ -360,14 +356,14 @@ func (api API) PostPolicyBucketHandler(w http.ResponseWriter, req *http.Request) reader, err := req.MultipartReader() if err != nil { errorIf(probe.NewError(err), "Unable to initialize multipart reader.", nil) - writeErrorResponse(w, req, MalformedPOSTRequest, 1, req.URL.Path) + writeErrorResponse(w, req, MalformedPOSTRequest, req.URL.Path) return } fileBody, formValues, perr := extractHTTPFormValues(reader) if perr != nil { errorIf(perr.Trace(), "Unable to parse form values.", nil) - writeErrorResponse(w, req, MalformedPOSTRequest, 1, req.URL.Path) + writeErrorResponse(w, req, MalformedPOSTRequest, req.URL.Path) return } bucket := mux.Vars(req)["bucket"] @@ -376,22 +372,22 @@ func (api API) PostPolicyBucketHandler(w http.ResponseWriter, req *http.Request) signature, perr := initPostPresignedPolicyV4(formValues) if perr != nil { errorIf(perr.Trace(), "Unable to initialize post policy presigned.", nil) - writeErrorResponse(w, req, MalformedPOSTRequest, 1, req.URL.Path) + writeErrorResponse(w, req, MalformedPOSTRequest, req.URL.Path) return } if perr = applyPolicy(formValues, signature.PresignedPolicy); perr != nil { errorIf(perr.Trace(), "Invalid request, policy doesn't match with the endpoint.", nil) - writeErrorResponse(w, req, MalformedPOSTRequest, 1, req.URL.Path) + writeErrorResponse(w, req, MalformedPOSTRequest, req.URL.Path) return } var ok bool if ok, perr = signature.DoesPolicySignatureMatch(formValues["X-Amz-Date"]); perr != nil { errorIf(perr.Trace(), "Unable to verify signature.", nil) - writeErrorResponse(w, req, SignatureDoesNotMatch, 1, req.URL.Path) + writeErrorResponse(w, req, SignatureDoesNotMatch, req.URL.Path) return } if ok == false { - writeErrorResponse(w, req, SignatureDoesNotMatch, 1, req.URL.Path) + writeErrorResponse(w, req, SignatureDoesNotMatch, req.URL.Path) return } metadata, perr := api.Donut.CreateObject(bucket, object, "", 0, fileBody, nil, nil) @@ -399,30 +395,30 @@ func (api API) PostPolicyBucketHandler(w http.ResponseWriter, req *http.Request) errorIf(perr.Trace(), "CreateObject failed.", nil) switch perr.ToGoError().(type) { case donut.BucketNotFound: - writeErrorResponse(w, req, NoSuchBucket, 1, req.URL.Path) + writeErrorResponse(w, req, NoSuchBucket, req.URL.Path) case donut.BucketNameInvalid: - writeErrorResponse(w, req, InvalidBucketName, 1, req.URL.Path) + writeErrorResponse(w, req, InvalidBucketName, req.URL.Path) case donut.ObjectExists: - writeErrorResponse(w, req, MethodNotAllowed, 1, req.URL.Path) + writeErrorResponse(w, req, MethodNotAllowed, req.URL.Path) case donut.BadDigest: - writeErrorResponse(w, req, BadDigest, 1, req.URL.Path) + writeErrorResponse(w, req, BadDigest, req.URL.Path) case signv4.MissingDateHeader: - writeErrorResponse(w, req, RequestTimeTooSkewed, 1, req.URL.Path) + writeErrorResponse(w, req, RequestTimeTooSkewed, req.URL.Path) case signv4.DoesNotMatch: - writeErrorResponse(w, req, SignatureDoesNotMatch, 1, req.URL.Path) + writeErrorResponse(w, req, SignatureDoesNotMatch, req.URL.Path) case donut.IncompleteBody: - writeErrorResponse(w, req, IncompleteBody, 1, req.URL.Path) + writeErrorResponse(w, req, IncompleteBody, req.URL.Path) case donut.EntityTooLarge: - writeErrorResponse(w, req, EntityTooLarge, 1, req.URL.Path) + writeErrorResponse(w, req, EntityTooLarge, req.URL.Path) case donut.InvalidDigest: - writeErrorResponse(w, req, InvalidDigest, 1, req.URL.Path) + writeErrorResponse(w, req, InvalidDigest, req.URL.Path) default: - writeErrorResponse(w, req, InternalError, 1, req.URL.Path) + writeErrorResponse(w, req, InternalError, req.URL.Path) } return } w.Header().Set("ETag", metadata.MD5Sum) - writeSuccessResponse(w, 1) + writeSuccessResponse(w) } // PutBucketACLHandler - PUT Bucket ACL @@ -438,12 +434,10 @@ func (api API) PutBucketACLHandler(w http.ResponseWriter, req *http.Request) { <-op.ProceedCh } - acceptsContentType := getContentType(req) - // read from 'x-amz-acl' aclType := getACLType(req) if aclType == unsupportedACLType { - writeErrorResponse(w, req, NotImplemented, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, NotImplemented, req.URL.Path) return } @@ -457,7 +451,7 @@ func (api API) PutBucketACLHandler(w http.ResponseWriter, req *http.Request) { signature, err = initSignatureV4(req) if err != nil { errorIf(err.Trace(), "Initializing signature v4 failed.", nil) - writeErrorResponse(w, req, InternalError, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, InternalError, req.URL.Path) return } } @@ -467,17 +461,17 @@ func (api API) PutBucketACLHandler(w http.ResponseWriter, req *http.Request) { errorIf(err.Trace(), "PutBucketACL failed.", nil) switch err.ToGoError().(type) { case signv4.DoesNotMatch: - writeErrorResponse(w, req, SignatureDoesNotMatch, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, SignatureDoesNotMatch, req.URL.Path) case donut.BucketNameInvalid: - writeErrorResponse(w, req, InvalidBucketName, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, InvalidBucketName, req.URL.Path) case donut.BucketNotFound: - writeErrorResponse(w, req, NoSuchBucket, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, NoSuchBucket, req.URL.Path) default: - writeErrorResponse(w, req, InternalError, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, InternalError, req.URL.Path) } return } - writeSuccessResponse(w, acceptsContentType) + writeSuccessResponse(w) } // HeadBucketHandler - HEAD Bucket @@ -496,8 +490,6 @@ func (api API) HeadBucketHandler(w http.ResponseWriter, req *http.Request) { <-op.ProceedCh } - acceptsContentType := getContentType(req) - vars := mux.Vars(req) bucket := vars["bucket"] @@ -508,7 +500,7 @@ func (api API) HeadBucketHandler(w http.ResponseWriter, req *http.Request) { signature, err = initSignatureV4(req) if err != nil { errorIf(err.Trace(), "Initializing signature v4 failed.", nil) - writeErrorResponse(w, req, InternalError, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, InternalError, req.URL.Path) return } } @@ -518,15 +510,15 @@ func (api API) HeadBucketHandler(w http.ResponseWriter, req *http.Request) { errorIf(err.Trace(), "GetBucketMetadata failed.", nil) switch err.ToGoError().(type) { case signv4.DoesNotMatch: - writeErrorResponse(w, req, SignatureDoesNotMatch, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, SignatureDoesNotMatch, req.URL.Path) case donut.BucketNotFound: - writeErrorResponse(w, req, NoSuchBucket, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, NoSuchBucket, req.URL.Path) case donut.BucketNameInvalid: - writeErrorResponse(w, req, InvalidBucketName, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, InvalidBucketName, req.URL.Path) default: - writeErrorResponse(w, req, InternalError, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, InternalError, req.URL.Path) } return } - writeSuccessResponse(w, acceptsContentType) + writeSuccessResponse(w) } diff --git a/server-api-contenttype.go b/server-api-contenttype.go deleted file mode 100644 index 49e95d00e..000000000 --- a/server-api-contenttype.go +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Minio Cloud Storage, (C) 2015 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 main - -import "net/http" - -type contentType int - -const ( - unknownContentType contentType = iota - xmlContentType - jsonContentType -) - -// Get content type requested from 'Accept' header -func getContentType(req *http.Request) contentType { - acceptHeader := req.Header.Get("Accept") - switch { - case acceptHeader == "application/json": - return jsonContentType - default: - return xmlContentType - } -} - -// Content type to human readable string -func getContentTypeString(content contentType) string { - switch content { - case jsonContentType: - { - return "application/json" - } - case xmlContentType: - { - return "application/xml" - } - default: - { - return "application/xml" - } - } -} diff --git a/server-api-generic-handlers.go b/server-api-generic-handlers.go index 0f06848bd..74b2b3641 100644 --- a/server-api-generic-handlers.go +++ b/server-api-generic-handlers.go @@ -28,10 +28,6 @@ import ( // MiddlewareHandler - useful to chain different middleware http.Handler type MiddlewareHandler func(http.Handler) http.Handler -type contentTypeHandler struct { - handler http.Handler -} - type timeHandler struct { handler http.Handler } @@ -74,44 +70,29 @@ func parseDate(req *http.Request) (time.Time, error) { return time.Time{}, errors.New("invalid request") } -// ValidContentTypeHandler to validate Accept type -func ValidContentTypeHandler(h http.Handler) http.Handler { - return contentTypeHandler{h} -} - -func (h contentTypeHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { - acceptsContentType := getContentType(r) - if acceptsContentType == unknownContentType { - writeErrorResponse(w, r, NotAcceptable, acceptsContentType, r.URL.Path) - return - } - h.handler.ServeHTTP(w, r) -} - // TimeValidityHandler to validate parsable time over http header func TimeValidityHandler(h http.Handler) http.Handler { return timeHandler{h} } func (h timeHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { - acceptsContentType := getContentType(r) // Verify if date headers are set, if not reject the request if r.Header.Get("Authorization") != "" { if r.Header.Get(http.CanonicalHeaderKey("x-amz-date")) == "" && r.Header.Get("Date") == "" { // there is no way to knowing if this is a valid request, could be a attack reject such clients - writeErrorResponse(w, r, RequestTimeTooSkewed, acceptsContentType, r.URL.Path) + writeErrorResponse(w, r, RequestTimeTooSkewed, r.URL.Path) return } date, err := parseDate(r) if err != nil { // there is no way to knowing if this is a valid request, could be a attack reject such clients - writeErrorResponse(w, r, RequestTimeTooSkewed, acceptsContentType, r.URL.Path) + writeErrorResponse(w, r, RequestTimeTooSkewed, r.URL.Path) return } duration := time.Since(date) minutes := time.Duration(5) * time.Minute if duration.Minutes() > minutes.Minutes() { - writeErrorResponse(w, r, RequestTimeTooSkewed, acceptsContentType, r.URL.Path) + writeErrorResponse(w, r, RequestTimeTooSkewed, r.URL.Path) return } } @@ -127,20 +108,19 @@ func ValidateAuthHeaderHandler(h http.Handler) http.Handler { // validate auth header handler ServeHTTP() wrapper func (h validateAuthHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { - acceptsContentType := getContentType(r) accessKeyID, err := stripAccessKeyID(r.Header.Get("Authorization")) switch err.ToGoError() { case errInvalidRegion: - writeErrorResponse(w, r, AuthorizationHeaderMalformed, acceptsContentType, r.URL.Path) + writeErrorResponse(w, r, AuthorizationHeaderMalformed, r.URL.Path) return case errAccessKeyIDInvalid: - writeErrorResponse(w, r, InvalidAccessKeyID, acceptsContentType, r.URL.Path) + writeErrorResponse(w, r, InvalidAccessKeyID, r.URL.Path) return case nil: // load auth config authConfig, err := auth.LoadConfig() if err != nil { - writeErrorResponse(w, r, InternalError, acceptsContentType, r.URL.Path) + writeErrorResponse(w, r, InternalError, r.URL.Path) return } // Access key not found @@ -150,7 +130,7 @@ func (h validateAuthHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { return } } - writeErrorResponse(w, r, InvalidAccessKeyID, acceptsContentType, r.URL.Path) + writeErrorResponse(w, r, InvalidAccessKeyID, r.URL.Path) return // All other errors for now, serve them default: @@ -175,9 +155,8 @@ func IgnoreResourcesHandler(h http.Handler) http.Handler { // Resource handler ServeHTTP() wrapper func (h resourceHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { - acceptsContentType := getContentType(r) if ignoreNotImplementedObjectResources(r) || ignoreNotImplementedBucketResources(r) { - writeErrorResponse(w, r, NotImplemented, acceptsContentType, r.URL.Path) + writeErrorResponse(w, r, NotImplemented, r.URL.Path) return } h.handler.ServeHTTP(w, r) diff --git a/server-api-headers.go b/server-api-headers.go index c05e8685e..8564d2db1 100644 --- a/server-api-headers.go +++ b/server-api-headers.go @@ -19,7 +19,6 @@ package main import ( "bytes" "crypto/rand" - "encoding/json" "encoding/xml" "net/http" "runtime" @@ -28,11 +27,6 @@ import ( "github.com/minio/minio/pkg/donut" ) -// No encoder interface exists, so we create one. -type encoder interface { - Encode(v interface{}) error -} - //// helpers // Static alphaNumeric table used for generating unique request ids @@ -49,32 +43,21 @@ func generateRequestID() []byte { } // Write http common headers -func setCommonHeaders(w http.ResponseWriter, acceptsType string, contentLength int) { +func setCommonHeaders(w http.ResponseWriter, contentLength int) { // set unique request ID for each reply w.Header().Set("X-Amz-Request-Id", string(generateRequestID())) w.Header().Set("Server", ("Minio/" + minioReleaseTag + " (" + runtime.GOOS + ";" + runtime.GOARCH + ")")) - w.Header().Set("Accept-Ranges", "bytes") - w.Header().Set("Content-Type", acceptsType) w.Header().Set("Connection", "close") // should be set to '0' by default w.Header().Set("Content-Length", strconv.Itoa(contentLength)) } // Write error response headers -func encodeErrorResponse(response interface{}, acceptsType contentType) []byte { +func encodeErrorResponse(response interface{}) []byte { var bytesBuffer bytes.Buffer - var e encoder // write common headers - switch acceptsType { - case xmlContentType: - e = xml.NewEncoder(&bytesBuffer) - case jsonContentType: - e = json.NewEncoder(&bytesBuffer) - // by default even if unknown Accept header received handle it by sending XML contenttype response - default: - e = xml.NewEncoder(&bytesBuffer) - } + e := xml.NewEncoder(&bytesBuffer) e.Encode(response) return bytesBuffer.Bytes() } @@ -84,16 +67,17 @@ func setObjectHeaders(w http.ResponseWriter, metadata donut.ObjectMetadata, cont // set common headers if contentRange != nil { if contentRange.length > 0 { - setCommonHeaders(w, metadata.Metadata["contentType"], int(contentRange.length)) + setCommonHeaders(w, int(contentRange.length)) } else { - setCommonHeaders(w, metadata.Metadata["contentType"], int(metadata.Size)) + setCommonHeaders(w, int(metadata.Size)) } } else { - setCommonHeaders(w, metadata.Metadata["contentType"], int(metadata.Size)) + setCommonHeaders(w, int(metadata.Size)) } // set object headers lastModified := metadata.Created.Format(http.TimeFormat) // object related headers + w.Header().Set("Content-Type", metadata.Metadata["contentType"]) w.Header().Set("ETag", "\""+metadata.MD5Sum+"\"") w.Header().Set("Last-Modified", lastModified) @@ -106,15 +90,9 @@ func setObjectHeaders(w http.ResponseWriter, metadata donut.ObjectMetadata, cont } } -func encodeSuccessResponse(response interface{}, acceptsType contentType) []byte { - var e encoder +func encodeSuccessResponse(response interface{}) []byte { var bytesBuffer bytes.Buffer - switch acceptsType { - case xmlContentType: - e = xml.NewEncoder(&bytesBuffer) - case jsonContentType: - e = json.NewEncoder(&bytesBuffer) - } + e := xml.NewEncoder(&bytesBuffer) e.Encode(response) return bytesBuffer.Bytes() } diff --git a/server-api-object-handlers.go b/server-api-object-handlers.go index c06841e01..2e9f385b4 100644 --- a/server-api-object-handlers.go +++ b/server-api-object-handlers.go @@ -44,8 +44,7 @@ func (api API) GetObjectHandler(w http.ResponseWriter, req *http.Request) { <-op.ProceedCh } - acceptsContentType := getContentType(req) - if !api.isValidOp(w, req, acceptsContentType) { + if !api.isValidOp(w, req) { return } @@ -61,7 +60,7 @@ func (api API) GetObjectHandler(w http.ResponseWriter, req *http.Request) { signature, err = initSignatureV4(req) if err != nil { errorIf(err.Trace(), "Initializing signature v4 failed.", nil) - writeErrorResponse(w, req, InternalError, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, InternalError, req.URL.Path) return } } else { @@ -72,11 +71,11 @@ func (api API) GetObjectHandler(w http.ResponseWriter, req *http.Request) { switch err.ToGoError() { case errAccessKeyIDInvalid: errorIf(err.Trace(), "Invalid access key id requested.", nil) - writeErrorResponse(w, req, InvalidAccessKeyID, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, InvalidAccessKeyID, req.URL.Path) return default: errorIf(err.Trace(), "Initializing signature v4 failed.", nil) - writeErrorResponse(w, req, InternalError, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, InternalError, req.URL.Path) return } } @@ -87,24 +86,24 @@ func (api API) GetObjectHandler(w http.ResponseWriter, req *http.Request) { errorIf(err.Trace(), "GetObject failed.", nil) switch err.ToGoError().(type) { case signv4.DoesNotMatch: - writeErrorResponse(w, req, SignatureDoesNotMatch, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, SignatureDoesNotMatch, req.URL.Path) case donut.BucketNameInvalid: - writeErrorResponse(w, req, InvalidBucketName, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, InvalidBucketName, req.URL.Path) case donut.BucketNotFound: - writeErrorResponse(w, req, NoSuchBucket, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, NoSuchBucket, req.URL.Path) case donut.ObjectNotFound: - writeErrorResponse(w, req, NoSuchKey, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, NoSuchKey, req.URL.Path) case donut.ObjectNameInvalid: - writeErrorResponse(w, req, NoSuchKey, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, NoSuchKey, req.URL.Path) default: - writeErrorResponse(w, req, InternalError, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, InternalError, req.URL.Path) } return } var hrange *httpRange hrange, err = getRequestedRange(req.Header.Get("Range"), metadata.Size) if err != nil { - writeErrorResponse(w, req, InvalidRange, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, InvalidRange, req.URL.Path) return } setObjectHeaders(w, metadata, hrange) @@ -127,8 +126,7 @@ func (api API) HeadObjectHandler(w http.ResponseWriter, req *http.Request) { <-op.ProceedCh } - acceptsContentType := getContentType(req) - if !api.isValidOp(w, req, acceptsContentType) { + if !api.isValidOp(w, req) { return } @@ -144,7 +142,7 @@ func (api API) HeadObjectHandler(w http.ResponseWriter, req *http.Request) { signature, err = initSignatureV4(req) if err != nil { errorIf(err.Trace(), "Initializing signature v4 failed.", nil) - writeErrorResponse(w, req, InternalError, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, InternalError, req.URL.Path) return } } @@ -154,17 +152,17 @@ func (api API) HeadObjectHandler(w http.ResponseWriter, req *http.Request) { errorIf(err.Trace(), "GetObjectMetadata failed.", nil) switch err.ToGoError().(type) { case signv4.DoesNotMatch: - writeErrorResponse(w, req, SignatureDoesNotMatch, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, SignatureDoesNotMatch, req.URL.Path) case donut.BucketNameInvalid: - writeErrorResponse(w, req, InvalidBucketName, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, InvalidBucketName, req.URL.Path) case donut.BucketNotFound: - writeErrorResponse(w, req, NoSuchBucket, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, NoSuchBucket, req.URL.Path) case donut.ObjectNotFound: - writeErrorResponse(w, req, NoSuchKey, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, NoSuchKey, req.URL.Path) case donut.ObjectNameInvalid: - writeErrorResponse(w, req, NoSuchKey, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, NoSuchKey, req.URL.Path) default: - writeErrorResponse(w, req, InternalError, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, InternalError, req.URL.Path) } return } @@ -185,8 +183,7 @@ func (api API) PutObjectHandler(w http.ResponseWriter, req *http.Request) { <-op.ProceedCh } - acceptsContentType := getContentType(req) - if !api.isValidOp(w, req, acceptsContentType) { + if !api.isValidOp(w, req) { return } @@ -198,18 +195,18 @@ func (api API) PutObjectHandler(w http.ResponseWriter, req *http.Request) { // get Content-MD5 sent by client and verify if valid md5 := req.Header.Get("Content-MD5") if !isValidMD5(md5) { - writeErrorResponse(w, req, InvalidDigest, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, InvalidDigest, req.URL.Path) return } /// if Content-Length missing, deny the request size := req.Header.Get("Content-Length") if size == "" { - writeErrorResponse(w, req, MissingContentLength, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, MissingContentLength, req.URL.Path) return } /// maximum Upload size for objects in a single operation if isMaxObjectSize(size) { - writeErrorResponse(w, req, EntityTooLarge, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, EntityTooLarge, req.URL.Path) return } /// minimum Upload size for objects in a single operation @@ -219,7 +216,7 @@ func (api API) PutObjectHandler(w http.ResponseWriter, req *http.Request) { // create a 0byte file using a regular putObject() operation // // if isMinObjectSize(size) { - // writeErrorResponse(w, req, EntityTooSmall, acceptsContentType, req.URL.Path) + // writeErrorResponse(w, req, EntityTooSmall, req.URL.Path) // return // } var sizeInt64 int64 @@ -227,7 +224,7 @@ func (api API) PutObjectHandler(w http.ResponseWriter, req *http.Request) { var err error sizeInt64, err = strconv.ParseInt(size, 10, 64) if err != nil { - writeErrorResponse(w, req, InvalidRequest, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, InvalidRequest, req.URL.Path) return } } @@ -239,7 +236,7 @@ func (api API) PutObjectHandler(w http.ResponseWriter, req *http.Request) { signature, err = initSignatureV4(req) if err != nil { errorIf(err.Trace(), "Initializing signature v4 failed.", nil) - writeErrorResponse(w, req, InternalError, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, InternalError, req.URL.Path) return } } @@ -249,30 +246,30 @@ func (api API) PutObjectHandler(w http.ResponseWriter, req *http.Request) { errorIf(err.Trace(), "CreateObject failed.", nil) switch err.ToGoError().(type) { case donut.BucketNotFound: - writeErrorResponse(w, req, NoSuchBucket, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, NoSuchBucket, req.URL.Path) case donut.BucketNameInvalid: - writeErrorResponse(w, req, InvalidBucketName, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, InvalidBucketName, req.URL.Path) case donut.ObjectExists: - writeErrorResponse(w, req, MethodNotAllowed, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, MethodNotAllowed, req.URL.Path) case donut.BadDigest: - writeErrorResponse(w, req, BadDigest, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, BadDigest, req.URL.Path) case signv4.MissingDateHeader: - writeErrorResponse(w, req, RequestTimeTooSkewed, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, RequestTimeTooSkewed, req.URL.Path) case signv4.DoesNotMatch: - writeErrorResponse(w, req, SignatureDoesNotMatch, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, SignatureDoesNotMatch, req.URL.Path) case donut.IncompleteBody: - writeErrorResponse(w, req, IncompleteBody, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, IncompleteBody, req.URL.Path) case donut.EntityTooLarge: - writeErrorResponse(w, req, EntityTooLarge, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, EntityTooLarge, req.URL.Path) case donut.InvalidDigest: - writeErrorResponse(w, req, InvalidDigest, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, InvalidDigest, req.URL.Path) default: - writeErrorResponse(w, req, InternalError, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, InternalError, req.URL.Path) } return } w.Header().Set("ETag", metadata.MD5Sum) - writeSuccessResponse(w, acceptsContentType) + writeSuccessResponse(w) } /// Multipart API @@ -288,13 +285,12 @@ func (api API) NewMultipartUploadHandler(w http.ResponseWriter, req *http.Reques <-op.ProceedCh } - acceptsContentType := getContentType(req) - if !api.isValidOp(w, req, acceptsContentType) { + if !api.isValidOp(w, req) { return } if !isRequestUploads(req.URL.Query()) { - writeErrorResponse(w, req, MethodNotAllowed, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, MethodNotAllowed, req.URL.Path) return } @@ -310,7 +306,7 @@ func (api API) NewMultipartUploadHandler(w http.ResponseWriter, req *http.Reques signature, err = initSignatureV4(req) if err != nil { errorIf(err.Trace(), "Initializing signature v4 failed.", nil) - writeErrorResponse(w, req, InternalError, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, InternalError, req.URL.Path) return } } @@ -320,19 +316,19 @@ func (api API) NewMultipartUploadHandler(w http.ResponseWriter, req *http.Reques errorIf(err.Trace(), "NewMultipartUpload failed.", nil) switch err.ToGoError().(type) { case signv4.DoesNotMatch: - writeErrorResponse(w, req, SignatureDoesNotMatch, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, SignatureDoesNotMatch, req.URL.Path) case donut.ObjectExists: - writeErrorResponse(w, req, MethodNotAllowed, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, MethodNotAllowed, req.URL.Path) default: - writeErrorResponse(w, req, InternalError, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, InternalError, req.URL.Path) } return } response := generateInitiateMultipartUploadResponse(bucket, object, uploadID) - encodedSuccessResponse := encodeSuccessResponse(response, acceptsContentType) + encodedSuccessResponse := encodeSuccessResponse(response) // write headers - setCommonHeaders(w, getContentTypeString(acceptsContentType), len(encodedSuccessResponse)) + setCommonHeaders(w, len(encodedSuccessResponse)) // write body w.Write(encodedSuccessResponse) } @@ -348,28 +344,27 @@ func (api API) PutObjectPartHandler(w http.ResponseWriter, req *http.Request) { <-op.ProceedCh } - acceptsContentType := getContentType(req) - if !api.isValidOp(w, req, acceptsContentType) { + if !api.isValidOp(w, req) { return } // get Content-MD5 sent by client and verify if valid md5 := req.Header.Get("Content-MD5") if !isValidMD5(md5) { - writeErrorResponse(w, req, InvalidDigest, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, InvalidDigest, req.URL.Path) return } /// if Content-Length missing, throw away size := req.Header.Get("Content-Length") if size == "" { - writeErrorResponse(w, req, MissingContentLength, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, MissingContentLength, req.URL.Path) return } /// maximum Upload size for multipart objects in a single operation if isMaxObjectSize(size) { - writeErrorResponse(w, req, EntityTooLarge, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, EntityTooLarge, req.URL.Path) return } @@ -378,7 +373,7 @@ func (api API) PutObjectPartHandler(w http.ResponseWriter, req *http.Request) { var err error sizeInt64, err = strconv.ParseInt(size, 10, 64) if err != nil { - writeErrorResponse(w, req, InvalidRequest, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, InvalidRequest, req.URL.Path) return } } @@ -395,7 +390,7 @@ func (api API) PutObjectPartHandler(w http.ResponseWriter, req *http.Request) { var err error partID, err = strconv.Atoi(partIDString) if err != nil { - writeErrorResponse(w, req, InvalidPart, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, InvalidPart, req.URL.Path) return } } @@ -407,7 +402,7 @@ func (api API) PutObjectPartHandler(w http.ResponseWriter, req *http.Request) { signature, err = initSignatureV4(req) if err != nil { errorIf(err.Trace(), "Initializing signature v4 failed.", nil) - writeErrorResponse(w, req, InternalError, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, InternalError, req.URL.Path) return } } @@ -417,26 +412,26 @@ func (api API) PutObjectPartHandler(w http.ResponseWriter, req *http.Request) { errorIf(err.Trace(), "CreateObjectPart failed.", nil) switch err.ToGoError().(type) { case donut.InvalidUploadID: - writeErrorResponse(w, req, NoSuchUpload, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, NoSuchUpload, req.URL.Path) case donut.ObjectExists: - writeErrorResponse(w, req, MethodNotAllowed, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, MethodNotAllowed, req.URL.Path) case donut.BadDigest: - writeErrorResponse(w, req, BadDigest, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, BadDigest, req.URL.Path) case signv4.DoesNotMatch: - writeErrorResponse(w, req, SignatureDoesNotMatch, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, SignatureDoesNotMatch, req.URL.Path) case donut.IncompleteBody: - writeErrorResponse(w, req, IncompleteBody, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, IncompleteBody, req.URL.Path) case donut.EntityTooLarge: - writeErrorResponse(w, req, EntityTooLarge, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, EntityTooLarge, req.URL.Path) case donut.InvalidDigest: - writeErrorResponse(w, req, InvalidDigest, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, InvalidDigest, req.URL.Path) default: - writeErrorResponse(w, req, InternalError, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, InternalError, req.URL.Path) } return } w.Header().Set("ETag", calculatedMD5) - writeSuccessResponse(w, acceptsContentType) + writeSuccessResponse(w) } // AbortMultipartUploadHandler - Abort multipart upload @@ -450,8 +445,7 @@ func (api API) AbortMultipartUploadHandler(w http.ResponseWriter, req *http.Requ <-op.ProceedCh } - acceptsContentType := getContentType(req) - if !api.isValidOp(w, req, acceptsContentType) { + if !api.isValidOp(w, req) { return } @@ -468,7 +462,7 @@ func (api API) AbortMultipartUploadHandler(w http.ResponseWriter, req *http.Requ signature, err = initSignatureV4(req) if err != nil { errorIf(err.Trace(), "Initializing signature v4 failed.", nil) - writeErrorResponse(w, req, InternalError, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, InternalError, req.URL.Path) return } } @@ -478,15 +472,15 @@ func (api API) AbortMultipartUploadHandler(w http.ResponseWriter, req *http.Requ errorIf(err.Trace(), "AbortMutlipartUpload failed.", nil) switch err.ToGoError().(type) { case signv4.DoesNotMatch: - writeErrorResponse(w, req, SignatureDoesNotMatch, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, SignatureDoesNotMatch, req.URL.Path) case donut.InvalidUploadID: - writeErrorResponse(w, req, NoSuchUpload, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, NoSuchUpload, req.URL.Path) default: - writeErrorResponse(w, req, InternalError, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, InternalError, req.URL.Path) } return } - setCommonHeaders(w, getContentTypeString(acceptsContentType), 0) + setCommonHeaders(w, 0) w.WriteHeader(http.StatusNoContent) } @@ -501,18 +495,17 @@ func (api API) ListObjectPartsHandler(w http.ResponseWriter, req *http.Request) <-op.ProceedCh } - acceptsContentType := getContentType(req) - if !api.isValidOp(w, req, acceptsContentType) { + if !api.isValidOp(w, req) { return } objectResourcesMetadata := getObjectResources(req.URL.Query()) if objectResourcesMetadata.PartNumberMarker < 0 { - writeErrorResponse(w, req, InvalidPartNumberMarker, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, InvalidPartNumberMarker, req.URL.Path) return } if objectResourcesMetadata.MaxParts < 0 { - writeErrorResponse(w, req, InvalidMaxParts, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, InvalidMaxParts, req.URL.Path) return } if objectResourcesMetadata.MaxParts == 0 { @@ -530,7 +523,7 @@ func (api API) ListObjectPartsHandler(w http.ResponseWriter, req *http.Request) signature, err = initSignatureV4(req) if err != nil { errorIf(err.Trace(), "Initializing signature v4 failed.", nil) - writeErrorResponse(w, req, InternalError, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, InternalError, req.URL.Path) return } } @@ -540,18 +533,18 @@ func (api API) ListObjectPartsHandler(w http.ResponseWriter, req *http.Request) errorIf(err.Trace(), "ListObjectParts failed.", nil) switch err.ToGoError().(type) { case signv4.DoesNotMatch: - writeErrorResponse(w, req, SignatureDoesNotMatch, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, SignatureDoesNotMatch, req.URL.Path) case donut.InvalidUploadID: - writeErrorResponse(w, req, NoSuchUpload, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, NoSuchUpload, req.URL.Path) default: - writeErrorResponse(w, req, InternalError, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, InternalError, req.URL.Path) } return } response := generateListPartsResponse(objectResourcesMetadata) - encodedSuccessResponse := encodeSuccessResponse(response, acceptsContentType) + encodedSuccessResponse := encodeSuccessResponse(response) // write headers - setCommonHeaders(w, getContentTypeString(acceptsContentType), len(encodedSuccessResponse)) + setCommonHeaders(w, len(encodedSuccessResponse)) // write body w.Write(encodedSuccessResponse) } @@ -567,8 +560,7 @@ func (api API) CompleteMultipartUploadHandler(w http.ResponseWriter, req *http.R <-op.ProceedCh } - acceptsContentType := getContentType(req) - if !api.isValidOp(w, req, acceptsContentType) { + if !api.isValidOp(w, req) { return } @@ -585,7 +577,7 @@ func (api API) CompleteMultipartUploadHandler(w http.ResponseWriter, req *http.R signature, err = initSignatureV4(req) if err != nil { errorIf(err.Trace(), "Initializing signature v4 failed.", nil) - writeErrorResponse(w, req, InternalError, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, InternalError, req.URL.Path) return } } @@ -594,28 +586,28 @@ func (api API) CompleteMultipartUploadHandler(w http.ResponseWriter, req *http.R errorIf(err.Trace(), "CompleteMultipartUpload failed.", nil) switch err.ToGoError().(type) { case donut.InvalidUploadID: - writeErrorResponse(w, req, NoSuchUpload, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, NoSuchUpload, req.URL.Path) case donut.InvalidPart: - writeErrorResponse(w, req, InvalidPart, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, InvalidPart, req.URL.Path) case donut.InvalidPartOrder: - writeErrorResponse(w, req, InvalidPartOrder, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, InvalidPartOrder, req.URL.Path) case signv4.MissingDateHeader: - writeErrorResponse(w, req, RequestTimeTooSkewed, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, RequestTimeTooSkewed, req.URL.Path) case signv4.DoesNotMatch: - writeErrorResponse(w, req, SignatureDoesNotMatch, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, SignatureDoesNotMatch, req.URL.Path) case donut.IncompleteBody: - writeErrorResponse(w, req, IncompleteBody, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, IncompleteBody, req.URL.Path) case donut.MalformedXML: - writeErrorResponse(w, req, MalformedXML, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, MalformedXML, req.URL.Path) default: - writeErrorResponse(w, req, InternalError, acceptsContentType, req.URL.Path) + writeErrorResponse(w, req, InternalError, req.URL.Path) } return } response := generateCompleteMultpartUploadResponse(bucket, object, "", metadata.MD5Sum) - encodedSuccessResponse := encodeSuccessResponse(response, acceptsContentType) + encodedSuccessResponse := encodeSuccessResponse(response) // write headers - setCommonHeaders(w, getContentTypeString(acceptsContentType), len(encodedSuccessResponse)) + setCommonHeaders(w, len(encodedSuccessResponse)) // write body w.Write(encodedSuccessResponse) } diff --git a/server-api-response.go b/server-api-response.go index 54ab10c35..5bdcfa97e 100644 --- a/server-api-response.go +++ b/server-api-response.go @@ -177,19 +177,19 @@ func generateListMultipartUploadsResponse(bucket string, metadata donut.BucketMu } // writeSuccessResponse write success headers -func writeSuccessResponse(w http.ResponseWriter, acceptsContentType contentType) { - setCommonHeaders(w, getContentTypeString(acceptsContentType), 0) +func writeSuccessResponse(w http.ResponseWriter) { + setCommonHeaders(w, 0) w.WriteHeader(http.StatusOK) } // writeErrorRespone write error headers -func writeErrorResponse(w http.ResponseWriter, req *http.Request, errorType int, acceptsContentType contentType, resource string) { +func writeErrorResponse(w http.ResponseWriter, req *http.Request, errorType int, resource string) { error := getErrorCode(errorType) // generate error response errorResponse := getErrorResponse(error, resource) - encodedErrorResponse := encodeErrorResponse(errorResponse, acceptsContentType) + encodedErrorResponse := encodeErrorResponse(errorResponse) // set common headers - setCommonHeaders(w, getContentTypeString(acceptsContentType), len(encodedErrorResponse)) + setCommonHeaders(w, len(encodedErrorResponse)) // write Header w.WriteHeader(error.HTTPStatusCode) // HEAD should have no body, do not attempt to write to it diff --git a/server-router.go b/server-router.go index a6f8fb533..ee54e31bf 100644 --- a/server-router.go +++ b/server-router.go @@ -83,7 +83,6 @@ func getNewAPI() API { // getAPIHandler api handler func getAPIHandler(api API) http.Handler { var mwHandlers = []MiddlewareHandler{ - ValidContentTypeHandler, TimeValidityHandler, IgnoreResourcesHandler, ValidateAuthHeaderHandler,