Documentation
¶
Index ¶
- Constants
- Variables
- func ContextWithPreProxyHook(ctx context.Context, h func(r *http.Request) error) context.Context
- func ContextWithProxyHeader(ctx context.Context, h http.Header) context.Context
- func CookieNames(cks []*http.Cookie) []string
- func DeleteCookie(w http.ResponseWriter, cookieNames []string, prefix string)
- func ErrorHandler(a api.API[*api.Request, *api.Response], ref *k.Reference) (core.ErrorHandler, error)
- func GetCookie(key string, cks []*http.Cookie) string
- func GlobalErrorHandler(name string) core.ErrorHandler
- func Handler(a api.API[*api.Request, *api.Response], spec *v1.HTTPHandlerSpec) (methods []string, patterns []string, h http.Handler, err error)
- func Methods(methods []v1.HTTPMethod) []string
- func MiddlewareChain(middleware []core.Middleware, terminator http.Handler) http.Handler
- func PreProxyHookFromContext(ctx context.Context) []func(r *http.Request) error
- func ProxyHeaderFromContext(ctx context.Context) http.Header
- func SetCookie(w http.ResponseWriter, cookieNames []string, c core.CookieCreator, ...)
- func SetGlobalErrorHandler(name string, handler core.ErrorHandler)
- func TripperwareChain(tripperware []core.Tripperware, terminator http.RoundTripper) http.RoundTripper
- type CookieCreator
- type DefaultErrorHandler
- type ErrorElem
- type ErrorElems
- type ErrorMessage
- type HTTPError
- type HandlerBase
- type MIMEContent
- type WrappedWriter
- func (w *WrappedWriter) ContentLength() int64
- func (w *WrappedWriter) Flush()
- func (w *WrappedWriter) StatusCode() int
- func (w *WrappedWriter) Unwrap() http.ResponseWriter
- func (w *WrappedWriter) Write(b []byte) (int, error)
- func (w *WrappedWriter) WriteHeader(statusCode int)
- func (w *WrappedWriter) Written() bool
- type Writer
Constants ¶
const ( ErrPkg = "utilhttp" ErrTypeMime = "mime" ErrTypeErrHandler = "error handler" ErrTypeChain = "chain" // ErrDscIO is a error description. // This description indicates io error. // Especially for file io error ErrDscIO = "io error." // ErrDscParseMime is a error description. // This description indicates the failure of // parsing media type string. ErrDscParseMime = "failed to parse media type." // ErrDscRegexp is a error description. // This description indicates the failure of // parsing regular expression. ErrDscRegexp = "failed to parse regular expression." // ErrDscAssert is a error description. // This description indicates the failure of // type assertion. ErrDscAssert = "type assertion failed." )
const DefaultErrorHandlerName = "__default__"
DefaultErrorHandlerName is the name of default error handler. Use SetGlobalErrorHandler method to replace the default error handler. Even the default error handler can be replaced, it cannot be set to nil. To get the default error handler use this like below.
eh := http.GlobalErrorHandler(http.DefaultErrorHandlerName)
Variables ¶
var ( ErrLoggingOnly error = NewHTTPError(nil, -1) // -1 Logging only status for default error handler. ErrBadRequest error = NewHTTPError(nil, http.StatusBadRequest) // 400 RFC 9110, 15.5.1 ErrPaymentRequired error = NewHTTPError(nil, http.StatusPaymentRequired) // 402 RFC 9110, 15.5.3 ErrForbidden error = NewHTTPError(nil, http.StatusForbidden) // 403 RFC 9110, 15.5.4 ErrNotFound error = NewHTTPError(nil, http.StatusNotFound) // 404 RFC 9110, 15.5.5 ErrMethodNotAllowed error = NewHTTPError(nil, http.StatusMethodNotAllowed) // 405 RFC 9110, 15.5.6 ErrNotAcceptable error = NewHTTPError(nil, http.StatusNotAcceptable) // 406 RFC 9110, 15.5.7 ErrProxyAuthRequired error = NewHTTPError(nil, http.StatusProxyAuthRequired) // 407 RFC 9110, 15.5.8 ErrRequestTimeout error = NewHTTPError(nil, http.StatusRequestTimeout) // 408 RFC 9110, 15.5.9 ErrConflict error = NewHTTPError(nil, http.StatusConflict) // 409 RFC 9110, 15.5.10 ErrGone error = NewHTTPError(nil, http.StatusGone) // 410 RFC 9110, 15.5.11 ErrLengthRequired error = NewHTTPError(nil, http.StatusLengthRequired) // 411 RFC 9110, 15.5.12 ErrPreconditionFailed error = NewHTTPError(nil, http.StatusPreconditionFailed) // 412 RFC 9110, 15.5.13 ErrRequestEntityTooLarge error = NewHTTPError(nil, http.StatusRequestEntityTooLarge) // 413 RFC 9110, 15.5.14 ErrRequestURITooLong error = NewHTTPError(nil, http.StatusRequestURITooLong) // 414 RFC 9110, 15.5.15 ErrUnsupportedMediaType error = NewHTTPError(nil, http.StatusUnsupportedMediaType) // 415 RFC 9110, 15.5.16 ErrTooManyRequests error = NewHTTPError(nil, http.StatusTooManyRequests) // 429 RFC 6585, 4 ErrRequestHeaderFieldsTooLarge error = NewHTTPError(nil, http.StatusRequestHeaderFieldsTooLarge) // 431 RFC 6585, 5 ErrInternalServerError error = NewHTTPError(nil, http.StatusInternalServerError) // 500 RFC 9110, 15.6.1 ErrNotImplemented error = NewHTTPError(nil, http.StatusNotImplemented) // 501 RFC 9110, 15.6.2 ErrBadGateway error = NewHTTPError(nil, http.StatusBadGateway) // 502 RFC 9110, 15.6.3 ErrGatewayTimeout error = NewHTTPError(nil, http.StatusGatewayTimeout) // 504 RFC 9110, 15.6.5 )
var HTTPMethods = map[v1.HTTPMethod]string{ v1.HTTPMethod_GET: http.MethodGet, v1.HTTPMethod_HEAD: http.MethodHead, v1.HTTPMethod_POST: http.MethodPost, v1.HTTPMethod_PUT: http.MethodPut, v1.HTTPMethod_PATCH: http.MethodPatch, v1.HTTPMethod_DELETE: http.MethodDelete, v1.HTTPMethod_CONNECT: http.MethodConnect, v1.HTTPMethod_OPTIONS: http.MethodOptions, v1.HTTPMethod_TRACE: http.MethodTrace, }
HTTPMethods is the all mapping of HTTP methods. Currently following methods are contained.
- Get
- Head
- Post
- Put
- Patch
- Delete
- Connect
- Options
- Trace
Functions ¶
func ContextWithPreProxyHook ¶
ContextWithPreProxyHook register pre proxy hook function to the context. context.Background() will be used if nil context was given.
ctx := r.Context() ctx = ContextWithPreProxyHook(ctx, func(r *http.Request) error {....}) r = r.WithContext(newCtx)
func ContextWithProxyHeader ¶
ContextWithProxyHeader register http header that should be proxied. A new http.Header will be created if nil header was given by the second argument h. context.Background() will be used if nil ctx was given. Update the caller's context when non nil context was returned.
ctx := r.Context() ctx := ContextWithProxyHeader(ctx, http.Header{"foo":[]string{"bar"}}) r = r.WithContext(newCtx)
func CookieNames ¶
CookieNames returns a list of cookie names.
func DeleteCookie ¶
func DeleteCookie(w http.ResponseWriter, cookieNames []string, prefix string)
DeleteCookie deletes the cookies which have the given prefix. If the prefix is "session", then the cookies with name "session0", "session1", "session2", ... will be deleted.
func ErrorHandler ¶
func ErrorHandler(a api.API[*api.Request, *api.Response], ref *k.Reference) (core.ErrorHandler, error)
ErrorHandler returns a error handler by getting it from the given api. The default error handler will be returned when a nil reference was given by the second argument ref. This function can panic if the first argument api is nil.
func GetCookie ¶
GetCookie returns single cookie value bounded to the given key. For example, if the cookies have "session0=value1", "session1=value2", "session2=value3" then the joined values of them "value1value2value3" will be returned. Use SetCookie to save a large value into the cookie. An empty string "" will be returned when the given key was empty.
func GlobalErrorHandler ¶
func GlobalErrorHandler(name string) core.ErrorHandler
GlobalErrorHandler returns a error handler which is stored in the global error handler holder by name. A default registered error handler can be obtained by the name http.DefaultErrorHandlerName. If there is no handler, GlobalErrorHandler returns nil.
When getting the default error handler, use like below. The error handler gotten by the name DefaultErrorHandlerName is always non nil.
eh := http.GlobalErrorHandler(http.DefaultErrorHandlerName)
If it's not the default logger, nil check should be taken.
eh := http.GlobalErrorHandler("yourErrorHandlerName") if eh == nil { // use other error handler. }
func Handler ¶
func Handler(a api.API[*api.Request, *api.Response], spec *v1.HTTPHandlerSpec) (methods []string, patterns []string, h http.Handler, err error)
Handler returns http handler generated by the given spec. This function returns http methods, path pattern, http handler and error. The methods are compacted to contains only unique values.
func Methods ¶
func Methods(methods []v1.HTTPMethod) []string
Methods returns a list of http methods in string. Unknown HTTP methods are ignored. Currently following methods are supported.
- Get
- Head
- Post
- Put
- Patch
- Delete
- Connect
- Options
- Trace
func MiddlewareChain ¶
MiddlewareChain returns a handler with given middleware applied. For example, when the 3 middleware and a terminator were give, returned Handler will be like below. The terminator must not be nil and nil middleware is ignored. This function panics when nil terminator is given.
middleware[0]( middleware[1]( middleware[2]( terminator ) ) )
func PreProxyHookFromContext ¶
PreProxyHookFromContext returns pre proxy hook functions. Empty slice will be returned if no function was found in the context or nil context was given.
func ProxyHeaderFromContext ¶
ProxyHeaderFromContext returns http headers to proxy. nil will be returned if no header was found in the context or nil context was given.
func SetCookie ¶
func SetCookie(w http.ResponseWriter, cookieNames []string, c core.CookieCreator, prefix string, val string)
SetCookie sets a large value to the cookie by splitting it into smaller values. Maximum size of the value is restricted to 1<<12 - 1<<7 = 3968 bytes. Use GetCookie to extract the original value from cookies. This function do nothing and return immediately when the given prefix was empty..
func SetGlobalErrorHandler ¶
func SetGlobalErrorHandler(name string, handler core.ErrorHandler)
SetGlobalErrorHandler stores the given error handler in the global error handler holder. This replaces the existing error handler if there have already been the same named handler. To delete the handler, set nil as the second argument. The error handler named http.DefaultErrorHandlerName can be replaced but cannot be deleted.
To delete error handler:
http.SetGlobalErrorHandler("errorHandlerName", nil)
To replace default error handler:
var eh core.ErrorHandler eh = <error handler you want to use> http.SetGlobalErrorHandler(http.DefaultErrorHandlerName, eh)
func TripperwareChain ¶
func TripperwareChain(tripperware []core.Tripperware, terminator http.RoundTripper) http.RoundTripper
TripperwareChain returns a RoundTripper with given tripperware applied. For example, when the 3 tripperware and a terminator were give, returned RoundTripper will be like below. The terminator must not be nil and nil tripperware is ignored. This function panics when nil terminator is given.
tripperware[0]( tripperware[1]( tripperware[2]( terminator ) ) )
Types ¶
type CookieCreator ¶
type CookieCreator struct { Name string Value string Path string Domain string ExpiresIn time.Duration // MaxAge=0 means no 'Max-Age' attribute specified. // MaxAge<0 means delete cookie now, equivalently 'Max-Age: 0' // MaxAge>0 means Max-Age attribute present and given in seconds MaxAge int Secure bool HTTPOnly bool SameSite http.SameSite }
CookieCreator creates a new cookie with predefined cookie attributes. Be careful to set all attribute as secure as possible.
References:
- https://datatracker.ietf.org/doc/html/rfc6265
- https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies
- https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie
func DefaultCookieCreator ¶
func DefaultCookieCreator() *CookieCreator
DefaultCookieCreator return a new instance of cookie creator of the default implementation. Attributes are as follows. Cookie name and value should be changed at least.
- Name: ""
- Value: ""
- Path: "/"
- Domain: ""
- ExpiresIn: 0
- MaxAge: 0
- Secure: true
- HTTPOnly: true
- SameSite: Default
References:
func NewCookieCreator ¶
func NewCookieCreator(spec *v1.CookieSpec) *CookieCreator
NewCookieCreator return a new cookie creator object. Default cookie creator is returned when nil was given.
References:
func (*CookieCreator) NewCookie ¶
func (c *CookieCreator) NewCookie() *http.Cookie
NewCookie returns a new instance of cookie.
type DefaultErrorHandler ¶
type DefaultErrorHandler struct { // LG is the logger to output logs. LG log.Logger // StackAlways is the flag to output // stacktraces even the client-side error. // If set to true, this error handler always // show stacktrace with debug level. StackAlways bool // Msgs is the list of error messages // to overwrite the default. Msgs []*ErrorMessage }
DefaultErrorHandler is a HTTP error handler that returns HTTP error response to the clients. This implements core.
func (*DefaultErrorHandler) ServeHTTPError ¶
func (h *DefaultErrorHandler) ServeHTTPError(w http.ResponseWriter, r *http.Request, err error)
type ErrorElem ¶
type ErrorElem struct { // XMLName is the name of this xml space. // This field is only for xml marshaling. XMLName xml.Name `xml:"error" json:"-" yaml:"-"` // Code is an error code. // For example "E1234". Code string `json:"code" yaml:"code" xml:"code"` // Message is an error message. // For example, "invalid request header". Message string `json:"message" yaml:"message" xml:"message"` // Detail is more details about this error. Detail string `json:"detail,omitempty" yaml:"detail,omitempty" xml:"detail,omitempty"` }
ErrorElem represents a single error.
type ErrorElems ¶
type ErrorElems struct { // XMLName is the name of this xml space. // This field is only for xml marshaling. XMLName xml.Name `xml:"result" json:"-" yaml:"-"` // Status is a HTTP status code. // For example, 500. Status int `json:"status" yaml:"status" xml:"status"` // StatusText is a HTTP status text. // For example, "InternalServerError". StatusText string `json:"statusText" yaml:"statusText" xml:"statusText"` // Errors is the list of errors. Errors []*ErrorElem `json:"errors,omitempty" yaml:"errors,omitempty" xml:"errors>error,omitempty"` }
ErrorElems represents aggregated errors.
type ErrorMessage ¶
type ErrorMessage struct {
// contains filtered or unexported fields
}
func NewErrorMessage ¶
func NewErrorMessage(spec *v1.ErrorMessageSpec) (*ErrorMessage, error)
func (*ErrorMessage) Content ¶
func (m *ErrorMessage) Content(accept string) *MIMEContent
type HTTPError ¶
type HTTPError struct {
// contains filtered or unexported fields
}
HTTPError is the error response information. This struct holds and provides information about HTTP response error. Use NewHTTPError function to create a new instance. This implements core.ErrorResponse interface.
func NewHTTPError ¶
NewHTTPError returns a new HTTP error instance.
func (*HTTPError) Content ¶
Content returns content type and body content. Supported content types are as follows. Default "application/json" will be returned when unsupported content type was given.
- "application/json", "text/json"
- "application/xml", "text/xml"
- "application/yaml", "text/yaml"
- "text/plain"
func (*HTTPError) Header ¶
Header returns http header. Note that modifying the returned header changes the state of this HTTPError object.
func (*HTTPError) StatusCode ¶
StatusCode returns http status code.
type HandlerBase ¶
type HandlerBase struct { // AcceptPattern is the url path patterns this handler can accepts. // Path patterns that http.ServeMux can handle are allowed. // Do not contain hostname or methods. // - https://pkg.go.dev/net/http#ServeMux AcceptPatterns []string // AcceptMethods is the http methods this handler can accept. // Methods defined in the http package are allowed. // - https://pkg.go.dev/net/http#pkg-constants AcceptMethods []string }
HandlerBase is the base struct for a http handler.
func (*HandlerBase) Methods ¶
func (h *HandlerBase) Methods() []string
Methods returns the http methods this handler can handle.
func (*HandlerBase) Patterns ¶
func (h *HandlerBase) Patterns() []string
Patterns returns the http path pattern that this handler can handle.
type MIMEContent ¶
MIMEContent provides HTTP content corresponding to a MIMEType. MIMEContent utilize txtutil.Template in it to provides a HTTP body content.
func NewMIMEContent ¶
func NewMIMEContent(spec *v1.MIMEContentSpec) (*MIMEContent, error)
type WrappedWriter ¶
type WrappedWriter struct { http.ResponseWriter // contains filtered or unexported fields }
WrappedWriter wraps http.ResponseWriter and holds http status code. This implements io.Writer interface.
func (*WrappedWriter) ContentLength ¶
func (w *WrappedWriter) ContentLength() int64
func (*WrappedWriter) Flush ¶
func (w *WrappedWriter) Flush()
func (*WrappedWriter) StatusCode ¶
func (w *WrappedWriter) StatusCode() int
func (*WrappedWriter) Unwrap ¶
func (w *WrappedWriter) Unwrap() http.ResponseWriter
func (*WrappedWriter) WriteHeader ¶
func (w *WrappedWriter) WriteHeader(statusCode int)
func (*WrappedWriter) Written ¶
func (w *WrappedWriter) Written() bool
type Writer ¶
type Writer interface { http.ResponseWriter // Written returns if status code or body were written or not. // Calling Write(nil) is considered to be written even it does not // write any bytes. // If ContentLength() > 0, Written() always returns true. // If ContentLength() == 0, Written() can be true or false. Written() bool // StatusCode returns the written status code. // If both status code and body were not written at all, // StatusCode() returns zero. // If body was written without writing status code, // StatusCode() returns 200 which is the same behavior with // [http.ResponseWriter.WriteHeader] method. // See the comment of https://pkg.go.dev/net/http#ResponseWriter.WriteHeader StatusCode() int // ContentLength returns the actual written bytes. // If ContentLength() > 0, Written() always returns true. // If ContentLength() == 0, Written() can be true or false. ContentLength() int64 }
Writer is the response writer that can obtain written status code and written bytes.
func WrapWriter ¶
func WrapWriter(w http.ResponseWriter) Writer
WrapWriter wraps http.ResponseWriter with a writer that can record written status code and written bytes. When nil is given as the argument, this returns a new io.Writer with wrapping nil http.ResponseWriter and the returned writer will panic on write. Actual implementation of returned Writer is *WrappedWriter.