Improve method to get relative and full addresses (first unit tests!)

This commit is contained in:
Jan-Lukas Else 2021-06-10 22:09:50 +02:00
parent 4f1c07957d
commit a2f5ddbdcf
29 changed files with 227 additions and 110 deletions

View File

@ -409,7 +409,7 @@ func (a *goBlog) apNewID(blog *configBlog) (hash string, url string) {
} }
func (a *goBlog) apIri(b *configBlog) string { func (a *goBlog) apIri(b *configBlog) string {
return a.cfg.Server.PublicAddress + b.Path return a.getFullAddress(b.Path)
} }
func apRequestIsSuccess(code int) bool { func apRequestIsSuccess(code int) bool {

View File

@ -127,7 +127,7 @@ func (a *goBlog) toASNote(p *post) *asNote {
as.Tag = append(as.Tag, &asTag{ as.Tag = append(as.Tag, &asTag{
Type: "Hashtag", Type: "Hashtag",
Name: tag, Name: tag,
Href: a.cfg.Server.PublicAddress + a.cfg.Blogs[p.Blog].getRelativePath(fmt.Sprintf("/%s/%s", tagTax, urlize(tag))), Href: a.getFullAddress(a.getRelativePath(p.Blog, fmt.Sprintf("/%s/%s", tagTax, urlize(tag)))),
}) })
} }
} }
@ -165,7 +165,7 @@ func (a *goBlog) serveActivityStreams(blog string, w http.ResponseWriter, r *htt
Name: b.Title, Name: b.Title,
Summary: b.Description, Summary: b.Description,
PreferredUsername: blog, PreferredUsername: blog,
Inbox: a.cfg.Server.PublicAddress + "/activitypub/inbox/" + blog, Inbox: a.getFullAddress("/activitypub/inbox/" + blog),
PublicKey: &asPublicKey{ PublicKey: &asPublicKey{
Owner: a.apIri(b), Owner: a.apIri(b),
ID: a.apIri(b) + "#main-key", ID: a.apIri(b) + "#main-key",

View File

@ -1,13 +0,0 @@
package main
import "strings"
func (blog *configBlog) getRelativePath(path string) string {
if !strings.HasPrefix(path, "/") {
path = "/" + path
}
if blog.Path != "/" {
return blog.Path + path
}
return path
}

View File

@ -20,10 +20,11 @@ func (a *goBlog) initBlogStats() {
func (a *goBlog) serveBlogStats(w http.ResponseWriter, r *http.Request) { func (a *goBlog) serveBlogStats(w http.ResponseWriter, r *http.Request) {
blog := r.Context().Value(blogContextKey).(string) blog := r.Context().Value(blogContextKey).(string)
canonical := a.blogPath(blog) + a.cfg.Blogs[blog].BlogStats.Path bc := a.cfg.Blogs[blog]
canonical := bc.getRelativePath(bc.BlogStats.Path)
a.render(w, r, templateBlogStats, &renderData{ a.render(w, r, templateBlogStats, &renderData{
BlogString: blog, BlogString: blog,
Canonical: canonical, Canonical: a.getFullAddress(canonical),
Data: map[string]interface{}{ Data: map[string]interface{}{
"TableUrl": canonical + ".table.html", "TableUrl": canonical + ".table.html",
}, },

View File

@ -42,7 +42,7 @@ func (a *goBlog) serveComment(w http.ResponseWriter, r *http.Request) {
blog := r.Context().Value(blogContextKey).(string) blog := r.Context().Value(blogContextKey).(string)
a.render(w, r, templateComment, &renderData{ a.render(w, r, templateComment, &renderData{
BlogString: blog, BlogString: blog,
Canonical: a.cfg.Server.PublicAddress + a.cfg.Blogs[blog].getRelativePath(fmt.Sprintf("/comment/%d", id)), Canonical: a.getFullAddress(a.cfg.Blogs[blog].getRelativePath(fmt.Sprintf("/comment/%d", id))),
Data: comment, Data: comment,
}) })
} }
@ -75,9 +75,9 @@ func (a *goBlog) createComment(w http.ResponseWriter, r *http.Request) {
// Serve error // Serve error
a.serveError(w, r, err.Error(), http.StatusInternalServerError) a.serveError(w, r, err.Error(), http.StatusInternalServerError)
} else { } else {
commentAddress := fmt.Sprintf("%s/%d", a.blogPath(r.Context().Value(blogContextKey).(string))+"/comment", commentID) commentAddress := fmt.Sprintf("%s/%d", a.getRelativePath(r.Context().Value(blogContextKey).(string), "/comment"), commentID)
// Send webmention // Send webmention
_ = a.createWebmention(a.cfg.Server.PublicAddress+commentAddress, a.cfg.Server.PublicAddress+target) _ = a.createWebmention(a.getFullAddress(commentAddress), a.getFullAddress(target))
// Redirect to comment // Redirect to comment
http.Redirect(w, r, commentAddress, http.StatusFound) http.Redirect(w, r, commentAddress, http.StatusFound)
} }

View File

@ -77,8 +77,8 @@ func (a *goBlog) commentsAdmin(w http.ResponseWriter, r *http.Request) {
"Comments": comments, "Comments": comments,
"HasPrev": hasPrev, "HasPrev": hasPrev,
"HasNext": hasNext, "HasNext": hasNext,
"Prev": slashIfEmpty(prevPath), "Prev": prevPath,
"Next": slashIfEmpty(nextPath), "Next": nextPath,
}, },
}) })
} }

View File

@ -15,7 +15,7 @@ func (a *goBlog) serveCustomPage(w http.ResponseWriter, r *http.Request) {
} }
a.render(w, r, page.Template, &renderData{ a.render(w, r, page.Template, &renderData{
BlogString: r.Context().Value(blogContextKey).(string), BlogString: r.Context().Value(blogContextKey).(string),
Canonical: a.cfg.Server.PublicAddress + page.Path, Canonical: a.getFullAddress(page.Path),
Data: page.Data, Data: page.Data,
}) })
} }

View File

@ -33,7 +33,7 @@ func (a *goBlog) generateFeed(blog string, f feedType, w http.ResponseWriter, r
feed := &feeds.Feed{ feed := &feeds.Feed{
Title: title, Title: title,
Description: description, Description: description,
Link: &feeds.Link{Href: a.cfg.Server.PublicAddress + strings.TrimSuffix(r.URL.Path, "."+string(f))}, Link: &feeds.Link{Href: a.getFullAddress(strings.TrimSuffix(r.URL.Path, "."+string(f)))},
Created: now, Created: now,
Author: &feeds.Author{ Author: &feeds.Author{
Name: a.cfg.User.Name, Name: a.cfg.User.Name,

2
go.mod
View File

@ -61,7 +61,7 @@ require (
go.uber.org/atomic v1.8.0 // indirect go.uber.org/atomic v1.8.0 // indirect
go.uber.org/multierr v1.7.0 // indirect go.uber.org/multierr v1.7.0 // indirect
go.uber.org/zap v1.17.0 // indirect go.uber.org/zap v1.17.0 // indirect
golang.org/x/net v0.0.0-20210525063256-abc453219eb5 golang.org/x/net v0.0.0-20210610132358-84b48f89b13b
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
golang.org/x/sys v0.0.0-20210608053332-aa57babbf139 // indirect golang.org/x/sys v0.0.0-20210608053332-aa57babbf139 // indirect
golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf // indirect golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf // indirect

3
go.sum
View File

@ -416,8 +416,9 @@ golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81R
golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM= golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM=
golang.org/x/net v0.0.0-20210525063256-abc453219eb5 h1:wjuX4b5yYQnEQHzd+CBcrcC6OVR2J1CN6mUy0oSxIPo=
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20210610132358-84b48f89b13b h1:k+E048sYJHyVnsr1GDrRZWQ32D2C7lWs9JRc0bel53A=
golang.org/x/net v0.0.0-20210610132358-84b48f89b13b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/oauth2 v0.0.0-20170912212905-13449ad91cb2/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20170912212905-13449ad91cb2/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=

View File

@ -7,7 +7,7 @@ import (
) )
func (a *goBlog) healthcheck() bool { func (a *goBlog) healthcheck() bool {
req, err := http.NewRequest(http.MethodGet, a.cfg.Server.PublicAddress+"/ping", nil) req, err := http.NewRequest(http.MethodGet, a.getFullAddress("/ping"), nil)
if err != nil { if err != nil {
fmt.Println(err.Error()) fmt.Println(err.Error())
return false return false

47
http.go
View File

@ -247,11 +247,9 @@ func (a *goBlog) buildStaticHandlersRouters() error {
sbm := middleware.WithValue(blogContextKey, blog) sbm := middleware.WithValue(blogContextKey, blog)
a.setBlogMiddlewares[blog] = sbm a.setBlogMiddlewares[blog] = sbm
blogPath := a.blogPath(blog)
for _, section := range blogConfig.Sections { for _, section := range blogConfig.Sections {
if section.Name != "" { if section.Name != "" {
secPath := blogPath + "/" + section.Name secPath := blogConfig.getRelativePath(section.Name)
a.sectionMiddlewares[secPath] = middleware.WithValue(indexConfigKey, &indexConfig{ a.sectionMiddlewares[secPath] = middleware.WithValue(indexConfigKey, &indexConfig{
path: secPath, path: secPath,
section: section, section: section,
@ -261,14 +259,14 @@ func (a *goBlog) buildStaticHandlersRouters() error {
for _, taxonomy := range blogConfig.Taxonomies { for _, taxonomy := range blogConfig.Taxonomies {
if taxonomy.Name != "" { if taxonomy.Name != "" {
taxPath := blogPath + "/" + taxonomy.Name taxPath := blogConfig.getRelativePath(taxonomy.Name)
a.taxonomyMiddlewares[taxPath] = middleware.WithValue(taxonomyContextKey, taxonomy) a.taxonomyMiddlewares[taxPath] = middleware.WithValue(taxonomyContextKey, taxonomy)
} }
} }
if blogConfig.Photos != nil && blogConfig.Photos.Enabled { if blogConfig.Photos != nil && blogConfig.Photos.Enabled {
a.photosMiddlewares[blog] = middleware.WithValue(indexConfigKey, &indexConfig{ a.photosMiddlewares[blog] = middleware.WithValue(indexConfigKey, &indexConfig{
path: blogPath + blogConfig.Photos.Path, path: blogConfig.getRelativePath(blogConfig.Photos.Path),
parameter: blogConfig.Photos.Parameter, parameter: blogConfig.Photos.Parameter,
title: blogConfig.Photos.Title, title: blogConfig.Photos.Title,
description: blogConfig.Photos.Description, description: blogConfig.Photos.Description,
@ -277,7 +275,7 @@ func (a *goBlog) buildStaticHandlersRouters() error {
} }
if blogConfig.Search != nil && blogConfig.Search.Enabled { if blogConfig.Search != nil && blogConfig.Search.Enabled {
a.searchMiddlewares[blog] = middleware.WithValue(pathContextKey, blogPath+blogConfig.Search.Path) a.searchMiddlewares[blog] = middleware.WithValue(pathContextKey, blogConfig.getRelativePath(blogConfig.Search.Path))
} }
for _, cp := range blogConfig.CustomPages { for _, cp := range blogConfig.CustomPages {
@ -285,7 +283,7 @@ func (a *goBlog) buildStaticHandlersRouters() error {
} }
if commentsConfig := blogConfig.Comments; commentsConfig != nil && commentsConfig.Enabled { if commentsConfig := blogConfig.Comments; commentsConfig != nil && commentsConfig.Enabled {
a.commentsMiddlewares[blog] = middleware.WithValue(pathContextKey, blogPath+"/comment") a.commentsMiddlewares[blog] = middleware.WithValue(pathContextKey, blogConfig.getRelativePath("/comment"))
} }
} }
@ -401,8 +399,6 @@ func (a *goBlog) buildDynamicRouter() (*chi.Mux, error) {
r.With(a.privateModeHandler...).With(a.cache.cacheMiddleware).Get("/s/{id:[0-9a-fA-F]+}", a.redirectToLongPath) r.With(a.privateModeHandler...).With(a.cache.cacheMiddleware).Get("/s/{id:[0-9a-fA-F]+}", a.redirectToLongPath)
for blog, blogConfig := range a.cfg.Blogs { for blog, blogConfig := range a.cfg.Blogs {
blogPath := a.blogPath(blog)
sbm := a.setBlogMiddlewares[blog] sbm := a.setBlogMiddlewares[blog]
// Sections // Sections
@ -411,7 +407,7 @@ func (a *goBlog) buildDynamicRouter() (*chi.Mux, error) {
r.Use(a.cache.cacheMiddleware, sbm) r.Use(a.cache.cacheMiddleware, sbm)
for _, section := range blogConfig.Sections { for _, section := range blogConfig.Sections {
if section.Name != "" { if section.Name != "" {
secPath := blogPath + "/" + section.Name secPath := blogConfig.getRelativePath(section.Name)
r.Group(func(r chi.Router) { r.Group(func(r chi.Router) {
r.Use(a.sectionMiddlewares[secPath]) r.Use(a.sectionMiddlewares[secPath])
r.Get(secPath, a.serveIndex) r.Get(secPath, a.serveIndex)
@ -425,7 +421,7 @@ func (a *goBlog) buildDynamicRouter() (*chi.Mux, error) {
// Taxonomies // Taxonomies
for _, taxonomy := range blogConfig.Taxonomies { for _, taxonomy := range blogConfig.Taxonomies {
if taxonomy.Name != "" { if taxonomy.Name != "" {
taxPath := blogPath + "/" + taxonomy.Name taxPath := blogConfig.getRelativePath(taxonomy.Name)
taxValues, err := a.db.allTaxonomyValues(blog, taxonomy.Name) taxValues, err := a.db.allTaxonomyValues(blog, taxonomy.Name)
if err != nil { if err != nil {
return nil, err return nil, err
@ -459,7 +455,7 @@ func (a *goBlog) buildDynamicRouter() (*chi.Mux, error) {
r.Group(func(r chi.Router) { r.Group(func(r chi.Router) {
r.Use(a.privateModeHandler...) r.Use(a.privateModeHandler...)
r.Use(a.cache.cacheMiddleware, sbm, a.photosMiddlewares[blog]) r.Use(a.cache.cacheMiddleware, sbm, a.photosMiddlewares[blog])
photoPath := blogPath + blogConfig.Photos.Path photoPath := blogConfig.getRelativePath(blogConfig.Photos.Path)
r.Get(photoPath, a.serveIndex) r.Get(photoPath, a.serveIndex)
r.Get(photoPath+feedPath, a.serveIndex) r.Get(photoPath+feedPath, a.serveIndex)
r.Get(photoPath+paginationPath, a.serveIndex) r.Get(photoPath+paginationPath, a.serveIndex)
@ -468,13 +464,13 @@ func (a *goBlog) buildDynamicRouter() (*chi.Mux, error) {
// Search // Search
if blogConfig.Search != nil && blogConfig.Search.Enabled { if blogConfig.Search != nil && blogConfig.Search.Enabled {
searchPath := blogPath + blogConfig.Search.Path searchPath := blogConfig.getRelativePath(blogConfig.Search.Path)
r.With(sbm, a.searchMiddlewares[blog]).Mount(searchPath, a.searchRouter) r.With(sbm, a.searchMiddlewares[blog]).Mount(searchPath, a.searchRouter)
} }
// Stats // Stats
if blogConfig.BlogStats != nil && blogConfig.BlogStats.Enabled { if blogConfig.BlogStats != nil && blogConfig.BlogStats.Enabled {
statsPath := blogPath + blogConfig.BlogStats.Path statsPath := blogConfig.getRelativePath(blogConfig.BlogStats.Path)
r.Group(func(r chi.Router) { r.Group(func(r chi.Router) {
r.Use(a.privateModeHandler...) r.Use(a.privateModeHandler...)
r.Use(a.cache.cacheMiddleware, sbm) r.Use(a.cache.cacheMiddleware, sbm)
@ -492,7 +488,7 @@ func (a *goBlog) buildDynamicRouter() (*chi.Mux, error) {
monthRegex := `/{month:x|\d\d}` monthRegex := `/{month:x|\d\d}`
dayRegex := `/{day:\d\d}` dayRegex := `/{day:\d\d}`
yearPath := blogPath + yearRegex yearPath := blogConfig.getRelativePath(yearRegex)
r.Get(yearPath, a.serveDate) r.Get(yearPath, a.serveDate)
r.Get(yearPath+feedPath, a.serveDate) r.Get(yearPath+feedPath, a.serveDate)
r.Get(yearPath+paginationPath, a.serveDate) r.Get(yearPath+paginationPath, a.serveDate)
@ -514,8 +510,8 @@ func (a *goBlog) buildDynamicRouter() (*chi.Mux, error) {
r.Use(a.privateModeHandler...) r.Use(a.privateModeHandler...)
r.Use(sbm) r.Use(sbm)
r.With(a.checkActivityStreamsRequest, a.cache.cacheMiddleware).Get(blogConfig.Path, a.serveHome) r.With(a.checkActivityStreamsRequest, a.cache.cacheMiddleware).Get(blogConfig.Path, a.serveHome)
r.With(a.cache.cacheMiddleware).Get(blogConfig.Path+feedPath, a.serveHome) r.With(a.cache.cacheMiddleware).Get(blogConfig.getRelativePath(feedPath), a.serveHome)
r.With(a.cache.cacheMiddleware).Get(blogPath+paginationPath, a.serveHome) r.With(a.cache.cacheMiddleware).Get(blogConfig.getRelativePath(paginationPath), a.serveHome)
}) })
} }
@ -535,21 +531,20 @@ func (a *goBlog) buildDynamicRouter() (*chi.Mux, error) {
if randomPath == "" { if randomPath == "" {
randomPath = "/random" randomPath = "/random"
} }
r.With(a.privateModeHandler...).With(sbm).Get(blogPath+randomPath, a.redirectToRandomPost) r.With(a.privateModeHandler...).With(sbm).Get(blogConfig.getRelativePath(randomPath), a.redirectToRandomPost)
} }
// Editor // Editor
r.With(sbm).Mount(blogPath+"/editor", a.editorRouter) r.With(sbm).Mount(blogConfig.getRelativePath("/editor"), a.editorRouter)
// Comments // Comments
if commentsConfig := blogConfig.Comments; commentsConfig != nil && commentsConfig.Enabled { if commentsConfig := blogConfig.Comments; commentsConfig != nil && commentsConfig.Enabled {
commentsPath := blogPath + "/comment" r.With(sbm, a.commentsMiddlewares[blog]).Mount(blogConfig.getRelativePath("/comment"), a.commentsRouter)
r.With(sbm, a.commentsMiddlewares[blog]).Mount(commentsPath, a.commentsRouter)
} }
// Blogroll // Blogroll
if brConfig := blogConfig.Blogroll; brConfig != nil && brConfig.Enabled { if brConfig := blogConfig.Blogroll; brConfig != nil && brConfig.Enabled {
brPath := blogPath + brConfig.Path brPath := blogConfig.getRelativePath(brConfig.Path)
r.Group(func(r chi.Router) { r.Group(func(r chi.Router) {
r.Use(a.privateModeHandler...) r.Use(a.privateModeHandler...)
r.Use(a.cache.cacheMiddleware, sbm) r.Use(a.cache.cacheMiddleware, sbm)
@ -577,14 +572,6 @@ func (a *goBlog) buildDynamicRouter() (*chi.Mux, error) {
return r, nil return r, nil
} }
func (a *goBlog) blogPath(blog string) string {
blogPath := a.cfg.Blogs[blog].Path
if blogPath == "/" {
return ""
}
return blogPath
}
const blogContextKey requestContextKey = "blog" const blogContextKey requestContextKey = "blog"
const pathContextKey requestContextKey = "httpPath" const pathContextKey requestContextKey = "httpPath"

View File

@ -28,7 +28,7 @@ func (a *goBlog) serveMicropubQuery(w http.ResponseWriter, r *http.Request) {
w.Header().Set(contentType, contentTypeJSONUTF8) w.Header().Set(contentType, contentTypeJSONUTF8)
w.WriteHeader(http.StatusOK) w.WriteHeader(http.StatusOK)
b, _ := json.Marshal(&micropubConfig{ b, _ := json.Marshal(&micropubConfig{
MediaEndpoint: a.cfg.Server.PublicAddress + micropubPath + micropubMediaSubPath, MediaEndpoint: a.getFullAddress(micropubPath + micropubMediaSubPath),
}) })
_, _ = writeMinified(w, contentTypeJSON, b) _, _ = writeMinified(w, contentTypeJSON, b)
case "source": case "source":

View File

@ -113,7 +113,7 @@ func (a *goBlog) uploadFile(filename string, f io.Reader) (string, error) {
if ms != nil && ms.MediaURL != "" { if ms != nil && ms.MediaURL != "" {
return ms.MediaURL + loc, nil return ms.MediaURL + loc, nil
} }
return a.cfg.Server.PublicAddress + loc, nil return a.getFullAddress(loc), nil
} }
func (config *configMicropubMedia) uploadToBunny(filename string, f io.Reader) (location string, err error) { func (config *configMicropubMedia) uploadToBunny(filename string, f io.Reader) (location string, err error) {

View File

@ -9,7 +9,7 @@ func (a *goBlog) serveNodeInfoDiscover(w http.ResponseWriter, r *http.Request) {
b, _ := json.Marshal(map[string]interface{}{ b, _ := json.Marshal(map[string]interface{}{
"links": []map[string]interface{}{ "links": []map[string]interface{}{
{ {
"href": a.cfg.Server.PublicAddress + "/nodeinfo", "href": a.getFullAddress("/nodeinfo"),
"rel": "http://nodeinfo.diaspora.software/ns/schema/2.1", "rel": "http://nodeinfo.diaspora.software/ns/schema/2.1",
}, },
}, },

View File

@ -158,8 +158,8 @@ func (a *goBlog) notificationsAdmin(w http.ResponseWriter, r *http.Request) {
"Notifications": notifications, "Notifications": notifications,
"HasPrev": hasPrev, "HasPrev": hasPrev,
"HasNext": hasNext, "HasNext": hasNext,
"Prev": slashIfEmpty(prevPath), "Prev": prevPath,
"Next": slashIfEmpty(nextPath), "Next": nextPath,
}, },
}) })
} }

View File

@ -9,7 +9,7 @@ func (a *goBlog) serveOpenSearch(w http.ResponseWriter, r *http.Request) {
blog := r.Context().Value(blogContextKey).(string) blog := r.Context().Value(blogContextKey).(string)
b := a.cfg.Blogs[blog] b := a.cfg.Blogs[blog]
title := b.Title title := b.Title
sURL := a.cfg.Server.PublicAddress + b.getRelativePath(b.Search.Path) sURL := a.getFullAddress(b.getRelativePath(b.Search.Path))
xml := fmt.Sprintf("<?xml version=\"1.0\"?><OpenSearchDescription xmlns=\"http://a9.com/-/spec/opensearch/1.1/\" xmlns:moz=\"http://www.mozilla.org/2006/browser/search/\">"+ xml := fmt.Sprintf("<?xml version=\"1.0\"?><OpenSearchDescription xmlns=\"http://a9.com/-/spec/opensearch/1.1/\" xmlns:moz=\"http://www.mozilla.org/2006/browser/search/\">"+
"<ShortName>%s</ShortName><Description>%s</Description>"+ "<ShortName>%s</ShortName><Description>%s</Description>"+
"<Url type=\"text/html\" method=\"post\" template=\"%s\"><Param name=\"q\" value=\"{searchTerms}\" /></Url>"+ "<Url type=\"text/html\" method=\"post\" template=\"%s\"><Param name=\"q\" value=\"{searchTerms}\" /></Url>"+
@ -17,7 +17,7 @@ func (a *goBlog) serveOpenSearch(w http.ResponseWriter, r *http.Request) {
"</OpenSearchDescription>", "</OpenSearchDescription>",
title, title, sURL, sURL) title, title, sURL, sURL)
w.Header().Set(contentType, "application/opensearchdescription+xml") w.Header().Set(contentType, "application/opensearchdescription+xml")
writeMinified(w, contentTypeXML, []byte(xml)) _, _ = writeMinified(w, contentTypeXML, []byte(xml))
} }
func openSearchUrl(b *configBlog) string { func openSearchUrl(b *configBlog) string {

45
paths.go Normal file
View File

@ -0,0 +1,45 @@
package main
import "strings"
func (a *goBlog) getRelativePath(blog, path string) string {
// Get blog
bc := a.cfg.Blogs[blog]
if bc == nil {
return ""
}
// Get relative path
return bc.getRelativePath(path)
}
func (blog *configBlog) getRelativePath(path string) string {
// Check if path is absolute
if !strings.HasPrefix(path, "/") {
path = "/" + path
}
// Check if blog uses subpath
if blog.Path != "" && blog.Path != "/" {
// Check if path is root
if path == "/" {
path = blog.Path
} else {
path = blog.Path + path
}
}
return path
}
func (a *goBlog) getFullAddress(path string) string {
// Call method with just the relevant config
return a.cfg.Server.getFullAddress(path)
}
func (cfg *configServer) getFullAddress(path string) string {
// Remove trailing slash
pa := strings.TrimSuffix(cfg.PublicAddress, "/")
// Check if path is root => blank path
if path == "/" {
path = ""
}
return pa + path
}

108
paths_test.go Normal file
View File

@ -0,0 +1,108 @@
package main
import (
"reflect"
"testing"
)
func Test_getFullAddress(t *testing.T) {
cfg1 := &configServer{
PublicAddress: "https://example.com",
}
cfg2 := &configServer{
PublicAddress: "https://example.com/",
}
app := &goBlog{
cfg: &config{
Server: cfg1,
},
}
if got := cfg1.getFullAddress("/test"); !reflect.DeepEqual(got, "https://example.com/test") {
t.Errorf("Wrong full path, got: %v", got)
}
if got := cfg2.getFullAddress("/test"); !reflect.DeepEqual(got, "https://example.com/test") {
t.Errorf("Wrong full path, got: %v", got)
}
if got := app.getFullAddress("/test"); !reflect.DeepEqual(got, "https://example.com/test") {
t.Errorf("Wrong full path, got: %v", got)
}
if got := cfg1.getFullAddress("/"); !reflect.DeepEqual(got, "https://example.com") {
t.Errorf("Wrong full path, got: %v", got)
}
if got := cfg1.getFullAddress(""); !reflect.DeepEqual(got, "https://example.com") {
t.Errorf("Wrong full path, got: %v", got)
}
}
func Test_getRelativeBlogPath(t *testing.T) {
blog1 := &configBlog{
Path: "",
}
blog2 := &configBlog{
Path: "",
}
blog3 := &configBlog{
Path: "/de",
}
if got := blog1.getRelativePath(""); !reflect.DeepEqual(got, "/") {
t.Errorf("Wrong relative blog path, got: %v", got)
}
if got := blog2.getRelativePath(""); !reflect.DeepEqual(got, "/") {
t.Errorf("Wrong relative blog path, got: %v", got)
}
if got := blog3.getRelativePath(""); !reflect.DeepEqual(got, "/de") {
t.Errorf("Wrong relative blog path, got: %v", got)
}
if got := blog1.getRelativePath("test"); !reflect.DeepEqual(got, "/test") {
t.Errorf("Wrong relative blog path, got: %v", got)
}
if got := blog2.getRelativePath("test"); !reflect.DeepEqual(got, "/test") {
t.Errorf("Wrong relative blog path, got: %v", got)
}
if got := blog3.getRelativePath("test"); !reflect.DeepEqual(got, "/de/test") {
t.Errorf("Wrong relative blog path, got: %v", got)
}
if got := blog1.getRelativePath("/test"); !reflect.DeepEqual(got, "/test") {
t.Errorf("Wrong relative blog path, got: %v", got)
}
if got := blog2.getRelativePath("/test"); !reflect.DeepEqual(got, "/test") {
t.Errorf("Wrong relative blog path, got: %v", got)
}
if got := blog3.getRelativePath("/test"); !reflect.DeepEqual(got, "/de/test") {
t.Errorf("Wrong relative blog path, got: %v", got)
}
app := &goBlog{
cfg: &config{
Blogs: map[string]*configBlog{
"de": blog3,
},
},
}
if got := app.getRelativePath("de", "/test"); !reflect.DeepEqual(got, "/de/test") {
t.Errorf("Wrong relative blog path, got: %v", got)
}
if got := app.getRelativePath("", "/test"); !reflect.DeepEqual(got, "") {
t.Errorf("Wrong relative blog path, got: %v", got)
}
}

View File

@ -53,7 +53,7 @@ func (a *goBlog) servePost(w http.ResponseWriter, r *http.Request) {
return return
} }
if asRequest, ok := r.Context().Value(asRequestKey).(bool); ok && asRequest { if asRequest, ok := r.Context().Value(asRequestKey).(bool); ok && asRequest {
if r.URL.Path == a.blogPath(p.Blog) { if r.URL.Path == a.getRelativePath(p.Blog, "") {
a.serveActivityStreams(p.Blog, w, r) a.serveActivityStreams(p.Blog, w, r)
return return
} }
@ -116,7 +116,7 @@ func (a *goBlog) serveHome(w http.ResponseWriter, r *http.Request) {
return return
} }
a.serveIndex(w, r.WithContext(context.WithValue(r.Context(), indexConfigKey, &indexConfig{ a.serveIndex(w, r.WithContext(context.WithValue(r.Context(), indexConfigKey, &indexConfig{
path: a.blogPath(blog), path: a.getRelativePath(blog, ""),
}))) })))
} }
@ -136,7 +136,6 @@ func (a *goBlog) serveDate(w http.ResponseWriter, r *http.Request) {
return return
} }
var title, dPath strings.Builder var title, dPath strings.Builder
dPath.WriteString(a.blogPath(r.Context().Value(blogContextKey).(string)) + "/")
if year != 0 { if year != 0 {
ys := fmt.Sprintf("%0004d", year) ys := fmt.Sprintf("%0004d", year)
title.WriteString(ys) title.WriteString(ys)
@ -157,7 +156,7 @@ func (a *goBlog) serveDate(w http.ResponseWriter, r *http.Request) {
dPath.WriteString(fmt.Sprintf("/%02d", day)) dPath.WriteString(fmt.Sprintf("/%02d", day))
} }
a.serveIndex(w, r.WithContext(context.WithValue(r.Context(), indexConfigKey, &indexConfig{ a.serveIndex(w, r.WithContext(context.WithValue(r.Context(), indexConfigKey, &indexConfig{
path: dPath.String(), path: a.getRelativePath(r.Context().Value(blogContextKey).(string), dPath.String()),
year: year, year: year,
month: month, month: month,
day: day, day: day,
@ -257,7 +256,7 @@ func (a *goBlog) serveIndex(w http.ResponseWriter, r *http.Request) {
if prevPage < 2 { if prevPage < 2 {
prevPath = path prevPath = path
} else { } else {
prevPath = fmt.Sprintf("%s/page/%d", path, prevPage) prevPath = fmt.Sprintf("%s/page/%d", strings.TrimSuffix(path, "/"), prevPage)
} }
hasNext, _ = p.HasNext() hasNext, _ = p.HasNext()
if hasNext { if hasNext {
@ -265,23 +264,23 @@ func (a *goBlog) serveIndex(w http.ResponseWriter, r *http.Request) {
} else { } else {
nextPage, _ = p.Page() nextPage, _ = p.Page()
} }
nextPath = fmt.Sprintf("%s/page/%d", path, nextPage) nextPath = fmt.Sprintf("%s/page/%d", strings.TrimSuffix(path, "/"), nextPage)
summaryTemplate := ic.summaryTemplate summaryTemplate := ic.summaryTemplate
if summaryTemplate == "" { if summaryTemplate == "" {
summaryTemplate = templateSummary summaryTemplate = templateSummary
} }
a.render(w, r, templateIndex, &renderData{ a.render(w, r, templateIndex, &renderData{
BlogString: blog, BlogString: blog,
Canonical: a.cfg.Server.PublicAddress + path, Canonical: a.getFullAddress(path),
Data: map[string]interface{}{ Data: map[string]interface{}{
"Title": title, "Title": title,
"Description": description, "Description": description,
"Posts": posts, "Posts": posts,
"HasPrev": hasPrev, "HasPrev": hasPrev,
"HasNext": hasNext, "HasNext": hasNext,
"First": slashIfEmpty(path), "First": path,
"Prev": slashIfEmpty(prevPath), "Prev": prevPath,
"Next": slashIfEmpty(nextPath), "Next": nextPath,
"SummaryTemplate": summaryTemplate, "SummaryTemplate": summaryTemplate,
}, },
}) })

View File

@ -9,7 +9,7 @@ import (
) )
func (a *goBlog) fullPostURL(p *post) string { func (a *goBlog) fullPostURL(p *post) string {
return a.cfg.Server.PublicAddress + p.Path return a.getFullAddress(p.Path)
} }
func (a *goBlog) shortPostURL(p *post) string { func (a *goBlog) shortPostURL(p *post) string {
@ -20,7 +20,7 @@ func (a *goBlog) shortPostURL(p *post) string {
if a.cfg.Server.ShortPublicAddress != "" { if a.cfg.Server.ShortPublicAddress != "" {
return a.cfg.Server.ShortPublicAddress + s return a.cfg.Server.ShortPublicAddress + s
} }
return a.cfg.Server.PublicAddress + s return a.getFullAddress(s)
} }
func (p *post) firstParameter(parameter string) (result string) { func (p *post) firstParameter(parameter string) (result string) {

View File

@ -141,7 +141,7 @@ func (a *goBlog) initRendering() error {
"urlize": urlize, "urlize": urlize,
"sort": sortedStrings, "sort": sortedStrings,
"absolute": func(path string) string { "absolute": func(path string) string {
return a.cfg.Server.PublicAddress + path return a.getFullAddress(path)
}, },
"blogrelative": func(blog *configBlog, path string) string { "blogrelative": func(blog *configBlog, path string) string {
return blog.getRelativePath(path) return blog.getRelativePath(path)

View File

@ -6,7 +6,7 @@ import (
) )
func (a *goBlog) serveRobotsTXT(w http.ResponseWriter, r *http.Request) { func (a *goBlog) serveRobotsTXT(w http.ResponseWriter, r *http.Request) {
_, _ = w.Write([]byte(fmt.Sprintf("User-agent: *\nSitemap: %v", a.cfg.Server.PublicAddress+sitemapPath))) _, _ = w.Write([]byte(fmt.Sprintf("User-agent: *\nSitemap: %v", a.getFullAddress(sitemapPath))))
} }
func servePrivateRobotsTXT(w http.ResponseWriter, r *http.Request) { func servePrivateRobotsTXT(w http.ResponseWriter, r *http.Request) {

View File

@ -25,7 +25,7 @@ func (a *goBlog) serveSearch(w http.ResponseWriter, r *http.Request) {
} }
a.render(w, r, templateSearch, &renderData{ a.render(w, r, templateSearch, &renderData{
BlogString: blog, BlogString: blog,
Canonical: a.cfg.Server.PublicAddress + servePath, Canonical: a.getFullAddress(servePath),
}) })
} }

View File

@ -7,7 +7,7 @@ import (
func (a *goBlog) redirectShortDomain(next http.Handler) http.Handler { func (a *goBlog) redirectShortDomain(next http.Handler) http.Handler {
return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
if a.cfg.Server.shortPublicHostname != "" && r.Host == a.cfg.Server.shortPublicHostname { if a.cfg.Server.shortPublicHostname != "" && r.Host == a.cfg.Server.shortPublicHostname {
http.Redirect(rw, r, a.cfg.Server.PublicAddress+r.RequestURI, http.StatusMovedPermanently) http.Redirect(rw, r, a.getFullAddress(r.RequestURI), http.StatusMovedPermanently)
return return
} }
next.ServeHTTP(rw, r) next.ServeHTTP(rw, r)

View File

@ -17,18 +17,14 @@ func (a *goBlog) serveSitemap(w http.ResponseWriter, r *http.Request) {
// Blogs // Blogs
for b, bc := range a.cfg.Blogs { for b, bc := range a.cfg.Blogs {
// Blog // Blog
blogPath := bc.Path
if blogPath == "/" {
blogPath = ""
}
sm.Add(&sitemap.URL{ sm.Add(&sitemap.URL{
Loc: a.cfg.Server.PublicAddress + blogPath, Loc: a.getFullAddress(bc.Path),
}) })
// Sections // Sections
for _, section := range bc.Sections { for _, section := range bc.Sections {
if section.Name != "" { if section.Name != "" {
sm.Add(&sitemap.URL{ sm.Add(&sitemap.URL{
Loc: a.cfg.Server.PublicAddress + bc.getRelativePath("/"+section.Name), Loc: a.getFullAddress(bc.getRelativePath(section.Name)),
}) })
} }
} }
@ -38,13 +34,13 @@ func (a *goBlog) serveSitemap(w http.ResponseWriter, r *http.Request) {
// Taxonomy // Taxonomy
taxPath := bc.getRelativePath("/" + taxonomy.Name) taxPath := bc.getRelativePath("/" + taxonomy.Name)
sm.Add(&sitemap.URL{ sm.Add(&sitemap.URL{
Loc: a.cfg.Server.PublicAddress + taxPath, Loc: a.getFullAddress(taxPath),
}) })
// Values // Values
if taxValues, err := a.db.allTaxonomyValues(b, taxonomy.Name); err == nil { if taxValues, err := a.db.allTaxonomyValues(b, taxonomy.Name); err == nil {
for _, tv := range taxValues { for _, tv := range taxValues {
sm.Add(&sitemap.URL{ sm.Add(&sitemap.URL{
Loc: a.cfg.Server.PublicAddress + taxPath + "/" + urlize(tv), Loc: a.getFullAddress(taxPath + "/" + urlize(tv)),
}) })
} }
} }
@ -58,7 +54,7 @@ func (a *goBlog) serveSitemap(w http.ResponseWriter, r *http.Request) {
yearPath := bc.getRelativePath("/" + fmt.Sprintf("%0004d", d.year)) yearPath := bc.getRelativePath("/" + fmt.Sprintf("%0004d", d.year))
if !already[yearPath] { if !already[yearPath] {
sm.Add(&sitemap.URL{ sm.Add(&sitemap.URL{
Loc: a.cfg.Server.PublicAddress + yearPath, Loc: a.getFullAddress(yearPath),
}) })
already[yearPath] = true already[yearPath] = true
} }
@ -66,7 +62,7 @@ func (a *goBlog) serveSitemap(w http.ResponseWriter, r *http.Request) {
monthPath := yearPath + "/" + fmt.Sprintf("%02d", d.month) monthPath := yearPath + "/" + fmt.Sprintf("%02d", d.month)
if !already[monthPath] { if !already[monthPath] {
sm.Add(&sitemap.URL{ sm.Add(&sitemap.URL{
Loc: a.cfg.Server.PublicAddress + monthPath, Loc: a.getFullAddress(monthPath),
}) })
already[monthPath] = true already[monthPath] = true
} }
@ -74,15 +70,15 @@ func (a *goBlog) serveSitemap(w http.ResponseWriter, r *http.Request) {
dayPath := monthPath + "/" + fmt.Sprintf("%02d", d.day) dayPath := monthPath + "/" + fmt.Sprintf("%02d", d.day)
if !already[dayPath] { if !already[dayPath] {
sm.Add(&sitemap.URL{ sm.Add(&sitemap.URL{
Loc: a.cfg.Server.PublicAddress + dayPath, Loc: a.getFullAddress(dayPath),
}) })
already[dayPath] = true already[dayPath] = true
} }
// Generic month // Generic month
genericMonthPath := blogPath + "/x/" + fmt.Sprintf("%02d", d.month) genericMonthPath := bc.getRelativePath("/x/" + fmt.Sprintf("%02d", d.month))
if !already[genericMonthPath] { if !already[genericMonthPath] {
sm.Add(&sitemap.URL{ sm.Add(&sitemap.URL{
Loc: a.cfg.Server.PublicAddress + genericMonthPath, Loc: a.getFullAddress(genericMonthPath),
}) })
already[genericMonthPath] = true already[genericMonthPath] = true
} }
@ -90,7 +86,7 @@ func (a *goBlog) serveSitemap(w http.ResponseWriter, r *http.Request) {
genericMonthDayPath := genericMonthPath + "/" + fmt.Sprintf("%02d", d.day) genericMonthDayPath := genericMonthPath + "/" + fmt.Sprintf("%02d", d.day)
if !already[genericMonthDayPath] { if !already[genericMonthDayPath] {
sm.Add(&sitemap.URL{ sm.Add(&sitemap.URL{
Loc: a.cfg.Server.PublicAddress + genericMonthDayPath, Loc: a.getFullAddress(genericMonthDayPath),
}) })
already[genericMonthDayPath] = true already[genericMonthDayPath] = true
} }
@ -99,31 +95,31 @@ func (a *goBlog) serveSitemap(w http.ResponseWriter, r *http.Request) {
// Photos // Photos
if bc.Photos != nil && bc.Photos.Enabled { if bc.Photos != nil && bc.Photos.Enabled {
sm.Add(&sitemap.URL{ sm.Add(&sitemap.URL{
Loc: a.cfg.Server.PublicAddress + bc.getRelativePath(bc.Photos.Path), Loc: a.getFullAddress(bc.getRelativePath(bc.Photos.Path)),
}) })
} }
// Search // Search
if bc.Search != nil && bc.Search.Enabled { if bc.Search != nil && bc.Search.Enabled {
sm.Add(&sitemap.URL{ sm.Add(&sitemap.URL{
Loc: a.cfg.Server.PublicAddress + bc.getRelativePath(bc.Search.Path), Loc: a.getFullAddress(bc.getRelativePath(bc.Search.Path)),
}) })
} }
// Stats // Stats
if bc.BlogStats != nil && bc.BlogStats.Enabled { if bc.BlogStats != nil && bc.BlogStats.Enabled {
sm.Add(&sitemap.URL{ sm.Add(&sitemap.URL{
Loc: a.cfg.Server.PublicAddress + bc.getRelativePath(bc.BlogStats.Path), Loc: a.getFullAddress(bc.getRelativePath(bc.BlogStats.Path)),
}) })
} }
// Blogroll // Blogroll
if bc.Blogroll != nil && bc.Blogroll.Enabled { if bc.Blogroll != nil && bc.Blogroll.Enabled {
sm.Add(&sitemap.URL{ sm.Add(&sitemap.URL{
Loc: a.cfg.Server.PublicAddress + bc.getRelativePath(bc.Blogroll.Path), Loc: a.getFullAddress(bc.getRelativePath(bc.Blogroll.Path)),
}) })
} }
// Custom pages // Custom pages
for _, cp := range bc.CustomPages { for _, cp := range bc.CustomPages {
sm.Add(&sitemap.URL{ sm.Add(&sitemap.URL{
Loc: a.cfg.Server.PublicAddress + cp.Path, Loc: a.getFullAddress(cp.Path),
}) })
} }
} }

View File

@ -14,7 +14,7 @@ func (a *goBlog) serveTaxonomy(w http.ResponseWriter, r *http.Request) {
} }
a.render(w, r, templateTaxonomy, &renderData{ a.render(w, r, templateTaxonomy, &renderData{
BlogString: blog, BlogString: blog,
Canonical: a.cfg.Server.PublicAddress + r.URL.Path, Canonical: a.getFullAddress(r.URL.Path),
Data: map[string]interface{}{ Data: map[string]interface{}{
"Taxonomy": tax, "Taxonomy": tax,
"ValueGroups": groupStrings(allValues), "ValueGroups": groupStrings(allValues),

View File

@ -106,13 +106,6 @@ func unescapedPath(p string) string {
return p return p
} }
func slashIfEmpty(s string) string {
if s == "" {
return "/"
}
return s
}
type stringGroup struct { type stringGroup struct {
Identifier string Identifier string
Strings []string Strings []string

View File

@ -97,8 +97,8 @@ func (a *goBlog) webmentionAdmin(w http.ResponseWriter, r *http.Request) {
"Mentions": mentions, "Mentions": mentions,
"HasPrev": hasPrev, "HasPrev": hasPrev,
"HasNext": hasNext, "HasNext": hasNext,
"Prev": slashIfEmpty(prevPath) + query, "Prev": prevPath + query,
"Next": slashIfEmpty(nextPath) + query, "Next": nextPath + query,
}, },
}) })
} }