contentType: Reply back proper contentTypes based on the file extension.

Currently the server would set 'application/octet-stream' for all
objects, set this value based on the file extension transparently.

This is useful in case of minio browser to facilitate displaying
proper icons for the different mime data types.
master
Harshavardhana 9 years ago
parent 23ca11f75b
commit 0aedb67de0
  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
lastModified := metadata.Created.Format(http.TimeFormat)
// object related headers
w.Header().Set("Content-Type", "application/octet-stream")
w.Header().Set("Content-Type", metadata.ContentType)
if 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.LastModified = object.Created.Format(rfcFormat)
content.ETag = "\"" + object.Md5 + "\""
if object.Md5 != "" {
content.ETag = "\"" + object.Md5 + "\""
}
content.Size = object.Size
content.StorageClass = "STANDARD"
content.Owner = owner

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

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

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

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

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

@ -51,6 +51,8 @@ type ObjectInfo struct {
LastModified time.Time `json:"lastModified"`
// Size in bytes of the object.
Size int64 `json:"size"`
// ContentType is mime type of the object.
ContentType string `json:"contentType"`
}
// 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 {
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{
Key: object.Key,
LastModified: object.LastModified,
Size: object.Size,
Key: objectInfo.Key,
LastModified: objectInfo.LastModified,
Size: objectInfo.Size,
ContentType: objectInfo.ContentType,
})
}
return nil

Loading…
Cancel
Save