aboutsummaryrefslogtreecommitdiffstats
path: root/swarm/api/api.go
diff options
context:
space:
mode:
authorAlexey Sharov <www.pismeco@gmail.com>2018-10-01 19:39:39 +0800
committerAnton Evangelatov <anton.evangelatov@gmail.com>2018-10-01 19:39:39 +0800
commitdc5d643bb59812cda578fac941c2f1da316bc9d7 (patch)
tree7405f387672f0548eb4734a93581780c96cee7a9 /swarm/api/api.go
parentb69942befeb9f1af55cad0f91953bdaea2ea3efb (diff)
downloaddexon-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.go51
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
+}