mirror of
https://github.com/superseriousbusiness/gotosocial.git
synced 2025-01-20 13:18:46 +01:00
Special-case 400 errors other than 408/429
Most client errors should remove the subscription.
This commit is contained in:
parent
48e87ed470
commit
d1f0e0f449
@ -218,13 +218,34 @@ func (r *realSender) sendToSubscription(
|
||||
_ = resp.Body.Close()
|
||||
}()
|
||||
|
||||
// If there's an error, log the response.
|
||||
if resp.StatusCode < 200 || resp.StatusCode > 299 {
|
||||
if resp.StatusCode >= 400 && resp.StatusCode <= 499 &&
|
||||
resp.StatusCode != http.StatusRequestTimeout &&
|
||||
resp.StatusCode != http.StatusTooManyRequests {
|
||||
// We should not send any more notifications to this subscription. Try to delete it.
|
||||
if err := r.state.DB.DeleteWebPushSubscriptionByTokenID(ctx, subscription.TokenID); err != nil {
|
||||
return gtserror.Newf(
|
||||
"received HTTP status %s but failed to delete subscription: %s",
|
||||
resp.Status,
|
||||
err,
|
||||
)
|
||||
}
|
||||
log.Infof(
|
||||
ctx,
|
||||
"Deleted Web Push subscription with token ID %s because push server sent HTTP status %s",
|
||||
subscription.TokenID,
|
||||
resp.Status,
|
||||
)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Otherwise, try to get the response body.
|
||||
bodyBytes, err := io.ReadAll(io.LimitReader(resp.Body, responseBodyMaxLen))
|
||||
if err != nil {
|
||||
return gtserror.Newf("error reading Web Push server response: %w", err)
|
||||
}
|
||||
|
||||
// Log the error with its response body.
|
||||
return gtserror.Newf(
|
||||
"unexpected HTTP status %s received when sending Web Push notification: %s",
|
||||
resp.Status,
|
||||
|
@ -178,9 +178,12 @@ func (rc *notifyingReadCloser) Close() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (suite *RealSenderStandardTestSuite) TestSendSuccess() {
|
||||
// Set a timeout on the whole test. If it fails due to the timeout,
|
||||
// the push notification was not sent for some reason.
|
||||
// Simulate sending a push notification with the suite's fake web client.
|
||||
func (suite *RealSenderStandardTestSuite) simulatePushNotification(
|
||||
statusCode int,
|
||||
expectDeletedSubscription bool,
|
||||
) error {
|
||||
// Don't let the test run forever if the push notification was not sent for some reason.
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
defer cancel()
|
||||
|
||||
@ -193,17 +196,17 @@ func (suite *RealSenderStandardTestSuite) TestSendSuccess() {
|
||||
bodyClosed: make(chan struct{}, 1),
|
||||
}
|
||||
|
||||
// Simulate a successful response from the Web Push server.
|
||||
// Simulate a response from the Web Push server.
|
||||
suite.webPushHttpClientDo = func(request *http.Request) (*http.Response, error) {
|
||||
return &http.Response{
|
||||
Status: "200 OK",
|
||||
StatusCode: 200,
|
||||
Status: http.StatusText(statusCode),
|
||||
StatusCode: statusCode,
|
||||
Body: rc,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Send the push notification.
|
||||
suite.NoError(suite.webPushSender.Send(ctx, notification, nil, nil))
|
||||
sendError := suite.webPushSender.Send(ctx, notification, nil, nil)
|
||||
|
||||
// Wait for it to be sent or for the context to time out.
|
||||
bodyClosed := false
|
||||
@ -216,6 +219,42 @@ func (suite *RealSenderStandardTestSuite) TestSendSuccess() {
|
||||
}
|
||||
suite.True(bodyClosed)
|
||||
suite.False(contextExpired)
|
||||
|
||||
// Look for the associated Web Push subscription. Some server responses should delete it.
|
||||
subscription, err := suite.state.DB.GetWebPushSubscriptionByTokenID(
|
||||
ctx,
|
||||
suite.testWebPushSubscriptions["local_account_1_token_1"].TokenID,
|
||||
)
|
||||
if expectDeletedSubscription {
|
||||
suite.ErrorIs(err, db.ErrNoEntries)
|
||||
} else {
|
||||
suite.NotNil(subscription)
|
||||
}
|
||||
|
||||
return sendError
|
||||
}
|
||||
|
||||
// Test a successful response to sending a push notification.
|
||||
func (suite *RealSenderStandardTestSuite) TestSendSuccess() {
|
||||
suite.NoError(suite.simulatePushNotification(http.StatusOK, false))
|
||||
}
|
||||
|
||||
// Test a rate-limiting response to sending a push notification.
|
||||
// This should not delete the subscription.
|
||||
func (suite *RealSenderStandardTestSuite) TestRateLimited() {
|
||||
suite.NoError(suite.simulatePushNotification(http.StatusTooManyRequests, false))
|
||||
}
|
||||
|
||||
// Test a non-special-cased client error response to sending a push notification.
|
||||
// This should delete the subscription.
|
||||
func (suite *RealSenderStandardTestSuite) TestClientError() {
|
||||
suite.NoError(suite.simulatePushNotification(http.StatusBadRequest, true))
|
||||
}
|
||||
|
||||
// Test a server error response to sending a push notification.
|
||||
// This should not delete the subscription.
|
||||
func (suite *RealSenderStandardTestSuite) TestServerError() {
|
||||
suite.NoError(suite.simulatePushNotification(http.StatusInternalServerError, false))
|
||||
}
|
||||
|
||||
func TestRealSenderStandardTestSuite(t *testing.T) {
|
||||
|
Loading…
Reference in New Issue
Block a user