From 7ce47130fd0687b8c19b0cb603050ccae1e69bba Mon Sep 17 00:00:00 2001 From: Harshavardhana Date: Fri, 15 May 2015 21:27:00 -0700 Subject: [PATCH] HEAD request should have Content-Length for only successful response, there is no response body for errors, just header is sufficient - fixes #603 http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.13 """ in the case of the HEAD method, the size of the entity-body that would have been sent had the request been a GET. """ --- pkg/api/api_bucket_handlers.go | 32 +++++++++-- pkg/api/api_object_handlers.go | 100 +++++++++++++++++++++------------ 2 files changed, 91 insertions(+), 41 deletions(-) diff --git a/pkg/api/api_bucket_handlers.go b/pkg/api/api_bucket_handlers.go index 8e0f9cf0e..ac6788fe0 100644 --- a/pkg/api/api_bucket_handlers.go +++ b/pkg/api/api_bucket_handlers.go @@ -285,11 +285,31 @@ func (server *minioAPI) putBucketACLHandler(w http.ResponseWriter, req *http.Req // return responses such as 404 Not Found and 403 Forbidden. func (server *minioAPI) headBucketHandler(w http.ResponseWriter, req *http.Request) { acceptsContentType := getContentType(req) - // verify if bucket allows this operation - if !server.isValidOp(w, req, acceptsContentType) { - return - } - // Always a success if isValidOp succeeds - writeSuccessResponse(w, acceptsContentType) + vars := mux.Vars(req) + bucket := vars["bucket"] + + _, err := server.driver.GetBucketMetadata(bucket) + switch iodine.ToError(err).(type) { + case nil: + { + writeSuccessResponse(w, acceptsContentType) + } + case drivers.BucketNotFound: + { + error := getErrorCode(NoSuchBucket) + w.WriteHeader(error.HTTPStatusCode) + } + case drivers.BucketNameInvalid: + { + error := getErrorCode(InvalidBucketName) + w.WriteHeader(error.HTTPStatusCode) + } + default: + { + log.Println(err) + error := getErrorCode(InternalError) + w.WriteHeader(error.HTTPStatusCode) + } + } } diff --git a/pkg/api/api_object_handlers.go b/pkg/api/api_object_handlers.go index 8676a50d4..2b38da17c 100644 --- a/pkg/api/api_object_handlers.go +++ b/pkg/api/api_object_handlers.go @@ -115,16 +115,22 @@ func (server *minioAPI) headObjectHandler(w http.ResponseWriter, req *http.Reque } case drivers.ObjectNotFound: { - writeErrorResponse(w, req, NoSuchKey, acceptsContentType, req.URL.Path) + error := getErrorCode(NoSuchKey) + w.Header().Set("Server", "Minio") + w.WriteHeader(error.HTTPStatusCode) } case drivers.ObjectNameInvalid: { - writeErrorResponse(w, req, NoSuchKey, acceptsContentType, req.URL.Path) + error := getErrorCode(NoSuchKey) + w.Header().Set("Server", "Minio") + w.WriteHeader(error.HTTPStatusCode) } default: { log.Error.Println(iodine.New(err, nil)) - writeErrorResponse(w, req, InternalError, acceptsContentType, req.URL.Path) + error := getErrorCode(InternalError) + w.Header().Set("Server", "Minio") + w.WriteHeader(error.HTTPStatusCode) } } } @@ -227,17 +233,23 @@ func (server *minioAPI) newMultipartUploadHandler(w http.ResponseWriter, req *ht uploadID, err := server.driver.NewMultipartUpload(bucket, object, "") switch err := iodine.ToError(err).(type) { case nil: - response := generateInitiateMultipartUploadResult(bucket, object, uploadID) - encodedSuccessResponse := encodeSuccessResponse(response, acceptsContentType) - // write headers - setCommonHeaders(w, getContentTypeString(acceptsContentType), len(encodedSuccessResponse)) - // write body - w.Write(encodedSuccessResponse) + { + response := generateInitiateMultipartUploadResult(bucket, object, uploadID) + encodedSuccessResponse := encodeSuccessResponse(response, acceptsContentType) + // write headers + setCommonHeaders(w, getContentTypeString(acceptsContentType), len(encodedSuccessResponse)) + // write body + w.Write(encodedSuccessResponse) + } case drivers.ObjectExists: - writeErrorResponse(w, req, MethodNotAllowed, acceptsContentType, req.URL.Path) + { + writeErrorResponse(w, req, MethodNotAllowed, acceptsContentType, req.URL.Path) + } default: - log.Println(iodine.New(err, nil)) - writeErrorResponse(w, req, InternalError, acceptsContentType, req.URL.Path) + { + log.Println(iodine.New(err, nil)) + writeErrorResponse(w, req, InternalError, acceptsContentType, req.URL.Path) + } } } @@ -346,13 +358,19 @@ func (server *minioAPI) abortMultipartUploadHandler(w http.ResponseWriter, req * err := server.driver.AbortMultipartUpload(bucket, object, objectResourcesMetadata.UploadID) switch err := iodine.ToError(err).(type) { case nil: - setCommonHeaders(w, getContentTypeString(acceptsContentType), 0) - w.WriteHeader(http.StatusNoContent) + { + setCommonHeaders(w, getContentTypeString(acceptsContentType), 0) + w.WriteHeader(http.StatusNoContent) + } case drivers.InvalidUploadID: - writeErrorResponse(w, req, NoSuchUpload, acceptsContentType, req.URL.Path) + { + writeErrorResponse(w, req, NoSuchUpload, acceptsContentType, req.URL.Path) + } default: - log.Println(err) - writeErrorResponse(w, req, InternalError, acceptsContentType, req.URL.Path) + { + log.Println(err) + writeErrorResponse(w, req, InternalError, acceptsContentType, req.URL.Path) + } } } @@ -375,17 +393,23 @@ func (server *minioAPI) listObjectPartsHandler(w http.ResponseWriter, req *http. objectResourcesMetadata, err := server.driver.ListObjectParts(bucket, object, objectResourcesMetadata) switch err := iodine.ToError(err).(type) { case nil: - response := generateListPartsResult(objectResourcesMetadata) - encodedSuccessResponse := encodeSuccessResponse(response, acceptsContentType) - // write headers - setCommonHeaders(w, getContentTypeString(acceptsContentType), len(encodedSuccessResponse)) - // write body - w.Write(encodedSuccessResponse) + { + response := generateListPartsResult(objectResourcesMetadata) + encodedSuccessResponse := encodeSuccessResponse(response, acceptsContentType) + // write headers + setCommonHeaders(w, getContentTypeString(acceptsContentType), len(encodedSuccessResponse)) + // write body + w.Write(encodedSuccessResponse) + } case drivers.InvalidUploadID: - writeErrorResponse(w, req, NoSuchUpload, acceptsContentType, req.URL.Path) + { + writeErrorResponse(w, req, NoSuchUpload, acceptsContentType, req.URL.Path) + } default: - log.Println(err) - writeErrorResponse(w, req, InternalError, acceptsContentType, req.URL.Path) + { + log.Println(err) + writeErrorResponse(w, req, InternalError, acceptsContentType, req.URL.Path) + } } } @@ -422,16 +446,22 @@ func (server *minioAPI) completeMultipartUploadHandler(w http.ResponseWriter, re etag, err := server.driver.CompleteMultipartUpload(bucket, object, objectResourcesMetadata.UploadID, partMap) switch err := iodine.ToError(err).(type) { case nil: - response := generateCompleteMultpartUploadResult(bucket, object, "", etag) - encodedSuccessResponse := encodeSuccessResponse(response, acceptsContentType) - // write headers - setCommonHeaders(w, getContentTypeString(acceptsContentType), len(encodedSuccessResponse)) - // write body - w.Write(encodedSuccessResponse) + { + response := generateCompleteMultpartUploadResult(bucket, object, "", etag) + encodedSuccessResponse := encodeSuccessResponse(response, acceptsContentType) + // write headers + setCommonHeaders(w, getContentTypeString(acceptsContentType), len(encodedSuccessResponse)) + // write body + w.Write(encodedSuccessResponse) + } case drivers.InvalidUploadID: - writeErrorResponse(w, req, NoSuchUpload, acceptsContentType, req.URL.Path) + { + writeErrorResponse(w, req, NoSuchUpload, acceptsContentType, req.URL.Path) + } default: - log.Println(iodine.New(err, nil)) - writeErrorResponse(w, req, InternalError, acceptsContentType, req.URL.Path) + { + log.Println(iodine.New(err, nil)) + writeErrorResponse(w, req, InternalError, acceptsContentType, req.URL.Path) + } } }