HEAD on an object should mimic GET without body (#6508)

Add "Range" header support etc.
master
Harshavardhana 6 years ago committed by Nitish Tiwari
parent df60b3c733
commit 48bfebe442
  1. 6
      cmd/encryption-v1_test.go
  2. 87
      cmd/object-handlers.go

@ -632,7 +632,7 @@ func TestGetDecryptedRange(t *testing.T) {
if err != nil { if err != nil {
t.Errorf("Case %d: unexpected err: %v", i, err) t.Errorf("Case %d: unexpected err: %v", i, err)
} }
var rLen int64 = pkgSz + 32 var rLen = pkgSz + 32
if test.decSz < pkgSz { if test.decSz < pkgSz {
rLen = test.decSz + 32 rLen = test.decSz + 32
} }
@ -648,7 +648,7 @@ func TestGetDecryptedRange(t *testing.T) {
if err != nil { if err != nil {
t.Errorf("Case %d: unexpected err: %v", i, err) t.Errorf("Case %d: unexpected err: %v", i, err)
} }
var rLen int64 = (pkgSz + 32) * 2 var rLen = (pkgSz + 32) * 2
if test.decSz < 2*pkgSz { if test.decSz < 2*pkgSz {
rLen = (pkgSz + 32) + (test.decSz - pkgSz + 32) rLen = (pkgSz + 32) + (test.decSz - pkgSz + 32)
} }
@ -663,7 +663,7 @@ func TestGetDecryptedRange(t *testing.T) {
if err != nil { if err != nil {
t.Errorf("Case %d: unexpected err: %v", i, err) t.Errorf("Case %d: unexpected err: %v", i, err)
} }
var rLen int64 = (pkgSz + 32) * 2 var rLen = (pkgSz + 32) * 2
if test.decSz-pkgSz < 2*pkgSz { if test.decSz-pkgSz < 2*pkgSz {
rLen = (pkgSz + 32) + (test.decSz - pkgSz + 32*2) rLen = (pkgSz + 32) + (test.decSz - pkgSz + 32*2)
} }

@ -217,12 +217,14 @@ func (api objectAPIHandlers) SelectObjectContentHandler(w http.ResponseWriter, r
// Set encryption response headers // Set encryption response headers
if objectAPI.IsEncryptionSupported() { if objectAPI.IsEncryptionSupported() {
switch { if crypto.IsEncrypted(objInfo.UserDefined) {
case crypto.S3.IsEncrypted(objInfo.UserDefined): switch {
w.Header().Set(crypto.SSEHeader, crypto.SSEAlgorithmAES256) case crypto.S3.IsEncrypted(objInfo.UserDefined):
case crypto.IsEncrypted(objInfo.UserDefined): w.Header().Set(crypto.SSEHeader, crypto.SSEAlgorithmAES256)
w.Header().Set(crypto.SSECAlgorithm, r.Header.Get(crypto.SSECAlgorithm)) case crypto.SSEC.IsEncrypted(objInfo.UserDefined):
w.Header().Set(crypto.SSECKeyMD5, r.Header.Get(crypto.SSECKeyMD5)) w.Header().Set(crypto.SSECAlgorithm, r.Header.Get(crypto.SSECAlgorithm))
w.Header().Set(crypto.SSECKeyMD5, r.Header.Get(crypto.SSECKeyMD5))
}
} }
} }
@ -345,7 +347,6 @@ func (api objectAPIHandlers) GetObjectHandler(w http.ResponseWriter, r *http.Req
return return
} }
// log the error.
logger.LogIf(ctx, err) logger.LogIf(ctx, err)
} }
} }
@ -372,12 +373,14 @@ func (api objectAPIHandlers) GetObjectHandler(w http.ResponseWriter, r *http.Req
// Set encryption response headers // Set encryption response headers
if objectAPI.IsEncryptionSupported() { if objectAPI.IsEncryptionSupported() {
switch { if crypto.IsEncrypted(objInfo.UserDefined) {
case crypto.S3.IsEncrypted(objInfo.UserDefined): switch {
w.Header().Set(crypto.SSEHeader, crypto.SSEAlgorithmAES256) case crypto.S3.IsEncrypted(objInfo.UserDefined):
case crypto.IsEncrypted(objInfo.UserDefined): w.Header().Set(crypto.SSEHeader, crypto.SSEAlgorithmAES256)
w.Header().Set(crypto.SSECAlgorithm, r.Header.Get(crypto.SSECAlgorithm)) case crypto.SSEC.IsEncrypted(objInfo.UserDefined):
w.Header().Set(crypto.SSECKeyMD5, r.Header.Get(crypto.SSECKeyMD5)) w.Header().Set(crypto.SSECAlgorithm, r.Header.Get(crypto.SSECAlgorithm))
w.Header().Set(crypto.SSECKeyMD5, r.Header.Get(crypto.SSECKeyMD5))
}
} }
} }
@ -487,22 +490,44 @@ func (api objectAPIHandlers) HeadObjectHandler(w http.ResponseWriter, r *http.Re
return return
} }
// Get request range.
var rs *HTTPRangeSpec
rangeHeader := r.Header.Get("Range")
if rangeHeader != "" {
var err error
if rs, err = parseRequestRangeSpec(rangeHeader); err != nil {
// Handle only errInvalidRange. Ignore other
// parse error and treat it as regular Get
// request like Amazon S3.
if err == errInvalidRange {
writeErrorResponseHeadersOnly(w, ErrInvalidRange)
return
}
logger.LogIf(ctx, err)
}
}
objInfo, err := getObjectInfo(ctx, bucket, object, opts) objInfo, err := getObjectInfo(ctx, bucket, object, opts)
if err != nil { if err != nil {
writeErrorResponseHeadersOnly(w, toAPIErrorCode(err)) writeErrorResponseHeadersOnly(w, toAPIErrorCode(err))
return return
} }
var encrypted bool
if objectAPI.IsEncryptionSupported() { if objectAPI.IsEncryptionSupported() {
if encrypted, err = DecryptObjectInfo(objInfo, r.Header); err != nil { if _, err = DecryptObjectInfo(objInfo, r.Header); err != nil {
writeErrorResponse(w, toAPIErrorCode(err), r.URL) writeErrorResponseHeadersOnly(w, toAPIErrorCode(err))
return return
} else if encrypted { }
s3Encrypted := crypto.S3.IsEncrypted(objInfo.UserDefined) }
if s3Encrypted {
// Set encryption response headers
if objectAPI.IsEncryptionSupported() {
if crypto.IsEncrypted(objInfo.UserDefined) {
switch {
case crypto.S3.IsEncrypted(objInfo.UserDefined):
w.Header().Set(crypto.SSEHeader, crypto.SSEAlgorithmAES256) w.Header().Set(crypto.SSEHeader, crypto.SSEAlgorithmAES256)
} else { case crypto.SSEC.IsEncrypted(objInfo.UserDefined):
w.Header().Set(crypto.SSECAlgorithm, r.Header.Get(crypto.SSECAlgorithm)) w.Header().Set(crypto.SSECAlgorithm, r.Header.Get(crypto.SSECAlgorithm))
w.Header().Set(crypto.SSECKeyMD5, r.Header.Get(crypto.SSECKeyMD5)) w.Header().Set(crypto.SSECKeyMD5, r.Header.Get(crypto.SSECKeyMD5))
} }
@ -515,7 +540,7 @@ func (api objectAPIHandlers) HeadObjectHandler(w http.ResponseWriter, r *http.Re
} }
// Set standard object headers. // Set standard object headers.
if hErr := setObjectHeaders(w, objInfo, nil); hErr != nil { if hErr := setObjectHeaders(w, objInfo, rs); hErr != nil {
writeErrorResponse(w, toAPIErrorCode(hErr), r.URL) writeErrorResponse(w, toAPIErrorCode(hErr), r.URL)
return return
} }
@ -524,7 +549,11 @@ func (api objectAPIHandlers) HeadObjectHandler(w http.ResponseWriter, r *http.Re
setHeadGetRespHeaders(w, r.URL.Query()) setHeadGetRespHeaders(w, r.URL.Query())
// Successful response. // Successful response.
w.WriteHeader(http.StatusOK) if rs != nil {
w.WriteHeader(http.StatusPartialContent)
} else {
w.WriteHeader(http.StatusOK)
}
// Get host and port from Request.RemoteAddr. // Get host and port from Request.RemoteAddr.
host, port, err := net.SplitHostPort(handlers.GetSourceIP(r)) host, port, err := net.SplitHostPort(handlers.GetSourceIP(r))
@ -1064,12 +1093,14 @@ func (api objectAPIHandlers) PutObjectHandler(w http.ResponseWriter, r *http.Req
w.Header().Set("ETag", "\""+objInfo.ETag+"\"") w.Header().Set("ETag", "\""+objInfo.ETag+"\"")
if objectAPI.IsEncryptionSupported() { if objectAPI.IsEncryptionSupported() {
if crypto.S3.IsEncrypted(objInfo.UserDefined) { if crypto.IsEncrypted(objInfo.UserDefined) {
w.Header().Set(crypto.SSEHeader, crypto.SSEAlgorithmAES256) switch {
} case crypto.S3.IsEncrypted(objInfo.UserDefined):
if crypto.SSEC.IsRequested(r.Header) { w.Header().Set(crypto.SSEHeader, crypto.SSEAlgorithmAES256)
w.Header().Set(crypto.SSECAlgorithm, r.Header.Get(crypto.SSECAlgorithm)) case crypto.SSEC.IsRequested(r.Header):
w.Header().Set(crypto.SSECKeyMD5, r.Header.Get(crypto.SSECKeyMD5)) w.Header().Set(crypto.SSECAlgorithm, r.Header.Get(crypto.SSECAlgorithm))
w.Header().Set(crypto.SSECKeyMD5, r.Header.Get(crypto.SSECKeyMD5))
}
} }
} }

Loading…
Cancel
Save