diff --git a/activityPub.go b/activityPub.go index cb5af35..ba709ba 100644 --- a/activityPub.go +++ b/activityPub.go @@ -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 diff --git a/activityStreams.go b/activityStreams.go index 50a02ef..12cedaf 100644 --- a/activityStreams.go +++ b/activityStreams.go @@ -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 diff --git a/api.go b/api.go index 9dd3561..f20ab16 100644 --- a/api.go +++ b/api.go @@ -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 } } diff --git a/authentication.go b/authentication.go index c20d5ad..9bce37d 100644 --- a/authentication.go +++ b/authentication.go @@ -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{ diff --git a/customPages.go b/customPages.go index d77e28a..e935ff6 100644 --- a/customPages.go +++ b/customPages.go @@ -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) diff --git a/editor.go b/editor.go index ceddb74..b43c814 100644 --- a/editor.go +++ b/editor.go @@ -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 } diff --git a/errors.go b/errors.go index 9d47f32..4790516 100644 --- a/errors.go +++ b/errors.go @@ -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) } diff --git a/feeds.go b/feeds.go index bfdc807..7e7501d 100644 --- a/feeds.go +++ b/feeds.go @@ -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) diff --git a/http.go b/http.go index 9f23fd2..083f82a 100644 --- a/http.go +++ b/http.go @@ -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 } diff --git a/indieAuth.go b/indieAuth.go index 826d3a5..39f7ab9 100644 --- a/indieAuth.go +++ b/indieAuth.go @@ -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, " ")))) diff --git a/indieAuthServer.go b/indieAuthServer.go index 5394e54..d446dbe 100644 --- a/indieAuthServer.go +++ b/indieAuthServer.go @@ -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 } } diff --git a/micropub.go b/micropub.go index 046eace..54a07f4 100644 --- a/micropub.go +++ b/micropub.go @@ -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 := µformatItem{} 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) diff --git a/micropubMedia.go b/micropubMedia.go index 398ca35..aea7e7f 100644 --- a/micropubMedia.go +++ b/micropubMedia.go @@ -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 diff --git a/postAliases.go b/postAliases.go index c1f8358..da3257d 100644 --- a/postAliases.go +++ b/postAliases.go @@ -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) diff --git a/posts.go b/posts.go index cd9c629..f51ca34 100644 --- a/posts.go +++ b/posts.go @@ -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 diff --git a/search.go b/search.go index 400dcee..882d16c 100644 --- a/search.go +++ b/search.go @@ -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 != "" { diff --git a/sitemap.go b/sitemap.go index b40458c..8fe1705 100644 --- a/sitemap.go +++ b/sitemap.go @@ -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() diff --git a/taxonomies.go b/taxonomies.go index d03ef1f..2226334 100644 --- a/taxonomies.go +++ b/taxonomies.go @@ -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{ diff --git a/templates/error.gohtml b/templates/error.gohtml index e95273a..93b2e44 100644 --- a/templates/error.gohtml +++ b/templates/error.gohtml @@ -5,7 +5,7 @@ {{ define "main" }}
{{ with .Data.Title }}

{{ . }}

{{ end }} - {{ with .Data.Message }}{{ md . }}{{ end }} + {{ with .Data.Message }}

{{ . }}

{{ end }}
{{ end }} diff --git a/webmention.go b/webmention.go index 5863b2f..ca40b44 100644 --- a/webmention.go +++ b/webmention.go @@ -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()