fs: ListObjects should populate ETag properly if fs.json is available. (#2480)

Fixes #2470
master
Harshavardhana 8 years ago committed by GitHub
parent cb77586508
commit 810dcbf34b
  1. 1
      fs-v1-multipart.go
  2. 33
      fs-v1.go
  3. 3
      web-handlers.go
  4. 3
      xl-v1-multipart.go
  5. 4
      xl-v1-object.go

@ -219,6 +219,7 @@ func (fs fsObjects) ListMultipartUploads(bucket, prefix, keyMarker, uploadIDMark
func (fs fsObjects) newMultipartUpload(bucket string, object string, meta map[string]string) (uploadID string, err error) { func (fs fsObjects) newMultipartUpload(bucket string, object string, meta map[string]string) (uploadID string, err error) {
// Initialize `fs.json` values. // Initialize `fs.json` values.
fsMeta := newFSMetaV1() fsMeta := newFSMetaV1()
// Save additional metadata only if extended headers such as "X-Amz-Meta-" are set. // Save additional metadata only if extended headers such as "X-Amz-Meta-" are set.
if hasExtendedHeader(meta) { if hasExtendedHeader(meta) {
fsMeta.Meta = meta fsMeta.Meta = meta

@ -23,7 +23,6 @@ import (
"io" "io"
"os" "os"
"path" "path"
"path/filepath"
"sort" "sort"
"strings" "strings"
@ -336,7 +335,7 @@ func (fs fsObjects) GetObjectInfo(bucket, object string) (ObjectInfo, error) {
// Guess content-type from the extension if possible. // Guess content-type from the extension if possible.
if fsMeta.Meta["content-type"] == "" { if fsMeta.Meta["content-type"] == "" {
if objectExt := filepath.Ext(object); objectExt != "" { if objectExt := path.Ext(object); objectExt != "" {
if content, ok := mimedb.DB[strings.ToLower(strings.TrimPrefix(objectExt, "."))]; ok { if content, ok := mimedb.DB[strings.ToLower(strings.TrimPrefix(objectExt, "."))]; ok {
fsMeta.Meta["content-type"] = content.ContentType fsMeta.Meta["content-type"] = content.ContentType
} }
@ -369,6 +368,10 @@ func (fs fsObjects) PutObject(bucket string, object string, size int64, data io.
Object: object, Object: object,
} }
} }
// No metadata is set, allocate a new one.
if metadata == nil {
metadata = make(map[string]string)
}
uniqueID := getUUID() uniqueID := getUUID()
@ -419,10 +422,9 @@ func (fs fsObjects) PutObject(bucket string, object string, size int64, data io.
} }
newMD5Hex := hex.EncodeToString(md5Writer.Sum(nil)) newMD5Hex := hex.EncodeToString(md5Writer.Sum(nil))
// md5Hex representation. // Update the md5sum if not set with the newly calculated one.
var md5Hex string if len(metadata["md5Sum"]) == 0 {
if len(metadata) != 0 { metadata["md5Sum"] = newMD5Hex
md5Hex = metadata["md5Sum"]
} }
// Validate if payload is valid. // Validate if payload is valid.
@ -435,6 +437,8 @@ func (fs fsObjects) PutObject(bucket string, object string, size int64, data io.
} }
} }
// md5Hex representation.
md5Hex := metadata["md5Sum"]
if md5Hex != "" { if md5Hex != "" {
if newMD5Hex != md5Hex { if newMD5Hex != md5Hex {
// MD5 mismatch, delete the temporary object. // MD5 mismatch, delete the temporary object.
@ -505,7 +509,9 @@ func isBucketExist(storage StorageAPI, bucketName string) bool {
return true return true
} }
func (fs fsObjects) listObjects(bucket, prefix, marker, delimiter string, maxKeys int) (ListObjectsInfo, error) { // ListObjects - list all objects at prefix upto maxKeys., optionally delimited by '/'. Maintains the list pool
// state for future re-entrant list requests.
func (fs fsObjects) ListObjects(bucket, prefix, marker, delimiter string, maxKeys int) (ListObjectsInfo, error) {
// Convert entry to FileInfo // Convert entry to FileInfo
entryToFileInfo := func(entry string) (fileInfo FileInfo, err error) { entryToFileInfo := func(entry string) (fileInfo FileInfo, err error) {
if strings.HasSuffix(entry, slashSeparator) { if strings.HasSuffix(entry, slashSeparator) {
@ -517,8 +523,16 @@ func (fs fsObjects) listObjects(bucket, prefix, marker, delimiter string, maxKey
if fileInfo, err = fs.storage.StatFile(bucket, entry); err != nil { if fileInfo, err = fs.storage.StatFile(bucket, entry); err != nil {
return return
} }
fsMeta, mErr := readFSMetadata(fs.storage, minioMetaBucket, path.Join(bucketMetaPrefix, bucket, entry))
if mErr != nil && mErr != errFileNotFound {
return FileInfo{}, mErr
}
if len(fsMeta.Meta) == 0 {
fsMeta.Meta = make(map[string]string)
}
// Object name needs to be full path. // Object name needs to be full path.
fileInfo.Name = entry fileInfo.Name = entry
fileInfo.MD5Sum = fsMeta.Meta["md5Sum"]
return return
} }
@ -640,11 +654,6 @@ func (fs fsObjects) listObjects(bucket, prefix, marker, delimiter string, maxKey
return result, nil return result, nil
} }
// ListObjects - list all objects.
func (fs fsObjects) ListObjects(bucket, prefix, marker, delimiter string, maxKeys int) (ListObjectsInfo, error) {
return fs.listObjects(bucket, prefix, marker, delimiter, maxKeys)
}
// HealObject - no-op for fs. Valid only for XL. // HealObject - no-op for fs. Valid only for XL.
func (fs fsObjects) HealObject(bucket, object string) error { func (fs fsObjects) HealObject(bucket, object string) error {
return NotImplemented{} return NotImplemented{}

@ -21,7 +21,6 @@ import (
"net/http" "net/http"
"os" "os"
"path" "path"
"path/filepath"
"runtime" "runtime"
"strconv" "strconv"
"time" "time"
@ -430,7 +429,7 @@ func (web *webAPIHandlers) Download(w http.ResponseWriter, r *http.Request) {
return return
} }
// Add content disposition. // Add content disposition.
w.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=\"%s\"", filepath.Base(object))) w.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=\"%s\"", path.Base(object)))
objInfo, err := web.ObjectAPI.GetObjectInfo(bucket, object) objInfo, err := web.ObjectAPI.GetObjectInfo(bucket, object)
if err != nil { if err != nil {

@ -23,7 +23,6 @@ import (
"io" "io"
"io/ioutil" "io/ioutil"
"path" "path"
"path/filepath"
"strings" "strings"
"time" "time"
@ -259,7 +258,7 @@ func (xl xlObjects) newMultipartUpload(bucket string, object string, meta map[st
// If not set default to "application/octet-stream" // If not set default to "application/octet-stream"
if meta["content-type"] == "" { if meta["content-type"] == "" {
contentType := "application/octet-stream" contentType := "application/octet-stream"
if objectExt := filepath.Ext(object); objectExt != "" { if objectExt := path.Ext(object); objectExt != "" {
content, ok := mimedb.DB[strings.ToLower(strings.TrimPrefix(objectExt, "."))] content, ok := mimedb.DB[strings.ToLower(strings.TrimPrefix(objectExt, "."))]
if ok { if ok {
contentType = content.ContentType contentType = content.ContentType

@ -21,7 +21,6 @@ import (
"encoding/hex" "encoding/hex"
"io" "io"
"path" "path"
"path/filepath"
"strings" "strings"
"sync" "sync"
"time" "time"
@ -498,6 +497,7 @@ func (xl xlObjects) PutObject(bucket string, object string, size int64, data io.
if metadata == nil { if metadata == nil {
metadata = make(map[string]string) metadata = make(map[string]string)
} }
uniqueID := getUUID() uniqueID := getUUID()
tempErasureObj := path.Join(tmpMetaPrefix, uniqueID, "part.1") tempErasureObj := path.Join(tmpMetaPrefix, uniqueID, "part.1")
minioMetaTmpBucket := path.Join(minioMetaBucket, tmpMetaPrefix) minioMetaTmpBucket := path.Join(minioMetaBucket, tmpMetaPrefix)
@ -581,7 +581,7 @@ func (xl xlObjects) PutObject(bucket string, object string, size int64, data io.
// Guess content-type from the extension if possible. // Guess content-type from the extension if possible.
if metadata["content-type"] == "" { if metadata["content-type"] == "" {
if objectExt := filepath.Ext(object); objectExt != "" { if objectExt := path.Ext(object); objectExt != "" {
if content, ok := mimedb.DB[strings.ToLower(strings.TrimPrefix(objectExt, "."))]; ok { if content, ok := mimedb.DB[strings.ToLower(strings.TrimPrefix(objectExt, "."))]; ok {
metadata["content-type"] = content.ContentType metadata["content-type"] = content.ContentType
} }

Loading…
Cancel
Save