diff options
author | 2023-01-16 16:19:17 +0100 | |
---|---|---|
committer | 2023-01-16 16:19:17 +0100 | |
commit | d4cddf460a5145965b398e167f3cea24b5e3e436 (patch) | |
tree | 913fb17d42b2585e0420d5d3578cd5dc0b302eec /internal/api/fileserver | |
parent | [chore]: Bump github.com/minio/minio-go/v7 from 7.0.44 to 7.0.47 (#1348) (diff) | |
download | gotosocial-d4cddf460a5145965b398e167f3cea24b5e3e436.tar.xz |
[bugfix] Parse video metadata more accurately; allow Range in fileserver (#1342)
* don't serve unused fields for video attachments
* parse video bitrate + duration more accurately
* use ServeContent where appropriate to respect Range
* abstract temp file seeker into its own function
Diffstat (limited to 'internal/api/fileserver')
-rw-r--r-- | internal/api/fileserver/servefile.go | 35 |
1 files changed, 31 insertions, 4 deletions
diff --git a/internal/api/fileserver/servefile.go b/internal/api/fileserver/servefile.go index 2b47db6f2..592d83672 100644 --- a/internal/api/fileserver/servefile.go +++ b/internal/api/fileserver/servefile.go @@ -29,6 +29,7 @@ import ( apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model" apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util" "github.com/superseriousbusiness/gotosocial/internal/gtserror" + "github.com/superseriousbusiness/gotosocial/internal/iotools" "github.com/superseriousbusiness/gotosocial/internal/log" "github.com/superseriousbusiness/gotosocial/internal/oauth" ) @@ -128,8 +129,34 @@ func (m *Module) ServeFile(c *gin.Context) { return } - // we're good, return the slurped bytes + the rest of the content - c.DataFromReader(http.StatusOK, content.ContentLength, format, io.MultiReader( - bytes.NewReader(b), content.Content, - ), nil) + // reconstruct the original content reader + r := io.MultiReader(bytes.NewReader(b), content.Content) + + // Check the Range header: if this is a simple query for the whole file, we can return it now. + if c.GetHeader("Range") == "" && c.GetHeader("If-Range") == "" { + c.DataFromReader(http.StatusOK, content.ContentLength, format, r, nil) + return + } + + // Range is set, so we need a ReadSeeker to pass to the ServeContent function. + tfs, err := iotools.TempFileSeeker(r) + if err != nil { + err = fmt.Errorf("ServeFile: error creating temp file seeker: %w", err) + apiutil.ErrorHandler(c, gtserror.NewErrorInternalError(err), m.processor.InstanceGet) + return + } + defer func() { + if err := tfs.Close(); err != nil { + log.Errorf("ServeFile: error closing temp file seeker: %s", err) + } + }() + + // to avoid ServeContent wasting time seeking for the + // mime type, set this header already since we know it + c.Header("Content-Type", format) + + // allow ServeContent to handle the rest of the request; + // it will handle Range as appropriate, and write correct + // response headers, http code, etc + http.ServeContent(c.Writer, c.Request, fileName, content.ContentUpdated, tfs) } |