Documentation
¶
Index ¶
- Constants
- Variables
- func CtxDebug(ctx context.Context) bool
- func CtxRequestID(ctx context.Context) string
- func CtxTemplate(ctx context.Context) string
- func CtxTracerProvider(ctx context.Context) oteltrace.TracerProvider
- func DefaultTemplateFinder(_ context.Context, statusCode int) (string, error)
- func DirFS(pathName string, filesystem fs.FS) func(http.ResponseWriter, *http.Request) error
- func FileFS(file string, filesystem fs.FS) func(http.ResponseWriter, *http.Request) error
- func IsTLS(r *http.Request) bool
- func IsWebSocket(r *http.Request) bool
- func MustSubFS(currentFs fs.FS, fsRoot string) fs.FS
- func NegotiateFormat(r *http.Request, offered string, rest ...string) string
- func RealIP(req *http.Request) string
- func Scheme(r *http.Request) string
- func StatusCode(w http.ResponseWriter) int
- func WithAccept(ctx context.Context, kind AcceptKind) context.Context
- func WithData(ctx context.Context, data H) context.Context
- func WithDebug(ctx context.Context, debug bool) context.Context
- func WithRequestID(ctx context.Context, id string) context.Context
- func WithTemplate(ctx context.Context, template string) context.Context
- func WithTracerProvider(ctx context.Context, provider oteltrace.TracerProvider) context.Context
- func Wrap(handler http.Handler, mw1 func(http.Handler) http.Handler, ...) http.Handler
- type AcceptKind
- type BeforeRenderFunc
- type DefaultErrorHandler
- type DefaultErrorWrapper
- type ErrorHandler
- type ErrorHandlerFunc
- type ErrorResolverFunc
- type ErrorWrapper
- type H
- type HTTPError
- type IPExtractor
- type Mux
- func (m *Mux) Add(pattern string, handler func(http.ResponseWriter, *http.Request) error)
- func (m *Mux) DisableNotFoundHandler()
- func (m *Mux) Group() *Mux
- func (m *Mux) Handle(pattern string, handler http.Handler)
- func (m *Mux) HandleFunc(pattern string, handler func(http.ResponseWriter, *http.Request))
- func (m *Mux) Handler(r *http.Request) (h http.Handler, pattern string)
- func (m *Mux) Mount(basePath string) *Mux
- func (m *Mux) Route(configureFn func(*Mux))
- func (m *Mux) ServeHTTP(w http.ResponseWriter, r *http.Request)
- func (m *Mux) Use(middleware func(http.Handler) http.Handler, ...)
- func (m *Mux) With(middleware func(http.Handler) http.Handler, ...) *Mux
- type NegotiateFunc
- type NegotiateRenderer
- type Renderer
- type RendererHTML
- type RendererJSON
- type RendererXML
- type RendererYAML
- type Response
- func (r *Response) After(fn func())
- func (r *Response) Before(fn func())
- func (r *Response) Flush()
- func (r *Response) Header() http.Header
- func (r *Response) Hijack() (net.Conn, *bufio.ReadWriter, error)
- func (r *Response) Pusher() http.Pusher
- func (r *Response) Reset(w http.ResponseWriter)
- func (r *Response) StatusCode() int
- func (r *Response) Unwrap() http.ResponseWriter
- func (r *Response) Write(b []byte) (n int, err error)
- func (r *Response) WriteHeader(code int)
- type TemplateEngine
- type TemplateFinder
- type TemplateFinderFunc
- type TrustOption
Examples ¶
Constants ¶
const ( ErrorTemplate = "@error/error.html" FatalTemplate = "@error/fatal.html" )
const ( MIMEApplicationJSON = "application/json" MIMEApplicationJSONCharsetUTF8 = MIMEApplicationJSON + "; " + charsetUTF8 MIMEApplicationYAML = "application/x-yaml" MIMEApplicationYAMLCharsetUTF8 = MIMEApplicationYAML + "; " + charsetUTF8 MIMEApplicationYAML2 = "application/yaml" MIMEApplicationYAML2CharsetUTF8 = MIMEApplicationYAML2 + "; " + charsetUTF8 MIMEApplicationJavaScript = "application/javascript" MIMEApplicationJavaScriptCharsetUTF8 = MIMEApplicationJavaScript + "; " + charsetUTF8 MIMEApplicationXML = "application/xml" MIMEApplicationXMLCharsetUTF8 = MIMEApplicationXML + "; " + charsetUTF8 MIMETextXML = "text/xml" MIMETextXMLCharsetUTF8 = MIMETextXML + "; " + charsetUTF8 MIMEApplicationForm = "application/x-www-form-urlencoded" MIMEApplicationProtobuf = "application/protobuf" MIMEApplicationMsgpack = "application/msgpack" MIMETextHTML = "text/html" MIMETextHTMLCharsetUTF8 = MIMETextHTML + "; " + charsetUTF8 MIMETextPlain = "text/plain" MIMETextPlainCharsetUTF8 = MIMETextPlain + "; " + charsetUTF8 MIMEMultipartForm = "multipart/form-data" MIMEOctetStream = "application/octet-stream" )
const ( HeaderUserAgent = "User-Agent" HeaderAccept = "Accept" HeaderAcceptEncoding = "Accept-Encoding" HeaderAcceptLanguage = "Accept-Language" // HeaderAllow is the name of the "Allow" header field used to list the set of methods // advertised as supported by the target resource. Returning an Allow header is mandatory // for status 405 (method not found) and useful for the OPTIONS method in responses. // See RFC 7231: https://datatracker.ietf.org/doc/html/rfc7231#section-7.4.1 HeaderAllow = "Allow" HeaderAuthorization = "Authorization" HeaderContentDisposition = "Content-Disposition" HeaderContentEncoding = "Content-Encoding" HeaderContentLength = "Content-Length" HeaderContentLocation = "Content-Location" HeaderContentType = "Content-Type" HeaderCookie = "Cookie" HeaderSetCookie = "Set-Cookie" HeaderIfModifiedSince = "If-Modified-Since" HeaderLastModified = "Last-Modified" HeaderLocation = "Location" HeaderRetryAfter = "Retry-After" HeaderUpgrade = "Upgrade" HeaderVary = "Vary" HeaderWWWAuthenticate = "WWW-Authenticate" HeaderXForwardedFor = "X-Forwarded-For" HeaderXForwardedProto = "X-Forwarded-Proto" HeaderXForwardedProtocol = "X-Forwarded-Protocol" HeaderXForwardedSsl = "X-Forwarded-Ssl" HeaderXUrlScheme = "X-Url-Scheme" HeaderXHTTPMethodOverride = "X-HTTP-Method-Override" HeaderXRealIP = "X-Real-Ip" HeaderXRequestID = "X-Request-Id" HeaderXCorrelationID = "X-Correlation-Id" HeaderXRequestedWith = "X-Requested-With" HeaderServer = "Server" HeaderOrigin = "Origin" HeaderCacheControl = "Cache-Control" HeaderConnection = "Connection" // Access control HeaderAccessControlRequestMethod = "Access-Control-Request-Method" HeaderAccessControlRequestHeaders = "Access-Control-Request-Headers" HeaderAccessControlAllowOrigin = "Access-Control-Allow-Origin" HeaderAccessControlAllowMethods = "Access-Control-Allow-Methods" HeaderAccessControlAllowHeaders = "Access-Control-Allow-Headers" HeaderAccessControlAllowCredentials = "Access-Control-Allow-Credentials" HeaderAccessControlExposeHeaders = "Access-Control-Expose-Headers" HeaderAccessControlMaxAge = "Access-Control-Max-Age" // Security HeaderStrictTransportSecurity = "Strict-Transport-Security" HeaderXContentTypeOptions = "X-Content-Type-Options" HeaderXXSSProtection = "X-XSS-Protection" HeaderXFrameOptions = "X-Frame-Options" HeaderContentSecurityPolicy = "Content-Security-Policy" HeaderContentSecurityPolicyReportOnly = "Content-Security-Policy-Report-Only" HeaderXCSRFToken = "X-CSRF-Token" HeaderReferrerPolicy = "Referrer-Policy" // CloudFlare HeaderCFConnectingIP = "CF-Connecting-IP" HeaderCFConnectingIPv6 = "CF-Connecting-IPv6" // Telegram HeaderTelegramSecretToken = "X-Telegram-Bot-Api-Secret-Token" // Shopify HeaderShopifyAccessToken = "X-Shopify-Access-Token" HeaderShopifyApiVersion = "X-Shopify-Api-Version" HeaderShopifyTopic = "X-Shopify-Topic" HeaderShopifyShopDomain = "X-Shopify-Shop-Domain" HeaderShopifyHmac = "X-Shopify-Hmac-Sha256" )
Variables ¶
var ( ErrUnsupportedMediaType = NewHTTPError(http.StatusUnsupportedMediaType) ErrNotFound = NewHTTPError(http.StatusNotFound) ErrForbidden = NewHTTPError(http.StatusForbidden) ErrConflict = NewHTTPError(http.StatusConflict) ErrMethodNotAllowed = NewHTTPError(http.StatusMethodNotAllowed) ErrStatusRequestEntityTooLarge = NewHTTPError(http.StatusRequestEntityTooLarge) ErrTooManyRequests = NewHTTPError(http.StatusTooManyRequests) ErrBadRequest = NewHTTPError(http.StatusBadRequest) ErrBadGateway = NewHTTPError(http.StatusBadGateway) ErrInternalServerError = NewHTTPError(http.StatusInternalServerError) ErrRequestTimeout = NewHTTPError(http.StatusRequestTimeout) )
Errors
var ( ErrDataTypeMismatch = errors.New("data type mismatch, use HTML(template, data) function") ErrTemplateNotFound = errors.New("template not found") )
var ErrHeaderAlreadyCommitted = errors.New("response already committed")
var ErrNegotiate = errors.New("the accepted formats are not offered by the server")
var ErrRendererNotFound = errors.New("renderer not found")
Functions ¶
func CtxRequestID ¶
func CtxTemplate ¶ added in v0.0.2
func CtxTracerProvider ¶
func CtxTracerProvider(ctx context.Context) oteltrace.TracerProvider
func DefaultTemplateFinder ¶ added in v0.0.2
func IsWebSocket ¶
IsWebSocket returns true if HTTP connection is WebSocket otherwise false.
func MustSubFS ¶
MustSubFS creates sub FS from current filesystem or panic on failure. Panic happens when `fsRoot` contains invalid path according to `fs.ValidPath` rules.
MustSubFS is helpful when dealing with `embed.FS` because for example `//go:embed assets/images` embeds files with paths including `assets/images` as their prefix. In that case use `fs := MustSubFS(fs, "rootDirectory") to create sub fs which uses necessary prefix for directory path.
func StatusCode ¶
func StatusCode(w http.ResponseWriter) int
func WithAccept ¶
func WithAccept(ctx context.Context, kind AcceptKind) context.Context
func WithTemplate ¶ added in v0.0.2
func WithTracerProvider ¶
Types ¶
type AcceptKind ¶
type AcceptKind int
const ( AcceptUnknown AcceptKind = iota AcceptHTML AcceptJSON AcceptXML AcceptYAML )
func CtxAccept ¶
func CtxAccept(ctx context.Context) AcceptKind
func (AcceptKind) String ¶
func (k AcceptKind) String() string
type BeforeRenderFunc ¶ added in v0.0.2
type BeforeRenderFunc func(w http.ResponseWriter, r *http.Request, statusCode int, data any, kind AcceptKind) error
type DefaultErrorHandler ¶
type DefaultErrorHandler struct {
// contains filtered or unexported fields
}
func NewDefaultErrorHandler ¶
func NewDefaultErrorHandler(renderer Renderer, resolver ErrorResolverFunc, logger *zap.Logger) *DefaultErrorHandler
func (*DefaultErrorHandler) ServeHTTP ¶
func (h *DefaultErrorHandler) ServeHTTP(w http.ResponseWriter, r *http.Request, err error)
type DefaultErrorWrapper ¶
type DefaultErrorWrapper struct {
// contains filtered or unexported fields
}
func NewDefaultErrorWrapper ¶
func NewDefaultErrorWrapper(errorHandler ErrorHandler) *DefaultErrorWrapper
func (*DefaultErrorWrapper) Wrap ¶
func (ew *DefaultErrorWrapper) Wrap(handler func(http.ResponseWriter, *http.Request) error) http.Handler
type ErrorHandler ¶
type ErrorHandler interface {
ServeHTTP(http.ResponseWriter, *http.Request, error)
}
type ErrorHandlerFunc ¶
type ErrorHandlerFunc func(http.ResponseWriter, *http.Request, error)
func (ErrorHandlerFunc) ServeHTTP ¶
func (f ErrorHandlerFunc) ServeHTTP(w http.ResponseWriter, r *http.Request, err error)
type ErrorResolverFunc ¶ added in v0.0.2
func ErrorResolver ¶ added in v0.0.2
func ErrorResolver(asHTTPError func(err error, target **HTTPError)) ErrorResolverFunc
type ErrorWrapper ¶
type HTTPError ¶
type HTTPError struct {
Code int `json:"code"`
Message any `json:"message"`
Internal error `json:"-"` // Stores the error returned by an external dependency
}
HTTPError represents an error that occurred while handling a request.
func NewHTTPError ¶
NewHTTPError creates a new HTTPError instance.
func NewHTTPErrorWithInternal ¶
NewHTTPErrorWithInternal creates a new HTTPError instance with internal error set.
func (*HTTPError) WithInternal ¶
WithInternal returns clone of HTTPError with err set to HTTPError.Internal field
type IPExtractor ¶
IPExtractor is a function to extract IP addr from http.Request.
func ExtractIPDirect ¶
func ExtractIPDirect() IPExtractor
ExtractIPDirect extracts IP address using actual IP address. Use this if your server faces to internet directory (i.e.: uses no proxy).
func ExtractIPFromCFHeader ¶
func ExtractIPFromCFHeader() IPExtractor
ExtractIPFromCFHeader extracts IP address using cf-connecting-ip header. Use this if you are using CloudFlare. See [CloudFlare](https://developers.cloudflare.com/fundamentals/reference/http-request-headers/#cf-connecting-ip)
func ExtractIPFromRealIPHeader ¶
func ExtractIPFromRealIPHeader(options ...TrustOption) IPExtractor
ExtractIPFromRealIPHeader extracts IP address using x-real-ip header. Use this if you put proxy which uses this header.
func ExtractIPFromXFFHeader ¶
func ExtractIPFromXFFHeader(options ...TrustOption) IPExtractor
ExtractIPFromXFFHeader extracts IP address using x-forwarded-for header. Use this if you put proxy which uses this header. This returns nearest untrustable IP. If all IPs are trustable, returns furthest one (i.e.: XFF[0]).
type Mux ¶
type Mux struct {
// contains filtered or unexported fields
}
func Mount ¶
func Mount(basePath string, mux *http.ServeMux, errorWrapper ErrorWrapper) *Mux
Example ¶
group := Mount("/api", http.NewServeMux(), nil)
// apply middleware to the group
group.Use(func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Add("X-Test-Middleware", "true")
next.ServeHTTP(w, r)
})
})
// add test handlers
group.HandleFunc("GET /test", func(w http.ResponseWriter, _ *http.Request) {
w.WriteHeader(http.StatusOK)
})
group.HandleFunc("POST /test2", func(w http.ResponseWriter, _ *http.Request) {
w.WriteHeader(http.StatusOK)
})
// start the server
if err := http.ListenAndServe(":8080", group); err != nil {
panic(err)
}
func NewMux ¶
func NewMux(mux *http.ServeMux, errorWrapper ErrorWrapper) *Mux
Example ¶
group := NewMux(http.NewServeMux(), nil)
// apply middleware to the group
group.Use(func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Add("X-Mounted-Middleware", "true")
next.ServeHTTP(w, r)
})
})
// add test handlers
group.HandleFunc("GET /test", func(w http.ResponseWriter, _ *http.Request) {
w.WriteHeader(http.StatusOK)
})
group.HandleFunc("POST /test2", func(w http.ResponseWriter, _ *http.Request) {
w.WriteHeader(http.StatusOK)
})
// start the server
if err := http.ListenAndServe(":8080", group); err != nil {
panic(err)
}
func (*Mux) DisableNotFoundHandler ¶
func (m *Mux) DisableNotFoundHandler()
DisableNotFoundHandler disables the automatic registration of a not found handler for the root path.
func (*Mux) Group ¶
Group creates a new group with the same middleware stack as the original on top of the existing Mux.
func (*Mux) Handle ¶
Handle adds a new route to the Group's mux, applying all middlewares to the handler.
func (*Mux) HandleFunc ¶
HandleFunc registers the handler function for the given pattern to the Group's mux. The handler is wrapped with the Group's middlewares.
func (*Mux) Handler ¶
Handler returns the handler and the pattern that matches the request. It always returns a non-nil handler, see http.ServeMux.Handler documentation for details.
func (*Mux) Mount ¶
Mount creates a new group with a specified base path on top of the existing Mux.
func (*Mux) Route ¶
Route allows for configuring the Group inside the configureFn function.
Example ¶
group := NewMux(http.NewServeMux(), nil)
// configure the group using Set
group.Route(func(g *Mux) {
// apply middleware to the group
g.Use(func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Add("X-Test-Middleware", "true")
next.ServeHTTP(w, r)
})
})
// add test handlers
g.HandleFunc("GET /test", func(w http.ResponseWriter, _ *http.Request) {
w.WriteHeader(http.StatusOK)
})
g.HandleFunc("POST /test2", func(w http.ResponseWriter, _ *http.Request) {
w.WriteHeader(http.StatusOK)
})
})
// start the server
if err := http.ListenAndServe(":8080", group); err != nil {
panic(err)
}
func (*Mux) ServeHTTP ¶
func (m *Mux) ServeHTTP(w http.ResponseWriter, r *http.Request)
ServeHTTP implements the http.Handler interface
type NegotiateFunc ¶ added in v0.0.2
type NegotiateRenderer ¶
type NegotiateRenderer struct {
// contains filtered or unexported fields
}
func NewNegotiateRenderer ¶
func NewNegotiateRenderer(renderers map[AcceptKind]Renderer, negotiate NegotiateFunc, offered string, rest ...string) *NegotiateRenderer
func (*NegotiateRenderer) Render ¶
func (nr *NegotiateRenderer) Render(w http.ResponseWriter, r *http.Request, statusCode int, data any) error
type RendererHTML ¶
type RendererHTML struct {
// contains filtered or unexported fields
}
func NewRendererHTML ¶
func NewRendererHTML(engine TemplateEngine, finder TemplateFinder, beforeRender ...BeforeRenderFunc) *RendererHTML
func (*RendererHTML) Render ¶
func (rr *RendererHTML) Render(w http.ResponseWriter, r *http.Request, statusCode int, data any) (err error)
type RendererJSON ¶
type RendererJSON struct {
// contains filtered or unexported fields
}
func NewRendererJSON ¶
func NewRendererJSON(beforeRender ...BeforeRenderFunc) *RendererJSON
func (*RendererJSON) Render ¶
func (rr *RendererJSON) Render(w http.ResponseWriter, r *http.Request, statusCode int, data any) error
type RendererXML ¶
type RendererXML struct {
// contains filtered or unexported fields
}
func NewRendererXML ¶
func NewRendererXML(beforeRender ...BeforeRenderFunc) *RendererXML
func (*RendererXML) Render ¶
func (rr *RendererXML) Render(w http.ResponseWriter, r *http.Request, statusCode int, data any) error
type RendererYAML ¶
type RendererYAML struct {
// contains filtered or unexported fields
}
func NewRendererYAML ¶
func NewRendererYAML(beforeRender ...BeforeRenderFunc) *RendererYAML
func (*RendererYAML) Render ¶
func (rr *RendererYAML) Render(w http.ResponseWriter, r *http.Request, statusCode int, data any) error
type Response ¶
type Response struct {
Writer http.ResponseWriter
Status int
Size int64
Committed bool
// contains filtered or unexported fields
}
Response wraps a http.ResponseWriter and implements its interface to be used by an HTTP handler to construct an HTTP response. See: https://golang.org/pkg/net/http/#ResponseWriter
func NewResponse ¶
func NewResponse(w http.ResponseWriter) *Response
NewResponse creates a new instance of Response.
func UnwrapResponse ¶
func UnwrapResponse(w http.ResponseWriter) *Response
func (*Response) After ¶
func (r *Response) After(fn func())
After registers a function which is called just after the response is written. If the `Content-Length` is unknown, none of the after function is executed.
func (*Response) Before ¶
func (r *Response) Before(fn func())
Before registers a function which is called just before the response is written.
func (*Response) Flush ¶
func (r *Response) Flush()
Flush implements the http.Flusher interface to allow an HTTP handler to flush buffered data to the client. See http.Flusher(https://golang.org/pkg/net/http/#Flusher)
func (*Response) Header ¶
Header returns the header map for the writer that will be sent by WriteHeader. Changing the header after a call to WriteHeader (or Write) has no effect unless the modified headers were declared as trailers by setting the "Trailer" header before the call to WriteHeader (see example) To suppress implicit response headers, set their value to nil. Example: https://golang.org/pkg/net/http/#example_ResponseWriter_trailers
func (*Response) Hijack ¶
Hijack implements the http.Hijacker interface to allow an HTTP handler to take over the connection. See http.Hijacker(https://golang.org/pkg/net/http/#Hijacker)
func (*Response) Pusher ¶
Pusher implements the http.Pusher interface to allow an HTTP handler to constructs a synthetic request using the given target and options. See http.Pusher(https://golang.org/pkg/net/http/#Pusher)
func (*Response) Reset ¶
func (r *Response) Reset(w http.ResponseWriter)
func (*Response) StatusCode ¶
func (*Response) Unwrap ¶
func (r *Response) Unwrap() http.ResponseWriter
Unwrap returns the original http.ResponseWriter. ResponseController can be used to access the original http.ResponseWriter. See [https://go.dev/blog/go1.20]
func (*Response) WriteHeader ¶
WriteHeader sends an HTTP response header with status code. If WriteHeader is not called explicitly, the first call to Write will trigger an implicit WriteHeader(http.StatusOK). Thus explicit calls to WriteHeader are mainly used to send error codes.
type TemplateEngine ¶
type TemplateFinder ¶ added in v0.0.2
type TemplateFinderFunc ¶ added in v0.0.2
type TrustOption ¶
type TrustOption func(*ipChecker)
TrustOption is config for which IP address to trust
func TrustIPRange ¶
func TrustIPRange(ipRange *net.IPNet) TrustOption
TrustIPRange add trustable IP ranges using CIDR notation.
func TrustLinkLocal ¶
func TrustLinkLocal(v bool) TrustOption
TrustLinkLocal configures if you trust link-local address (default: true).
func TrustLoopback ¶
func TrustLoopback(v bool) TrustOption
TrustLoopback configures if you trust loopback address (default: true).
func TrustPrivateNet ¶
func TrustPrivateNet(v bool) TrustOption
TrustPrivateNet configures if you trust private network address (default: true).