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
This commit is contained in:
committed by
Anton Evangelatov
parent
b69942befe
commit
dc5d643bb5
@ -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
|
||||
}
|
||||
|
Reference in New Issue
Block a user