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
@ -21,7 +21,6 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
@ -97,51 +96,50 @@ func (fs *FileSystem) Upload(lpath, index string, toEncrypt bool) (string, error
|
||||
list = append(list, entry)
|
||||
}
|
||||
|
||||
cnt := len(list)
|
||||
errors := make([]error, cnt)
|
||||
done := make(chan bool, maxParallelFiles)
|
||||
dcnt := 0
|
||||
awg := &sync.WaitGroup{}
|
||||
errors := make([]error, len(list))
|
||||
sem := make(chan bool, maxParallelFiles)
|
||||
defer close(sem)
|
||||
|
||||
for i, entry := range list {
|
||||
if i >= dcnt+maxParallelFiles {
|
||||
<-done
|
||||
dcnt++
|
||||
}
|
||||
awg.Add(1)
|
||||
go func(i int, entry *manifestTrieEntry, done chan bool) {
|
||||
sem <- true
|
||||
go func(i int, entry *manifestTrieEntry) {
|
||||
defer func() { <-sem }()
|
||||
|
||||
f, err := os.Open(entry.Path)
|
||||
if err == nil {
|
||||
stat, _ := f.Stat()
|
||||
var hash storage.Address
|
||||
var wait func(context.Context) error
|
||||
ctx := context.TODO()
|
||||
hash, wait, err = fs.api.fileStore.Store(ctx, f, stat.Size(), toEncrypt)
|
||||
if hash != nil {
|
||||
list[i].Hash = hash.Hex()
|
||||
}
|
||||
err = wait(ctx)
|
||||
awg.Done()
|
||||
if err == nil {
|
||||
first512 := make([]byte, 512)
|
||||
fread, _ := f.ReadAt(first512, 0)
|
||||
if fread > 0 {
|
||||
mimeType := http.DetectContentType(first512[:fread])
|
||||
if filepath.Ext(entry.Path) == ".css" {
|
||||
mimeType = "text/css"
|
||||
}
|
||||
list[i].ContentType = mimeType
|
||||
}
|
||||
}
|
||||
f.Close()
|
||||
if err != nil {
|
||||
errors[i] = err
|
||||
return
|
||||
}
|
||||
errors[i] = err
|
||||
done <- true
|
||||
}(i, entry, done)
|
||||
defer f.Close()
|
||||
|
||||
stat, err := f.Stat()
|
||||
if err != nil {
|
||||
errors[i] = err
|
||||
return
|
||||
}
|
||||
|
||||
var hash storage.Address
|
||||
var wait func(context.Context) error
|
||||
ctx := context.TODO()
|
||||
hash, wait, err = fs.api.fileStore.Store(ctx, f, stat.Size(), toEncrypt)
|
||||
if hash != nil {
|
||||
list[i].Hash = hash.Hex()
|
||||
}
|
||||
if err := wait(ctx); err != nil {
|
||||
errors[i] = err
|
||||
return
|
||||
}
|
||||
|
||||
list[i].ContentType, err = DetectContentType(f.Name(), f)
|
||||
if err != nil {
|
||||
errors[i] = err
|
||||
return
|
||||
}
|
||||
|
||||
}(i, entry)
|
||||
}
|
||||
for dcnt < cnt {
|
||||
<-done
|
||||
dcnt++
|
||||
for i := 0; i < cap(sem); i++ {
|
||||
sem <- true
|
||||
}
|
||||
|
||||
trie := &manifestTrie{
|
||||
@ -168,7 +166,6 @@ func (fs *FileSystem) Upload(lpath, index string, toEncrypt bool) (string, error
|
||||
if err2 == nil {
|
||||
hs = trie.ref.Hex()
|
||||
}
|
||||
awg.Wait()
|
||||
return hs, err2
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user