diff options
author | Alexey Sharov <www.pismeco@gmail.com> | 2018-10-01 19:39:39 +0800 |
---|---|---|
committer | Anton Evangelatov <anton.evangelatov@gmail.com> | 2018-10-01 19:39:39 +0800 |
commit | dc5d643bb59812cda578fac941c2f1da316bc9d7 (patch) | |
tree | 7405f387672f0548eb4734a93581780c96cee7a9 /swarm/api/api.go | |
parent | b69942befeb9f1af55cad0f91953bdaea2ea3efb (diff) | |
download | dexon-dc5d643bb59812cda578fac941c2f1da316bc9d7.tar dexon-dc5d643bb59812cda578fac941c2f1da316bc9d7.tar.gz dexon-dc5d643bb59812cda578fac941c2f1da316bc9d7.tar.bz2 dexon-dc5d643bb59812cda578fac941c2f1da316bc9d7.tar.lz dexon-dc5d643bb59812cda578fac941c2f1da316bc9d7.tar.xz dexon-dc5d643bb59812cda578fac941c2f1da316bc9d7.tar.zst dexon-dc5d643bb59812cda578fac941c2f1da316bc9d7.zip |
cmd/swarm, swarm: cross-platform Content-Type detection (#17782)
- Mime types generator (Standard "mime" package rely on system-settings, see mime.osInitMime)
- Changed swarm/api.Upload:
- simplify I/O throttling by semaphore primitive and use file name where possible
- f.Close() must be called in Defer - otherwise panic or future added early return will cause leak of file descriptors
- one error was suppressed
Diffstat (limited to 'swarm/api/api.go')
-rw-r--r-- | swarm/api/api.go | 51 |
1 files changed, 46 insertions, 5 deletions
diff --git a/swarm/api/api.go b/swarm/api/api.go index 70c12a757..7b8f04c13 100644 --- a/swarm/api/api.go +++ b/swarm/api/api.go @@ -16,6 +16,9 @@ package api +//go:generate mimegen --types=./../../cmd/swarm/mimegen/mime.types --package=api --out=gen_mime.go +//go:generate gofmt -s -w gen_mime.go + import ( "archive/tar" "context" @@ -29,8 +32,6 @@ import ( "path" "strings" - "github.com/ethereum/go-ethereum/swarm/storage/mru/lookup" - "bytes" "mime" "path/filepath" @@ -45,7 +46,8 @@ import ( "github.com/ethereum/go-ethereum/swarm/spancontext" "github.com/ethereum/go-ethereum/swarm/storage" "github.com/ethereum/go-ethereum/swarm/storage/mru" - opentracing "github.com/opentracing/opentracing-go" + "github.com/ethereum/go-ethereum/swarm/storage/mru/lookup" + "github.com/opentracing/opentracing-go" ) var ( @@ -757,9 +759,14 @@ func (a *API) UploadTar(ctx context.Context, bodyReader io.ReadCloser, manifestP // add the entry under the path from the request manifestPath := path.Join(manifestPath, hdr.Name) + contentType := hdr.Xattrs["user.swarm.content-type"] + if contentType == "" { + contentType = mime.TypeByExtension(filepath.Ext(hdr.Name)) + } + //DetectContentType("") entry := &ManifestEntry{ Path: manifestPath, - ContentType: hdr.Xattrs["user.swarm.content-type"], + ContentType: contentType, Mode: hdr.Mode, Size: hdr.Size, ModTime: hdr.ModTime, @@ -770,10 +777,15 @@ func (a *API) UploadTar(ctx context.Context, bodyReader io.ReadCloser, manifestP return nil, fmt.Errorf("error adding manifest entry from tar stream: %s", err) } if hdr.Name == defaultPath { + contentType := hdr.Xattrs["user.swarm.content-type"] + if contentType == "" { + contentType = mime.TypeByExtension(filepath.Ext(hdr.Name)) + } + entry := &ManifestEntry{ Hash: contentKey.Hex(), Path: "", // default entry - ContentType: hdr.Xattrs["user.swarm.content-type"], + ContentType: contentType, Mode: hdr.Mode, Size: hdr.Size, ModTime: hdr.ModTime, @@ -1033,3 +1045,32 @@ func (a *API) ResolveResourceView(ctx context.Context, uri *URI, values mru.Valu } return view, nil } + +// MimeOctetStream default value of http Content-Type header +const MimeOctetStream = "application/octet-stream" + +// DetectContentType by file file extension, or fallback to content sniff +func DetectContentType(fileName string, f io.ReadSeeker) (string, error) { + ctype := mime.TypeByExtension(filepath.Ext(fileName)) + if ctype != "" { + return ctype, nil + } + + // save/rollback to get content probe from begin of file + currentPosition, err := f.Seek(0, io.SeekCurrent) + if err != nil { + return MimeOctetStream, fmt.Errorf("seeker can't seek, %s", err) + } + + // read a chunk to decide between utf-8 text and binary + var buf [512]byte + n, _ := f.Read(buf[:]) + ctype = http.DetectContentType(buf[:n]) + + _, err = f.Seek(currentPosition, io.SeekStart) // rewind to output whole file + if err != nil { + return MimeOctetStream, fmt.Errorf("seeker can't seek, %s", err) + } + + return ctype, nil +} |