[bug] Handle 410 on webfinger properly (#1601)

When we receive an HTTP 410 on webfinger it means the resource we asked
for (the account) is gone, but the endpoint itself responded. In such
cases we want to treat the request as successful from a cache (renewal)
point of view, while still returning an error from Finger.

Follow-up for #1588
This commit is contained in:
Daenney 2023-03-09 11:17:11 +01:00 committed by GitHub
parent d0dee8d0b6
commit 9ba35c65eb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -82,14 +82,19 @@ func (t *transport) Finger(ctx context.Context, targetUsername string, targetDom
} }
defer rsp.Body.Close() defer rsp.Body.Close()
// Check if the request succeeded so we can bail out early // Check if the request succeeded so we can bail out early or if we explicitly
if rsp.StatusCode == http.StatusOK { // got a "this resource is gone" response which will happen when a user has
// deleted the account
if rsp.StatusCode == http.StatusOK || rsp.StatusCode == http.StatusGone {
if cached { if cached {
// If we got a success on a cached URL, i.e one set by us later on when // If we got a response we consider successful on a cached URL, i.e one set
// a host-meta based webfinger request succeeded, set it again here to // by us later on when a host-meta based webfinger request succeeded, set it
// renew the TTL // again here to renew the TTL
t.controller.state.Caches.GTS.Webfinger().Set(targetDomain, url) t.controller.state.Caches.GTS.Webfinger().Set(targetDomain, url)
} }
if rsp.StatusCode == http.StatusGone {
return nil, fmt.Errorf("account has been deleted/is gone")
}
return io.ReadAll(rsp.Body) return io.ReadAll(rsp.Body)
} }
@ -135,6 +140,13 @@ func (t *transport) Finger(ctx context.Context, targetUsername string, targetDom
defer rsp.Body.Close() defer rsp.Body.Close()
if rsp.StatusCode != http.StatusOK { if rsp.StatusCode != http.StatusOK {
// A HTTP 410 indicates we got a response to our webfinger query, but the resource
// we asked for is gone. This means the endpoint itself is valid and we should
// cache it for future queries to the same domain
if rsp.StatusCode == http.StatusGone {
t.controller.state.Caches.GTS.Webfinger().Set(targetDomain, host)
return nil, fmt.Errorf("account has been deleted/is gone")
}
// We've reached the end of the line here, both the original request // We've reached the end of the line here, both the original request
// and our attempt to resolve it through the fallback have failed // and our attempt to resolve it through the fallback have failed
return nil, fmt.Errorf("GET request to %s failed: %s", req.URL.String(), rsp.Status) return nil, fmt.Errorf("GET request to %s failed: %s", req.URL.String(), rsp.Status)