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:
parent
fbd10bd2f5
commit
828e693f44
@ -21,7 +21,6 @@ import (
|
|||||||
"google.golang.org/api/googleapi"
|
"google.golang.org/api/googleapi"
|
||||||
"net/http"
|
"net/http"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Storage interface {
|
type Storage interface {
|
||||||
@ -329,11 +328,8 @@ func NewGDriveStorage(clientJsonFilepath string, localConfigPath string, basedir
|
|||||||
}
|
}
|
||||||
|
|
||||||
const GDriveRootConfigFile = "root_id.conf"
|
const GDriveRootConfigFile = "root_id.conf"
|
||||||
const GDriveTimeoutTimerInterval = time.Second * 10
|
|
||||||
const GDriveDirectoryMimeType = "application/vnd.google-apps.folder"
|
const GDriveDirectoryMimeType = "application/vnd.google-apps.folder"
|
||||||
|
|
||||||
type gDriveTimeoutReaderWrapper func(io.Reader) io.Reader
|
|
||||||
|
|
||||||
func (s *GDrive) setupRoot() error {
|
func (s *GDrive) setupRoot() error {
|
||||||
rootFileConfig := filepath.Join(s.localConfigPath, GDriveRootConfigFile)
|
rootFileConfig := filepath.Join(s.localConfigPath, GDriveRootConfigFile)
|
||||||
|
|
||||||
@ -366,100 +362,6 @@ func (s *GDrive) setupRoot() error {
|
|||||||
return nil
|
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 {
|
func (s *GDrive) hasChecksum(f *drive.File) bool {
|
||||||
return f.Md5Checksum != ""
|
return f.Md5Checksum != ""
|
||||||
}
|
}
|
||||||
@ -566,16 +468,14 @@ func (s *GDrive) Get(token string, filename string) (reader io.ReadCloser, conte
|
|||||||
contentLength = uint64(fi.Size)
|
contentLength = uint64(fi.Size)
|
||||||
contentType = fi.MimeType
|
contentType = fi.MimeType
|
||||||
|
|
||||||
// Get timeout reader wrapper and context
|
ctx := context.Background()
|
||||||
timeoutReaderWrapper, ctx := s.getTimeoutReaderWrapperContext(time.Duration(GDriveTimeoutTimerInterval))
|
|
||||||
|
|
||||||
var res *http.Response
|
var res *http.Response
|
||||||
res, err = s.service.Files.Get(fileId).Context(ctx).Download()
|
res, err = s.service.Files.Get(fileId).Context(ctx).Download()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
reader = timeoutReaderWrapper(res.Body).(io.ReadCloser)
|
reader = res.Body
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -616,9 +516,6 @@ func (s *GDrive) Put(token string, filename string, reader io.Reader, contentTyp
|
|||||||
dirId = di.Id
|
dirId = di.Id
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wrap reader in timeout reader
|
|
||||||
timeoutReaderWrapper, ctx := s.getTimeoutReaderWrapperContext(time.Duration(GDriveTimeoutTimerInterval))
|
|
||||||
|
|
||||||
// Instantiate empty drive file
|
// Instantiate empty drive file
|
||||||
dst := &drive.File{
|
dst := &drive.File{
|
||||||
Name: filename,
|
Name: filename,
|
||||||
@ -626,7 +523,9 @@ func (s *GDrive) Put(token string, filename string, reader io.Reader, contentTyp
|
|||||||
MimeType: contentType,
|
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 {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user