1
0
mirror of https://github.com/dutchcoders/transfer.sh.git synced 2020-11-18 19:53:40 -08:00

Timeout reader wrapper actually prevents big upload

This commit is contained in:
Andrea Spacca 2018-06-23 13:12:00 +02:00
parent fbd10bd2f5
commit 828e693f44

View File

@ -21,7 +21,6 @@ import (
"google.golang.org/api/googleapi"
"net/http"
"io/ioutil"
"time"
)
type Storage interface {
@ -329,11 +328,8 @@ func NewGDriveStorage(clientJsonFilepath string, localConfigPath string, basedir
}
const GDriveRootConfigFile = "root_id.conf"
const GDriveTimeoutTimerInterval = time.Second * 10
const GDriveDirectoryMimeType = "application/vnd.google-apps.folder"
type gDriveTimeoutReaderWrapper func(io.Reader) io.Reader
func (s *GDrive) setupRoot() error {
rootFileConfig := filepath.Join(s.localConfigPath, GDriveRootConfigFile)
@ -366,100 +362,6 @@ func (s *GDrive) setupRoot() error {
return nil
}
func (s *GDrive) getTimeoutReader(r io.Reader, cancel context.CancelFunc, timeout time.Duration) io.Reader {
return &GDriveTimeoutReader{
reader: r,
cancel: cancel,
mutex: &sync.Mutex{},
maxIdleTimeout: timeout,
}
}
type GDriveTimeoutReader struct {
reader io.Reader
cancel context.CancelFunc
lastActivity time.Time
timer *time.Timer
mutex *sync.Mutex
maxIdleTimeout time.Duration
done bool
}
func (r *GDriveTimeoutReader) Read(p []byte) (int, error) {
if r.timer == nil {
r.startTimer()
}
r.mutex.Lock()
// Read
n, err := r.reader.Read(p)
r.lastActivity = time.Now()
r.done = (err != nil)
r.mutex.Unlock()
if r.done {
r.stopTimer()
}
return n, err
}
func (r *GDriveTimeoutReader) Close() error {
return r.reader.(io.ReadCloser).Close()
}
func (r *GDriveTimeoutReader) startTimer() {
r.mutex.Lock()
defer r.mutex.Unlock()
if !r.done {
r.timer = time.AfterFunc(GDriveTimeoutTimerInterval, r.timeout)
}
}
func (r *GDriveTimeoutReader) stopTimer() {
r.mutex.Lock()
defer r.mutex.Unlock()
if r.timer != nil {
r.timer.Stop()
}
}
func (r *GDriveTimeoutReader) timeout() {
r.mutex.Lock()
if r.done {
r.mutex.Unlock()
return
}
if time.Since(r.lastActivity) > r.maxIdleTimeout {
r.cancel()
r.mutex.Unlock()
return
}
r.mutex.Unlock()
r.startTimer()
}
func (s *GDrive) getTimeoutReaderWrapperContext(timeout time.Duration) (gDriveTimeoutReaderWrapper, context.Context) {
ctx, cancel := context.WithCancel(context.TODO())
wrapper := func(r io.Reader) io.Reader {
// Return untouched reader if timeout is 0
if timeout == 0 {
return r
}
return s.getTimeoutReader(r, cancel, timeout)
}
return wrapper, ctx
}
func (s *GDrive) hasChecksum(f *drive.File) bool {
return f.Md5Checksum != ""
}
@ -566,16 +468,14 @@ func (s *GDrive) Get(token string, filename string) (reader io.ReadCloser, conte
contentLength = uint64(fi.Size)
contentType = fi.MimeType
// Get timeout reader wrapper and context
timeoutReaderWrapper, ctx := s.getTimeoutReaderWrapperContext(time.Duration(GDriveTimeoutTimerInterval))
ctx := context.Background()
var res *http.Response
res, err = s.service.Files.Get(fileId).Context(ctx).Download()
if err != nil {
return
}
reader = timeoutReaderWrapper(res.Body).(io.ReadCloser)
reader = res.Body
return
}
@ -616,9 +516,6 @@ func (s *GDrive) Put(token string, filename string, reader io.Reader, contentTyp
dirId = di.Id
}
// Wrap reader in timeout reader
timeoutReaderWrapper, ctx := s.getTimeoutReaderWrapperContext(time.Duration(GDriveTimeoutTimerInterval))
// Instantiate empty drive file
dst := &drive.File{
Name: filename,
@ -626,7 +523,9 @@ func (s *GDrive) Put(token string, filename string, reader io.Reader, contentTyp
MimeType: contentType,
}
_, err = s.service.Files.Create(dst).Context(ctx).Media(timeoutReaderWrapper(reader)).Do()
ctx := context.Background()
_, err = s.service.Files.Create(dst).Context(ctx).Media(reader).Do()
if err != nil {
return err
}