diff --git a/internal/app/handlers.go b/internal/app/handlers.go index 4aca0ff6..4529e7a8 100644 --- a/internal/app/handlers.go +++ b/internal/app/handlers.go @@ -747,7 +747,7 @@ func (app *App) integrationsGetFile(c *gin.Context) { return } - reader, err := integrationProvider.Download(fileID) + reader, _, err := integrationProvider.Download(fileID) if err != nil { log.Error(err) c.AbortWithStatus(http.StatusInternalServerError) diff --git a/internal/integrations/dropbox.go b/internal/integrations/dropbox.go index 41f7113f..0cf450b3 100644 --- a/internal/integrations/dropbox.go +++ b/internal/integrations/dropbox.go @@ -65,8 +65,8 @@ func (d *DropBox) List(folderID string, depth int) (*messages.IntegrationFolder, return response, nil } -func (d *DropBox) Download(fileID string) (io.ReadCloser, error) { - return nil, nil +func (d *DropBox) Download(fileID string) (io.ReadCloser, int64, error) { + return nil, 0, nil } func (d *DropBox) Upload(folderID, name, fileType string, reader io.ReadCloser) (string, error) { diff --git a/internal/integrations/integrations.go b/internal/integrations/integrations.go index c57065d6..186408cc 100644 --- a/internal/integrations/integrations.go +++ b/internal/integrations/integrations.go @@ -22,7 +22,7 @@ const ( // IntegrationProvider abstracts 3rd party integrations type IntegrationProvider interface { List(folderID string, depth int) (result *messages.IntegrationFolder, err error) - Download(fileID string) (io.ReadCloser, error) + Download(fileID string) (io.ReadCloser, int64, error) Upload(folderID, name, fileType string, reader io.ReadCloser) (string, error) } @@ -132,7 +132,7 @@ func visitDir(root, currentPath string, depth int, parentFolder *messages.Integr ID: encodedPath, FileID: encodedPath, Name: docName, - Size: int(d.Size()), + Size: d.Size(), SourceFileType: contentType, } diff --git a/internal/integrations/localfs.go b/internal/integrations/localfs.go index c6e0702b..a4ee97a8 100644 --- a/internal/integrations/localfs.go +++ b/internal/integrations/localfs.go @@ -54,15 +54,21 @@ func (d *localFS) List(folder string, depth int) (*messages.IntegrationFolder, e return response, nil } -func (d *localFS) Download(fileID string) (io.ReadCloser, error) { +func (d *localFS) Download(fileID string) (io.ReadCloser, int64, error) { decoded, err := decodeName(fileID) if err != nil { - return nil, err + return nil, 0, err } localPath := path.Join(d.rootPath, path.Clean(decoded)) - return os.Open(localPath) + st, err := os.Stat(localPath) + if err != nil { + return nil, 0, err + } + + res, err := os.Open(localPath) + return res, st.Size(), err } func (d *localFS) Upload(folderID, name, fileType string, reader io.ReadCloser) (id string, err error) { folder := "/" diff --git a/internal/integrations/webdav.go b/internal/integrations/webdav.go index 74ab2900..e9ed35ed 100644 --- a/internal/integrations/webdav.go +++ b/internal/integrations/webdav.go @@ -89,12 +89,20 @@ func (w *WebDavIntegration) Upload(folderID, name, fileType string, reader io.Re } // Download downloads -func (w *WebDavIntegration) Download(fileID string) (io.ReadCloser, error) { +func (w *WebDavIntegration) Download(fileID string) (io.ReadCloser, int64, error) { decoded, err := decodeName(fileID) if err != nil { - return nil, err + return nil, 0, err + } + + st, err := w.c.Stat(decoded) + if err != nil { + return nil, 0, err } - return w.c.ReadStream(decoded) + + res, err := w.c.ReadStream(decoded) + + return res, st.Size(), err } // List populates the response diff --git a/internal/messages/messages.go b/internal/messages/messages.go index 1b20a8d5..80777bee 100644 --- a/internal/messages/messages.go +++ b/internal/messages/messages.go @@ -159,7 +159,7 @@ type IntegrationFile struct { ID string `json:"id"` Name string `json:"name"` ProvidedFileType string `json:"providedFileType"` - Size int `json:"size"` + Size int64 `json:"size"` SourceFileType string `json:"sourceFileType"` } diff --git a/internal/ui/handlers.go b/internal/ui/handlers.go index 7378d028..745d6141 100644 --- a/internal/ui/handlers.go +++ b/internal/ui/handlers.go @@ -675,3 +675,29 @@ func (app *ReactAppWrapper) exploreIntegration(c *gin.Context) { c.JSON(http.StatusOK, response) } + +func (app *ReactAppWrapper) downloadThroughIntegration(c *gin.Context) { + uid := c.GetString(userIDContextKey) + + integrationID := common.ParamS(intIDParam, c) + + integrationProvider, err := integrations.GetIntegrationProvider(app.userStorer, uid, integrationID) + if err != nil { + log.Error(err) + c.AbortWithStatus(http.StatusInternalServerError) + return + } + + fileid := common.ParamS("path", c) + + response, size, err := integrationProvider.Download(fileid) + if err != nil { + log.Error(err) + c.AbortWithStatus(http.StatusInternalServerError) + return + } + + defer response.Close() + + c.DataFromReader(http.StatusOK, size, "", response, nil) +} diff --git a/internal/ui/routes.go b/internal/ui/routes.go index e3eab7ef..8eebef32 100644 --- a/internal/ui/routes.go +++ b/internal/ui/routes.go @@ -80,6 +80,7 @@ func (app *ReactAppWrapper) RegisterRoutes(router *gin.Engine) { auth.DELETE("integrations/:intid", app.deleteIntegration) auth.GET("integrations/:intid/explore/*path", app.exploreIntegration) + auth.GET("integrations/:intid/download/*path", app.downloadThroughIntegration) //admin admin := auth.Group("")