Browse Source

More reliable basedire ownership

pull/118/head
Andrea Spacca 6 years ago
parent
commit
028bcb62de
3 changed files with 58 additions and 41 deletions
  1. +1
    -0
      README.md
  2. +9
    -2
      cmd/cmd.go
  3. +48
    -39
      server/storage.go

+ 1
- 0
README.md View File

@@ -52,6 +52,7 @@ aws-secret-key | aws access key | | AWS_SECRET_KEY
bucket | aws bucket | | BUCKET
basedir | path storage for local/gdrive provider| |
gdrive-client-json-filepath | path to client json config for gdrive provider| |
gdrive-local-config-path | path to local transfer.sh config cache for gdrive provider| |
lets-encrypt-hosts | hosts to use for lets encrypt certificates (comma seperated) | |
log | path to log file| |



+ 9
- 2
cmd/cmd.go View File

@@ -107,7 +107,12 @@ var globalFlags = []cli.Flag{
Value: "",
EnvVar: "",
},

cli.StringFlag{
Name: "gdrive-local-config-path",
Usage: "",
Value: "",
EnvVar: "",
},
cli.IntFlag{
Name: "rate-limit",
Usage: "requests per minute",
@@ -243,9 +248,11 @@ func New() *Cmd {
case "gdrive":
if clientJsonFilepath := c.String("gdrive-client-json-filepath"); clientJsonFilepath == "" {
panic("client-json-filepath not set.")
} else if localConfigPath := c.String("gdrive-local-config-path"); localConfigPath == "" {
panic("local-config-path not set.")
} else if basedir := c.String("basedir"); basedir == "" {
panic("basedir not set.")
} else if storage, err := server.NewGDriveStorage(clientJsonFilepath, basedir); err != nil {
} else if storage, err := server.NewGDriveStorage(clientJsonFilepath, localConfigPath, basedir); err != nil {
panic(err)
} else {
options = append(options, server.UseStorage(storage))


+ 48
- 39
server/storage.go View File

@@ -297,10 +297,12 @@ func (s *S3Storage) Put(token string, filename string, reader io.Reader, content

type GDrive struct {
service *drive.Service
rootId string
basedir string
localConfigPath string
}

func NewGDriveStorage(clientJsonFilepath string, basedir string) (*GDrive, error) {
func NewGDriveStorage(clientJsonFilepath string, localConfigPath string, basedir string) (*GDrive, error) {
b, err := ioutil.ReadFile(clientJsonFilepath)
if err != nil {
return nil, err
@@ -317,14 +319,53 @@ func NewGDriveStorage(clientJsonFilepath string, basedir string) (*GDrive, error
return nil, err
}

return &GDrive{service: srv, basedir: basedir}, nil
storage := &GDrive{service: srv, basedir: basedir, rootId: "", localConfigPath:localConfigPath}
err = storage.setupRoot()
if err != nil {
return nil, err
}

return storage, nil
}

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)

rootId, err := ioutil.ReadFile(rootFileConfig)
if err != nil && !os.IsNotExist(err) {
return err
}

if string(rootId) != "" {
s.rootId = string(rootId)
return nil
}

dir := &drive.File{
Name: s.basedir,
MimeType: GDriveDirectoryMimeType,
}

di, err := s.service.Files.Create(dir).Fields("id").Do()
if err != nil {
return err
}

s.rootId = di.Id
err = ioutil.WriteFile(rootFileConfig, []byte(s.rootId), os.FileMode(0600))
if err != nil {
return err
}

return nil
}

func (s *GDrive) getTimeoutReader(r io.Reader, cancel context.CancelFunc, timeout time.Duration) io.Reader {
return &GDriveTimeoutReader{
reader: r,
@@ -428,42 +469,15 @@ func (s *GDrive) list(nextPageToken string, q string) (*drive.FileList, error){
}

func (s *GDrive) findId(filename string, token string) (string, error) {
fileId, rootId, tokenId, nextPageToken := "", "", "", ""
fileId, tokenId, nextPageToken := "", "", ""

q := fmt.Sprintf("name='%s' and trashed=false", s.basedir)
q := fmt.Sprintf("'%s' in parents and name='%s' and mimeType='%s' and trashed=false", s.rootId, token, GDriveDirectoryMimeType)
l, err := s.list(nextPageToken, q)
for 0 < len(l.Files) {
if err != nil {
return "", err
}

for _, fi := range l.Files {
rootId = fi.Id
break
}

if l.NextPageToken == "" {
break
}

l, err = s.list(l.NextPageToken, q)
}

if token == "" {
if rootId == "" {
return "", fmt.Errorf("Cannot find file %s/%s", token, filename)
}

return rootId, nil
}

q = fmt.Sprintf("'%s' in parents and name='%s' and mimeType='%s' and trashed=false", rootId, token, GDriveDirectoryMimeType)
l, err = s.list(nextPageToken, q)
for 0 < len(l.Files) {
if err != nil {
return "", err
}

for _, fi := range l.Files {
tokenId = fi.Id
break
@@ -553,7 +567,7 @@ func (s *GDrive) Get(token string, filename string) (reader io.ReadCloser, conte
contentType = mime.TypeByExtension(fi.MimeType)

// Get timeout reader wrapper and context
timeoutReaderWrapper, ctx := s.getTimeoutReaderWrapperContext(time.Duration(10))
timeoutReaderWrapper, ctx := s.getTimeoutReaderWrapperContext(time.Duration(GDriveTimeoutTimerInterval))

var res *http.Response
res, err = s.service.Files.Get(fileId).Context(ctx).Download()
@@ -581,11 +595,6 @@ func (s *GDrive) IsNotExist(err error) bool {
}

func (s *GDrive) Put(token string, filename string, reader io.Reader, contentType string, contentLength uint64) error {
rootId, err := s.findId("", "")
if err != nil {
return err
}

dirId, err := s.findId("", token)
if err != nil {
return err
@@ -595,7 +604,7 @@ func (s *GDrive) Put(token string, filename string, reader io.Reader, contentTyp
if dirId == "" {
dir := &drive.File{
Name: token,
Parents: []string{rootId},
Parents: []string{s.rootId},
MimeType: GDriveDirectoryMimeType,
}

@@ -608,7 +617,7 @@ func (s *GDrive) Put(token string, filename string, reader io.Reader, contentTyp
}

// Wrap reader in timeout reader
timeoutReaderWrapper, ctx := s.getTimeoutReaderWrapperContext(time.Duration(10))
timeoutReaderWrapper, ctx := s.getTimeoutReaderWrapperContext(time.Duration(GDriveTimeoutTimerInterval))

// Instantiate empty drive file
dst := &drive.File{


Loading…
Cancel
Save