@@ -27,17 +27,17 @@ func sourceURL(raw string) (*url.URL, error) {
u, e := url.Parse(raw)
if e != nil || u == nil || (u.Scheme != "http" && u.Scheme != "https") || u.Hostname() == "" || u.User != nil {
- return nil, fmt.Errorf("fetch URL has an invalid scheme, host, or credentials")
+ return nil, fmt.Errorf("bad fetch url")
}
if p := u.Port(); p != "" && p != "80" && p != "443" {
- return nil, fmt.Errorf("port is not allowed")
+ return nil, fmt.Errorf("port not allowed")
}
return u, nil
}
func redirectCheck(max int) func(*http.Request, []*http.Request) error {
return func(r *http.Request, via []*http.Request) error {
if len(via) > max {
- return fmt.Errorf("redirect limit")
+ return fmt.Errorf("too many redirects")
}
_, e := sourceURL(r.URL.String())
return e
@@ -45,7 +45,7 @@ } }
func NewSafeFetcher(c Config) (*SafeFetcher, error) {
if c.FetchTimeout <= 0 || c.MaxBody <= 0 || c.Redirects <= 0 {
- return nil, fmt.Errorf("fetch limits are invalid")
+ return nil, fmt.Errorf("bad fetch limits")
}
tr := &http.Transport{Proxy: nil, ForceAttemptHTTP2: true, ResponseHeaderTimeout: c.FetchTimeout, TLSHandshakeTimeout: c.FetchTimeout, IdleConnTimeout: 30 * time.Second, MaxIdleConns: 4, MaxIdleConnsPerHost: 2, MaxResponseHeaderBytes: 32 << 10}
cfg := safeurl.GetConfigBuilder().SetAllowedSchemes("http", "https").SetAllowedPorts(80, 443).EnableIPv6(true).SetTimeout(c.FetchTimeout).SetCheckRedirect(redirectCheck(c.Redirects)).SetTransport(tr).Build()
@@ -72,14 +72,14 @@ return p, nil }
media, _, err := mime.ParseMediaType(res.Header.Get("Content-Type"))
if err != nil || (media != "text/html" && media != "application/xhtml+xml") {
- return Page{}, fmt.Errorf("source Content-Type must be HTML")
+ return Page{}, fmt.Errorf("not html")
}
body, e := io.ReadAll(io.LimitReader(res.Body, f.limit+1))
if e != nil {
return Page{}, e
}
if int64(len(body)) > f.limit {
- return Page{}, fmt.Errorf("decoded body exceeds the size limit")
+ return Page{}, fmt.Errorf("body too big")
}
p.Body = body
return p, nil
@@ -21,7 +21,7 @@ func landingDocument(publicURL string) ([]byte, error) {
base, e := url.Parse(publicURL)
if e != nil || base.Scheme == "" || base.Host == "" {
- return nil, fmt.Errorf("cannot use public URL as base: %q", publicURL)
+ return nil, fmt.Errorf("bad public url %q", publicURL)
}
entry, e := renderEntry(landingMarkdown, base)
if e != nil {
@@ -42,7 +42,7 @@ return nil, e }
name, rest := splitEntry(doc)
if name == nil {
- return nil, fmt.Errorf("missing primary heading")
+ return nil, fmt.Errorf("landing has no h1")
}
name.SetAttributeString("class", "p-name")
var buf bytes.Buffer
@@ -30,7 +30,7 @@ if e := c.Validate(); e != nil { return nil, e
}
if s == nil || f == nil {
- return nil, fmt.Errorf("processing dependencies are required")
+ return nil, fmt.Errorf("need a store and a fetcher")
}
landing, e := landingDocument(c.PublicURL)
if e != nil {
@@ -98,7 +98,7 @@ return }
if e = a.Store.Finish(ctx, j, e, a.Config.Attempts, time.Now()); e != nil {
a.unhealthy.Store(true)
- log.Print("failed to store mention processing state")
+ log.Print("could not save the job")
}
}
}
@@ -134,16 +134,16 @@ }) m.HandleFunc("POST /webmention", func(w http.ResponseWriter, r *http.Request) {
media, _, e := mime.ParseMediaType(r.Header.Get("Content-Type"))
if e != nil || media != "application/x-www-form-urlencoded" {
- http.Error(w, "form content type is required", 400)
+ http.Error(w, "need a urlencoded form", 400)
return
}
r.Body = http.MaxBytesReader(w, r.Body, a.Config.MaxForm)
if e = r.ParseForm(); e != nil {
- http.Error(w, "form is invalid or exceeds the size limit", 400)
+ http.Error(w, "bad form", 400)
return
}
if len(r.PostForm["source"]) != 1 || len(r.PostForm["target"]) != 1 {
- http.Error(w, "source and target are each required once", 400)
+ http.Error(w, "source and target, once each", 400)
return
}
source, target := r.PostForm.Get("source"), r.PostForm.Get("target")
@@ -151,7 +151,7 @@ u, sourceErr := sourceURL(source) t, targetErr := url.Parse(target)
public, _ := url.Parse(a.Config.PublicURL)
if sourceErr != nil || targetErr != nil || rootURLString(t) != rootURLString(public) {
- http.Error(w, "source or target is invalid", 400)
+ http.Error(w, "bad source or target", 400)
return
}
u.Fragment = ""
@@ -163,13 +163,13 @@ } e = a.Store.Enqueue(r.Context(), source, rootURLString(t), a.Config.Queue, time.Now())
if errors.Is(e, ErrStored) {
w.Header().Set("Content-Type", "text/plain; charset=utf-8")
- fmt.Fprintln(w, "Kept the stored snapshot. The relay does not refetch or change it.")
+ fmt.Fprintln(w, "already stored")
return
}
if errors.Is(e, ErrOutstanding) {
w.Header().Set("Content-Type", "text/plain; charset=utf-8")
w.WriteHeader(202)
- fmt.Fprintln(w, "The mention is already durably accepted. Existing processing continues. Publication follows source verification.")
+ fmt.Fprintln(w, "already in the queue")
return
}
if errors.Is(e, ErrFull) {
@@ -177,12 +177,12 @@ http.Error(w, "mention queue is full", 503) return
}
if e != nil {
- http.Error(w, "durable acceptance failed", 503)
+ http.Error(w, "could not save the mention", 503)
return
}
w.Header().Set("Content-Type", "text/plain; charset=utf-8")
w.WriteHeader(202)
- fmt.Fprintln(w, "Durably accepted the mention. Publication follows source verification.")
+ fmt.Fprintln(w, "accepted")
})
m.HandleFunc("GET /collections/{name}", func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Access-Control-Allow-Origin", "*")
@@ -209,13 +209,13 @@ http.NotFound(w, r) return
}
if e != nil {
- http.Error(w, "failed to read stored data", 503)
+ http.Error(w, "could not read the feed", 503)
return
}
if suffix == ".jf2" {
b, e := JF2(a.Config.PublicURL, id, posts, a.Config.FeedLimit)
if e != nil {
- http.Error(w, "failed to build JF2", 500)
+ http.Error(w, "could not build the jf2", 500)
return
}
w.Header().Set("Content-Type", "application/jf2feed+json")
@@ -224,7 +224,7 @@ return }
b, e := Atom(a.Config.PublicURL, id, updated, posts, a.Config.FeedLimit)
if e != nil {
- http.Error(w, "failed to build Atom", 500)
+ http.Error(w, "could not build the atom", 500)
return
}
w.Header().Set("Content-Type", "application/atom+xml; charset=utf-8")
@@ -234,7 +234,7 @@ m.HandleFunc("GET /healthz", func(w http.ResponseWriter, r *http.Request) { ctx, cancel := context.WithTimeout(r.Context(), time.Second)
defer cancel()
if a.active.Load() != int32(a.Config.Workers) || a.unhealthy.Load() || a.Store.Health(ctx) != nil {
- http.Error(w, "worker or storage is unavailable", 503)
+ http.Error(w, "not healthy", 503)
return
}
fmt.Fprintln(w, "ok")