mirror of
https://github.com/go-gitea/gitea
synced 2025-07-26 20:28:40 +00:00
@@ -83,7 +83,7 @@ func GetRawFile(ctx *context.APIContext) {
|
||||
|
||||
ctx.RespHeader().Set(giteaObjectTypeHeader, string(files_service.GetObjectTypeFromTreeEntry(entry)))
|
||||
|
||||
if err := common.ServeBlob(ctx.Base, ctx.Repo.TreePath, blob, lastModified); err != nil {
|
||||
if err := common.ServeBlob(ctx.Base, ctx.Repo.Repository, ctx.Repo.TreePath, blob, lastModified); err != nil {
|
||||
ctx.APIErrorInternal(err)
|
||||
}
|
||||
}
|
||||
@@ -144,7 +144,7 @@ func GetRawFileOrLFS(ctx *context.APIContext) {
|
||||
}
|
||||
|
||||
// OK not cached - serve!
|
||||
if err := common.ServeBlob(ctx.Base, ctx.Repo.TreePath, blob, lastModified); err != nil {
|
||||
if err := common.ServeBlob(ctx.Base, ctx.Repo.Repository, ctx.Repo.TreePath, blob, lastModified); err != nil {
|
||||
ctx.APIErrorInternal(err)
|
||||
}
|
||||
return
|
||||
|
@@ -32,7 +32,7 @@ func RenderPanicErrorPage(w http.ResponseWriter, req *http.Request, err any) {
|
||||
|
||||
routing.UpdatePanicError(req.Context(), err)
|
||||
|
||||
httpcache.SetCacheControlInHeader(w.Header(), 0, "no-transform")
|
||||
httpcache.SetCacheControlInHeader(w.Header(), &httpcache.CacheControlOptions{NoTransform: true})
|
||||
w.Header().Set(`X-Frame-Options`, setting.CORSConfig.XFrameOptions)
|
||||
|
||||
tmplCtx := context.TemplateContext{}
|
||||
|
@@ -5,17 +5,21 @@ package common
|
||||
|
||||
import (
|
||||
"io"
|
||||
"path"
|
||||
"time"
|
||||
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
"code.gitea.io/gitea/modules/git"
|
||||
"code.gitea.io/gitea/modules/httpcache"
|
||||
"code.gitea.io/gitea/modules/httplib"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/structs"
|
||||
"code.gitea.io/gitea/services/context"
|
||||
)
|
||||
|
||||
// ServeBlob download a git.Blob
|
||||
func ServeBlob(ctx *context.Base, filePath string, blob *git.Blob, lastModified *time.Time) error {
|
||||
func ServeBlob(ctx *context.Base, repo *repo_model.Repository, filePath string, blob *git.Blob, lastModified *time.Time) error {
|
||||
if httpcache.HandleGenericETagTimeCache(ctx.Req, ctx.Resp, `"`+blob.ID.String()+`"`, lastModified) {
|
||||
return nil
|
||||
}
|
||||
@@ -30,14 +34,19 @@ func ServeBlob(ctx *context.Base, filePath string, blob *git.Blob, lastModified
|
||||
}
|
||||
}()
|
||||
|
||||
httplib.ServeContentByReader(ctx.Req, ctx.Resp, filePath, blob.Size(), dataRc)
|
||||
_ = repo.LoadOwner(ctx)
|
||||
httplib.ServeContentByReader(ctx.Req, ctx.Resp, blob.Size(), dataRc, &httplib.ServeHeaderOptions{
|
||||
Filename: path.Base(filePath),
|
||||
CacheIsPublic: !repo.IsPrivate && repo.Owner != nil && repo.Owner.Visibility == structs.VisibleTypePublic,
|
||||
CacheDuration: setting.StaticCacheTime,
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
func ServeContentByReader(ctx *context.Base, filePath string, size int64, reader io.Reader) {
|
||||
httplib.ServeContentByReader(ctx.Req, ctx.Resp, filePath, size, reader)
|
||||
httplib.ServeContentByReader(ctx.Req, ctx.Resp, size, reader, &httplib.ServeHeaderOptions{Filename: path.Base(filePath)})
|
||||
}
|
||||
|
||||
func ServeContentByReadSeeker(ctx *context.Base, filePath string, modTime *time.Time, reader io.ReadSeeker) {
|
||||
httplib.ServeContentByReadSeeker(ctx.Req, ctx.Resp, filePath, modTime, reader)
|
||||
httplib.ServeContentByReadSeeker(ctx.Req, ctx.Resp, modTime, reader, &httplib.ServeHeaderOptions{Filename: path.Base(filePath)})
|
||||
}
|
||||
|
@@ -19,12 +19,12 @@ import (
|
||||
"code.gitea.io/gitea/modules/web/routing"
|
||||
)
|
||||
|
||||
func storageHandler(storageSetting *setting.Storage, prefix string, objStore storage.ObjectStorage) http.HandlerFunc {
|
||||
func avatarStorageHandler(storageSetting *setting.Storage, prefix string, objStore storage.ObjectStorage) http.HandlerFunc {
|
||||
prefix = strings.Trim(prefix, "/")
|
||||
funcInfo := routing.GetFuncInfo(storageHandler, prefix)
|
||||
funcInfo := routing.GetFuncInfo(avatarStorageHandler, prefix)
|
||||
|
||||
if storageSetting.ServeDirect() {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
||||
return func(w http.ResponseWriter, req *http.Request) {
|
||||
if req.Method != "GET" && req.Method != "HEAD" {
|
||||
http.Error(w, http.StatusText(http.StatusMethodNotAllowed), http.StatusMethodNotAllowed)
|
||||
return
|
||||
@@ -52,10 +52,10 @@ func storageHandler(storageSetting *setting.Storage, prefix string, objStore sto
|
||||
}
|
||||
|
||||
http.Redirect(w, req, u.String(), http.StatusTemporaryRedirect)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
||||
return func(w http.ResponseWriter, req *http.Request) {
|
||||
if req.Method != "GET" && req.Method != "HEAD" {
|
||||
http.Error(w, http.StatusText(http.StatusMethodNotAllowed), http.StatusMethodNotAllowed)
|
||||
return
|
||||
@@ -93,6 +93,8 @@ func storageHandler(storageSetting *setting.Storage, prefix string, objStore sto
|
||||
return
|
||||
}
|
||||
defer fr.Close()
|
||||
httpcache.ServeContentWithCacheControl(w, req, path.Base(rPath), fi.ModTime(), fr)
|
||||
})
|
||||
|
||||
httpcache.SetCacheControlInHeader(w.Header(), httpcache.CacheControlForPublicStatic())
|
||||
http.ServeContent(w, req, path.Base(rPath), fi.ModTime(), fr)
|
||||
}
|
||||
}
|
||||
|
@@ -38,7 +38,7 @@ func RobotsTxt(w http.ResponseWriter, req *http.Request) {
|
||||
if ok, _ := util.IsExist(robotsTxt); !ok {
|
||||
robotsTxt = util.FilePathJoinAbs(setting.CustomPath, "robots.txt") // the legacy "robots.txt"
|
||||
}
|
||||
httpcache.SetCacheControlInHeader(w.Header(), setting.StaticCacheTime)
|
||||
httpcache.SetCacheControlInHeader(w.Header(), httpcache.CacheControlForPublicStatic())
|
||||
http.ServeFile(w, req, robotsTxt)
|
||||
}
|
||||
|
||||
|
@@ -46,7 +46,7 @@ func ServeBlobOrLFS(ctx *context.Context, blob *git.Blob, lastModified *time.Tim
|
||||
log.Error("ServeBlobOrLFS: Close: %v", err)
|
||||
}
|
||||
closed = true
|
||||
return common.ServeBlob(ctx.Base, ctx.Repo.TreePath, blob, lastModified)
|
||||
return common.ServeBlob(ctx.Base, ctx.Repo.Repository, ctx.Repo.TreePath, blob, lastModified)
|
||||
}
|
||||
if httpcache.HandleGenericETagCache(ctx.Req, ctx.Resp, `"`+pointer.Oid+`"`) {
|
||||
return nil
|
||||
@@ -78,7 +78,7 @@ func ServeBlobOrLFS(ctx *context.Context, blob *git.Blob, lastModified *time.Tim
|
||||
}
|
||||
closed = true
|
||||
|
||||
return common.ServeBlob(ctx.Base, ctx.Repo.TreePath, blob, lastModified)
|
||||
return common.ServeBlob(ctx.Base, ctx.Repo.Repository, ctx.Repo.TreePath, blob, lastModified)
|
||||
}
|
||||
|
||||
func getBlobForEntry(ctx *context.Context) (*git.Blob, *time.Time) {
|
||||
@@ -114,7 +114,7 @@ func SingleDownload(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
if err := common.ServeBlob(ctx.Base, ctx.Repo.TreePath, blob, lastModified); err != nil {
|
||||
if err := common.ServeBlob(ctx.Base, ctx.Repo.Repository, ctx.Repo.TreePath, blob, lastModified); err != nil {
|
||||
ctx.ServerError("ServeBlob", err)
|
||||
}
|
||||
}
|
||||
@@ -142,7 +142,7 @@ func DownloadByID(ctx *context.Context) {
|
||||
}
|
||||
return
|
||||
}
|
||||
if err = common.ServeBlob(ctx.Base, ctx.Repo.TreePath, blob, nil); err != nil {
|
||||
if err = common.ServeBlob(ctx.Base, ctx.Repo.Repository, ctx.Repo.TreePath, blob, nil); err != nil {
|
||||
ctx.ServerError("ServeBlob", err)
|
||||
}
|
||||
}
|
||||
|
@@ -740,7 +740,7 @@ func WikiRaw(ctx *context.Context) {
|
||||
}
|
||||
|
||||
if entry != nil {
|
||||
if err = common.ServeBlob(ctx.Base, ctx.Repo.TreePath, entry.Blob(), nil); err != nil {
|
||||
if err = common.ServeBlob(ctx.Base, ctx.Repo.Repository, ctx.Repo.TreePath, entry.Blob(), nil); err != nil {
|
||||
ctx.ServerError("ServeBlob", err)
|
||||
}
|
||||
return
|
||||
|
@@ -16,7 +16,7 @@ func cacheableRedirect(ctx *context.Context, location string) {
|
||||
// here we should not use `setting.StaticCacheTime`, it is pretty long (default: 6 hours)
|
||||
// we must make sure the redirection cache time is short enough, otherwise a user won't see the updated avatar in 6 hours
|
||||
// it's OK to make the cache time short, it is only a redirection, and doesn't cost much to make a new request
|
||||
httpcache.SetCacheControlInHeader(ctx.Resp.Header(), 5*time.Minute)
|
||||
httpcache.SetCacheControlInHeader(ctx.Resp.Header(), &httpcache.CacheControlOptions{MaxAge: 5 * time.Minute})
|
||||
ctx.Redirect(location)
|
||||
}
|
||||
|
||||
|
@@ -233,8 +233,8 @@ func Routes() *web.Router {
|
||||
|
||||
routes.Head("/", misc.DummyOK) // for health check - doesn't need to be passed through gzip handler
|
||||
routes.Methods("GET, HEAD, OPTIONS", "/assets/*", optionsCorsHandler(), public.FileHandlerFunc())
|
||||
routes.Methods("GET, HEAD", "/avatars/*", storageHandler(setting.Avatar.Storage, "avatars", storage.Avatars))
|
||||
routes.Methods("GET, HEAD", "/repo-avatars/*", storageHandler(setting.RepoAvatar.Storage, "repo-avatars", storage.RepoAvatars))
|
||||
routes.Methods("GET, HEAD", "/avatars/*", avatarStorageHandler(setting.Avatar.Storage, "avatars", storage.Avatars))
|
||||
routes.Methods("GET, HEAD", "/repo-avatars/*", avatarStorageHandler(setting.RepoAvatar.Storage, "repo-avatars", storage.RepoAvatars))
|
||||
routes.Methods("GET, HEAD", "/apple-touch-icon.png", misc.StaticRedirect("/assets/img/apple-touch-icon.png"))
|
||||
routes.Methods("GET, HEAD", "/apple-touch-icon-precomposed.png", misc.StaticRedirect("/assets/img/apple-touch-icon.png"))
|
||||
routes.Methods("GET, HEAD", "/favicon.ico", misc.StaticRedirect("/assets/img/favicon.png"))
|
||||
|
Reference in New Issue
Block a user