Browse Source

Improve error rendering

master
Jan-Lukas Else 3 weeks ago
parent
commit
9e4a03549f
20 changed files with 109 additions and 92 deletions
  1. +8
    -8
      activityPub.go
  2. +2
    -2
      activityStreams.go
  3. +4
    -4
      api.go
  4. +3
    -3
      authentication.go
  5. +1
    -1
      customPages.go
  6. +6
    -6
      editor.go
  7. +16
    -3
      errors.go
  8. +1
    -1
      feeds.go
  9. +4
    -0
      http.go
  10. +1
    -1
      indieAuth.go
  11. +15
    -15
      indieAuthServer.go
  12. +22
    -22
      micropub.go
  13. +8
    -8
      micropubMedia.go
  14. +2
    -2
      postAliases.go
  15. +3
    -3
      posts.go
  16. +1
    -1
      search.go
  17. +1
    -1
      sitemap.go
  18. +1
    -1
      taxonomies.go
  19. +1
    -1
      templates/error.gohtml
  20. +9
    -9
      webmention.go

+ 8
- 8
activityPub.go View File

@ -74,13 +74,13 @@ func initActivityPub() error {
func apHandleWebfinger(w http.ResponseWriter, r *http.Request) {
re, err := regexp.Compile(`^acct:(.*)@` + regexp.QuoteMeta(appConfig.Server.Domain) + `$`)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
serveError(w, r, err.Error(), http.StatusInternalServerError)
return
}
name := re.ReplaceAllString(r.URL.Query().Get("resource"), "$1")
blog := appConfig.Blogs[name]
if blog == nil {
http.Error(w, "Not found", http.StatusNotFound)
serveError(w, r, "Blog not found", http.StatusNotFound)
return
}
w.Header().Set(contentType, "application/jrd+json"+charsetUtf8Suffix)
@ -100,7 +100,7 @@ func apHandleInbox(w http.ResponseWriter, r *http.Request) {
blogName := chi.URLParam(r, "blog")
blog := appConfig.Blogs[blogName]
if blog == nil {
http.Error(w, "Inbox not found", http.StatusNotFound)
serveError(w, r, "Inbox not found", http.StatusNotFound)
return
}
blogIri := blog.apIri()
@ -108,7 +108,7 @@ func apHandleInbox(w http.ResponseWriter, r *http.Request) {
requestActor, requestKey, requestActorStatus, err := apVerifySignature(r)
if err != nil {
// Send 401 because signature could not be verified
http.Error(w, err.Error(), http.StatusUnauthorized)
serveError(w, r, err.Error(), http.StatusUnauthorized)
return
}
if requestActorStatus != 0 {
@ -122,7 +122,7 @@ func apHandleInbox(w http.ResponseWriter, r *http.Request) {
return
}
}
http.Error(w, "Error when trying to get request actor", http.StatusBadRequest)
serveError(w, r, "Error when trying to get request actor", http.StatusBadRequest)
return
}
// Parse activity
@ -130,17 +130,17 @@ func apHandleInbox(w http.ResponseWriter, r *http.Request) {
err = json.NewDecoder(r.Body).Decode(&activity)
_ = r.Body.Close()
if err != nil {
http.Error(w, "Failed to decode body", http.StatusBadRequest)
serveError(w, r, "Failed to decode body", http.StatusBadRequest)
return
}
// Get and check activity actor
activityActor, ok := activity["actor"].(string)
if !ok {
http.Error(w, "actor in activity is no string", http.StatusBadRequest)
serveError(w, r, "actor in activity is no string", http.StatusBadRequest)
return
}
if activityActor != requestActor.ID {
http.Error(w, "Request actor isn't activity actor", http.StatusForbidden)
serveError(w, r, "Request actor isn't activity actor", http.StatusForbidden)
return
}
// Do


+ 2
- 2
activityStreams.go View File

@ -119,10 +119,10 @@ func (p *post) toASNote() *asNote {
return as
}
func (b *configBlog) serveActivityStreams(blog string, w http.ResponseWriter) {
func (b *configBlog) serveActivityStreams(blog string, w http.ResponseWriter, r *http.Request) {
publicKeyDer, err := x509.MarshalPKIXPublicKey(&apPrivateKey.PublicKey)
if err != nil {
http.Error(w, "Failed to marshal public key", http.StatusInternalServerError)
serveError(w, r, "Failed to marshal public key", http.StatusInternalServerError)
return
}
// Send JSON


+ 4
- 4
api.go View File

@ -17,12 +17,12 @@ func apiPostCreateHugo(w http.ResponseWriter, r *http.Request) {
}()
bodyContent, err := ioutil.ReadAll(r.Body)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
serveError(w, r, err.Error(), http.StatusBadRequest)
return
}
p, aliases, err := parseHugoFile(string(bodyContent))
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
serveError(w, r, err.Error(), http.StatusInternalServerError)
return
}
p.Blog = blog
@ -31,7 +31,7 @@ func apiPostCreateHugo(w http.ResponseWriter, r *http.Request) {
p.Slug = slug
err = p.replace()
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
serveError(w, r, err.Error(), http.StatusBadRequest)
return
}
aliases = append(aliases, alias)
@ -51,7 +51,7 @@ func apiPostCreateHugo(w http.ResponseWriter, r *http.Request) {
p.Parameters["aliases"] = aliases
err = p.replace()
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
serveError(w, r, err.Error(), http.StatusBadRequest)
return
}
}


+ 3
- 3
authentication.go View File

@ -82,7 +82,7 @@ func checkLogin(w http.ResponseWriter, r *http.Request) bool {
// Set basic auth
req.SetBasicAuth(r.FormValue("username"), r.FormValue("password"))
// Send cookie
sendTokenCookie(w)
sendTokenCookie(w, r)
// Serve original request
d.ServeHTTP(w, req)
return true
@ -90,11 +90,11 @@ func checkLogin(w http.ResponseWriter, r *http.Request) bool {
return false
}
func sendTokenCookie(w http.ResponseWriter) {
func sendTokenCookie(w http.ResponseWriter, r *http.Request) {
expiration := time.Now().Add(7 * 24 * time.Hour)
tokenString, err := jwt.NewWithClaims(jwt.SigningMethodHS256, &jwt.StandardClaims{ExpiresAt: expiration.Unix()}).SignedString(jwtKey())
if err != nil {
http.Error(w, "failed to sign JWT", http.StatusInternalServerError)
serveError(w, r, "Failed to sign JWT", http.StatusInternalServerError)
return
}
http.SetCookie(w, &http.Cookie{


+ 1
- 1
customPages.go View File

@ -3,7 +3,7 @@ package main
import "net/http"
func serveCustomPage(blog *configBlog, page *customPage) func(w http.ResponseWriter, r *http.Request) {
return func(w http.ResponseWriter, r *http.Request) {
return func(w http.ResponseWriter, _ *http.Request) {
if appConfig.Cache != nil && appConfig.Cache.Enable && page.Cache {
if page.CacheExpiration != 0 {
setInternalCacheExpirationHeader(w, page.CacheExpiration)


+ 6
- 6
editor.go View File

@ -10,7 +10,7 @@ import (
const editorPath = "/editor"
func serveEditor(w http.ResponseWriter, r *http.Request) {
func serveEditor(w http.ResponseWriter, _ *http.Request) {
render(w, templateEditor, &renderData{})
}
@ -20,12 +20,12 @@ func serveEditorPost(w http.ResponseWriter, r *http.Request) {
case "loadupdate":
parsedURL, err := url.Parse(r.FormValue("url"))
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
serveError(w, r, err.Error(), http.StatusBadRequest)
return
}
post, err := getPost(parsedURL.Path)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
serveError(w, r, err.Error(), http.StatusBadRequest)
return
}
mf := post.toMfItem()
@ -49,12 +49,12 @@ func serveEditorPost(w http.ResponseWriter, r *http.Request) {
}
jsonBytes, err := json.Marshal(mf)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
serveError(w, r, err.Error(), http.StatusInternalServerError)
return
}
req, err := http.NewRequest(http.MethodPost, "", bytes.NewReader(jsonBytes))
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
serveError(w, r, err.Error(), http.StatusInternalServerError)
return
}
req.Header.Set(contentType, contentTypeJSON)
@ -62,7 +62,7 @@ func serveEditorPost(w http.ResponseWriter, r *http.Request) {
case "upload":
editorMicropubPost(w, r, true)
default:
http.Error(w, "unknown editoraction", http.StatusBadRequest)
serveError(w, r, "Unknown editoraction", http.StatusBadRequest)
}
return
}


+ 16
- 3
errors.go View File

@ -3,6 +3,7 @@ package main
import (
"fmt"
"net/http"
"strings"
)
type errorData struct {
@ -11,11 +12,23 @@ type errorData struct {
}
func serve404(w http.ResponseWriter, r *http.Request) {
serveError(w, r, fmt.Sprintf("%s was not found", r.RequestURI), http.StatusNotFound)
}
func serveError(w http.ResponseWriter, r *http.Request, message string, status int) {
if !strings.Contains(strings.ToLower(r.Header.Get("Accept")), contentTypeHTML) {
http.Error(w, message, status)
return
}
title := fmt.Sprintf("%d %s", status, http.StatusText(status))
if message == "" {
message = http.StatusText(status)
}
render(w, templateError, &renderData{
Data: &errorData{
Title: "404 Not Found",
Message: fmt.Sprintf("`%s` was not found", r.RequestURI),
Title: title,
Message: message,
},
})
w.WriteHeader(http.StatusNotFound)
w.WriteHeader(status)
}

+ 1
- 1
feeds.go View File

@ -81,7 +81,7 @@ func generateFeed(blog string, f feedType, w http.ResponseWriter, r *http.Reques
}
if err != nil {
w.Header().Del(contentType)
http.Error(w, err.Error(), http.StatusInternalServerError)
serveError(w, r, err.Error(), http.StatusInternalServerError)
return
}
w.WriteHeader(http.StatusOK)


+ 4
- 0
http.go View File

@ -296,6 +296,10 @@ func buildHandler() (http.Handler, error) {
// Check redirects, then serve 404
r.With(checkRegexRedirects, cacheMiddleware, minifier.Middleware).NotFound(serve404)
r.With(minifier.Middleware).MethodNotAllowed(func(rw http.ResponseWriter, r *http.Request) {
serveError(rw, r, "", http.StatusMethodNotAllowed)
})
return r, nil
}


+ 1
- 1
indieAuth.go View File

@ -14,7 +14,7 @@ func checkIndieAuth(next http.Handler) http.Handler {
}
tokenData, err := verifyIndieAuthToken(bearerToken)
if err != nil {
http.Error(w, err.Error(), http.StatusUnauthorized)
serveError(w, r, err.Error(), http.StatusUnauthorized)
return
}
next.ServeHTTP(w, r.WithContext(context.WithValue(r.Context(), "scope", strings.Join(tokenData.Scopes, " "))))


+ 15
- 15
indieAuthServer.go View File

@ -35,18 +35,18 @@ func indieAuthRequest(w http.ResponseWriter, r *http.Request) {
State: r.Form.Get("state"),
}
if rt := r.Form.Get("response_type"); rt != "code" && rt != "id" && rt != "" {
http.Error(w, "response_type must be code", http.StatusBadRequest)
serveError(w, r, "response_type must be code", http.StatusBadRequest)
return
}
if scope := r.Form.Get("scope"); scope != "" {
data.Scopes = strings.Split(scope, " ")
}
if !isValidProfileURL(data.ClientID) || !isValidProfileURL(data.RedirectURI) {
http.Error(w, "client_id and redirect_uri need to by valid URLs", http.StatusBadRequest)
serveError(w, r, "client_id and redirect_uri need to by valid URLs", http.StatusBadRequest)
return
}
if data.State == "" {
http.Error(w, "state must not be empty", http.StatusBadRequest)
serveError(w, r, "state must not be empty", http.StatusBadRequest)
return
}
render(w, "indieauth", &renderData{
@ -90,7 +90,7 @@ func indieAuthAccept(w http.ResponseWriter, r *http.Request) {
data.code = fmt.Sprintf("%x", sha.Sum(nil))
err := data.saveAuthorization()
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
serveError(w, r, err.Error(), http.StatusInternalServerError)
return
}
http.Redirect(w, r, data.RedirectURI+"?code="+data.code+"&state="+data.State, http.StatusFound)
@ -114,11 +114,11 @@ func indieAuthVerification(w http.ResponseWriter, r *http.Request) {
}
valid, err := data.verifyAuthorization()
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
serveError(w, r, err.Error(), http.StatusInternalServerError)
return
}
if !valid {
http.Error(w, "Authentication not valid", http.StatusForbidden)
serveError(w, r, "Authentication not valid", http.StatusForbidden)
return
}
res := &tokenResponse{
@ -128,7 +128,7 @@ func indieAuthVerification(w http.ResponseWriter, r *http.Request) {
err = json.NewEncoder(w).Encode(res)
if err != nil {
w.Header().Del(contentType)
http.Error(w, err.Error(), http.StatusInternalServerError)
serveError(w, r, err.Error(), http.StatusInternalServerError)
return
}
}
@ -138,7 +138,7 @@ func indieAuthToken(w http.ResponseWriter, r *http.Request) {
// Token verification
data, err := verifyIndieAuthToken(r.Header.Get("Authorization"))
if err != nil {
http.Error(w, "Invalid token or token not found", http.StatusUnauthorized)
serveError(w, r, "Invalid token or token not found", http.StatusUnauthorized)
return
}
res := &tokenResponse{
@ -150,7 +150,7 @@ func indieAuthToken(w http.ResponseWriter, r *http.Request) {
err = json.NewEncoder(w).Encode(res)
if err != nil {
w.Header().Del(contentType)
http.Error(w, err.Error(), http.StatusInternalServerError)
serveError(w, r, err.Error(), http.StatusInternalServerError)
return
}
return
@ -171,15 +171,15 @@ func indieAuthToken(w http.ResponseWriter, r *http.Request) {
}
valid, err := data.verifyAuthorization()
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
serveError(w, r, err.Error(), http.StatusInternalServerError)
return
}
if !valid {
http.Error(w, "Authentication not valid", http.StatusForbidden)
serveError(w, r, "Authentication not valid", http.StatusForbidden)
return
}
if len(data.Scopes) < 1 {
http.Error(w, "No scope", http.StatusBadRequest)
serveError(w, r, "No scope", http.StatusBadRequest)
return
}
data.time = time.Now()
@ -188,7 +188,7 @@ func indieAuthToken(w http.ResponseWriter, r *http.Request) {
data.token = fmt.Sprintf("%x", sha.Sum(nil))
err = data.saveToken()
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
serveError(w, r, err.Error(), http.StatusInternalServerError)
return
}
res := &tokenResponse{
@ -201,12 +201,12 @@ func indieAuthToken(w http.ResponseWriter, r *http.Request) {
err = json.NewEncoder(w).Encode(res)
if err != nil {
w.Header().Del(contentType)
http.Error(w, err.Error(), http.StatusInternalServerError)
serveError(w, r, err.Error(), http.StatusInternalServerError)
return
}
return
}
http.Error(w, "", http.StatusBadRequest)
serveError(w, r, "", http.StatusBadRequest)
return
}
}


+ 22
- 22
micropub.go View File

@ -36,12 +36,12 @@ func serveMicropubQuery(w http.ResponseWriter, r *http.Request) {
if urlString := r.URL.Query().Get("url"); urlString != "" {
u, err := url.Parse(r.URL.Query().Get("url"))
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
serveError(w, r, err.Error(), http.StatusBadRequest)
return
}
p, err := getPost(u.Path)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
serveError(w, r, err.Error(), http.StatusBadRequest)
return
}
mf = p.toMfItem()
@ -53,7 +53,7 @@ func serveMicropubQuery(w http.ResponseWriter, r *http.Request) {
offset: offset,
})
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
serveError(w, r, err.Error(), http.StatusInternalServerError)
return
}
list := map[string][]*microformatItem{}
@ -70,7 +70,7 @@ func serveMicropubQuery(w http.ResponseWriter, r *http.Request) {
for blog := range appConfig.Blogs {
values, err := allTaxonomyValues(blog, appConfig.Micropub.CategoryParam)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
serveError(w, r, err.Error(), http.StatusInternalServerError)
return
}
allCategories = append(allCategories, values...)
@ -81,7 +81,7 @@ func serveMicropubQuery(w http.ResponseWriter, r *http.Request) {
"categories": allCategories,
})
default:
w.WriteHeader(http.StatusNotFound)
serve404(w, r)
}
}
@ -124,38 +124,38 @@ func serveMicropubPost(w http.ResponseWriter, r *http.Request) {
err = r.ParseForm()
}
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
serveError(w, r, err.Error(), http.StatusBadRequest)
return
}
if action := micropubAction(r.Form.Get("action")); action != "" {
u, err := url.Parse(r.Form.Get("url"))
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
serveError(w, r, err.Error(), http.StatusBadRequest)
return
}
if action == actionDelete {
micropubDelete(w, r, u)
return
}
http.Error(w, "Action not supported", http.StatusNotImplemented)
serveError(w, r, "Action not supported", http.StatusNotImplemented)
return
}
p, err = convertMPValueMapToPost(r.Form)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
serveError(w, r, err.Error(), http.StatusInternalServerError)
return
}
} else if strings.Contains(ct, contentTypeJSON) {
parsedMfItem := &microformatItem{}
err := json.NewDecoder(r.Body).Decode(parsedMfItem)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
serveError(w, r, err.Error(), http.StatusInternalServerError)
return
}
if parsedMfItem.Action != "" {
u, err := url.Parse(parsedMfItem.URL)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
serveError(w, r, err.Error(), http.StatusBadRequest)
return
}
if parsedMfItem.Action == actionDelete {
@ -166,25 +166,25 @@ func serveMicropubPost(w http.ResponseWriter, r *http.Request) {
micropubUpdate(w, r, u, parsedMfItem)
return
}
http.Error(w, "Action not supported", http.StatusNotImplemented)
serveError(w, r, "Action not supported", http.StatusNotImplemented)
return
}
p, err = convertMPMfToPost(parsedMfItem)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
serveError(w, r, err.Error(), http.StatusInternalServerError)
return
}
} else {
http.Error(w, "wrong content type", http.StatusBadRequest)
serveError(w, r, "wrong content type", http.StatusBadRequest)
return
}
if !strings.Contains(r.Context().Value("scope").(string), "create") {
http.Error(w, "create scope missing", http.StatusForbidden)
serveError(w, r, "create scope missing", http.StatusForbidden)
return
}
err := p.create()
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
serveError(w, r, err.Error(), http.StatusInternalServerError)
return
}
http.Redirect(w, r, p.fullURL(), http.StatusAccepted)
@ -418,11 +418,11 @@ func (p *post) computeExtraPostParameters() error {
func micropubDelete(w http.ResponseWriter, r *http.Request, u *url.URL) {
if !strings.Contains(r.Context().Value("scope").(string), "delete") {
http.Error(w, "delete scope missing", http.StatusForbidden)
serveError(w, r, "delete scope missing", http.StatusForbidden)
return
}
if err := deletePost(u.Path); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
serveError(w, r, err.Error(), http.StatusBadRequest)
return
}
http.Redirect(w, r, u.String(), http.StatusNoContent)
@ -431,12 +431,12 @@ func micropubDelete(w http.ResponseWriter, r *http.Request, u *url.URL) {
func micropubUpdate(w http.ResponseWriter, r *http.Request, u *url.URL, mf *microformatItem) {
if !strings.Contains(r.Context().Value("scope").(string), "update") {
http.Error(w, "update scope missing", http.StatusForbidden)
serveError(w, r, "update scope missing", http.StatusForbidden)
return
}
p, err := getPost(u.Path)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
serveError(w, r, err.Error(), http.StatusBadRequest)
return
}
if mf.Replace != nil {
@ -550,12 +550,12 @@ func micropubUpdate(w http.ResponseWriter, r *http.Request, u *url.URL, mf *micr
}
err = p.computeExtraPostParameters()
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
serveError(w, r, err.Error(), http.StatusInternalServerError)
return
}
err = p.replace()
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
serveError(w, r, err.Error(), http.StatusInternalServerError)
return
}
http.Redirect(w, r, p.fullURL(), http.StatusNoContent)


+ 8
- 8
micropubMedia.go View File

@ -22,25 +22,25 @@ const micropubMediaSubPath = "/media"
func serveMicropubMedia(w http.ResponseWriter, r *http.Request) {
if !strings.Contains(r.Context().Value("scope").(string), "media") {
http.Error(w, "media scope missing", http.StatusForbidden)
serveError(w, r, "media scope missing", http.StatusForbidden)
return
}
if appConfig.Micropub.MediaStorage == nil {
http.Error(w, "Not configured", http.StatusNotImplemented)
serveError(w, r, "Not configured", http.StatusNotImplemented)
return
}
if ct := r.Header.Get(contentType); !strings.Contains(ct, contentTypeMultipartForm) {
http.Error(w, "wrong content-type", http.StatusBadRequest)
serveError(w, r, "wrong content-type", http.StatusBadRequest)
return
}
err := r.ParseMultipartForm(0)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
serveError(w, r, err.Error(), http.StatusBadRequest)
return
}
file, header, err := r.FormFile("file")
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
serveError(w, r, err.Error(), http.StatusBadRequest)
return
}
defer func() { _ = file.Close() }()
@ -48,7 +48,7 @@ func serveMicropubMedia(w http.ResponseWriter, r *http.Request) {
defer func() { _ = hashFile.Close() }()
fileName, err := getSHA256(hashFile)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
serveError(w, r, err.Error(), http.StatusInternalServerError)
return
}
fileExtension := filepath.Ext(header.Filename)
@ -65,13 +65,13 @@ func serveMicropubMedia(w http.ResponseWriter, r *http.Request) {
fileName += strings.ToLower(fileExtension)
location, err := appConfig.Micropub.MediaStorage.uploadToBunny(fileName, file)
if err != nil {
http.Error(w, "failed to upload original file: "+err.Error(), http.StatusInternalServerError)
serveError(w, r, "failed to upload original file: "+err.Error(), http.StatusInternalServerError)
return
}
if appConfig.Micropub.MediaStorage.TinifyKey != "" {
compressedLocation, err := appConfig.Micropub.MediaStorage.tinify(location)
if err != nil {
http.Error(w, "failed to compress file: "+err.Error(), http.StatusInternalServerError)
serveError(w, r, "failed to compress file: "+err.Error(), http.StatusInternalServerError)
return
} else if compressedLocation != "" {
location = compressedLocation


+ 2
- 2
postAliases.go View File

@ -22,7 +22,7 @@ func allPostAliases() ([]string, error) {
func servePostAlias(w http.ResponseWriter, r *http.Request) {
row, err := appDbQueryRow("select path from post_parameters where parameter = 'aliases' and value = @alias", sql.Named("alias", r.URL.Path))
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
serveError(w, r, err.Error(), http.StatusInternalServerError)
return
}
var path string
@ -31,7 +31,7 @@ func servePostAlias(w http.ResponseWriter, r *http.Request) {
serve404(w, r)
return
} else if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
serveError(w, r, err.Error(), http.StatusInternalServerError)
return
}
http.Redirect(w, r, path, http.StatusFound)


+ 3
- 3
posts.go View File

@ -41,7 +41,7 @@ func servePost(w http.ResponseWriter, r *http.Request) {
serve404(w, r)
return
} else if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
serveError(w, r, err.Error(), http.StatusInternalServerError)
return
}
if as {
@ -95,7 +95,7 @@ func serveHome(blog string, path string) func(w http.ResponseWriter, r *http.Req
return func(w http.ResponseWriter, r *http.Request) {
as := strings.HasSuffix(r.URL.Path, ".as")
if as {
appConfig.Blogs[blog].serveActivityStreams(blog, w)
appConfig.Blogs[blog].serveActivityStreams(blog, w, r)
return
}
serveIndex(&indexConfig{
@ -202,7 +202,7 @@ func serveIndex(ic *indexConfig) func(w http.ResponseWriter, r *http.Request) {
var posts []*post
err := p.Results(&posts)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
serveError(w, r, err.Error(), http.StatusInternalServerError)
return
}
// Meta


+ 1
- 1
search.go View File

@ -13,7 +13,7 @@ func serveSearch(blog string, path string) func(w http.ResponseWriter, r *http.R
return func(w http.ResponseWriter, r *http.Request) {
err := r.ParseForm()
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
serveError(w, r, err.Error(), http.StatusBadRequest)
return
}
if q := r.Form.Get("q"); q != "" {


+ 1
- 1
sitemap.go View File

@ -13,7 +13,7 @@ const sitemapPath = "/sitemap.xml"
func serveSitemap(w http.ResponseWriter, r *http.Request) {
posts, err := getPosts(&postsRequestConfig{})
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
serveError(w, r, err.Error(), http.StatusInternalServerError)
return
}
sm := sitemap.New()


+ 1
- 1
taxonomies.go View File

@ -6,7 +6,7 @@ func serveTaxonomy(blog string, tax *taxonomy) func(w http.ResponseWriter, r *ht
return func(w http.ResponseWriter, r *http.Request) {
allValues, err := allTaxonomyValues(blog, tax.Name)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
serveError(w, r, err.Error(), http.StatusInternalServerError)
return
}
render(w, templateTaxonomy, &renderData{


+ 1
- 1
templates/error.gohtml View File

@ -5,7 +5,7 @@
{{ define "main" }}
<main>
{{ with .Data.Title }}<h1>{{ . }}</h1>{{ end }}
{{ with .Data.Message }}{{ md . }}{{ end }}
{{ with .Data.Message }}<p class="monospace">{{ . }}</p>{{ end }}
</main>
{{ end }}


+ 9
- 9
webmention.go View File

@ -45,15 +45,15 @@ func initWebmention() error {
func handleWebmention(w http.ResponseWriter, r *http.Request) {
m, err := extractMention(r)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
serveError(w, r, err.Error(), http.StatusBadRequest)
return
}
if !isAllowedHost(httptest.NewRequest(http.MethodGet, m.Target, nil), r.URL.Host, appConfig.Server.Domain) {
http.Error(w, "target not allowed", http.StatusBadRequest)
serveError(w, r, "target not allowed", http.StatusBadRequest)
return
}
if err = queueMention(m); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
serveError(w, r, err.Error(), http.StatusInternalServerError)
return
}
w.WriteHeader(http.StatusAccepted)
@ -85,14 +85,14 @@ func webmentionAdmin(w http.ResponseWriter, r *http.Request) {
status: webmentionStatusVerified,
})
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
serveError(w, r, err.Error(), http.StatusInternalServerError)
return
}
approved, err := getWebmentions(&webmentionsRequestConfig{
status: webmentionStatusApproved,
})
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
serveError(w, r, err.Error(), http.StatusInternalServerError)
return
}
render(w, "webmentionadmin", &renderData{
@ -106,12 +106,12 @@ func webmentionAdmin(w http.ResponseWriter, r *http.Request) {
func webmentionAdminDelete(w http.ResponseWriter, r *http.Request) {
id, err := strconv.Atoi(r.FormValue("mentionid"))
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
serveError(w, r, err.Error(), http.StatusBadRequest)
return
}
err = deleteWebmention(id)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
serveError(w, r, err.Error(), http.StatusInternalServerError)
return
}
purgeCache()
@ -122,12 +122,12 @@ func webmentionAdminDelete(w http.ResponseWriter, r *http.Request) {
func webmentionAdminApprove(w http.ResponseWriter, r *http.Request) {
id, err := strconv.Atoi(r.FormValue("mentionid"))
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
serveError(w, r, err.Error(), http.StatusBadRequest)
return
}
err = approveWebmention(id)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
serveError(w, r, err.Error(), http.StatusInternalServerError)
return
}
purgeCache()


Loading…
Cancel
Save