Merge pull request #1069 from harshavardhana/list-objects

contentType: Reply back proper contentTypes based on the file extension.
master
Harshavardhana 9 years ago
commit 9dfce111d9
  1. 2
      api-headers.go
  2. 4
      api-response.go
  3. 4
      bucket-handlers.go
  4. 8
      object-handlers.go
  5. 7
      pkg/fs/fs-multipart.go
  6. 10
      pkg/fs/fs-object.go
  7. 4
      pkg/fs/fs.go
  8. 2
      web-definitions.go
  9. 14
      web-handlers.go

@ -78,7 +78,7 @@ func setObjectHeaders(w http.ResponseWriter, metadata fs.ObjectMetadata, content
// set object headers // set object headers
lastModified := metadata.Created.Format(http.TimeFormat) lastModified := metadata.Created.Format(http.TimeFormat)
// object related headers // object related headers
w.Header().Set("Content-Type", "application/octet-stream") w.Header().Set("Content-Type", metadata.ContentType)
if metadata.Md5 != "" { if metadata.Md5 != "" {
w.Header().Set("ETag", "\""+metadata.Md5+"\"") w.Header().Set("ETag", "\""+metadata.Md5+"\"")
} }

@ -108,7 +108,9 @@ func generateListObjectsResponse(bucket, prefix, marker, delimiter string, maxKe
} }
content.Key = object.Object content.Key = object.Object
content.LastModified = object.Created.Format(rfcFormat) content.LastModified = object.Created.Format(rfcFormat)
content.ETag = "\"" + object.Md5 + "\"" if object.Md5 != "" {
content.ETag = "\"" + object.Md5 + "\""
}
content.Size = object.Size content.Size = object.Size
content.StorageClass = "STANDARD" content.StorageClass = "STANDARD"
content.Owner = owner content.Owner = owner

@ -361,7 +361,9 @@ func (api CloudStorageAPI) PostPolicyBucketHandler(w http.ResponseWriter, req *h
} }
return return
} }
w.Header().Set("ETag", "\""+metadata.Md5+"\"") if metadata.Md5 != "" {
w.Header().Set("ETag", "\""+metadata.Md5+"\"")
}
writeSuccessResponse(w, nil) writeSuccessResponse(w, nil)
} }

@ -204,7 +204,9 @@ func (api CloudStorageAPI) PutObjectHandler(w http.ResponseWriter, req *http.Req
} }
return return
} }
w.Header().Set("ETag", "\""+metadata.Md5+"\"") if metadata.Md5 != "" {
w.Header().Set("ETag", "\""+metadata.Md5+"\"")
}
writeSuccessResponse(w, nil) writeSuccessResponse(w, nil)
} }
@ -347,7 +349,9 @@ func (api CloudStorageAPI) PutObjectPartHandler(w http.ResponseWriter, req *http
} }
return return
} }
w.Header().Set("ETag", "\""+calculatedMD5+"\"") if calculatedMD5 != "" {
w.Header().Set("ETag", "\""+calculatedMD5+"\"")
}
writeSuccessResponse(w, nil) writeSuccessResponse(w, nil)
} }

@ -38,6 +38,7 @@ import (
"github.com/minio/minio-xl/pkg/crypto/sha256" "github.com/minio/minio-xl/pkg/crypto/sha256"
"github.com/minio/minio-xl/pkg/crypto/sha512" "github.com/minio/minio-xl/pkg/crypto/sha512"
"github.com/minio/minio-xl/pkg/probe" "github.com/minio/minio-xl/pkg/probe"
"github.com/minio/minio/pkg/contentdb"
"github.com/minio/minio/pkg/disk" "github.com/minio/minio/pkg/disk"
) )
@ -432,12 +433,16 @@ func (fs Filesystem) CompleteMultipartUpload(bucket, object, uploadID string, da
if err != nil { if err != nil {
return ObjectMetadata{}, probe.NewError(err) return ObjectMetadata{}, probe.NewError(err)
} }
contentType := "application/octet-stream"
if objectExt := filepath.Ext(objectPath); objectExt != "" {
contentType = contentdb.MustLookup(strings.TrimPrefix(objectExt, "."))
}
newObject := ObjectMetadata{ newObject := ObjectMetadata{
Bucket: bucket, Bucket: bucket,
Object: object, Object: object,
Created: st.ModTime(), Created: st.ModTime(),
Size: st.Size(), Size: st.Size(),
ContentType: "application/octet-stream", ContentType: contentType,
Md5: hex.EncodeToString(h.Sum(nil)), Md5: hex.EncodeToString(h.Sum(nil)),
} }
return newObject, nil return newObject, nil

@ -32,6 +32,7 @@ import (
"github.com/minio/minio-xl/pkg/atomic" "github.com/minio/minio-xl/pkg/atomic"
"github.com/minio/minio-xl/pkg/crypto/sha256" "github.com/minio/minio-xl/pkg/crypto/sha256"
"github.com/minio/minio-xl/pkg/probe" "github.com/minio/minio-xl/pkg/probe"
"github.com/minio/minio/pkg/contentdb"
"github.com/minio/minio/pkg/disk" "github.com/minio/minio/pkg/disk"
) )
@ -153,6 +154,9 @@ func getMetadata(rootPath, bucket, object string) (ObjectMetadata, *probe.Error)
if runtime.GOOS == "windows" { if runtime.GOOS == "windows" {
object = sanitizeWindowsPath(object) object = sanitizeWindowsPath(object)
} }
if objectExt := filepath.Ext(object); objectExt != "" {
contentType = contentdb.MustLookup(strings.TrimPrefix(objectExt, "."))
}
metadata := ObjectMetadata{ metadata := ObjectMetadata{
Bucket: bucket, Bucket: bucket,
Object: object, Object: object,
@ -279,12 +283,16 @@ func (fs Filesystem) CreateObject(bucket, object, expectedMD5Sum string, size in
if err != nil { if err != nil {
return ObjectMetadata{}, probe.NewError(err) return ObjectMetadata{}, probe.NewError(err)
} }
contentType := "application/octet-stream"
if objectExt := filepath.Ext(objectPath); objectExt != "" {
contentType = contentdb.MustLookup(strings.TrimPrefix(objectExt, "."))
}
newObject := ObjectMetadata{ newObject := ObjectMetadata{
Bucket: bucket, Bucket: bucket,
Object: object, Object: object,
Created: st.ModTime(), Created: st.ModTime(),
Size: st.Size(), Size: st.Size(),
ContentType: "application/octet-stream", ContentType: contentType,
Md5: md5Sum, Md5: md5Sum,
} }
return newObject, nil return newObject, nil

@ -23,6 +23,7 @@ import (
"time" "time"
"github.com/minio/minio-xl/pkg/probe" "github.com/minio/minio-xl/pkg/probe"
"github.com/minio/minio/pkg/contentdb"
) )
// Filesystem - local variables // Filesystem - local variables
@ -79,6 +80,9 @@ func New(rootPath string) (Filesystem, *probe.Error) {
return Filesystem{}, err.Trace() return Filesystem{}, err.Trace()
} }
} }
// Initialize content db.
contentdb.Init()
var buckets *Buckets var buckets *Buckets
buckets, err = loadBucketsMetadata() buckets, err = loadBucketsMetadata()
if err != nil { if err != nil {

@ -51,6 +51,8 @@ type ObjectInfo struct {
LastModified time.Time `json:"lastModified"` LastModified time.Time `json:"lastModified"`
// Size in bytes of the object. // Size in bytes of the object.
Size int64 `json:"size"` Size int64 `json:"size"`
// ContentType is mime type of the object.
ContentType string `json:"contentType"`
} }
// PutObjectURLArgs - args to generate url for upload access. // PutObjectURLArgs - args to generate url for upload access.

@ -95,10 +95,18 @@ func (web *WebAPI) ListObjects(r *http.Request, args *ListObjectsArgs, reply *[]
if object.Err != nil { if object.Err != nil {
return object.Err return object.Err
} }
// TODO - This can get slower for large directories, we can
// perhaps extend the ListObjects XML to reply back
// ContentType as well.
objectInfo, e := web.Client.StatObject(args.BucketName, object.Key)
if e != nil {
return e
}
*reply = append(*reply, ObjectInfo{ *reply = append(*reply, ObjectInfo{
Key: object.Key, Key: objectInfo.Key,
LastModified: object.LastModified, LastModified: objectInfo.LastModified,
Size: object.Size, Size: objectInfo.Size,
ContentType: objectInfo.ContentType,
}) })
} }
return nil return nil

Loading…
Cancel
Save