More optimal error responses

This commit is contained in:
Nixon 2024-08-13 16:28:06 -07:00
parent 2da51b1344
commit 82fa4064ca
No known key found for this signature in database
2 changed files with 70 additions and 17 deletions

57
errors.go Normal file
View file

@ -0,0 +1,57 @@
package keydbextension
import (
"encoding/json"
"fmt"
"net/http"
"sync"
)
const (
ErrNoAuthToken = "ErrNoAuthToken"
ErrUnauthorized = "ErrUnauthorized"
ErrIncompleteReq = "ErrIncompleteReq"
ErrConnFailed = "ErrConnFailed"
ErrReqNotProcessed = "ErrReqNotProcessed"
ErrUnknown = "ErrUnknown"
)
var (
errorResponses map[string][]byte
errorStatusCodes map[string]int
errorResponsesOnce sync.Once
)
func initErrorResponses() {
errorResponses = make(map[string][]byte)
errorStatusCodes = make(map[string]int)
errors := []struct {
key string
code int
message string
}{
{ErrNoAuthToken, http.StatusUnauthorized, "No auth token provided"},
{ErrUnauthorized, http.StatusForbidden, "Unauthorized access"},
{ErrIncompleteReq, http.StatusBadRequest, "Request was incomplete"},
{ErrConnFailed, 523, "Connection to GuardianPT failed"},
{ErrReqNotProcessed, 522, "Request could not be processed"},
{ErrUnknown, 520, "An unknown error occurred"},
}
for _, err := range errors {
error_code := fmt.Sprintf("0x%08X", 0xC0043293+err.code)
response, _ := json.Marshal(map[string]interface{}{
"error": true,
"code": error_code,
"message": err.message,
})
errorResponses[err.key] = response
errorStatusCodes[err.key] = err.code
}
}
func getHTTPStatusCode(key string) int {
errorResponsesOnce.Do(initErrorResponses)
return errorStatusCodes[key]
}

View file

@ -2,7 +2,6 @@ package keydbextension
import (
"context"
"encoding/json"
"fmt"
"net/http"
"strconv"
@ -69,18 +68,18 @@ func (handler *KeyDBHandler) Provision(ctx caddy.Context) error {
func (handler KeyDBHandler) ServeHTTP(writer http.ResponseWriter, request *http.Request, next caddyhttp.Handler) error {
authToken := request.Header.Get(authTokenHeader)
if authToken == "" {
sendJSONError(writer, http.StatusUnauthorized, "No auth token provided")
sendJSONError(writer, ErrNoAuthToken)
return nil
}
if !handler.validTokens[authToken] {
sendJSONError(writer, http.StatusForbidden, "Unauthorized access")
sendJSONError(writer, ErrUnauthorized)
return nil
}
question := request.URL.Query().Get("q")
if question == "" {
sendJSONError(writer, http.StatusBadRequest, "Request was incomplete")
sendJSONError(writer, ErrIncompleteReq)
return nil
}
@ -89,10 +88,10 @@ func (handler KeyDBHandler) ServeHTTP(writer http.ResponseWriter, request *http.
val, err := handler.client.Get(ctx, question).Result()
if err == redis.Nil {
sendJSONError(writer, http.StatusNotFound, "Connection to GuardianPT failed")
sendJSONError(writer, ErrConnFailed)
return nil
} else if err != nil {
sendJSONError(writer, http.StatusInternalServerError, "Request could not be processed")
sendJSONError(writer, ErrReqNotProcessed)
return err
}
@ -144,18 +143,15 @@ func parseCaddyfile(helper httpcaddyfile.Helper) (caddyhttp.MiddlewareHandler, e
}
// sendJSONError writes a JSON-formatted error response to the provided http.ResponseWriter.
func sendJSONError(w http.ResponseWriter, code int, message string) {
func sendJSONError(w http.ResponseWriter, errorKey string) {
errorResponse, exists := errorResponses[errorKey]
if !exists {
errorResponse = errorResponses["ErrUnknown"]
}
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(code)
// Spooky high error codes
mysteriousCode := fmt.Sprintf("0x%08X", 0xC0043293+code)
json.NewEncoder(w).Encode(map[string]interface{}{
"error": true,
"code": mysteriousCode,
"message": message,
})
w.WriteHeader(getHTTPStatusCode(errorKey))
w.Write(errorResponse)
}
// The KeyDBHandler type implements several interfaces that allow it to be used as a Caddy module: