Skip to content

Commit 58129f6

Browse files
committed
fix
1 parent c7455e9 commit 58129f6

File tree

9 files changed

+42
-40
lines changed

9 files changed

+42
-40
lines changed

cmd/web.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,16 @@ func serveInstalled(ctx *cli.Context) error {
172172
}
173173
}
174174

175+
legacyPublicAssetFiles := []string{"img", "css", "js"}
176+
for _, fn := range legacyPublicAssetFiles {
177+
if _, err := os.Stat(filepath.Join(setting.CustomPath, "public", fn)); err == nil {
178+
log.Error("Found legacy public asset %q in CustomPath. Please move it to %s/public/assets/%s", fn, setting.CustomPath, fn)
179+
}
180+
}
181+
if _, err := os.Stat(filepath.Join(setting.CustomPath, "robots.txt")); err == nil {
182+
log.Error(`Found legacy public asset "robots.txt" in CustomPath. Please move it to %s/public/robots.txt`, setting.CustomPath)
183+
}
184+
175185
routers.InitWebInstalled(graceful.GetManager().HammerContext())
176186

177187
// We check that AppDataPath exists here (it should have been created during installation)

docs/content/doc/administration/customizing-gitea.en-us.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,11 @@ is set under the "Configuration" tab on the site administration page.
5656

5757
To make Gitea serve custom public files (like pages and images), use the folder
5858
`$GITEA_CUSTOM/public/` as the webroot. Symbolic links will be followed.
59-
At the moment, only files in the `public/assets/` folder are served.
59+
At the moment, only the following files are served:
60+
61+
- `public/robots.txt`
62+
- files in the `public/.well-known/` folder
63+
- files in the `public/assets/` folder
6064

6165
For example, a file `image.png` stored in `$GITEA_CUSTOM/public/assets/`, can be accessed with
6266
the url `http://gitea.domain.tld/assets/image.png`.

modules/public/public.go

Lines changed: 11 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -28,27 +28,15 @@ func AssetFS() *assetfs.LayeredFS {
2828
return assetfs.Layered(CustomAssets(), BuiltinAssets())
2929
}
3030

31-
// AssetsHandlerFunc implements the static handler for serving custom or original assets.
32-
func AssetsHandlerFunc(prefix string) http.HandlerFunc {
31+
// FileHandlerFunc implements the static handler for serving files in "public" assets
32+
func FileHandlerFunc() http.HandlerFunc {
3333
assetFS := AssetFS()
34-
prefix = strings.TrimSuffix(prefix, "/") + "/"
3534
return func(resp http.ResponseWriter, req *http.Request) {
36-
subPath := req.URL.Path
37-
if !strings.HasPrefix(subPath, prefix) {
38-
return
39-
}
40-
subPath = strings.TrimPrefix(subPath, prefix)
41-
4235
if req.Method != "GET" && req.Method != "HEAD" {
4336
resp.WriteHeader(http.StatusNotFound)
4437
return
4538
}
46-
47-
if handleRequest(resp, req, assetFS, subPath) {
48-
return
49-
}
50-
51-
resp.WriteHeader(http.StatusNotFound)
39+
handleRequest(resp, req, assetFS, req.URL.Path)
5240
}
5341
}
5442

@@ -71,34 +59,34 @@ func setWellKnownContentType(w http.ResponseWriter, file string) {
7159
}
7260
}
7361

74-
func handleRequest(w http.ResponseWriter, req *http.Request, fs http.FileSystem, file string) bool {
62+
func handleRequest(w http.ResponseWriter, req *http.Request, fs http.FileSystem, file string) {
7563
// actually, fs (http.FileSystem) is designed to be a safe interface, relative paths won't bypass its parent directory, it's also fine to do a clean here
76-
f, err := fs.Open(util.PathJoinRelX("assets", file))
64+
f, err := fs.Open(util.PathJoinRelX(file))
7765
if err != nil {
7866
if os.IsNotExist(err) {
79-
return false
67+
w.WriteHeader(http.StatusNotFound)
68+
return
8069
}
8170
w.WriteHeader(http.StatusInternalServerError)
8271
log.Error("[Static] Open %q failed: %v", file, err)
83-
return true
72+
return
8473
}
8574
defer f.Close()
8675

8776
fi, err := f.Stat()
8877
if err != nil {
8978
w.WriteHeader(http.StatusInternalServerError)
9079
log.Error("[Static] %q exists, but fails to open: %v", file, err)
91-
return true
80+
return
9281
}
9382

94-
// Try to serve index file
83+
// need to serve index file? (no at the moment)
9584
if fi.IsDir() {
9685
w.WriteHeader(http.StatusNotFound)
97-
return true
86+
return
9887
}
9988

10089
serveContent(w, req, fi, fi.ModTime(), f)
101-
return true
10290
}
10391

10492
type GzipBytesProvider interface {

modules/setting/server.go

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -349,9 +349,4 @@ func loadServerFrom(rootCfg ConfigProvider) {
349349
default:
350350
LandingPageURL = LandingPage(landingPage)
351351
}
352-
353-
HasRobotsTxt, err = util.IsFile(path.Join(CustomPath, "robots.txt"))
354-
if err != nil {
355-
log.Error("Unable to check if %s is a file. Error: %v", path.Join(CustomPath, "robots.txt"), err)
356-
}
357352
}

public/.well-known/security.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Contact: ...
2+
Acknowledgments: ...
3+
Preferred-Languages: en
4+
Policy: ...

routers/install/routes.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import (
2020
func Routes() *web.Route {
2121
base := web.NewRoute()
2222
base.Use(common.ProtocolMiddlewares()...)
23-
base.RouteMethods("/assets/*", "GET, HEAD", public.AssetsHandlerFunc("/assets/"))
23+
base.RouteMethods("/assets/*", "GET, HEAD", public.FileHandlerFunc())
2424

2525
r := web.NewRoute()
2626
r.Use(common.Sessioner(), Contexter())

routers/web/misc/misc.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,12 @@ func DummyOK(w http.ResponseWriter, req *http.Request) {
3434
}
3535

3636
func RobotsTxt(w http.ResponseWriter, req *http.Request) {
37-
filePath := util.FilePathJoinAbs(setting.CustomPath, "robots.txt")
37+
robotsTxt := util.FilePathJoinAbs(setting.CustomPath, "public/robots.txt")
38+
if ok, _ := util.IsExist(robotsTxt); !ok {
39+
robotsTxt = util.FilePathJoinAbs(setting.CustomPath, "robots.txt") // the legacy "robots.txt"
40+
}
3841
httpcache.SetCacheControlInHeader(w.Header(), setting.StaticCacheTime)
39-
http.ServeFile(w, req, filePath)
42+
http.ServeFile(w, req, robotsTxt)
4043
}
4144

4245
func StaticRedirect(target string) func(w http.ResponseWriter, req *http.Request) {

routers/web/web.go

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ func Routes() *web.Route {
108108
routes := web.NewRoute()
109109

110110
routes.Head("/", misc.DummyOK) // for health check - doesn't need to be passed through gzip handler
111-
routes.RouteMethods("/assets/*", "GET, HEAD", CorsHandler(), public.AssetsHandlerFunc("/assets/"))
111+
routes.RouteMethods("/assets/*", "GET, HEAD", CorsHandler(), public.FileHandlerFunc())
112112
routes.RouteMethods("/avatars/*", "GET, HEAD", storageHandler(setting.Avatar.Storage, "avatars", storage.Avatars))
113113
routes.RouteMethods("/repo-avatars/*", "GET, HEAD", storageHandler(setting.RepoAvatar.Storage, "repo-avatars", storage.RepoAvatars))
114114
routes.RouteMethods("/apple-touch-icon.png", "GET, HEAD", misc.StaticRedirect("/assets/img/apple-touch-icon.png"))
@@ -132,15 +132,12 @@ func Routes() *web.Route {
132132
routes.RouteMethods("/captcha/*", "GET,HEAD", append(mid, captcha.Captchaer(context.GetImageCaptcha()))...)
133133
}
134134

135-
if setting.HasRobotsTxt {
136-
routes.Get("/robots.txt", append(mid, misc.RobotsTxt)...)
137-
}
138-
139135
if setting.Metrics.Enabled {
140136
prometheus.MustRegister(metrics.NewCollector())
141137
routes.Get("/metrics", append(mid, Metrics)...)
142138
}
143139

140+
routes.Get("/robots.txt", append(mid, misc.RobotsTxt)...)
144141
routes.Get("/ssh_info", misc.SSHInfo)
145142
routes.Get("/api/healthz", healthcheck.Check)
146143

@@ -336,8 +333,7 @@ func registerRoutes(m *web.Route) {
336333

337334
// FIXME: not all routes need go through same middleware.
338335
// Especially some AJAX requests, we can reduce middleware number to improve performance.
339-
// Routers.
340-
// for health check
336+
341337
m.Get("/", Home)
342338
m.Get("/sitemap.xml", sitemapEnabled, ignExploreSignIn, HomeSitemap)
343339
m.Group("/.well-known", func() {
@@ -349,7 +345,8 @@ func registerRoutes(m *web.Route) {
349345
m.Get("/change-password", func(ctx *context.Context) {
350346
ctx.Redirect(setting.AppSubURL + "/user/settings/account")
351347
})
352-
})
348+
m.Any("/*", CorsHandler(), public.FileHandlerFunc())
349+
}, CorsHandler())
353350

354351
m.Group("/explore", func() {
355352
m.Get("", func(ctx *context.Context) {

tests/integration/links_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ func TestLinksNoLogin(t *testing.T) {
3838
"/user2/repo1/projects/1",
3939
"/assets/img/404.png",
4040
"/assets/img/500.png",
41+
"/.well-known/security.txt",
4142
}
4243

4344
for _, link := range links {

0 commit comments

Comments
 (0)