|
|
|
@ -6,11 +6,37 @@ import (
|
|
|
|
|
"github.com/grufwub/go-errors"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// Gopher specific error codes
|
|
|
|
|
// Gopher specific errors
|
|
|
|
|
var (
|
|
|
|
|
errInvalidGophermap = errors.Error(invalidGophermapErrStr)
|
|
|
|
|
errSubgophermapIsDir = errors.Error(subgophermapIsDirErrStr)
|
|
|
|
|
errSubgophermapSize = errors.Error(subgophermapSizeErrStr)
|
|
|
|
|
errInvalidGophermap = errors.BaseError("invalid gophermap")
|
|
|
|
|
errSubgophermapIsDir = errors.BaseError("subgophermap path is dir")
|
|
|
|
|
errSubgophermapSize = errors.BaseError("subgophermap size too large")
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// Gopher response error text
|
|
|
|
|
const (
|
|
|
|
|
statusBadRequest = "400 Bad Request"
|
|
|
|
|
statusUnauthorized = "401 Unauthorised"
|
|
|
|
|
statusForbidden = "403 Forbidden"
|
|
|
|
|
statusNotFound = "404 Not Found"
|
|
|
|
|
statusRequestTimeout = "408 Request Time-out"
|
|
|
|
|
statusGone = "410 Gone"
|
|
|
|
|
statusInternalServerError = "500 Internal Server Error"
|
|
|
|
|
statusNotImplemented = "501 Not Implemented"
|
|
|
|
|
statusServiceUnavailable = "503 Service Unavailable"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// Gopher error responses
|
|
|
|
|
var (
|
|
|
|
|
errBadRequestRsp = buildErrorLine(statusBadRequest)
|
|
|
|
|
errUnauthorizedRsp = buildErrorLine(statusUnauthorized)
|
|
|
|
|
errForbiddenRsp = buildErrorLine(statusForbidden)
|
|
|
|
|
errNotFoundRsp = buildErrorLine(statusNotFound)
|
|
|
|
|
errRequestTimeoutRsp = buildErrorLine(statusRequestTimeout)
|
|
|
|
|
errGoneRsp = buildErrorLine(statusGone)
|
|
|
|
|
errInternalServerErrorRsp = buildErrorLine(statusInternalServerError)
|
|
|
|
|
errNotImplementedRsp = buildErrorLine(statusNotImplemented)
|
|
|
|
|
errServiceUnavailableRsp = buildErrorLine(statusServiceUnavailable)
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// generateErrorResponse takes an error code and generates an error response byte slice
|
|
|
|
@ -19,42 +45,39 @@ func generateErrorResponse(err error) ([]byte, bool) {
|
|
|
|
|
case errors.Is(err, core.ErrConnWrite):
|
|
|
|
|
return nil, false // no point responding if we couldn't write
|
|
|
|
|
case errors.Is(err, core.ErrConnRead):
|
|
|
|
|
return buildErrorLine(errorResponse503), true
|
|
|
|
|
return errServiceUnavailableRsp, true
|
|
|
|
|
case errors.Is(err, core.ErrConnClose):
|
|
|
|
|
return nil, false // no point responding if we couldn't close
|
|
|
|
|
case errors.Is(err, core.ErrMutexUpgrade):
|
|
|
|
|
return buildErrorLine(errorResponse500), true
|
|
|
|
|
return errServiceUnavailableRsp, true
|
|
|
|
|
case errors.Is(err, core.ErrMutexDowngrade):
|
|
|
|
|
return buildErrorLine(errorResponse500), true
|
|
|
|
|
return errServiceUnavailableRsp, true
|
|
|
|
|
case errors.Is(err, core.ErrFileOpen):
|
|
|
|
|
return buildErrorLine(errorResponse404), true
|
|
|
|
|
return errNotFoundRsp, true
|
|
|
|
|
case errors.Is(err, core.ErrFileStat):
|
|
|
|
|
return buildErrorLine(errorResponse500), true
|
|
|
|
|
return errNotFoundRsp, true
|
|
|
|
|
case errors.Is(err, core.ErrFileRead):
|
|
|
|
|
return buildErrorLine(errorResponse500), true
|
|
|
|
|
return errNotFoundRsp, true
|
|
|
|
|
case errors.Is(err, core.ErrFileType):
|
|
|
|
|
return buildErrorLine(errorResponse404), true
|
|
|
|
|
return errNotFoundRsp, true
|
|
|
|
|
case errors.Is(err, core.ErrDirectoryRead):
|
|
|
|
|
return buildErrorLine(errorResponse500), true
|
|
|
|
|
return errNotFoundRsp, true
|
|
|
|
|
case errors.Is(err, core.ErrRestrictedPath):
|
|
|
|
|
return buildErrorLine(errorResponse403), true
|
|
|
|
|
|
|
|
|
|
// All forms of invalid request
|
|
|
|
|
return errForbiddenRsp, true
|
|
|
|
|
case errors.Is(err, core.ErrInvalidRequest):
|
|
|
|
|
return buildErrorLine(errorResponse400), true
|
|
|
|
|
return errBadRequestRsp, true
|
|
|
|
|
case errors.Is(err, core.ErrParsingScheme):
|
|
|
|
|
return buildErrorLine(errorResponse400), true
|
|
|
|
|
|
|
|
|
|
return errBadRequestRsp, true
|
|
|
|
|
case errors.Is(err, core.ErrCGIStart):
|
|
|
|
|
return buildErrorLine(errorResponse500), true
|
|
|
|
|
return errInternalServerErrorRsp, true
|
|
|
|
|
case errors.Is(err, core.ErrCGIExitCode):
|
|
|
|
|
return buildErrorLine(errorResponse500), true
|
|
|
|
|
return errServiceUnavailableRsp, true
|
|
|
|
|
case errors.Is(err, errInvalidGophermap):
|
|
|
|
|
return buildErrorLine(errorResponse500), true
|
|
|
|
|
return errInternalServerErrorRsp, true
|
|
|
|
|
case errors.Is(err, errSubgophermapIsDir):
|
|
|
|
|
return buildErrorLine(errorResponse500), true
|
|
|
|
|
return errInternalServerErrorRsp, true
|
|
|
|
|
case errors.Is(err, errSubgophermapSize):
|
|
|
|
|
return buildErrorLine(errorResponse500), true
|
|
|
|
|
return errInternalServerErrorRsp, true
|
|
|
|
|
default:
|
|
|
|
|
return nil, false
|
|
|
|
|
}
|
|
|
|
|