Commit 29379e6
Eric Bower
·
2025-07-21 10:24:39 -0400 EDT
parent 97df9d9
feat(prose): allow `robots.txt` to be uploaded and served for blog
4 files changed,
+35,
-2
+27,
-0
| ... | ... | @@ -328,6 +328,32 @@ func postRawHandler(w http.ResponseWriter, r *http.Request) { | |
| 328 | 328 | } | |
| 329 | 329 | } | |
| 330 | 330 | ||
| 331 | + | func robotsHandler(w http.ResponseWriter, r *http.Request) { | |
| 332 | + | username := shared.GetUsernameFromRequest(r) | |
| 333 | + | cfg := shared.GetCfg(r) | |
| 334 | + | dbpool := shared.GetDB(r) | |
| 335 | + | logger := shared.GetLogger(r) | |
| 336 | + | user, err := dbpool.FindUserByName(username) | |
| 337 | + | if err != nil { | |
| 338 | + | logger.Info("blog not found", "user", username) | |
| 339 | + | http.Error(w, "blog not found", http.StatusNotFound) | |
| 340 | + | return | |
| 341 | + | } | |
| 342 | + | logger = shared.LoggerWithUser(logger, user) | |
| 343 | + | w.Header().Add("Content-Type", "text/plain") | |
| 344 | + | ||
| 345 | + | post, err := dbpool.FindPostWithFilename("robots.txt", user.ID, cfg.Space) | |
| 346 | + | txt := "" | |
| 347 | + | if err == nil { | |
| 348 | + | txt = post.Text | |
| 349 | + | } | |
| 350 | + | _, err = w.Write([]byte(txt)) | |
| 351 | + | if err != nil { | |
| 352 | + | logger.Error("write to response writer", "err", err) | |
| 353 | + | http.Error(w, "server error", 500) | |
| 354 | + | } | |
| 355 | + | } | |
| 356 | + | ||
| 331 | 357 | func postHandler(w http.ResponseWriter, r *http.Request) { | |
| 332 | 358 | username := shared.GetUsernameFromRequest(r) | |
| 333 | 359 | subdomain := shared.GetSubdomain(r) |
| ... | ... | @@ -945,6 +971,7 @@ func createSubdomainRoutes(staticRoutes []shared.Route) []shared.Route { | |
| 945 | 971 | routes := []shared.Route{ | |
| 946 | 972 | shared.NewRoute("GET", "/", blogHandler), | |
| 947 | 973 | shared.NewRoute("GET", "/_styles.css", blogStyleHandler), | |
| 974 | + | shared.NewRoute("GET", "/robots.txt", robotsHandler), | |
| 948 | 975 | shared.NewRoute("GET", "/rss", rssBlogHandler), | |
| 949 | 976 | shared.NewRoute("GET", "/rss.xml", rssBlogHandler), | |
| 950 | 977 | shared.NewRoute("GET", "/atom.xml", rssBlogHandler), |
+1,
-1
| ... | ... | @@ -36,7 +36,7 @@ func NewConfigSite(service string) *shared.ConfigSite { | |
| 36 | 36 | ".svg", | |
| 37 | 37 | ".ico", | |
| 38 | 38 | }, | |
| 39 | - | HiddenPosts: []string{"_readme.md", "_styles.css", "_footer.md", "_404.md"}, | |
| 39 | + | HiddenPosts: []string{"_readme.md", "_styles.css", "_footer.md", "_404.md", "robots.txt"}, | |
| 40 | 40 | Logger: shared.CreateLogger(service, withPipe), | |
| 41 | 41 | MaxSize: maxSize, | |
| 42 | 42 | MaxAssetSize: maxImgSize, |
+6,
-1
| ... | ... | @@ -29,10 +29,15 @@ func (p *MarkdownHooks) FileValidate(s *pssh.SSHServerConnSession, data *filehan | |
| 29 | 29 | return false, err | |
| 30 | 30 | } | |
| 31 | 31 | ||
| 32 | + | fp := strings.Replace(data.Filename, "/", "", 1) | |
| 32 | 33 | // special styles css file we want to permit but no other css file. | |
| 33 | 34 | // sometimes the directory is provided in the filename, so we want to | |
| 34 | 35 | // remove that before we perform this check. | |
| 35 | - | if strings.Replace(data.Filename, "/", "", 1) == "_styles.css" { | |
| 36 | + | if fp == "_styles.css" { | |
| 37 | + | return true, nil | |
| 38 | + | } | |
| 39 | + | // allow users to upload robots file | |
| 40 | + | if fp == "robots.txt" { | |
| 36 | 41 | return true, nil | |
| 37 | 42 | } | |
| 38 | 43 |
+1,
-0
| ... | ... | @@ -53,6 +53,7 @@ func StartSshServer() { | |
| 53 | 53 | ||
| 54 | 54 | fileMap := map[string]filehandlers.ReadWriteHandler{ | |
| 55 | 55 | ".md": filehandlers.NewScpPostHandler(dbh, cfg, hooks), | |
| 56 | + | ".txt": filehandlers.NewScpPostHandler(dbh, cfg, hooks), | |
| 56 | 57 | ".css": filehandlers.NewScpPostHandler(dbh, cfg, hooks), | |
| 57 | 58 | "fallback": uploadimgs.NewUploadImgHandler(dbh, cfg, st), | |
| 58 | 59 | } |