mirror of
https://github.com/minio/minio.git
synced 2024-12-25 22:55:54 -05:00
Merge pull request #1021 from harshavardhana/transfer-encoding
http: Enable Transfer-Encoding chunked transfer
This commit is contained in:
commit
3bf7685327
@ -32,7 +32,7 @@ import (
|
|||||||
// Static alphaNumeric table used for generating unique request ids
|
// Static alphaNumeric table used for generating unique request ids
|
||||||
var alphaNumericTable = []byte("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ")
|
var alphaNumericTable = []byte("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ")
|
||||||
|
|
||||||
// generateRequestID generate request id
|
// generateRequestID - Generate request id
|
||||||
func generateRequestID() []byte {
|
func generateRequestID() []byte {
|
||||||
alpha := make([]byte, 16)
|
alpha := make([]byte, 16)
|
||||||
rand.Read(alpha)
|
rand.Read(alpha)
|
||||||
@ -43,14 +43,11 @@ func generateRequestID() []byte {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Write http common headers
|
// Write http common headers
|
||||||
func setCommonHeaders(w http.ResponseWriter, contentLength int) {
|
func setCommonHeaders(w http.ResponseWriter) {
|
||||||
// set unique request ID for each reply
|
// Set unique request ID for each reply.
|
||||||
w.Header().Set("X-Amz-Request-Id", string(generateRequestID()))
|
w.Header().Set("X-Amz-Request-Id", string(generateRequestID()))
|
||||||
w.Header().Set("Server", ("Minio/" + minioReleaseTag + " (" + runtime.GOOS + "; " + runtime.GOARCH + ")"))
|
w.Header().Set("Server", ("Minio/" + minioReleaseTag + " (" + runtime.GOOS + "; " + runtime.GOARCH + ")"))
|
||||||
w.Header().Set("Accept-Ranges", "bytes")
|
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
|
// Write error response headers
|
||||||
@ -68,12 +65,15 @@ func setObjectHeaders(w http.ResponseWriter, metadata fs.ObjectMetadata, content
|
|||||||
// set common headers
|
// set common headers
|
||||||
if contentRange != nil {
|
if contentRange != nil {
|
||||||
if contentRange.length > 0 {
|
if contentRange.length > 0 {
|
||||||
setCommonHeaders(w, int(contentRange.length))
|
w.Header().Set("Content-Length", strconv.FormatInt(contentRange.length, 10))
|
||||||
|
setCommonHeaders(w)
|
||||||
} else {
|
} else {
|
||||||
setCommonHeaders(w, int(metadata.Size))
|
w.Header().Set("Content-Length", strconv.FormatInt(metadata.Size, 10))
|
||||||
|
setCommonHeaders(w)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
setCommonHeaders(w, int(metadata.Size))
|
w.Header().Set("Content-Length", strconv.FormatInt(metadata.Size, 10))
|
||||||
|
setCommonHeaders(w)
|
||||||
}
|
}
|
||||||
// set object headers
|
// set object headers
|
||||||
lastModified := metadata.Created.Format(http.TimeFormat)
|
lastModified := metadata.Created.Format(http.TimeFormat)
|
||||||
|
@ -206,15 +206,20 @@ func generateListMultipartUploadsResponse(bucket string, metadata fs.BucketMulti
|
|||||||
return listMultipartUploadsResponse
|
return listMultipartUploadsResponse
|
||||||
}
|
}
|
||||||
|
|
||||||
// writeSuccessResponse write success headers
|
// writeSuccessResponse write success headers and response if any.
|
||||||
func writeSuccessResponse(w http.ResponseWriter) {
|
func writeSuccessResponse(w http.ResponseWriter, response []byte) {
|
||||||
setCommonHeaders(w, 0)
|
setCommonHeaders(w)
|
||||||
|
if response == nil {
|
||||||
w.WriteHeader(http.StatusOK)
|
w.WriteHeader(http.StatusOK)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
w.Write(response)
|
||||||
|
w.(http.Flusher).Flush()
|
||||||
}
|
}
|
||||||
|
|
||||||
// writeSuccessNoContent write success headers with http status 204
|
// writeSuccessNoContent write success headers with http status 204
|
||||||
func writeSuccessNoContent(w http.ResponseWriter) {
|
func writeSuccessNoContent(w http.ResponseWriter) {
|
||||||
setCommonHeaders(w, 0)
|
setCommonHeaders(w)
|
||||||
w.WriteHeader(http.StatusNoContent)
|
w.WriteHeader(http.StatusNoContent)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -225,12 +230,13 @@ func writeErrorResponse(w http.ResponseWriter, req *http.Request, errorType int,
|
|||||||
errorResponse := getErrorResponse(error, resource)
|
errorResponse := getErrorResponse(error, resource)
|
||||||
encodedErrorResponse := encodeErrorResponse(errorResponse)
|
encodedErrorResponse := encodeErrorResponse(errorResponse)
|
||||||
// set common headers
|
// set common headers
|
||||||
setCommonHeaders(w, len(encodedErrorResponse))
|
setCommonHeaders(w)
|
||||||
// write Header
|
// write Header
|
||||||
w.WriteHeader(error.HTTPStatusCode)
|
w.WriteHeader(error.HTTPStatusCode)
|
||||||
// HEAD should have no body, do not attempt to write to it
|
// HEAD should have no body, do not attempt to write to it
|
||||||
if req.Method != "HEAD" {
|
if req.Method != "HEAD" {
|
||||||
// write error body
|
// write error body
|
||||||
w.Write(encodedErrorResponse)
|
w.Write(encodedErrorResponse)
|
||||||
|
w.(http.Flusher).Flush()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,9 +14,6 @@ environment:
|
|||||||
# scripts that run after cloning repository
|
# scripts that run after cloning repository
|
||||||
install:
|
install:
|
||||||
- set PATH=%GOPATH%\bin;c:\go\bin;%PATH%
|
- 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 version
|
||||||
- go env
|
- go env
|
||||||
|
|
||||||
|
@ -58,8 +58,8 @@ func (api CloudStorageAPI) GetBucketLocationHandler(w http.ResponseWriter, req *
|
|||||||
// we bring in a mechanism of configurable regions. For the time being
|
// we bring in a mechanism of configurable regions. For the time being
|
||||||
// default region is empty i.e 'us-east-1'.
|
// default region is empty i.e 'us-east-1'.
|
||||||
encodedSuccessResponse := encodeSuccessResponse(LocationResponse{}) // generate response
|
encodedSuccessResponse := encodeSuccessResponse(LocationResponse{}) // generate response
|
||||||
setCommonHeaders(w, len(encodedSuccessResponse)) // write headers
|
setCommonHeaders(w) // write headers
|
||||||
w.Write(encodedSuccessResponse) // write body
|
writeSuccessResponse(w, encodedSuccessResponse)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ListMultipartUploadsHandler - GET Bucket (List Multipart uploads)
|
// ListMultipartUploadsHandler - GET Bucket (List Multipart uploads)
|
||||||
@ -104,10 +104,10 @@ func (api CloudStorageAPI) ListMultipartUploadsHandler(w http.ResponseWriter, re
|
|||||||
// generate response
|
// generate response
|
||||||
response := generateListMultipartUploadsResponse(bucket, resources)
|
response := generateListMultipartUploadsResponse(bucket, resources)
|
||||||
encodedSuccessResponse := encodeSuccessResponse(response)
|
encodedSuccessResponse := encodeSuccessResponse(response)
|
||||||
// write headers
|
// write headers.
|
||||||
setCommonHeaders(w, len(encodedSuccessResponse))
|
setCommonHeaders(w)
|
||||||
// write body
|
// write success response.
|
||||||
w.Write(encodedSuccessResponse)
|
writeSuccessResponse(w, encodedSuccessResponse)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ListObjectsHandler - GET Bucket (List Objects)
|
// 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)
|
objects, resources, err := api.Filesystem.ListObjects(bucket, resources)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
// generate response
|
// Generate response
|
||||||
response := generateListObjectsResponse(bucket, objects, resources)
|
response := generateListObjectsResponse(bucket, objects, resources)
|
||||||
encodedSuccessResponse := encodeSuccessResponse(response)
|
encodedSuccessResponse := encodeSuccessResponse(response)
|
||||||
// write headers
|
// Write headers
|
||||||
setCommonHeaders(w, len(encodedSuccessResponse))
|
setCommonHeaders(w)
|
||||||
// write body
|
// Write success response.
|
||||||
w.Write(encodedSuccessResponse)
|
writeSuccessResponse(w, encodedSuccessResponse)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
switch err.ToGoError().(type) {
|
switch err.ToGoError().(type) {
|
||||||
@ -180,9 +180,9 @@ func (api CloudStorageAPI) ListBucketsHandler(w http.ResponseWriter, req *http.R
|
|||||||
response := generateListBucketsResponse(buckets)
|
response := generateListBucketsResponse(buckets)
|
||||||
encodedSuccessResponse := encodeSuccessResponse(response)
|
encodedSuccessResponse := encodeSuccessResponse(response)
|
||||||
// write headers
|
// write headers
|
||||||
setCommonHeaders(w, len(encodedSuccessResponse))
|
setCommonHeaders(w)
|
||||||
// write response
|
// write response
|
||||||
w.Write(encodedSuccessResponse)
|
writeSuccessResponse(w, encodedSuccessResponse)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
errorIf(err.Trace(), "ListBuckets failed.", nil)
|
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
|
// Make sure to add Location information here only for bucket
|
||||||
w.Header().Set("Location", "/"+bucket)
|
w.Header().Set("Location", "/"+bucket)
|
||||||
writeSuccessResponse(w)
|
writeSuccessResponse(w, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
// PostPolicyBucketHandler - POST policy
|
// PostPolicyBucketHandler - POST policy
|
||||||
@ -348,7 +348,7 @@ func (api CloudStorageAPI) PostPolicyBucketHandler(w http.ResponseWriter, req *h
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
w.Header().Set("ETag", "\""+metadata.Md5+"\"")
|
w.Header().Set("ETag", "\""+metadata.Md5+"\"")
|
||||||
writeSuccessResponse(w)
|
writeSuccessResponse(w, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
// PutBucketACLHandler - PUT Bucket ACL
|
// PutBucketACLHandler - PUT Bucket ACL
|
||||||
@ -384,7 +384,7 @@ func (api CloudStorageAPI) PutBucketACLHandler(w http.ResponseWriter, req *http.
|
|||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
writeSuccessResponse(w)
|
writeSuccessResponse(w, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetBucketACLHandler - GET ACL on a Bucket
|
// GetBucketACLHandler - GET ACL on a Bucket
|
||||||
@ -417,13 +417,13 @@ func (api CloudStorageAPI) GetBucketACLHandler(w http.ResponseWriter, req *http.
|
|||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// generate response
|
// Generate response
|
||||||
response := generateAccessControlPolicyResponse(bucketMetadata.ACL)
|
response := generateAccessControlPolicyResponse(bucketMetadata.ACL)
|
||||||
encodedSuccessResponse := encodeSuccessResponse(response)
|
encodedSuccessResponse := encodeSuccessResponse(response)
|
||||||
// write headers
|
// Write headers
|
||||||
setCommonHeaders(w, len(encodedSuccessResponse))
|
setCommonHeaders(w)
|
||||||
// write body
|
// Write success response.
|
||||||
w.Write(encodedSuccessResponse)
|
writeSuccessResponse(w, encodedSuccessResponse)
|
||||||
}
|
}
|
||||||
|
|
||||||
// HeadBucketHandler - HEAD Bucket
|
// HeadBucketHandler - HEAD Bucket
|
||||||
@ -458,7 +458,7 @@ func (api CloudStorageAPI) HeadBucketHandler(w http.ResponseWriter, req *http.Re
|
|||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
writeSuccessResponse(w)
|
writeSuccessResponse(w, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteBucketHandler - Delete bucket
|
// DeleteBucketHandler - Delete bucket
|
||||||
|
@ -194,7 +194,7 @@ func (api CloudStorageAPI) PutObjectHandler(w http.ResponseWriter, req *http.Req
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
w.Header().Set("ETag", "\""+metadata.Md5+"\"")
|
w.Header().Set("ETag", "\""+metadata.Md5+"\"")
|
||||||
writeSuccessResponse(w)
|
writeSuccessResponse(w, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Multipart CloudStorageAPI
|
/// Multipart CloudStorageAPI
|
||||||
@ -237,9 +237,9 @@ func (api CloudStorageAPI) NewMultipartUploadHandler(w http.ResponseWriter, req
|
|||||||
response := generateInitiateMultipartUploadResponse(bucket, object, uploadID)
|
response := generateInitiateMultipartUploadResponse(bucket, object, uploadID)
|
||||||
encodedSuccessResponse := encodeSuccessResponse(response)
|
encodedSuccessResponse := encodeSuccessResponse(response)
|
||||||
// write headers
|
// write headers
|
||||||
setCommonHeaders(w, len(encodedSuccessResponse))
|
setCommonHeaders(w)
|
||||||
// write body
|
// write success response.
|
||||||
w.Write(encodedSuccessResponse)
|
writeSuccessResponse(w, encodedSuccessResponse)
|
||||||
}
|
}
|
||||||
|
|
||||||
// PutObjectPartHandler - Upload part
|
// PutObjectPartHandler - Upload part
|
||||||
@ -326,7 +326,7 @@ func (api CloudStorageAPI) PutObjectPartHandler(w http.ResponseWriter, req *http
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
w.Header().Set("ETag", "\""+calculatedMD5+"\"")
|
w.Header().Set("ETag", "\""+calculatedMD5+"\"")
|
||||||
writeSuccessResponse(w)
|
writeSuccessResponse(w, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
// AbortMultipartUploadHandler - Abort multipart upload
|
// AbortMultipartUploadHandler - Abort multipart upload
|
||||||
@ -412,10 +412,10 @@ func (api CloudStorageAPI) ListObjectPartsHandler(w http.ResponseWriter, req *ht
|
|||||||
}
|
}
|
||||||
response := generateListPartsResponse(objectResourcesMetadata)
|
response := generateListPartsResponse(objectResourcesMetadata)
|
||||||
encodedSuccessResponse := encodeSuccessResponse(response)
|
encodedSuccessResponse := encodeSuccessResponse(response)
|
||||||
// write headers
|
// write headers.
|
||||||
setCommonHeaders(w, len(encodedSuccessResponse))
|
setCommonHeaders(w)
|
||||||
// write body
|
// write success response.
|
||||||
w.Write(encodedSuccessResponse)
|
writeSuccessResponse(w, encodedSuccessResponse)
|
||||||
}
|
}
|
||||||
|
|
||||||
// CompleteMultipartUploadHandler - Complete multipart upload
|
// CompleteMultipartUploadHandler - Complete multipart upload
|
||||||
@ -478,9 +478,9 @@ func (api CloudStorageAPI) CompleteMultipartUploadHandler(w http.ResponseWriter,
|
|||||||
response := generateCompleteMultpartUploadResponse(bucket, object, req.URL.String(), metadata.Md5)
|
response := generateCompleteMultpartUploadResponse(bucket, object, req.URL.String(), metadata.Md5)
|
||||||
encodedSuccessResponse := encodeSuccessResponse(response)
|
encodedSuccessResponse := encodeSuccessResponse(response)
|
||||||
// write headers
|
// write headers
|
||||||
setCommonHeaders(w, len(encodedSuccessResponse))
|
setCommonHeaders(w)
|
||||||
// write body
|
// write success response.
|
||||||
w.Write(encodedSuccessResponse)
|
writeSuccessResponse(w, encodedSuccessResponse)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Delete CloudStorageAPI
|
/// Delete CloudStorageAPI
|
||||||
|
Loading…
Reference in New Issue
Block a user