http: Enable Transfer-Encoding chunked transfer

Fixes #1020
This commit is contained in:
Harshavardhana 2016-01-08 00:40:06 -08:00
parent 82212f5fbc
commit 0c6a6dc380
5 changed files with 55 additions and 52 deletions

View file

@ -32,7 +32,7 @@ import (
// Static alphaNumeric table used for generating unique request ids
var alphaNumericTable = []byte("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ")
// generateRequestID generate request id
// generateRequestID - Generate request id
func generateRequestID() []byte {
alpha := make([]byte, 16)
rand.Read(alpha)
@ -43,14 +43,11 @@ func generateRequestID() []byte {
}
// Write http common headers
func setCommonHeaders(w http.ResponseWriter, contentLength int) {
// set unique request ID for each reply
func setCommonHeaders(w http.ResponseWriter) {
// 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("Connection", "close")
// should be set to '0' by default
w.Header().Set("Content-Length", strconv.Itoa(contentLength))
}
// Write error response headers
@ -68,12 +65,15 @@ func setObjectHeaders(w http.ResponseWriter, metadata fs.ObjectMetadata, content
// set common headers
if contentRange != nil {
if contentRange.length > 0 {
setCommonHeaders(w, int(contentRange.length))
w.Header().Set("Content-Length", strconv.FormatInt(contentRange.length, 10))
setCommonHeaders(w)
} else {
setCommonHeaders(w, int(metadata.Size))
w.Header().Set("Content-Length", strconv.FormatInt(metadata.Size, 10))
setCommonHeaders(w)
}
} else {
setCommonHeaders(w, int(metadata.Size))
w.Header().Set("Content-Length", strconv.FormatInt(metadata.Size, 10))
setCommonHeaders(w)
}
// set object headers
lastModified := metadata.Created.Format(http.TimeFormat)

View file

@ -206,15 +206,20 @@ func generateListMultipartUploadsResponse(bucket string, metadata fs.BucketMulti
return listMultipartUploadsResponse
}
// writeSuccessResponse write success headers
func writeSuccessResponse(w http.ResponseWriter) {
setCommonHeaders(w, 0)
w.WriteHeader(http.StatusOK)
// writeSuccessResponse write success headers and response if any.
func writeSuccessResponse(w http.ResponseWriter, response []byte) {
setCommonHeaders(w)
if response == nil {
w.WriteHeader(http.StatusOK)
return
}
w.Write(response)
w.(http.Flusher).Flush()
}
// writeSuccessNoContent write success headers with http status 204
func writeSuccessNoContent(w http.ResponseWriter) {
setCommonHeaders(w, 0)
setCommonHeaders(w)
w.WriteHeader(http.StatusNoContent)
}
@ -225,12 +230,13 @@ func writeErrorResponse(w http.ResponseWriter, req *http.Request, errorType int,
errorResponse := getErrorResponse(error, resource)
encodedErrorResponse := encodeErrorResponse(errorResponse)
// set common headers
setCommonHeaders(w, len(encodedErrorResponse))
setCommonHeaders(w)
// write Header
w.WriteHeader(error.HTTPStatusCode)
// HEAD should have no body, do not attempt to write to it
if req.Method != "HEAD" {
// write error body
w.Write(encodedErrorResponse)
w.(http.Flusher).Flush()
}
}

View file

@ -14,9 +14,6 @@ environment:
# scripts that run after cloning repository
install:
- set PATH=%GOPATH%\bin;c:\go\bin;%PATH%
- rd C:\Go /s /q
- appveyor DownloadFile https://storage.googleapis.com/golang/go1.5.1.windows-amd64.zip
- 7z x go1.5.1.windows-amd64.zip -oC:\ >nul
- go version
- go env

View file

@ -58,8 +58,8 @@ func (api CloudStorageAPI) GetBucketLocationHandler(w http.ResponseWriter, req *
// we bring in a mechanism of configurable regions. For the time being
// default region is empty i.e 'us-east-1'.
encodedSuccessResponse := encodeSuccessResponse(LocationResponse{}) // generate response
setCommonHeaders(w, len(encodedSuccessResponse)) // write headers
w.Write(encodedSuccessResponse) // write body
setCommonHeaders(w) // write headers
writeSuccessResponse(w, encodedSuccessResponse)
}
// ListMultipartUploadsHandler - GET Bucket (List Multipart uploads)
@ -104,10 +104,10 @@ func (api CloudStorageAPI) ListMultipartUploadsHandler(w http.ResponseWriter, re
// generate response
response := generateListMultipartUploadsResponse(bucket, resources)
encodedSuccessResponse := encodeSuccessResponse(response)
// write headers
setCommonHeaders(w, len(encodedSuccessResponse))
// write body
w.Write(encodedSuccessResponse)
// write headers.
setCommonHeaders(w)
// write success response.
writeSuccessResponse(w, encodedSuccessResponse)
}
// ListObjectsHandler - GET Bucket (List Objects)
@ -139,13 +139,13 @@ func (api CloudStorageAPI) ListObjectsHandler(w http.ResponseWriter, req *http.R
objects, resources, err := api.Filesystem.ListObjects(bucket, resources)
if err == nil {
// generate response
// Generate response
response := generateListObjectsResponse(bucket, objects, resources)
encodedSuccessResponse := encodeSuccessResponse(response)
// write headers
setCommonHeaders(w, len(encodedSuccessResponse))
// write body
w.Write(encodedSuccessResponse)
// Write headers
setCommonHeaders(w)
// Write success response.
writeSuccessResponse(w, encodedSuccessResponse)
return
}
switch err.ToGoError().(type) {
@ -180,9 +180,9 @@ func (api CloudStorageAPI) ListBucketsHandler(w http.ResponseWriter, req *http.R
response := generateListBucketsResponse(buckets)
encodedSuccessResponse := encodeSuccessResponse(response)
// write headers
setCommonHeaders(w, len(encodedSuccessResponse))
setCommonHeaders(w)
// write response
w.Write(encodedSuccessResponse)
writeSuccessResponse(w, encodedSuccessResponse)
return
}
errorIf(err.Trace(), "ListBuckets failed.", nil)
@ -265,7 +265,7 @@ func (api CloudStorageAPI) PutBucketHandler(w http.ResponseWriter, req *http.Req
}
// Make sure to add Location information here only for bucket
w.Header().Set("Location", "/"+bucket)
writeSuccessResponse(w)
writeSuccessResponse(w, nil)
}
// PostPolicyBucketHandler - POST policy
@ -348,7 +348,7 @@ func (api CloudStorageAPI) PostPolicyBucketHandler(w http.ResponseWriter, req *h
return
}
w.Header().Set("ETag", "\""+metadata.Md5+"\"")
writeSuccessResponse(w)
writeSuccessResponse(w, nil)
}
// PutBucketACLHandler - PUT Bucket ACL
@ -384,7 +384,7 @@ func (api CloudStorageAPI) PutBucketACLHandler(w http.ResponseWriter, req *http.
}
return
}
writeSuccessResponse(w)
writeSuccessResponse(w, nil)
}
// GetBucketACLHandler - GET ACL on a Bucket
@ -417,13 +417,13 @@ func (api CloudStorageAPI) GetBucketACLHandler(w http.ResponseWriter, req *http.
}
return
}
// generate response
// Generate response
response := generateAccessControlPolicyResponse(bucketMetadata.ACL)
encodedSuccessResponse := encodeSuccessResponse(response)
// write headers
setCommonHeaders(w, len(encodedSuccessResponse))
// write body
w.Write(encodedSuccessResponse)
// Write headers
setCommonHeaders(w)
// Write success response.
writeSuccessResponse(w, encodedSuccessResponse)
}
// HeadBucketHandler - HEAD Bucket
@ -458,7 +458,7 @@ func (api CloudStorageAPI) HeadBucketHandler(w http.ResponseWriter, req *http.Re
}
return
}
writeSuccessResponse(w)
writeSuccessResponse(w, nil)
}
// DeleteBucketHandler - Delete bucket

View file

@ -194,7 +194,7 @@ func (api CloudStorageAPI) PutObjectHandler(w http.ResponseWriter, req *http.Req
return
}
w.Header().Set("ETag", "\""+metadata.Md5+"\"")
writeSuccessResponse(w)
writeSuccessResponse(w, nil)
}
/// Multipart CloudStorageAPI
@ -237,9 +237,9 @@ func (api CloudStorageAPI) NewMultipartUploadHandler(w http.ResponseWriter, req
response := generateInitiateMultipartUploadResponse(bucket, object, uploadID)
encodedSuccessResponse := encodeSuccessResponse(response)
// write headers
setCommonHeaders(w, len(encodedSuccessResponse))
// write body
w.Write(encodedSuccessResponse)
setCommonHeaders(w)
// write success response.
writeSuccessResponse(w, encodedSuccessResponse)
}
// PutObjectPartHandler - Upload part
@ -326,7 +326,7 @@ func (api CloudStorageAPI) PutObjectPartHandler(w http.ResponseWriter, req *http
return
}
w.Header().Set("ETag", "\""+calculatedMD5+"\"")
writeSuccessResponse(w)
writeSuccessResponse(w, nil)
}
// AbortMultipartUploadHandler - Abort multipart upload
@ -412,10 +412,10 @@ func (api CloudStorageAPI) ListObjectPartsHandler(w http.ResponseWriter, req *ht
}
response := generateListPartsResponse(objectResourcesMetadata)
encodedSuccessResponse := encodeSuccessResponse(response)
// write headers
setCommonHeaders(w, len(encodedSuccessResponse))
// write body
w.Write(encodedSuccessResponse)
// write headers.
setCommonHeaders(w)
// write success response.
writeSuccessResponse(w, encodedSuccessResponse)
}
// CompleteMultipartUploadHandler - Complete multipart upload
@ -478,9 +478,9 @@ func (api CloudStorageAPI) CompleteMultipartUploadHandler(w http.ResponseWriter,
response := generateCompleteMultpartUploadResponse(bucket, object, req.URL.String(), metadata.Md5)
encodedSuccessResponse := encodeSuccessResponse(response)
// write headers
setCommonHeaders(w, len(encodedSuccessResponse))
// write body
w.Write(encodedSuccessResponse)
setCommonHeaders(w)
// write success response.
writeSuccessResponse(w, encodedSuccessResponse)
}
/// Delete CloudStorageAPI