mirror of
https://github.com/go-gitea/gitea.git
synced 2026-04-18 07:48:48 +01:00
Refactor storage content-type handling of ServeDirectURL (#36804)
* replace raw url.Values by *storage.ServeDirectOptions * implement content-type in azblob * implement content-disposition in azblob * add tests for content types in response * http.MethodPut for azure now allows implementing servedirect uploads --------- Signed-off-by: ChristopherHX <christopher.homberger@web.de> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
This commit is contained in:
@@ -10,8 +10,10 @@ import (
|
||||
"io"
|
||||
"net/url"
|
||||
"os"
|
||||
"path"
|
||||
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/public"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
)
|
||||
|
||||
@@ -56,6 +58,38 @@ type Object interface {
|
||||
Stat() (os.FileInfo, error)
|
||||
}
|
||||
|
||||
// ServeDirectOptions customizes HTTP headers for a generated signed URL.
|
||||
type ServeDirectOptions struct {
|
||||
// Overrides the automatically detected MIME type.
|
||||
ContentType string
|
||||
// Overrides the default Content-Disposition header, which is `inline; filename="name"`.
|
||||
ContentDisposition string
|
||||
}
|
||||
|
||||
// Safe defaults are applied only when not explicitly overridden by the caller.
|
||||
func prepareServeDirectOptions(optsOptional *ServeDirectOptions, name string) (ret ServeDirectOptions) {
|
||||
// Here we might not know the real filename, and it's quite inefficient to detect the MIME type by pre-fetching the object head.
|
||||
// So we just do a quick detection by extension name, at least it works for the "View Raw File" for an LFS file on the Web UI.
|
||||
// TODO: OBJECT-STORAGE-CONTENT-TYPE: need a complete solution and refactor for Azure in the future
|
||||
|
||||
if optsOptional != nil {
|
||||
ret = *optsOptional
|
||||
}
|
||||
|
||||
// TODO: UNIFY-CONTENT-DISPOSITION-FROM-STORAGE
|
||||
if ret.ContentType == "" {
|
||||
ext := path.Ext(name)
|
||||
ret.ContentType = public.DetectWellKnownMimeType(ext)
|
||||
}
|
||||
if ret.ContentDisposition == "" {
|
||||
// When using ServeDirect, the URL is from the object storage's web server,
|
||||
// it is not the same origin as Gitea server, so it should be safe enough to use "inline" to render the content directly.
|
||||
// If a browser doesn't support the content type to be displayed inline, browser will download with the filename.
|
||||
ret.ContentDisposition = fmt.Sprintf(`inline; filename="%s"`, quoteEscaper.Replace(name))
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
// ObjectStorage represents an object storage to handle a bucket and files
|
||||
type ObjectStorage interface {
|
||||
Open(path string) (Object, error)
|
||||
@@ -67,7 +101,15 @@ type ObjectStorage interface {
|
||||
|
||||
Stat(path string) (os.FileInfo, error)
|
||||
Delete(path string) error
|
||||
URL(path, name, method string, reqParams url.Values) (*url.URL, error)
|
||||
|
||||
// ServeDirectURL generates a "serve-direct" URL for the specified blob storage file,
|
||||
// end user (browser) will use this URL to access the file directly from the object storage, bypassing Gitea server.
|
||||
// Usually the link is time-limited (a few minutes) and contains a signature to ensure security.
|
||||
// The generated URL must NOT use the same origin as Gitea server, otherwise it will cause security issues.
|
||||
// * method defines which HTTP method is permitted for certain storage providers (e.g., MinIO).
|
||||
// * opt allows customizing the Content-Type and Content-Disposition headers.
|
||||
// TODO: need to merge "ServeDirect()" check into this function, avoid duplicate code and potential inconsistency.
|
||||
ServeDirectURL(path, name, method string, opt *ServeDirectOptions) (*url.URL, error)
|
||||
|
||||
// IterateObjects calls the iterator function for each object in the storage with the given path as prefix
|
||||
// The "fullPath" argument in callback is the full path in this storage.
|
||||
@@ -136,7 +178,7 @@ var (
|
||||
|
||||
// Actions represents actions storage
|
||||
Actions ObjectStorage = uninitializedStorage
|
||||
// Actions Artifacts represents actions artifacts storage
|
||||
// ActionsArtifacts Artifacts represents actions artifacts storage
|
||||
ActionsArtifacts ObjectStorage = uninitializedStorage
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user