mirror of
https://github.com/kataras/iris.git
synced 2025-01-23 02:31:04 +01:00
229 lines
8.3 KiB
Go
229 lines
8.3 KiB
Go
package iris
|
|
|
|
//taken from net/http
|
|
const (
|
|
StatusContinue = 100
|
|
StatusSwitchingProtocols = 101
|
|
|
|
StatusOK = 200
|
|
StatusCreated = 201
|
|
StatusAccepted = 202
|
|
StatusNonAuthoritativeInfo = 203
|
|
StatusNoContent = 204
|
|
StatusResetContent = 205
|
|
StatusPartialContent = 206
|
|
|
|
StatusMultipleChoices = 300
|
|
StatusMovedPermanently = 301
|
|
StatusFound = 302
|
|
StatusSeeOther = 303
|
|
StatusNotModified = 304
|
|
StatusUseProxy = 305
|
|
StatusTemporaryRedirect = 307
|
|
|
|
StatusBadRequest = 400
|
|
StatusUnauthorized = 401
|
|
StatusPaymentRequired = 402
|
|
StatusForbidden = 403
|
|
StatusNotFound = 404
|
|
StatusMethodNotAllowed = 405
|
|
StatusNotAcceptable = 406
|
|
StatusProxyAuthRequired = 407
|
|
StatusRequestTimeout = 408
|
|
StatusConflict = 409
|
|
StatusGone = 410
|
|
StatusLengthRequired = 411
|
|
StatusPreconditionFailed = 412
|
|
StatusRequestEntityTooLarge = 413
|
|
StatusRequestURITooLong = 414
|
|
StatusUnsupportedMediaType = 415
|
|
StatusRequestedRangeNotSatisfiable = 416
|
|
StatusExpectationFailed = 417
|
|
StatusTeapot = 418
|
|
StatusPreconditionRequired = 428
|
|
StatusTooManyRequests = 429
|
|
StatusRequestHeaderFieldsTooLarge = 431
|
|
StatusUnavailableForLegalReasons = 451
|
|
|
|
StatusInternalServerError = 500
|
|
StatusNotImplemented = 501
|
|
StatusBadGateway = 502
|
|
StatusServiceUnavailable = 503
|
|
StatusGatewayTimeout = 504
|
|
StatusHTTPVersionNotSupported = 505
|
|
StatusNetworkAuthenticationRequired = 511
|
|
)
|
|
|
|
var statusText = map[int]string{
|
|
StatusContinue: "Continue",
|
|
StatusSwitchingProtocols: "Switching Protocols",
|
|
|
|
StatusOK: "OK",
|
|
StatusCreated: "Created",
|
|
StatusAccepted: "Accepted",
|
|
StatusNonAuthoritativeInfo: "Non-Authoritative Information",
|
|
StatusNoContent: "No Content",
|
|
StatusResetContent: "Reset Content",
|
|
StatusPartialContent: "Partial Content",
|
|
|
|
StatusMultipleChoices: "Multiple Choices",
|
|
StatusMovedPermanently: "Moved Permanently",
|
|
StatusFound: "Found",
|
|
StatusSeeOther: "See Other",
|
|
StatusNotModified: "Not Modified",
|
|
StatusUseProxy: "Use Proxy",
|
|
StatusTemporaryRedirect: "Temporary Redirect",
|
|
|
|
StatusBadRequest: "Bad Request",
|
|
StatusUnauthorized: "Unauthorized",
|
|
StatusPaymentRequired: "Payment Required",
|
|
StatusForbidden: "Forbidden",
|
|
StatusNotFound: "Not Found",
|
|
StatusMethodNotAllowed: "Method Not Allowed",
|
|
StatusNotAcceptable: "Not Acceptable",
|
|
StatusProxyAuthRequired: "Proxy Authentication Required",
|
|
StatusRequestTimeout: "Request Timeout",
|
|
StatusConflict: "Conflict",
|
|
StatusGone: "Gone",
|
|
StatusLengthRequired: "Length Required",
|
|
StatusPreconditionFailed: "Precondition Failed",
|
|
StatusRequestEntityTooLarge: "Request Entity Too Large",
|
|
StatusRequestURITooLong: "Request URI Too Long",
|
|
StatusUnsupportedMediaType: "Unsupported Media Type",
|
|
StatusRequestedRangeNotSatisfiable: "Requested Range Not Satisfiable",
|
|
StatusExpectationFailed: "Expectation Failed",
|
|
StatusTeapot: "I'm a teapot",
|
|
StatusPreconditionRequired: "Precondition Required",
|
|
StatusTooManyRequests: "Too Many Requests",
|
|
StatusRequestHeaderFieldsTooLarge: "Request Header Fields Too Large",
|
|
StatusUnavailableForLegalReasons: "Unavailable For Legal Reasons",
|
|
|
|
StatusInternalServerError: "Internal Server Error",
|
|
StatusNotImplemented: "Not Implemented",
|
|
StatusBadGateway: "Bad Gateway",
|
|
StatusServiceUnavailable: "Service Unavailable",
|
|
StatusGatewayTimeout: "Gateway Timeout",
|
|
StatusHTTPVersionNotSupported: "HTTP Version Not Supported",
|
|
StatusNetworkAuthenticationRequired: "Network Authentication Required",
|
|
}
|
|
|
|
// StatusText returns a text for the HTTP status code. It returns the empty
|
|
// string if the code is unknown.
|
|
func StatusText(code int) string {
|
|
return statusText[code]
|
|
}
|
|
|
|
//
|
|
|
|
type (
|
|
|
|
// HTTPErrorHandler is just an object which stores a http status code and a handler
|
|
HTTPErrorHandler struct {
|
|
code int
|
|
handler HandlerFunc
|
|
}
|
|
|
|
// HTTPErrorContainer is the struct which contains the handlers which will execute if http error occurs
|
|
// One struct per Server instance, the meaning of this is that the developer can change the default error message and replace them with his/her own completely custom handlers
|
|
//
|
|
// Example of usage:
|
|
// iris.OnError(405, func (ctx *iris.Context){ c.SendStatus(405,"Method not allowed!!!")})
|
|
// and inside the handler which you have access to the current Context:
|
|
// ctx.EmitError(405)
|
|
HTTPErrorContainer struct {
|
|
// Errors contains all the httperrorhandlers
|
|
Errors []*HTTPErrorHandler
|
|
}
|
|
)
|
|
|
|
// HTTPErrorHandlerFunc creates a handler which is responsible to send a particular error to the client
|
|
func HTTPErrorHandlerFunc(statusCode int, message string) HandlerFunc {
|
|
return func(ctx *Context) {
|
|
ctx.SetStatusCode(statusCode)
|
|
ctx.SetBodyString(message)
|
|
}
|
|
}
|
|
|
|
// GetCode returns the http status code value
|
|
func (e *HTTPErrorHandler) GetCode() int {
|
|
return e.code
|
|
}
|
|
|
|
// GetHandler returns the handler which is type of HandlerFunc
|
|
func (e *HTTPErrorHandler) GetHandler() HandlerFunc {
|
|
return e.handler
|
|
}
|
|
|
|
// SetHandler sets the handler (type of HandlerFunc) to this particular ErrorHandler
|
|
func (e *HTTPErrorHandler) SetHandler(h HandlerFunc) {
|
|
e.handler = h
|
|
}
|
|
|
|
// defaultHTTPErrors creates and returns an instance of HTTPErrorContainer with default handlers
|
|
func defaultHTTPErrors() *HTTPErrorContainer {
|
|
httperrors := new(HTTPErrorContainer)
|
|
httperrors.Errors = make([]*HTTPErrorHandler, 0)
|
|
httperrors.OnError(StatusNotFound, HTTPErrorHandlerFunc(StatusNotFound, statusText[StatusNotFound]))
|
|
httperrors.OnError(StatusInternalServerError, HTTPErrorHandlerFunc(StatusInternalServerError, statusText[StatusInternalServerError]))
|
|
return httperrors
|
|
}
|
|
|
|
// GetByCode returns the error handler by it's http status code
|
|
func (he *HTTPErrorContainer) GetByCode(httpStatus int) *HTTPErrorHandler {
|
|
if he != nil {
|
|
for _, h := range he.Errors {
|
|
if h.GetCode() == httpStatus {
|
|
return h
|
|
}
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// OnError Registers a handler for a specific http error status
|
|
func (he *HTTPErrorContainer) OnError(httpStatus int, handler HandlerFunc) {
|
|
if httpStatus == StatusOK {
|
|
return
|
|
}
|
|
|
|
if errH := he.GetByCode(httpStatus); errH != nil {
|
|
|
|
errH.SetHandler(handler)
|
|
} else {
|
|
he.Errors = append(he.Errors, &HTTPErrorHandler{code: httpStatus, handler: handler})
|
|
}
|
|
|
|
}
|
|
|
|
///TODO: the errors must have .Next too, as middlewares inside the Context, if I let it as it is then we have problem
|
|
// we cannot set a logger and a custom handler at one error because now the error handler takes only one handelrFunc and executes there from here...
|
|
|
|
// EmitError executes the handler of the given error http status code
|
|
func (he *HTTPErrorContainer) EmitError(errCode int, ctx *Context) {
|
|
|
|
if errHandler := he.GetByCode(errCode); errHandler != nil {
|
|
ctx.SetStatusCode(errCode) // for any case, user can change it after if want to
|
|
errHandler.GetHandler().Serve(ctx)
|
|
} else {
|
|
//if no error is registed, then register it with the default http error text, and re-run the Emit
|
|
he.OnError(errCode, func(c *Context) {
|
|
c.SetStatusCode(errCode)
|
|
c.SetBodyString(StatusText(errCode))
|
|
})
|
|
he.EmitError(errCode, ctx)
|
|
}
|
|
}
|
|
|
|
// OnNotFound sets the handler for http status 404,
|
|
// default is a response with text: 'Not Found' and status: 404
|
|
func (he *HTTPErrorContainer) OnNotFound(handlerFunc HandlerFunc) {
|
|
he.OnError(StatusNotFound, handlerFunc)
|
|
}
|
|
|
|
// OnPanic sets the handler for http status 500,
|
|
// default is a response with text: The server encountered an unexpected condition which prevented it from fulfilling the request. and status: 500
|
|
func (he *HTTPErrorContainer) OnPanic(handlerFunc HandlerFunc) {
|
|
he.OnError(StatusInternalServerError, handlerFunc)
|
|
}
|