From e0f6d69b8b8fa0d9f769fbd469054e3056644d41 Mon Sep 17 00:00:00 2001 From: phenpessoa Date: Tue, 12 Dec 2023 10:30:45 -0300 Subject: [PATCH 1/4] webserver/validation: improve error handling on non OK status codes --- src/validation/errors.go | 15 ++++++++++++++ src/webserver.go | 44 +++++++++++++++++++++------------------- 2 files changed, 38 insertions(+), 21 deletions(-) diff --git a/src/validation/errors.go b/src/validation/errors.go index c0621f73..1285836b 100644 --- a/src/validation/errors.go +++ b/src/validation/errors.go @@ -197,6 +197,17 @@ var ( // ErrorMaintenanceMode will be sent if there is ongoing maintenance // Code: 20005 ErrorMaintenanceMode = Error{errors.New("maintenance mode active")} + + // ErrStatusForbidden will be sent if tibia sent us a 403 response. + // This usually happens when we are rate limited. + // Code: 20006 + ErrStatusForbidden = Error{errors.New("got status forbidden from tibia.com")} + + // ErrStatusForbidden will be sent if tibia sent us a 302 response, but it + // is not in MaintenanceMode. Because if it were, we would throw a + // ErrorMaintenanceMode. + // Code: 20007 + ErrStatusFound = Error{errors.New("got status found from tibia.com")} ) // Code will return the code of the error @@ -290,6 +301,10 @@ func (e Error) Code() int { return 20004 case ErrorMaintenanceMode: return 20005 + case ErrStatusForbidden: + return 20006 + case ErrStatusFound: + return 20007 default: return 0 } diff --git a/src/webserver.go b/src/webserver.go index 70e5f39a..9216dc46 100644 --- a/src/webserver.go +++ b/src/webserver.go @@ -4,6 +4,7 @@ import ( "bytes" "encoding/json" "errors" + "fmt" "log" "net/http" "os" @@ -1225,29 +1226,30 @@ func TibiaDataHTMLDataCollector(TibiaDataRequest TibiaDataRequestStruct) (string if err != nil { log.Printf("[error] TibiaDataHTMLDataCollector (Status: %s, URL: %s) in resp1: %s", res.Status(), res.Request.URL, err) + return "", err + } - switch res.StatusCode() { - case http.StatusForbidden: - // throttled request - LogMessage = "request throttled due to rate-limitation on tibia.com" - log.Printf("[warning] TibiaDataHTMLDataCollector: %s!", LogMessage) - return "", err - - case http.StatusFound: - // Check if page is in maintenance mode - location, _ := res.RawResponse.Location() - if location != nil && location.Host == "maintenance.tibia.com" { - LogMessage := "maintenance mode detected on tibia.com" - log.Printf("[info] TibiaDataHTMLDataCollector: %s!", LogMessage) - return "", validation.ErrorMaintenanceMode - } - fallthrough - - default: - LogMessage = "unknown error occurred on tibia.com" - log.Printf("[error] TibiaDataHTMLDataCollector: %s!", LogMessage) - return "", err + switch res.StatusCode() { + case http.StatusForbidden: + // throttled request + LogMessage = "request throttled due to rate-limitation on tibia.com" + log.Printf("[warning] TibiaDataHTMLDataCollector: %s!", LogMessage) + return "", validation.ErrStatusForbidden + case http.StatusFound: + // Check if page is in maintenance mode + location, _ := res.RawResponse.Location() + if location != nil && location.Host == "maintenance.tibia.com" { + LogMessage := "maintenance mode detected on tibia.com" + log.Printf("[info] TibiaDataHTMLDataCollector: %s!", LogMessage) + return "", validation.ErrorMaintenanceMode } + + LogMessage = fmt.Sprintf( + "unknown error occurred on tibia.com (Status: %d, Location: %s, RequestURL: %s)", + http.StatusFound, location.String(), res.Request.URL, + ) + log.Printf("[error] TibiaDataHTMLDataCollector: %s!", LogMessage) + return "", validation.ErrStatusFound } if TibiaDataRequest.RawBody { From eb1e89c66267adae2a8c8fa65e4985b911239379 Mon Sep 17 00:00:00 2001 From: phenpessoa Date: Tue, 12 Dec 2023 10:37:23 -0300 Subject: [PATCH 2/4] webserver/validation: handle unknown status codes --- src/validation/errors.go | 6 ++++++ src/webserver.go | 13 +++++++++++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/validation/errors.go b/src/validation/errors.go index 1285836b..b0dfb3c7 100644 --- a/src/validation/errors.go +++ b/src/validation/errors.go @@ -208,6 +208,10 @@ var ( // ErrorMaintenanceMode. // Code: 20007 ErrStatusFound = Error{errors.New("got status found from tibia.com")} + + // ErrStatusUnknown will be sent a HTTP request we are not expecting. + // Code: 20008 + ErrStatusUnknown = Error{errors.New("got unknown status from tibia.com")} ) // Code will return the code of the error @@ -305,6 +309,8 @@ func (e Error) Code() int { return 20006 case ErrStatusFound: return 20007 + case ErrStatusUnknown: + return 20008 default: return 0 } diff --git a/src/webserver.go b/src/webserver.go index 9216dc46..3532f0bc 100644 --- a/src/webserver.go +++ b/src/webserver.go @@ -1230,6 +1230,8 @@ func TibiaDataHTMLDataCollector(TibiaDataRequest TibiaDataRequestStruct) (string } switch res.StatusCode() { + case http.StatusOK: + // ok request, nothing to be done case http.StatusForbidden: // throttled request LogMessage = "request throttled due to rate-limitation on tibia.com" @@ -1245,11 +1247,18 @@ func TibiaDataHTMLDataCollector(TibiaDataRequest TibiaDataRequestStruct) (string } LogMessage = fmt.Sprintf( - "unknown error occurred on tibia.com (Status: %d, Location: %s, RequestURL: %s)", - http.StatusFound, location.String(), res.Request.URL, + "unknown error occurred on tibia.com (Status: %d, RequestURL: %s)", + http.StatusFound, res.Request.URL, ) log.Printf("[error] TibiaDataHTMLDataCollector: %s!", LogMessage) return "", validation.ErrStatusFound + default: + LogMessage = fmt.Sprintf( + "unknown error and status occurred on tibia.com (Status: %d, RequestURL: %s)", + res.StatusCode(), res.Request.URL, + ) + log.Printf("[error] TibiaDataHTMLDataCollector: %s!", LogMessage) + return "", validation.ErrStatusUnknown } if TibiaDataRequest.RawBody { From 0fc89be24eb43fa15a5b35d4104579af41ad3b97 Mon Sep 17 00:00:00 2001 From: phenpessoa Date: Tue, 12 Dec 2023 10:53:32 -0300 Subject: [PATCH 3/4] webserver: send StatusBadGateway in case there was an error on tibia.com --- src/webserver.go | 8 ++++++-- src/webserver_test.go | 15 +++++++++++++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/webserver.go b/src/webserver.go index 3532f0bc..ea2e132b 100644 --- a/src/webserver.go +++ b/src/webserver.go @@ -1088,13 +1088,17 @@ func TibiaDataErrorHandler(c *gin.Context, err error, httpCode int) { if httpCode == 0 { if t.Code() == 10 || t.Code() == 11 { httpCode = http.StatusInternalServerError - info.Status.HTTPCode = httpCode } else { httpCode = http.StatusBadRequest - info.Status.HTTPCode = httpCode } } + // A error occurred at tibia.com + if t.Code() > 20000 { + httpCode = http.StatusBadGateway + } + + info.Status.HTTPCode = httpCode info.Status.Error = t.Code() info.Status.Message = t.Error() case error: diff --git a/src/webserver_test.go b/src/webserver_test.go index ae49660d..56f28eba 100644 --- a/src/webserver_test.go +++ b/src/webserver_test.go @@ -282,4 +282,19 @@ func TestErrorHandler(t *testing.T) { c, _ = gin.CreateTestContext(w) TibiaDataErrorHandler(c, errors.New("test error"), 0) assert.Equal(http.StatusBadGateway, w.Code) + + w = httptest.NewRecorder() + c, _ = gin.CreateTestContext(w) + TibiaDataErrorHandler(c, validation.ErrStatusForbidden, http.StatusForbidden) + assert.Equal(http.StatusBadGateway, w.Code) + + w = httptest.NewRecorder() + c, _ = gin.CreateTestContext(w) + TibiaDataErrorHandler(c, validation.ErrStatusFound, http.StatusFound) + assert.Equal(http.StatusBadGateway, w.Code) + + w = httptest.NewRecorder() + c, _ = gin.CreateTestContext(w) + TibiaDataErrorHandler(c, validation.ErrStatusUnknown, http.StatusConflict) + assert.Equal(http.StatusBadGateway, w.Code) } From 257be71ef632fd8740eb428baf89be02211786dc Mon Sep 17 00:00:00 2001 From: phenpessoa Date: Tue, 12 Dec 2023 10:54:48 -0300 Subject: [PATCH 4/4] webserver: fix typo in comment --- src/webserver.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/webserver.go b/src/webserver.go index ea2e132b..b3210069 100644 --- a/src/webserver.go +++ b/src/webserver.go @@ -1093,7 +1093,7 @@ func TibiaDataErrorHandler(c *gin.Context, err error, httpCode int) { } } - // A error occurred at tibia.com + // An error occurred at tibia.com if t.Code() > 20000 { httpCode = http.StatusBadGateway }