Merge pull request #406 from fkautz/pr_out_simplfying_code_in_api_round_1_decoupling_functions_which_both_write_headers_and_data

This commit is contained in:
Frederick F. Kautz IV 2015-03-28 18:01:23 -07:00
commit c728798137
8 changed files with 221 additions and 135 deletions

View File

@ -46,41 +46,70 @@ func (server *minioAPI) listObjectsHandler(w http.ResponseWriter, req *http.Requ
acceptsContentType := getContentType(req) acceptsContentType := getContentType(req)
objects, resources, err := server.driver.ListObjects(bucket, resources) objects, resources, err := server.driver.ListObjects(bucket, resources)
switch err := err.(type) { switch err.(type) {
case nil: // success case nil: // success
{ {
// write headers
setCommonHeaders(w, getContentTypeString(acceptsContentType))
w.WriteHeader(http.StatusOK)
// write body
response := generateObjectsListResult(bucket, objects, resources) response := generateObjectsListResult(bucket, objects, resources)
w.Write(writeObjectHeadersAndResponse(w, response, acceptsContentType)) encodedResponse := encodeResponse(response, acceptsContentType)
w.Write(encodedResponse)
} }
case drivers.BucketNotFound: case drivers.BucketNotFound:
{ {
error := errorCodeError(NoSuchBucket) // get error
error := getErrorCode(NoSuchBucket)
errorResponse := getErrorResponse(error, bucket) errorResponse := getErrorResponse(error, bucket)
// write headers
setCommonHeaders(w, getContentTypeString(acceptsContentType))
w.WriteHeader(error.HTTPStatusCode) w.WriteHeader(error.HTTPStatusCode)
w.Write(writeErrorResponse(w, errorResponse, acceptsContentType))
// write body
encodedErrorResponse := encodeErrorResponse(errorResponse, acceptsContentType)
w.Write(encodedErrorResponse)
} }
case drivers.ImplementationError: case drivers.ImplementationError:
{ {
// Embed error log on server side // get error
log.Error.Println(err) error := getErrorCode(InternalError)
error := errorCodeError(InternalError)
errorResponse := getErrorResponse(error, bucket) errorResponse := getErrorResponse(error, bucket)
// write headers
setCommonHeaders(w, getContentTypeString(acceptsContentType))
w.WriteHeader(error.HTTPStatusCode) w.WriteHeader(error.HTTPStatusCode)
w.Write(writeErrorResponse(w, errorResponse, acceptsContentType))
// write body
encodedErrorResponse := encodeErrorResponse(errorResponse, acceptsContentType)
w.Write(encodedErrorResponse)
} }
case drivers.BucketNameInvalid: case drivers.BucketNameInvalid:
{ {
error := errorCodeError(InvalidBucketName) error := getErrorCode(InvalidBucketName)
errorResponse := getErrorResponse(error, bucket) errorResponse := getErrorResponse(error, bucket)
// write headers
setCommonHeaders(w, getContentTypeString(acceptsContentType))
w.WriteHeader(error.HTTPStatusCode) w.WriteHeader(error.HTTPStatusCode)
w.Write(writeErrorResponse(w, errorResponse, acceptsContentType))
// write body
encodedErrorResponse := encodeErrorResponse(errorResponse, acceptsContentType)
w.Write(encodedErrorResponse)
} }
case drivers.ObjectNameInvalid: case drivers.ObjectNameInvalid:
{ {
error := errorCodeError(NoSuchKey) error := getErrorCode(NoSuchKey)
errorResponse := getErrorResponse(error, resources.Prefix) errorResponse := getErrorResponse(error, resources.Prefix)
// write headers
setCommonHeaders(w, getContentTypeString(acceptsContentType))
w.WriteHeader(error.HTTPStatusCode) w.WriteHeader(error.HTTPStatusCode)
w.Write(writeErrorResponse(w, errorResponse, acceptsContentType))
// write body
encodedErrorResponse := encodeErrorResponse(errorResponse, acceptsContentType)
w.Write(encodedErrorResponse)
} }
} }
} }
@ -96,23 +125,37 @@ func (server *minioAPI) listBucketsHandler(w http.ResponseWriter, req *http.Requ
case nil: case nil:
{ {
response := generateBucketsListResult(buckets) response := generateBucketsListResult(buckets)
w.Write(writeObjectHeadersAndResponse(w, response, acceptsContentType)) // write headers
} setCommonHeaders(w, getContentTypeString(acceptsContentType))
case drivers.ImplementationError: w.WriteHeader(http.StatusOK)
{ // write response
log.Error.Println(err) encodedResponse := encodeResponse(response, acceptsContentType)
error := errorCodeError(InternalError) w.Write(encodedResponse)
errorResponse := getErrorResponse(error, "")
w.WriteHeader(error.HTTPStatusCode)
w.Write(writeErrorResponse(w, errorResponse, acceptsContentType))
} }
case drivers.BackendCorrupted: case drivers.BackendCorrupted:
{ {
log.Error.Println(err) log.Error.Println(err)
error := errorCodeError(InternalError) // get error
errorResponse := getErrorResponse(error, "") errorCode := getErrorCode(InternalError)
w.WriteHeader(error.HTTPStatusCode) errorResponse := getErrorResponse(errorCode, "")
w.Write(writeErrorResponse(w, errorResponse, acceptsContentType)) // write headers
setCommonHeaders(w, getContentTypeString(acceptsContentType))
w.WriteHeader(errorCode.HTTPStatusCode)
// write
encodedErrorResponse := encodeErrorResponse(errorResponse, acceptsContentType)
w.Write(encodedErrorResponse)
}
default:
{
log.Trace.Println(err)
// get error
errorCode := getErrorCode(InternalError)
errorResponse := getErrorResponse(errorCode, "")
// write headers
w.WriteHeader(errorCode.HTTPStatusCode)
// write body
encodedError := encodeErrorResponse(errorResponse, acceptsContentType)
w.Write(encodedError)
} }
} }
} }
@ -132,7 +175,7 @@ func (server *minioAPI) putBucketHandler(w http.ResponseWriter, req *http.Reques
} }
acceptsContentType := getContentType(req) acceptsContentType := getContentType(req)
switch err := err.(type) { switch err.(type) {
case nil: case nil:
{ {
w.Header().Set("Server", "Minio") w.Header().Set("Server", "Minio")
@ -140,26 +183,37 @@ func (server *minioAPI) putBucketHandler(w http.ResponseWriter, req *http.Reques
} }
case drivers.BucketNameInvalid: case drivers.BucketNameInvalid:
{ {
error := errorCodeError(InvalidBucketName) error := getErrorCode(InvalidBucketName)
errorResponse := getErrorResponse(error, bucket) errorResponse := getErrorResponse(error, bucket)
// write header
setCommonHeaders(w, getContentTypeString(acceptsContentType))
w.WriteHeader(error.HTTPStatusCode) w.WriteHeader(error.HTTPStatusCode)
w.Write(writeErrorResponse(w, errorResponse, acceptsContentType)) // write object
encodedResponse := encodeErrorResponse(errorResponse, acceptsContentType)
w.Write(encodedResponse)
} }
case drivers.BucketExists: case drivers.BucketExists:
{ {
error := errorCodeError(BucketAlreadyExists) error := getErrorCode(BucketAlreadyExists)
errorResponse := getErrorResponse(error, bucket) errorResponse := getErrorResponse(error, bucket)
// write header
setCommonHeaders(w, getContentTypeString(acceptsContentType))
w.WriteHeader(error.HTTPStatusCode) w.WriteHeader(error.HTTPStatusCode)
w.Write(writeErrorResponse(w, errorResponse, acceptsContentType)) // write object
encodedResponse := encodeErrorResponse(errorResponse, acceptsContentType)
w.Write(encodedResponse)
} }
case drivers.ImplementationError: case drivers.ImplementationError:
{ {
// Embed errors log on server side // Embed errors log on server side
log.Error.Println(err) error := getErrorCode(InternalError)
error := errorCodeError(InternalError)
errorResponse := getErrorResponse(error, bucket) errorResponse := getErrorResponse(error, bucket)
// write header
setCommonHeaders(w, getContentTypeString(acceptsContentType))
w.WriteHeader(error.HTTPStatusCode) w.WriteHeader(error.HTTPStatusCode)
w.Write(writeErrorResponse(w, errorResponse, acceptsContentType)) // write object
encodedResponse := encodeErrorResponse(errorResponse, acceptsContentType)
w.Write(encodedResponse)
} }
} }
} }

View File

@ -57,26 +57,29 @@ func (h vHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
acceptsContentType := getContentType(r) acceptsContentType := getContentType(r)
if accessKey != "" { if accessKey != "" {
if err := h.conf.ReadConfig(); err != nil { if err := h.conf.ReadConfig(); err != nil {
error := errorCodeError(InternalError) error := getErrorCode(InternalError)
errorResponse := getErrorResponse(error, "") errorResponse := getErrorResponse(error, "")
setCommonHeaders(w, getContentTypeString(acceptsContentType))
w.WriteHeader(error.HTTPStatusCode) w.WriteHeader(error.HTTPStatusCode)
w.Write(writeErrorResponse(w, errorResponse, acceptsContentType)) w.Write(encodeErrorResponse(errorResponse, acceptsContentType))
} else { } else {
user, ok := h.conf.Users[accessKey] user, ok := h.conf.Users[accessKey]
if ok == false { if ok == false {
error := errorCodeError(AccessDenied) error := getErrorCode(AccessDenied)
errorResponse := getErrorResponse(error, "") errorResponse := getErrorResponse(error, "")
setCommonHeaders(w, getContentTypeString(acceptsContentType))
w.WriteHeader(error.HTTPStatusCode) w.WriteHeader(error.HTTPStatusCode)
w.Write(writeErrorResponse(w, errorResponse, acceptsContentType)) w.Write(encodeErrorResponse(errorResponse, acceptsContentType))
} else { } else {
ok, _ = ValidateRequest(user, r) ok, _ = ValidateRequest(user, r)
if ok { if ok {
h.handler.ServeHTTP(w, r) h.handler.ServeHTTP(w, r)
} else { } else {
error := errorCodeError(AccessDenied) error := getErrorCode(AccessDenied)
errorResponse := getErrorResponse(error, "") errorResponse := getErrorResponse(error, "")
setCommonHeaders(w, getContentTypeString(acceptsContentType))
w.WriteHeader(error.HTTPStatusCode) w.WriteHeader(error.HTTPStatusCode)
w.Write(writeErrorResponse(w, errorResponse, acceptsContentType)) w.Write(encodeErrorResponse(errorResponse, acceptsContentType))
} }
} }
} }
@ -106,10 +109,11 @@ func ignoreResourcesHandler(h http.Handler) http.Handler {
func (h rHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { func (h rHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
acceptsContentType := getContentType(r) acceptsContentType := getContentType(r)
if ignoreUnImplementedObjectResources(r) || ignoreUnImplementedBucketResources(r) { if ignoreUnImplementedObjectResources(r) || ignoreUnImplementedBucketResources(r) {
error := errorCodeError(NotImplemented) error := getErrorCode(NotImplemented)
errorResponse := getErrorResponse(error, "") errorResponse := getErrorResponse(error, "")
setCommonHeaders(w, getContentTypeString(acceptsContentType))
w.WriteHeader(error.HTTPStatusCode) w.WriteHeader(error.HTTPStatusCode)
w.Write(writeErrorResponse(w, errorResponse, acceptsContentType)) w.Write(encodeErrorResponse(errorResponse, acceptsContentType))
} else { } else {
h.handler.ServeHTTP(w, r) h.handler.ServeHTTP(w, r)
} }

View File

@ -43,10 +43,11 @@ func (server *minioAPI) getObjectHandler(w http.ResponseWriter, req *http.Reques
httpRange, err := newRange(req, metadata.Size) httpRange, err := newRange(req, metadata.Size)
if err != nil { if err != nil {
log.Error.Println(err) log.Error.Println(err)
error := errorCodeError(InvalidRange) error := getErrorCode(InvalidRange)
errorResponse := getErrorResponse(error, "/"+bucket+"/"+object) errorResponse := getErrorResponse(error, "/"+bucket+"/"+object)
setCommonHeaders(w, getContentTypeString(acceptsContentType))
w.WriteHeader(error.HTTPStatusCode) w.WriteHeader(error.HTTPStatusCode)
w.Write(writeErrorResponse(w, errorResponse, acceptsContentType)) w.Write(encodeErrorResponse(errorResponse, acceptsContentType))
return return
} }
switch httpRange.start == 0 && httpRange.length == 0 { switch httpRange.start == 0 && httpRange.length == 0 {
@ -54,10 +55,11 @@ func (server *minioAPI) getObjectHandler(w http.ResponseWriter, req *http.Reques
writeObjectHeaders(w, metadata) writeObjectHeaders(w, metadata)
if _, err := server.driver.GetObject(w, bucket, object); err != nil { if _, err := server.driver.GetObject(w, bucket, object); err != nil {
log.Error.Println(err) log.Error.Println(err)
error := errorCodeError(InternalError) error := getErrorCode(InternalError)
errorResponse := getErrorResponse(error, "/"+bucket+"/"+object) errorResponse := getErrorResponse(error, "/"+bucket+"/"+object)
setCommonHeaders(w, getContentTypeString(acceptsContentType))
w.WriteHeader(error.HTTPStatusCode) w.WriteHeader(error.HTTPStatusCode)
w.Write(writeErrorResponse(w, errorResponse, acceptsContentType)) w.Write(encodeErrorResponse(errorResponse, acceptsContentType))
return return
} }
case false: case false:
@ -67,10 +69,11 @@ func (server *minioAPI) getObjectHandler(w http.ResponseWriter, req *http.Reques
_, err := server.driver.GetPartialObject(w, bucket, object, httpRange.start, httpRange.length) _, err := server.driver.GetPartialObject(w, bucket, object, httpRange.start, httpRange.length)
if err != nil { if err != nil {
log.Error.Println(err) log.Error.Println(err)
error := errorCodeError(InternalError) error := getErrorCode(InternalError)
errorResponse := getErrorResponse(error, "/"+bucket+"/"+object) errorResponse := getErrorResponse(error, "/"+bucket+"/"+object)
setCommonHeaders(w, getContentTypeString(acceptsContentType))
w.WriteHeader(error.HTTPStatusCode) w.WriteHeader(error.HTTPStatusCode)
w.Write(writeErrorResponse(w, errorResponse, acceptsContentType)) w.Write(encodeErrorResponse(errorResponse, acceptsContentType))
return return
} }
@ -78,40 +81,45 @@ func (server *minioAPI) getObjectHandler(w http.ResponseWriter, req *http.Reques
} }
case drivers.ObjectNotFound: case drivers.ObjectNotFound:
{ {
error := errorCodeError(NoSuchKey) error := getErrorCode(NoSuchKey)
errorResponse := getErrorResponse(error, "/"+bucket+"/"+object) errorResponse := getErrorResponse(error, "/"+bucket+"/"+object)
setCommonHeaders(w, getContentTypeString(acceptsContentType))
w.WriteHeader(error.HTTPStatusCode) w.WriteHeader(error.HTTPStatusCode)
w.Write(writeErrorResponse(w, errorResponse, acceptsContentType)) w.Write(encodeErrorResponse(errorResponse, acceptsContentType))
} }
case drivers.BucketNotFound: case drivers.BucketNotFound:
{ {
error := errorCodeError(NoSuchBucket) error := getErrorCode(NoSuchBucket)
errorResponse := getErrorResponse(error, "/"+bucket+"/"+object) errorResponse := getErrorResponse(error, "/"+bucket+"/"+object)
setCommonHeaders(w, getContentTypeString(acceptsContentType))
w.WriteHeader(error.HTTPStatusCode) w.WriteHeader(error.HTTPStatusCode)
w.Write(writeErrorResponse(w, errorResponse, acceptsContentType)) w.Write(encodeErrorResponse(errorResponse, acceptsContentType))
} }
case drivers.ObjectNameInvalid: case drivers.ObjectNameInvalid:
{ {
error := errorCodeError(NoSuchKey) error := getErrorCode(NoSuchKey)
errorResponse := getErrorResponse(error, "/"+bucket+"/"+object) errorResponse := getErrorResponse(error, "/"+bucket+"/"+object)
setCommonHeaders(w, getContentTypeString(acceptsContentType))
w.WriteHeader(error.HTTPStatusCode) w.WriteHeader(error.HTTPStatusCode)
w.Write(writeErrorResponse(w, errorResponse, acceptsContentType)) w.Write(encodeErrorResponse(errorResponse, acceptsContentType))
} }
case drivers.BucketNameInvalid: case drivers.BucketNameInvalid:
{ {
error := errorCodeError(InvalidBucketName) error := getErrorCode(InvalidBucketName)
errorResponse := getErrorResponse(error, "/"+bucket+"/"+object) errorResponse := getErrorResponse(error, "/"+bucket+"/"+object)
setCommonHeaders(w, getContentTypeString(acceptsContentType))
w.WriteHeader(error.HTTPStatusCode) w.WriteHeader(error.HTTPStatusCode)
w.Write(writeErrorResponse(w, errorResponse, acceptsContentType)) w.Write(encodeErrorResponse(errorResponse, acceptsContentType))
} }
default: default:
{ {
// Embed errors log on serve side // Embed errors log on serve side
log.Error.Println(err) log.Error.Println(err)
error := errorCodeError(InternalError) error := getErrorCode(InternalError)
errorResponse := getErrorResponse(error, "/"+bucket+"/"+object) errorResponse := getErrorResponse(error, "/"+bucket+"/"+object)
setCommonHeaders(w, getContentTypeString(acceptsContentType))
w.WriteHeader(error.HTTPStatusCode) w.WriteHeader(error.HTTPStatusCode)
w.Write(writeErrorResponse(w, errorResponse, acceptsContentType)) w.Write(encodeErrorResponse(errorResponse, acceptsContentType))
} }
} }
} }
@ -132,26 +140,29 @@ func (server *minioAPI) headObjectHandler(w http.ResponseWriter, req *http.Reque
writeObjectHeaders(w, metadata) writeObjectHeaders(w, metadata)
case drivers.ObjectNotFound: case drivers.ObjectNotFound:
{ {
error := errorCodeError(NoSuchKey) error := getErrorCode(NoSuchKey)
errorResponse := getErrorResponse(error, "/"+bucket+"/"+object) errorResponse := getErrorResponse(error, "/"+bucket+"/"+object)
setCommonHeaders(w, getContentTypeString(acceptsContentType))
w.WriteHeader(error.HTTPStatusCode) w.WriteHeader(error.HTTPStatusCode)
w.Write(writeErrorResponse(w, errorResponse, acceptsContentType)) w.Write(encodeErrorResponse(errorResponse, acceptsContentType))
} }
case drivers.ObjectNameInvalid: case drivers.ObjectNameInvalid:
{ {
error := errorCodeError(NoSuchKey) error := getErrorCode(NoSuchKey)
errorResponse := getErrorResponse(error, "/"+bucket+"/"+object) errorResponse := getErrorResponse(error, "/"+bucket+"/"+object)
setCommonHeaders(w, getContentTypeString(acceptsContentType))
w.WriteHeader(error.HTTPStatusCode) w.WriteHeader(error.HTTPStatusCode)
w.Write(writeErrorResponse(w, errorResponse, acceptsContentType)) w.Write(encodeErrorResponse(errorResponse, acceptsContentType))
} }
case drivers.ImplementationError: case drivers.ImplementationError:
{ {
// Embed error log on server side // Embed error log on server side
log.Error.Println(err) log.Error.Println(err)
error := errorCodeError(InternalError) error := getErrorCode(InternalError)
errorResponse := getErrorResponse(error, "/"+bucket+"/"+object) errorResponse := getErrorResponse(error, "/"+bucket+"/"+object)
setCommonHeaders(w, getContentTypeString(acceptsContentType))
w.WriteHeader(error.HTTPStatusCode) w.WriteHeader(error.HTTPStatusCode)
w.Write(writeErrorResponse(w, errorResponse, acceptsContentType)) w.Write(encodeErrorResponse(errorResponse, acceptsContentType))
} }
} }
} }
@ -183,45 +194,51 @@ func (server *minioAPI) putObjectHandler(w http.ResponseWriter, req *http.Reques
{ {
// Embed error log on server side // Embed error log on server side
log.Error.Println(err) log.Error.Println(err)
error := errorCodeError(InternalError) error := getErrorCode(InternalError)
errorResponse := getErrorResponse(error, "/"+bucket+"/"+object) errorResponse := getErrorResponse(error, "/"+bucket+"/"+object)
setCommonHeaders(w, getContentTypeString(acceptsContentType))
w.WriteHeader(error.HTTPStatusCode) w.WriteHeader(error.HTTPStatusCode)
w.Write(writeErrorResponse(w, errorResponse, acceptsContentType)) w.Write(encodeErrorResponse(errorResponse, acceptsContentType))
} }
case drivers.BucketNotFound: case drivers.BucketNotFound:
{ {
error := errorCodeError(NoSuchBucket) error := getErrorCode(NoSuchBucket)
errorResponse := getErrorResponse(error, "/"+bucket+"/"+object) errorResponse := getErrorResponse(error, "/"+bucket+"/"+object)
setCommonHeaders(w, getContentTypeString(acceptsContentType))
w.WriteHeader(error.HTTPStatusCode) w.WriteHeader(error.HTTPStatusCode)
w.Write(writeErrorResponse(w, errorResponse, acceptsContentType)) w.Write(encodeErrorResponse(errorResponse, acceptsContentType))
} }
case drivers.BucketNameInvalid: case drivers.BucketNameInvalid:
{ {
error := errorCodeError(InvalidBucketName) error := getErrorCode(InvalidBucketName)
errorResponse := getErrorResponse(error, "/"+bucket+"/"+object) errorResponse := getErrorResponse(error, "/"+bucket+"/"+object)
setCommonHeaders(w, getContentTypeString(acceptsContentType))
w.WriteHeader(error.HTTPStatusCode) w.WriteHeader(error.HTTPStatusCode)
w.Write(writeErrorResponse(w, errorResponse, acceptsContentType)) w.Write(encodeErrorResponse(errorResponse, acceptsContentType))
} }
case drivers.ObjectExists: case drivers.ObjectExists:
{ {
error := errorCodeError(NotImplemented) error := getErrorCode(NotImplemented)
errorResponse := getErrorResponse(error, "/"+bucket+"/"+object) errorResponse := getErrorResponse(error, "/"+bucket+"/"+object)
setCommonHeaders(w, getContentTypeString(acceptsContentType))
w.WriteHeader(error.HTTPStatusCode) w.WriteHeader(error.HTTPStatusCode)
w.Write(writeErrorResponse(w, errorResponse, acceptsContentType)) w.Write(encodeErrorResponse(errorResponse, acceptsContentType))
} }
case drivers.BadDigest: case drivers.BadDigest:
{ {
error := errorCodeError(BadDigest) error := getErrorCode(BadDigest)
errorResponse := getErrorResponse(error, "/"+bucket+"/"+object) errorResponse := getErrorResponse(error, "/"+bucket+"/"+object)
setCommonHeaders(w, getContentTypeString(acceptsContentType))
w.WriteHeader(error.HTTPStatusCode) w.WriteHeader(error.HTTPStatusCode)
w.Write(writeErrorResponse(w, errorResponse, acceptsContentType)) w.Write(encodeErrorResponse(errorResponse, acceptsContentType))
} }
case drivers.InvalidDigest: case drivers.InvalidDigest:
{ {
error := errorCodeError(InvalidDigest) error := getErrorCode(InvalidDigest)
errorResponse := getErrorResponse(error, "/"+bucket+"/"+object) errorResponse := getErrorResponse(error, "/"+bucket+"/"+object)
setCommonHeaders(w, getContentTypeString(acceptsContentType))
w.WriteHeader(error.HTTPStatusCode) w.WriteHeader(error.HTTPStatusCode)
w.Write(writeErrorResponse(w, errorResponse, acceptsContentType)) w.Write(encodeErrorResponse(errorResponse, acceptsContentType))
} }
} }

View File

@ -36,10 +36,11 @@ func (server *minioAPI) putBucketPolicyHandler(w http.ResponseWriter, req *http.
policy, ok := drivers.Parsepolicy(req.Body) policy, ok := drivers.Parsepolicy(req.Body)
if ok == false { if ok == false {
error := errorCodeError(InvalidPolicyDocument) error := getErrorCode(InvalidPolicyDocument)
errorResponse := getErrorResponse(error, bucket) errorResponse := getErrorResponse(error, bucket)
setCommonHeaders(w, getContentTypeString(acceptsContentType))
w.WriteHeader(error.HTTPStatusCode) w.WriteHeader(error.HTTPStatusCode)
w.Write(writeErrorResponse(w, errorResponse, acceptsContentType)) w.Write(encodeErrorResponse(errorResponse, acceptsContentType))
return return
} }
@ -48,38 +49,42 @@ func (server *minioAPI) putBucketPolicyHandler(w http.ResponseWriter, req *http.
case nil: case nil:
{ {
w.WriteHeader(http.StatusNoContent) w.WriteHeader(http.StatusNoContent)
writeCommonHeaders(w, getContentString(acceptsContentType)) setCommonHeaders(w, getContentTypeString(acceptsContentType))
w.Header().Set("Connection", "keep-alive") w.Header().Set("Connection", "keep-alive")
} }
case drivers.BucketNameInvalid: case drivers.BucketNameInvalid:
{ {
error := errorCodeError(InvalidBucketName) error := getErrorCode(InvalidBucketName)
errorResponse := getErrorResponse(error, bucket) errorResponse := getErrorResponse(error, bucket)
setCommonHeaders(w, getContentTypeString(acceptsContentType))
w.WriteHeader(error.HTTPStatusCode) w.WriteHeader(error.HTTPStatusCode)
w.Write(writeErrorResponse(w, errorResponse, acceptsContentType)) w.Write(encodeErrorResponse(errorResponse, acceptsContentType))
} }
case drivers.BucketNotFound: case drivers.BucketNotFound:
{ {
error := errorCodeError(NoSuchBucket) error := getErrorCode(NoSuchBucket)
errorResponse := getErrorResponse(error, bucket) errorResponse := getErrorResponse(error, bucket)
setCommonHeaders(w, getContentTypeString(acceptsContentType))
w.WriteHeader(error.HTTPStatusCode) w.WriteHeader(error.HTTPStatusCode)
w.Write(writeErrorResponse(w, errorResponse, acceptsContentType)) w.Write(encodeErrorResponse(errorResponse, acceptsContentType))
} }
case drivers.BackendCorrupted: case drivers.BackendCorrupted:
{ {
log.Error.Println(err) log.Error.Println(err)
error := errorCodeError(InternalError) error := getErrorCode(InternalError)
errorResponse := getErrorResponse(error, bucket) errorResponse := getErrorResponse(error, bucket)
setCommonHeaders(w, getContentTypeString(acceptsContentType))
w.WriteHeader(error.HTTPStatusCode) w.WriteHeader(error.HTTPStatusCode)
w.Write(writeErrorResponse(w, errorResponse, acceptsContentType)) w.Write(encodeErrorResponse(errorResponse, acceptsContentType))
} }
case drivers.ImplementationError: case drivers.ImplementationError:
{ {
log.Error.Println(err) log.Error.Println(err)
error := errorCodeError(InternalError) error := getErrorCode(InternalError)
errorResponse := getErrorResponse(error, bucket) errorResponse := getErrorResponse(error, bucket)
setCommonHeaders(w, getContentTypeString(acceptsContentType))
w.WriteHeader(error.HTTPStatusCode) w.WriteHeader(error.HTTPStatusCode)
w.Write(writeErrorResponse(w, errorResponse, acceptsContentType)) w.Write(encodeErrorResponse(errorResponse, acceptsContentType))
} }
} }
} }
@ -99,51 +104,57 @@ func (server *minioAPI) getBucketPolicyHandler(w http.ResponseWriter, req *http.
{ {
responsePolicy, ret := json.Marshal(p) responsePolicy, ret := json.Marshal(p)
if ret != nil { if ret != nil {
error := errorCodeError(InternalError) error := getErrorCode(InternalError)
errorResponse := getErrorResponse(error, bucket) errorResponse := getErrorResponse(error, bucket)
setCommonHeaders(w, getContentTypeString(acceptsContentType))
w.WriteHeader(error.HTTPStatusCode) w.WriteHeader(error.HTTPStatusCode)
w.Write(writeErrorResponse(w, errorResponse, acceptsContentType)) w.Write(encodeErrorResponse(errorResponse, acceptsContentType))
} }
writeCommonHeaders(w, getContentString(acceptsContentType)) setCommonHeaders(w, getContentTypeString(acceptsContentType))
w.Header().Set("Connection", "keep-alive") w.Header().Set("Connection", "keep-alive")
w.Write(responsePolicy) w.Write(responsePolicy)
} }
case drivers.BucketNameInvalid: case drivers.BucketNameInvalid:
{ {
error := errorCodeError(InvalidBucketName) error := getErrorCode(InvalidBucketName)
errorResponse := getErrorResponse(error, bucket) errorResponse := getErrorResponse(error, bucket)
setCommonHeaders(w, getContentTypeString(acceptsContentType))
w.WriteHeader(error.HTTPStatusCode) w.WriteHeader(error.HTTPStatusCode)
w.Write(writeErrorResponse(w, errorResponse, acceptsContentType)) w.Write(encodeErrorResponse(errorResponse, acceptsContentType))
} }
case drivers.BucketNotFound: case drivers.BucketNotFound:
{ {
error := errorCodeError(NoSuchBucket) error := getErrorCode(NoSuchBucket)
errorResponse := getErrorResponse(error, bucket) errorResponse := getErrorResponse(error, bucket)
setCommonHeaders(w, getContentTypeString(acceptsContentType))
w.WriteHeader(error.HTTPStatusCode) w.WriteHeader(error.HTTPStatusCode)
w.Write(writeErrorResponse(w, errorResponse, acceptsContentType)) w.Write(encodeErrorResponse(errorResponse, acceptsContentType))
} }
case drivers.BucketPolicyNotFound: case drivers.BucketPolicyNotFound:
{ {
error := errorCodeError(NoSuchBucketPolicy) error := getErrorCode(NoSuchBucketPolicy)
errorResponse := getErrorResponse(error, bucket) errorResponse := getErrorResponse(error, bucket)
setCommonHeaders(w, getContentTypeString(acceptsContentType))
w.WriteHeader(error.HTTPStatusCode) w.WriteHeader(error.HTTPStatusCode)
w.Write(writeErrorResponse(w, errorResponse, acceptsContentType)) w.Write(encodeErrorResponse(errorResponse, acceptsContentType))
} }
case drivers.BackendCorrupted: case drivers.BackendCorrupted:
{ {
log.Error.Println(err) log.Error.Println(err)
error := errorCodeError(InternalError) error := getErrorCode(InternalError)
errorResponse := getErrorResponse(error, bucket) errorResponse := getErrorResponse(error, bucket)
setCommonHeaders(w, getContentTypeString(acceptsContentType))
w.WriteHeader(error.HTTPStatusCode) w.WriteHeader(error.HTTPStatusCode)
w.Write(writeErrorResponse(w, errorResponse, acceptsContentType)) w.Write(encodeErrorResponse(errorResponse, acceptsContentType))
} }
case drivers.ImplementationError: case drivers.ImplementationError:
{ {
log.Error.Println(err) log.Error.Println(err)
error := errorCodeError(InternalError) error := getErrorCode(InternalError)
errorResponse := getErrorResponse(error, bucket) errorResponse := getErrorResponse(error, bucket)
setCommonHeaders(w, getContentTypeString(acceptsContentType))
w.WriteHeader(error.HTTPStatusCode) w.WriteHeader(error.HTTPStatusCode)
w.Write(writeErrorResponse(w, errorResponse, acceptsContentType)) w.Write(encodeErrorResponse(errorResponse, acceptsContentType))
} }
} }
} }

View File

@ -18,36 +18,38 @@ package api
import ( import (
"net/http" "net/http"
"strings"
) )
type contentType int type contentType int
const ( const (
xmlType contentType = iota xmlContentType contentType = iota
jsonType jsonContentType
) )
// content-type to human readable map
var typeToString = map[contentType]string{
xmlType: "application/xml",
jsonType: "application/json",
}
// human readbale to content-type map
var acceptToType = map[string]contentType{
"application/xml": xmlType,
"application/json": jsonType,
}
// Get content type requested from 'Accept' header // Get content type requested from 'Accept' header
func getContentType(req *http.Request) contentType { func getContentType(req *http.Request) contentType {
if accept := req.Header.Get("Accept"); accept != "" { acceptHeader := req.Header.Get("Accept")
return acceptToType[accept] switch {
case strings.HasPrefix(acceptHeader, "application/json"):
return jsonContentType
default:
return xmlContentType
} }
return xmlType
} }
// Content type to human readable string // Content type to human readable string
func getContentString(content contentType) string { func getContentTypeString(content contentType) string {
return typeToString[content] switch content {
case jsonContentType:
{
return "application/json"
}
default:
{
return "application/xml"
}
}
} }

View File

@ -185,7 +185,7 @@ var errorCodeResponse = map[int]Error{
} }
// errorCodeError provides errorCode to Error. It returns empty if the code provided is unknown // errorCodeError provides errorCode to Error. It returns empty if the code provided is unknown
func errorCodeError(code int) Error { func getErrorCode(code int) Error {
return errorCodeResponse[code] return errorCodeResponse[code]
} }

View File

@ -35,22 +35,22 @@ type encoder interface {
//// helpers //// helpers
// Write http common headers // Write http common headers
func writeCommonHeaders(w http.ResponseWriter, acceptsType string) { func setCommonHeaders(w http.ResponseWriter, acceptsType string) {
w.Header().Set("Server", "Minio") w.Header().Set("Server", "Minio")
w.Header().Set("Accept-Ranges", "bytes") w.Header().Set("Accept-Ranges", "bytes")
w.Header().Set("Content-Type", acceptsType) w.Header().Set("Content-Type", acceptsType)
w.Header().Set("Connection", "close")
} }
// Write error response headers // Write error response headers
func writeErrorResponse(w http.ResponseWriter, response interface{}, acceptsType contentType) []byte { func encodeErrorResponse(response interface{}, acceptsType contentType) []byte {
var bytesBuffer bytes.Buffer var bytesBuffer bytes.Buffer
var encoder encoder var encoder encoder
// write common headers // write common headers
writeCommonHeaders(w, getContentString(acceptsType))
switch acceptsType { switch acceptsType {
case xmlType: case xmlContentType:
encoder = xml.NewEncoder(&bytesBuffer) encoder = xml.NewEncoder(&bytesBuffer)
case jsonType: case jsonContentType:
encoder = json.NewEncoder(&bytesBuffer) encoder = json.NewEncoder(&bytesBuffer)
} }
encoder.Encode(response) encoder.Encode(response)
@ -61,7 +61,7 @@ func writeErrorResponse(w http.ResponseWriter, response interface{}, acceptsType
func writeObjectHeaders(w http.ResponseWriter, metadata drivers.ObjectMetadata) { func writeObjectHeaders(w http.ResponseWriter, metadata drivers.ObjectMetadata) {
lastModified := metadata.Created.Format(time.RFC1123) lastModified := metadata.Created.Format(time.RFC1123)
// common headers // common headers
writeCommonHeaders(w, metadata.ContentType) setCommonHeaders(w, metadata.ContentType)
w.Header().Set("ETag", metadata.Md5) w.Header().Set("ETag", metadata.Md5)
w.Header().Set("Last-Modified", lastModified) w.Header().Set("Last-Modified", lastModified)
w.Header().Set("Content-Length", strconv.FormatInt(metadata.Size, 10)) w.Header().Set("Content-Length", strconv.FormatInt(metadata.Size, 10))
@ -72,27 +72,22 @@ func writeObjectHeaders(w http.ResponseWriter, metadata drivers.ObjectMetadata)
func writeRangeObjectHeaders(w http.ResponseWriter, metadata drivers.ObjectMetadata, ra string) { func writeRangeObjectHeaders(w http.ResponseWriter, metadata drivers.ObjectMetadata, ra string) {
lastModified := metadata.Created.Format(time.RFC1123) lastModified := metadata.Created.Format(time.RFC1123)
// common headers // common headers
writeCommonHeaders(w, metadata.ContentType) setCommonHeaders(w, metadata.ContentType)
w.Header().Set("ETag", metadata.Md5) w.Header().Set("ETag", metadata.Md5)
w.Header().Set("Last-Modified", lastModified) w.Header().Set("Last-Modified", lastModified)
w.Header().Set("Content-Range", ra) w.Header().Set("Content-Range", ra)
w.Header().Set("Content-Length", strconv.FormatInt(metadata.Size, 10)) w.Header().Set("Content-Length", strconv.FormatInt(metadata.Size, 10))
} }
// Write object header and response func encodeResponse(response interface{}, acceptsType contentType) []byte {
func writeObjectHeadersAndResponse(w http.ResponseWriter, response interface{}, acceptsType contentType) []byte {
var bytesBuffer bytes.Buffer
var encoder encoder var encoder encoder
// common headers var bytesBuffer bytes.Buffer
writeCommonHeaders(w, getContentString(acceptsType))
switch acceptsType { switch acceptsType {
case xmlType: case xmlContentType:
encoder = xml.NewEncoder(&bytesBuffer) encoder = xml.NewEncoder(&bytesBuffer)
case jsonType: case jsonContentType:
encoder = json.NewEncoder(&bytesBuffer) encoder = json.NewEncoder(&bytesBuffer)
} }
w.Header().Set("Connection", "close")
encoder.Encode(response) encoder.Encode(response)
return bytesBuffer.Bytes() return bytesBuffer.Bytes()
} }

View File

@ -60,6 +60,9 @@ var std = New(os.Stderr, "", LstdFlags)
// Error is an error logger // Error is an error logger
var Error = New(os.Stderr, "", 0) var Error = New(os.Stderr, "", 0)
// Trace is an error logger
var Trace = New(os.Stderr, "", 0)
// Cheap integer to fixed-width decimal ASCII. Give a negative width to avoid zero-padding. // Cheap integer to fixed-width decimal ASCII. Give a negative width to avoid zero-padding.
// Knows the buffer has capacity. // Knows the buffer has capacity.
func itoa(buf *[]byte, i int, wid int) { func itoa(buf *[]byte, i int, wid int) {