diff options
| author | 2023-11-13 19:48:51 +0100 | |
|---|---|---|
| committer | 2023-11-13 19:48:51 +0100 | |
| commit | 8d0c017cf205bcf57630c91b53079001deed4d36 (patch) | |
| tree | cf2240e3dff137df2871c9b93548a885833e9a52 /internal/api/util | |
| parent | [chore] update otel -> v1.20.0 (#2358) (diff) | |
| download | gotosocial-8d0c017cf205bcf57630c91b53079001deed4d36.tar.xz | |
[feature/performance] Wrap incoming HTTP requests in timeout handler (#2353)
* deinterface router, start messing about with deadlines
* weeeee
* thanks linter (thinter)
* write Connection: close when timing out requests
* update wording
* don't replace req
* don't bother with fancy Cause functions (I'll use them one day...)
Diffstat (limited to 'internal/api/util')
| -rw-r--r-- | internal/api/util/errorhandling.go | 46 | 
1 files changed, 34 insertions, 12 deletions
| diff --git a/internal/api/util/errorhandling.go b/internal/api/util/errorhandling.go index 33f501474..4fa544ffd 100644 --- a/internal/api/util/errorhandling.go +++ b/internal/api/util/errorhandling.go @@ -19,6 +19,7 @@ package util  import (  	"context" +	"errors"  	"net/http"  	"codeberg.org/gruf/go-kv" @@ -90,19 +91,40 @@ func genericErrorHandler(c *gin.Context, instanceGet func(ctx context.Context) (  // try to serve an appropriate application/json content-type error.  // To override the default response type, specify `offers`.  // -// If the requester already hung up on the request, ErrorHandler -// will overwrite the given errWithCode with a 499 error to indicate -// that the failure wasn't due to something we did, and will avoid -// trying to write extensive bytes to the caller by just aborting. +// If the requester already hung up on the request, or the server +// timed out a very slow request, ErrorHandler will overwrite the +// given errWithCode with a 408 or 499 error to indicate that the +// failure wasn't due to something we did, and will avoid trying +// to write extensive bytes to the caller by just aborting.  // -// See: https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#nginx. -func ErrorHandler(c *gin.Context, errWithCode gtserror.WithCode, instanceGet func(ctx context.Context) (*apimodel.InstanceV1, gtserror.WithCode), offers ...MIME) { -	if c.Request.Context().Err() != nil { -		// Context error means requester probably left already. -		// Wrap original error with a less alarming one. Then -		// we can return early, because it doesn't matter what -		// we send to the client at this point; they're gone. -		errWithCode = gtserror.NewErrorClientClosedRequest(errWithCode.Unwrap()) +// For 499, see https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#nginx. +func ErrorHandler( +	c *gin.Context, +	errWithCode gtserror.WithCode, +	instanceGet func(ctx context.Context) (*apimodel.InstanceV1, gtserror.WithCode), +	offers ...MIME, +) { +	if ctxErr := c.Request.Context().Err(); ctxErr != nil { +		// Context error means either client has left already, +		// or server has timed out a very slow request. +		// +		// Rewrap the error with something less scary, +		// and just abort the request gracelessly. +		err := errWithCode.Unwrap() + +		if errors.Is(ctxErr, context.DeadlineExceeded) { +			// We timed out the request. +			errWithCode = gtserror.NewErrorRequestTimeout(err) + +			// Be correct and write "close". +			// See: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Connection#close +			// and: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/408 +			c.Header("Connection", "close") +		} else { +			// Client timed out the request. +			errWithCode = gtserror.NewErrorClientClosedRequest(err) +		} +  		c.AbortWithStatus(errWithCode.Code())  		return  	} | 
