web

package
v0.0.0-...-bc49051 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 27, 2024 License: MIT Imports: 40 Imported by: 0

Documentation

Index

Constants

View Source
const (
	// DefaultCookieName is the default name of the field that contains the session id.
	DefaultCookieName = "SID"
	// DefaultCookiePath is the default cookie path.
	DefaultCookiePath = "/"
	// DefaultCookieSecure returns what the default value for the `Secure` bit of issued cookies will be.
	DefaultCookieSecure = true
	// DefaultCookieHTTPOnly returns what the default value for the `HTTPOnly` bit of issued cookies will be.
	DefaultCookieHTTPOnly = true
	// DefaultCookieSameSiteMode is the default cookie same site mode (currently http.SameSiteLaxMode).
	DefaultCookieSameSiteMode = http.SameSiteLaxMode
	// DefaultSessionTimeout is the default absolute timeout for a session (24 hours as a sane default).
	DefaultSessionTimeout time.Duration = 24 * time.Hour
	// DefaultUseSessionCache is the default if we should use the auth manager session cache.
	DefaultUseSessionCache = true
	// DefaultSessionTimeoutIsAbsolute is the default if we should set absolute session expiries.
	DefaultSessionTimeoutIsAbsolute = true
)
View Source
const (
	// ContentTypeApplicationJSON is a content type for JSON responses.
	// We specify chartset=utf-8 so that clients know to use the UTF-8 string encoding.
	ContentTypeApplicationJSON = "application/json; charset=utf-8"

	// ContentTypeApplicationXML is a content type header value.
	ContentTypeApplicationXML = "application/xml"

	// ContentTypeApplicationGob is a content type for Gob responses.
	// We specify chartset=utf-8 so that clients know to use the UTF-8 string encoding.
	ContentTypeApplicationGob = "application/gob"

	// ContentTypeApplicationFormEncoded is a content type header value.
	ContentTypeApplicationFormEncoded = "application/x-www-form-urlencoded"

	// ContentTypeApplicationOctetStream is a content type header value.
	ContentTypeApplicationOctetStream = "application/octet-stream"

	// ContentTypeHTML is a content type for html responses.
	// We specify chartset=utf-8 so that clients know to use the UTF-8 string encoding.
	ContentTypeHTML = "text/html; charset=utf-8"

	//ContentTypeXML is a content type for XML responses.
	// We specify chartset=utf-8 so that clients know to use the UTF-8 string encoding.
	ContentTypeXML = "text/xml; charset=utf-8"

	// ContentTypeText is a content type for text responses.
	// We specify chartset=utf-8 so that clients know to use the UTF-8 string encoding.
	ContentTypeText = "text/plain; charset=utf-8"

	// ContentEncodingIdentity is the identity (uncompressed) content encoding.
	ContentEncodingIdentity = "identity"

	// ContentEncodingGZIP is the gzip (compressed) content encoding.
	ContentEncodingGZIP = "gzip"

	// ConnectionClose is the connection value of "close"
	ConnectionClose = "close"
)
View Source
const (
	HeaderAccept                  = "Accept"
	HeaderAcceptEncoding          = "Accept-Encoding"
	HeaderAllow                   = "Allow"
	HeaderAuthorization           = "Authorization"
	HeaderCacheControl            = "Cache-Control"
	HeaderConnection              = "Connection"
	HeaderContentEncoding         = "Content-Encoding"
	HeaderContentLength           = "Content-Length"
	HeaderContentType             = "Content-Type"
	HeaderCookie                  = "Cookie"
	HeaderDate                    = "Date"
	HeaderETag                    = "ETag"
	HeaderForwarded               = "Forwarded"
	HeaderServer                  = "Server"
	HeaderSetCookie               = "Set-Cookie"
	HeaderStrictTransportSecurity = "Strict-Transport-Security"
	HeaderUserAgent               = "User-Agent"
	HeaderVary                    = "Vary"
	HeaderXContentTypeOptions     = "X-Content-Type-Options"
	HeaderXForwardedFor           = "X-Forwarded-For"
	HeaderXForwardedHost          = "X-Forwarded-Host"
	HeaderXForwardedPort          = "X-Forwarded-Port"
	HeaderXForwardedProto         = "X-Forwarded-Proto"
	HeaderXForwardedScheme        = "X-Forwarded-Scheme"
	HeaderXFrameOptions           = "X-Frame-Options"
	HeaderXRealIP                 = "X-Real-IP"
	HeaderXServedBy               = "X-Served-By"
	HeaderXXSSProtection          = "X-Xss-Protection"
)

Header names in canonical form.

View Source
const (
	// TemplateBadRequest is the default template name for bad request view results.
	TemplateBadRequest = "bad_request"
	// TemplateInternalError is the default template name for internal server error view results.
	TemplateInternalError = "error"
	// TemplateNotFound is the default template name for not found error view results.
	TemplateNotFound = "not_found"
	// TemplateNotAuthorized is the default template name for not authorized error view results.
	TemplateNotAuthorized = "not_authorized"
	// TemplateResult is the default template name for the result catchall endpoint.
	TemplateResult = "result"
)

Variables

View Source
var (
	// ErrSessionIDEmpty is thrown if a session id is empty.
	ErrSessionIDEmpty = errors.New("auth session id is empty")
	// ErrSecureSessionIDEmpty is an error that is thrown if a given secure session id is invalid.
	ErrSecureSessionIDEmpty = errors.New("auth secure session id is empty")
)
View Source
var (
	// ErrUnsetViewTemplate is an error that is thrown if a given secure session id is invalid.
	ErrUnsetViewTemplate = errors.New("view result template is unset")
)
View Source
var (
	KnownExtensions = map[string]string{
		".html": "text/html; charset=utf-8",
		".xml":  "text/xml; charset",
		".json": "application/json; charset=utf-8",
		".css":  "text/css; charset=utf-8",
		".js":   "application/javascript",
		".jpg":  "image/jpeg",
		".jpeg": "image/jpeg",
		".png":  "image/png",
	}
)

KnownExtenions are known extenions mapped to their content types.

Functions

func BodyAsJSON

func BodyAsJSON(r Context, ref any) error

BodyAsJSON reads a request body and deserializes it as json into a given reference.

func CleanPath

func CleanPath(p string) string

CleanPath is the URL version of path.Clean, it returns a canonical URL path for p, eliminating . and .. elements.

The following rules are applied iteratively until no further processing can be done:

  1. Replace multiple slashes with a single slash.
  2. Eliminate each . path name element (the current directory).
  3. Eliminate each inner .. path name element (the parent directory) along with the non-.. element that precedes it.
  4. Eliminate .. elements that begin a rooted path: that is, replace "/.." by "/" at the beginning of a path.

If the result of this process is an empty string, "/" is returned

func CopySingleHeaders

func CopySingleHeaders(headers map[string]string) http.Header

CopySingleHeaders copies headers in single value format.

func DetectFileContentType

func DetectFileContentType(path string) (string, error)

DetectFileContentType generates the content type of a given file by path.

func FormValue

func FormValue[T any](ctx Context, key string) (out T, err error)

FormValue parses a given post form value as retrieved from a given key.

func FormatFileSize

func FormatFileSize(sizeBytes int) string

FormatFileSize returns a string representation of a file size in bytes.

func GetRemoteAddr

func GetRemoteAddr(r *http.Request) string

GetRemoteAddr gets the origin/client ip for a request. X-FORWARDED-FOR is checked. If multiple IPs are included the first one is returned X-REAL-IP is checked. If multiple IPs are included the last one is returned Finally r.RemoteAddr is used Only benevolent services will allow access to the real IP.

func HeaderAny

func HeaderAny(headers http.Header, key, value string) bool

HeaderAny returns if any pieces of a header match a given value.

func HeaderLastValue

func HeaderLastValue(headers http.Header, key string) (string, bool)

HeaderLastValue returns the last value of a potential csv of headers.

func HeaderValue

func HeaderValue[T any](ctx Context, key string) (out T, err error)

HeaderValue parses a given header value as retrieved from a given key.

func Headers

func Headers(from map[string]string) http.Header

Headers creates headers from a given map.

func IsErrSessionInvalid

func IsErrSessionInvalid(err error) bool

IsErrSessionInvalid returns if an error is a session invalid error.

func LogOnError

func LogOnError(log Logger) func(Context, error)

LogOnError returns an OnError handler that logs errors.

func LogOnListen

func LogOnListen(app *App, log Logger) func()

LogOnListen returns an OnListen handler that logs when the server begins listening.

func LogOnRequest

func LogOnRequest(log Logger) func(RequestEvent)

LogOnRequest returns an OnRequest handler that logs requests.

func MergeHeaders

func MergeHeaders(headers ...http.Header) http.Header

MergeHeaders merges headers.

func MockSimulateLogin

func MockSimulateLogin(ctx context.Context, app *App, userID string, opts ...r2.Option) []r2.Option

MockSimulateLogin simulates a user login for a given app as mocked request params (i.e. r2 options).

This requires an auth manager to be configured to handle and persist sessions.

func MustParseURL

func MustParseURL(rawURL string) *url.URL

MustParseURL parses a url and panics if there is an error.

func NegotiateContentType

func NegotiateContentType(req *http.Request, availableContentTypes ...string) (string, error)

NegotiateContentType parses the "Accept" header off a request and returns the mutually negotiated content type based on a list of available content types.

If the "Accept" header is missing or empty, the first available content type will be selected as the negotiated content type.

An empty string will be returned if no match was found, and should then result in a 406 (Not Acceptable) response to the client.

An error will be returned if the request accept header is malformed.

func NewMockRequest

func NewMockRequest(method, path string) *http.Request

NewMockRequest creates a mock request.

func NewMockRequestWithCookie

func NewMockRequestWithCookie(method, path, cookieName, cookieValue string) *http.Request

NewMockRequestWithCookie creates a mock request with a cookie attached to it.

func NewSessionID

func NewSessionID() string

NewSessionID returns a new session id. It is not a uuid; session ids are generated using a secure random source. SessionIDs are generally 64 bytes.

func ParseValue

func ParseValue(value any, raw string) error

ParseValue is a helper to parse string values as given output values.

func QueryValue

func QueryValue[T any](ctx Context, key string) (out T, err error)

QueryValue parses a given query string value as retrieved from a given key.

func ReadSetCookies

func ReadSetCookies(h http.Header) []*http.Cookie

ReadSetCookies parses all "Set-Cookie" values from the header h and returns the successfully parsed Cookies.

It is a verbatim copy of the one found in `net/http` but exported so you can use it to.

func RedirectUpgrade

func RedirectUpgrade(rw http.ResponseWriter, req *http.Request)

RedirectUpgrade redirects HTTP to HTTPS as an http.HandlerFunc.

func RequestFuncStubs

func RequestFuncStubs() template.FuncMap

RequestFuncStubs are "stub" versions of the request bound funcs.

func RouteValue

func RouteValue[T any](ctx Context, key string) (out T, err error)

RouteValue parses a given route parameter value as retrieved from a given key.

func WriteGob

func WriteGob(w http.ResponseWriter, statusCode int, response interface{}) error

WriteGob marshalls an object to gob.

func WriteJSON

func WriteJSON(w http.ResponseWriter, statusCode int, response interface{}) error

WriteJSON marshalls an object to json.

Types

type Action

type Action func(Context) Result

Action is the function signature for controller actions.

func GZip

func GZip(action Action) Action

GZip is a middleware the implements gzip compression for requests that opt into it.

func NestMiddleware

func NestMiddleware(action Action, middleware ...Middleware) Action

NestMiddleware reads the middleware variadic args and organizes the calls recursively in the order they appear. I.e. NestMiddleware(inner, third, second, first) will call "first", "second", "third", then "inner".

func ProxyAction

func ProxyAction(target *url.URL) Action

ProxyAction returns an action that proxies requests to a given url.

Under the hood ist uses a `httputil.ReverseProxy` in single host mode.

func SessionAware

func SessionAware(action Action) Action

SessionAware is an action that injects the session into the context.

func SessionAwareStable

func SessionAwareStable(action Action) Action

SessionAwareStable is an action that injects the session into the context, but does not extend it if there is a session lifetime handler on the auth manager.

It is typically used for logout endpoints, where you don't want a session extension `Set-Cookie` response header to compete with the expiry header.

func SessionRequired

func SessionRequired(action Action) Action

SessionRequired is an action that requires a session to be present or identified in some form on the request.

type App

type App struct {
	Auth
	RouteTree
	Server

	Views        Views
	Localization Localization

	BaseURL     string
	Headers     http.Header
	PanicAction PanicAction
	// contains filtered or unexported fields
}

App is the container type for the application and its resources.

Typical usage is just to instantiate it with a bare constructor:

app := new(web.App)
app.Get("/", func(ctx web.Context) web.Result {
	return &web.JSONResult{StatusCode: http.StatusOK, Response: "OK!" }
}

func New

func New() *App

New returns a new app with defaults configured and applies a given set of options to it.

You can alternately use the `app := new(App)` form but it's highly recommended to use this constructor.

func (*App) ActionHandler

func (a *App) ActionHandler(action Action) Handler

ActionHandler is the translation step from Action to Handler.

func (*App) Delete

func (a *App) Delete(path string, action Action)

Delete registers a DELETE request route handler.

To add additional middleware, use `web.NextMiddleware(action, ...middleware)`.

func (*App) Get

func (a *App) Get(path string, action Action)

Get registers a GET request route handler.

To add additional middleware, use `web.NextMiddleware(action, ...middleware)`.

func (*App) HandleAction

func (a *App) HandleAction(method string, path string, action Action)

HandleAction registers an action for a given method and path with the given middleware.

func (*App) Head

func (a *App) Head(path string, action Action)

Head registers a HEAD request route handler.

To add additional middleware, use `web.NextMiddleware(action, ...middleware)`.

func (*App) Initialize

func (a *App) Initialize() error

Initialize calls initializers on the localization engine and the views cache.

If you don't use either of these facilities (e.g. if you're only implementing JSON api routes, you can skip calling this function).

func (*App) Lookup

func (a *App) Lookup(method, path string) (route *Route, params RouteParameters, skipSlashRedirect bool)

Lookup finds the route data for a given method and path.

func (*App) Options

func (a *App) Options(path string, action Action)

Options registers a OPTIONS request route handler.

To add additional middleware, use `web.NextMiddleware(action, ...middleware)`.

func (*App) Patch

func (a *App) Patch(path string, action Action)

Patch registers a PATCH request route handler.

To add additional middleware, use `web.NextMiddleware(action, ...middleware)`.

func (*App) Post

func (a *App) Post(path string, action Action)

Post registers a POST request route handler.

To add additional middleware, use `web.NextMiddleware(action, ...middleware)`.

func (*App) Put

func (a *App) Put(path string, action Action)

Put registers a PUT request route handler.

To add additional middleware, use `web.NextMiddleware(action, ...middleware)`.

func (*App) RegisterConfig

func (a *App) RegisterConfig(cfg Config)

RegisterConfig registers the config.

func (*App) RegisterControllers

func (a *App) RegisterControllers(controllers ...Controller)

RegisterControllers registers controllers.

func (*App) RegisterLoggerListeners

func (a *App) RegisterLoggerListeners(log Logger)

RegisterLoggerListeners registers a logger with the listen, request, and error handler lists.

func (*App) RegisterMiddleware

func (a *App) RegisterMiddleware(middleware ...Middleware)

RegisterMiddleware registers global middleware.

func (*App) RegisterOnError

func (a *App) RegisterOnError(fn func(Context, error))

RegisterOnError adds an on request hook.

func (*App) RegisterOnRequest

func (a *App) RegisterOnRequest(fn func(RequestEvent))

RegisterOnRequest adds an on request hook.

func (*App) Start

func (a *App) Start(ctx context.Context) error

Start implements the first phase of graceful.Graceful and initializes the view cache and does some other housekeeping before starting the server.

type Auth

type Auth struct {
	// AuthCookieDefaults hold the default cookie options when creating cookies.
	AuthCookieDefaults http.Cookie
	// AuthPersister is the underlying auth persistence handler.
	AuthPersister any
}

Auth is a manager for sessions.

func (Auth) CookieNameOrDefault

func (a Auth) CookieNameOrDefault() string

CookieNameOrDefault returns the configured cookie name or a default.

func (Auth) CookiePathOrDefault

func (a Auth) CookiePathOrDefault() string

CookiePathOrDefault returns the configured cookie path or a default.

func (Auth) Login

func (a Auth) Login(userID string, ctx Context) (session *Session, err error)

Login logs a userID in.

func (Auth) LoginRedirect

func (a Auth) LoginRedirect(ctx Context) Result

LoginRedirect returns a redirect result for when auth fails and you need to send the user to a login page.

func (Auth) Logout

func (a Auth) Logout(ctx Context) error

Logout unauthenticates a session.

func (Auth) VerifyOrExtendSession

func (a Auth) VerifyOrExtendSession(ctx Context) (session *Session, err error)

VerifyOrExtendSession reads a session value from a request and checks if it's valid. It also handles updating a rolling expiry.

func (Auth) VerifySession

func (a Auth) VerifySession(ctx Context) (sessionValue string, session *Session, err error)

VerifySession pulls the session cookie off the request, and validates it represents a valid session.

type BufferPool

type BufferPool struct {
	sync.Pool
}

BufferPool is a sync.Pool of bytes.Buffer.

func NewBufferPool

func NewBufferPool(defaultBufferSize int) *BufferPool

NewBufferPool returns a new Pool, which returns bytes buffers pre-sized to a given minimum size.

The purpose of a buffer pool is to reduce the number of gc collections incurred when using bytes buffers repeatedly; instead of marking the buffer as to be collected, it is returned to the pool to be re-used.

Example:

pool := bufferutil.NewBufferPool(1024) // pre-allocate 1024 bytes per buffer.

func() {
	buf := pool.Get()
	defer pool.Put(buf)

	// do things with the buffer ...
}()

func (*BufferPool) Get

func (p *BufferPool) Get() *bytes.Buffer

Get returns a pooled bytes.Buffer instance.

func (*BufferPool) Put

func (p *BufferPool) Put(b *bytes.Buffer)

Put returns the pooled instance.

type Config

type Config struct {
	Addr    string            `json:"addr,omitempty" yaml:"addr,omitempty"`
	BaseURL string            `json:"baseURL,omitempty" yaml:"baseURL,omitempty"`
	Headers map[string]string `json:"headers,omitempty" yaml:"headers,omitempty"`

	SkipTrailingSlashRedirects bool `json:"skipTrailingSlashRedirects,omitempty" yaml:"skipTrailingSlashRedirects,omitempty"`
	SkipHandlingMethodOptions  bool `json:"skipHandlingMethodOptions,omitempty" yaml:"skipHandlingMethodOptions,omitempty"`
	SkipMethodNotAllowed       bool `json:"skipMethodNotAllowed,omitempty" yaml:"skipMethodNotAllowed,omitempty"`

	MaxHeaderBytes      int           `json:"maxHeaderBytes,omitempty" yaml:"maxHeaderBytes,omitempty"`
	ReadTimeout         time.Duration `json:"readTimeout,omitempty" yaml:"readTimeout,omitempty"`
	ReadHeaderTimeout   time.Duration `json:"readHeaderTimeout,omitempty" yaml:"readHeaderTimeout,omitempty"`
	WriteTimeout        time.Duration `json:"writeTimeout,omitempty" yaml:"writeTimeout,omitempty"`
	IdleTimeout         time.Duration `json:"idleTimeout,omitempty" yaml:"idleTimeout,omitempty"`
	ShutdownGracePeriod time.Duration `json:"shutdownGracePeriod,omitempty" yaml:"shutdownGracePeriod,omitempty"`
}

Config is an object used to set up a web app.

func (*Config) ApplyTo

func (c *Config) ApplyTo(app *App)

ApplyTo applies a given config to an app.

func (Config) IsZero

func (c Config) IsZero() bool

IsZero returns if the config is unset or not.

func (*Config) Resolve

func (c *Config) Resolve(ctx context.Context) error

Resolve resolves the config from other sources.

func (*Config) ResolveAddrFromPort

func (c *Config) ResolveAddrFromPort(ctx context.Context) (*string, error)

ResolveAddrFromPort resolves the `Addr` field from a `$PORT` environment variable.

type Context

type Context interface {
	context.Context
	// App is a reference back to the parent application.
	App() *App
	// Views should return the underlying views cache.
	Views() *Views
	// Response is the response writer for the request.
	Response() ResponseWriter
	// Request is the inbound request metadata.
	Request() *http.Request
	// Route is the matching route for the request if relevant.
	Route() *Route
	// RouteParams is a cache of parameters or variables
	// within the route and their values.
	RouteParams() RouteParameters
	// WithSession sets the session on the context.
	WithSession(*Session) Context
	// Session holds an active session if that is relevant.
	Session() *Session
	// Elapsed returns the current elapsed time for the request.
	Elapsed() time.Duration
	// Localization returns the i18n primitives.
	Localization() *Localization
	// Locale is the detected language preference.
	Locale() string
}

Context is the struct that represents the context for an hc request.

func MockContext

func MockContext(method, path string) Context

MockContext returns a new mock ctx. It is intended to be used in testing.

func MockContextWithBuffer

func MockContextWithBuffer(method, path string, buf io.Writer) Context

MockContextWithBuffer returns a new mock ctx. It is intended to be used in testing.

type Controller

type Controller interface {
	Register(*App)
}

Controller is a type that can be Registered.

type FetchSessionHandler

type FetchSessionHandler interface {
	FetchSession(context.Context, string) (*Session, error)
}

FetchSessionHandler restores a session based on a session value.

type GZipResponseWriter

type GZipResponseWriter struct {
	// contains filtered or unexported fields
}

GZipResponseWriter is a response writer that compresses output.

func NewGZipResponseWriter

func NewGZipResponseWriter(w http.ResponseWriter) *GZipResponseWriter

NewGZipResponseWriter returns a new gzipped response writer.

func (*GZipResponseWriter) Close

func (crw *GZipResponseWriter) Close() error

Close closes any underlying resources.

func (*GZipResponseWriter) ContentLength

func (crw *GZipResponseWriter) ContentLength() int

ContentLength returns the content length for the request.

func (*GZipResponseWriter) Flush

func (crw *GZipResponseWriter) Flush()

Flush pushes any buffered data out to the response.

func (*GZipResponseWriter) Header

func (crw *GZipResponseWriter) Header() http.Header

Header returns the headers for the response.

func (*GZipResponseWriter) InnerResponse

func (crw *GZipResponseWriter) InnerResponse() http.ResponseWriter

InnerResponse returns the underlying response.

func (*GZipResponseWriter) StatusCode

func (crw *GZipResponseWriter) StatusCode() int

StatusCode returns the status code for the request.

func (*GZipResponseWriter) Write

func (crw *GZipResponseWriter) Write(b []byte) (int, error)

Write writes the byes to the stream.

func (*GZipResponseWriter) WriteHeader

func (crw *GZipResponseWriter) WriteHeader(code int)

WriteHeader writes a status code.

type GobResult

type GobResult struct {
	StatusCode int
	Response   any
}

GobResult is a gob rendered result.

func (*GobResult) Render

func (gr *GobResult) Render(ctx Context) error

Render renders the result

type GobResultProvider

type GobResultProvider struct{}

GobResultProvider returns gob results for common responses.

func (GobResultProvider) BadRequest

func (grp GobResultProvider) BadRequest(err error) Result

BadRequest returns a service response.

func (GobResultProvider) Forbidden

func (grp GobResultProvider) Forbidden() Result

Forbidden returns a service response.

func (GobResultProvider) InternalError

func (grp GobResultProvider) InternalError(err error) Result

InternalError returns a service response.

func (GobResultProvider) NotAuthorized

func (grp GobResultProvider) NotAuthorized() Result

NotAuthorized returns a service response.

func (GobResultProvider) NotFound

func (grp GobResultProvider) NotFound() Result

NotFound returns a service response.

func (GobResultProvider) OK

func (grp GobResultProvider) OK() Result

OK returns a service response.

func (GobResultProvider) Result

func (grp GobResultProvider) Result(statusCode int, result any) Result

Result returns a service response.

type Handler

Handler is the most basic route handler.

func WrapHandler

func WrapHandler(handler http.Handler) Handler

WrapHandler wraps an http.Handler as a Handler.

type JSONResult

type JSONResult struct {
	StatusCode int
	Response   any
	Err        error
}

JSONResult is a json result.

func (*JSONResult) Render

func (jr *JSONResult) Render(ctx Context) error

Render renders the result

type JSONResultProvider

type JSONResultProvider struct{}

JSONResultProvider are context results for api methods.

func JSON

func JSON() JSONResultProvider

JSON returns a json result provider.

func (JSONResultProvider) BadRequest

func (jrp JSONResultProvider) BadRequest(err error) Result

BadRequest returns a json response.

func (JSONResultProvider) Forbidden

func (jrp JSONResultProvider) Forbidden() Result

Forbidden returns a service response.

func (JSONResultProvider) InternalError

func (jrp JSONResultProvider) InternalError(err error) Result

InternalError returns a json response.

func (JSONResultProvider) NotAuthorized

func (jrp JSONResultProvider) NotAuthorized() Result

NotAuthorized returns a service response.

func (JSONResultProvider) NotFound

func (jrp JSONResultProvider) NotFound() Result

NotFound returns a service response.

func (JSONResultProvider) OK

func (jrp JSONResultProvider) OK() Result

OK returns a json response.

func (JSONResultProvider) Result

func (jrp JSONResultProvider) Result(statusCode int, result any) Result

Result returns a json response.

type KeepAliveListener

type KeepAliveListener struct {
	*net.TCPListener

	KeepAlive       bool
	KeepAlivePeriod time.Duration
}

KeepAliveListener sets TCP keep-alive timeouts on accepted connections. It's used by ListenAndServe and ListenAndServeTLS so dead TCP connections (e.g. closing laptop mid-download) eventually go away.

It is taken from net/http/server.go

func (KeepAliveListener) Accept

func (ln KeepAliveListener) Accept() (c net.Conn, err error)

Accept implements net.Listener

type ListenerOptions

type ListenerOptions struct {
	Network       string
	Addr          string
	ProxyProtocol *proxyproto.Config
	TLS           *tls.Config
}

ListenerOptions creates a listener based on options.

func (*ListenerOptions) GetListener

func (lc *ListenerOptions) GetListener() (net.Listener, error)

GetListener creates a listener.

type LocalSessionCache

type LocalSessionCache struct {
	sync.RWMutex
	Sessions map[string]*Session
}

LocalSessionCache is a memory cache of sessions. It is meant to be used in tests.

func (*LocalSessionCache) FetchSession

func (lsc *LocalSessionCache) FetchSession(_ context.Context, sessionID string) (*Session, error)

FetchSession is a shim to interface with the auth manager.

func (*LocalSessionCache) Get

func (lsc *LocalSessionCache) Get(sessionID string) *Session

Get gets a session.

func (*LocalSessionCache) PersistSession

func (lsc *LocalSessionCache) PersistSession(_ context.Context, session *Session) error

PersistSession is a shim to interface with the auth manager.

func (*LocalSessionCache) Remove

func (lsc *LocalSessionCache) Remove(sessionID string)

Remove removes a session from the cache.

func (*LocalSessionCache) RemoveSession

func (lsc *LocalSessionCache) RemoveSession(_ context.Context, sessionID string) error

RemoveSession is a shim to interface with the auth manager.

func (*LocalSessionCache) Upsert

func (lsc *LocalSessionCache) Upsert(session *Session)

Upsert adds or updates a session to the cache.

type Localization

type Localization struct {
	// contains filtered or unexported fields
}

Localization holds the translation catalog and lets us create a printer to emit translated strings.

func (*Localization) AddEntries

func (l *Localization) AddEntries(entries ...LocalizationEntry)

AddEntries adds entries to the localization catalog.

func (*Localization) AddYAML

func (l *Localization) AddYAML(yamlContents []byte)

AddYAML reads a given reader as yaml and adds translation entries.

func (*Localization) Initialize

func (l *Localization) Initialize() error

InitializeLocalization parses the localization entries

func (*Localization) Printer

func (l *Localization) Printer(preferred ...string) Printer

Printer yields a printer based on the localization catalog for a given language tag.

You _must_ call `.Initialize()` before using this method!!

type LocalizationEntry

type LocalizationEntry struct {
	Tag     string
	Key     string
	Message any
}

LocalizationEntry is a specific language translation for a string.

type Logger

type Logger interface {
	Output(int, string) error
}

Logger is a type that emits log messages.

type LoginRedirectHandler

type LoginRedirectHandler interface {
	LoginRedirect(Context) *url.URL
}

LoginRedirectHandler is a redirect handler.

type Middleware

type Middleware func(Action) Action

Middleware is a func that implements middleware

type MockResponseWriter

type MockResponseWriter struct {
	// contains filtered or unexported fields
}

MockResponseWriter is an object that satisfies response writer but uses an internal buffer.

func NewMockResponse

func NewMockResponse(buffer io.Writer) *MockResponseWriter

NewMockResponse returns a mocked response writer.

func (*MockResponseWriter) Bytes

func (res *MockResponseWriter) Bytes() []byte

Bytes returns the raw response.

func (*MockResponseWriter) Close

func (res *MockResponseWriter) Close() error

Close is a no-op.

func (*MockResponseWriter) ContentLength

func (res *MockResponseWriter) ContentLength() int

ContentLength returns the content length.

func (*MockResponseWriter) Flush

func (res *MockResponseWriter) Flush()

Flush is a no-op.

func (*MockResponseWriter) Header

func (res *MockResponseWriter) Header() http.Header

Header returns the response headers.

func (*MockResponseWriter) InnerResponse

func (res *MockResponseWriter) InnerResponse() http.ResponseWriter

InnerResponse returns the backing httpresponse writer.

func (*MockResponseWriter) StatusCode

func (res *MockResponseWriter) StatusCode() int

StatusCode returns the status code.

func (*MockResponseWriter) Write

func (res *MockResponseWriter) Write(buffer []byte) (int, error)

Write writes data and adds to ContentLength.

func (*MockResponseWriter) WriteHeader

func (res *MockResponseWriter) WriteHeader(statusCode int)

WriteHeader sets the status code.

type MockResult

type MockResult struct {
	*r2.Request
	App    *App
	Server *httptest.Server
}

MockResult is a result of a mocked request.

func Mock

func Mock(app *App, req *http.Request, options ...r2.Option) *MockResult

Mock sends a mock request to an app.

It will reset the app Server, Listener, and will set the request host to the listener address for a randomized local listener.

func MockGet

func MockGet(app *App, path string, options ...r2.Option) *MockResult

MockGet sends a mock get request to an app.

func MockMethod

func MockMethod(app *App, method, path string, options ...r2.Option) *MockResult

MockMethod sends a mock request with a given method to an app. You should use request options to set the body of the request if it's a post or put etc.

func MockPost

func MockPost(app *App, path string, body io.ReadCloser, options ...r2.Option) *MockResult

MockPost sends a mock post request to an app.

func MockPostJSON

func MockPostJSON(app *App, path string, body interface{}, options ...r2.Option) *MockResult

MockPostJSON sends a mock post request with a json body to an app.

func (*MockResult) Close

func (mr *MockResult) Close() error

Close stops the app.

type PanicAction

type PanicAction func(Context, interface{}) Result

PanicAction is a receiver for app.PanicHandler.

type PersistSessionHandler

type PersistSessionHandler interface {
	PersistSession(context.Context, *Session) error
}

PersistSessionHandler saves the session to a stable store.

type Printer

type Printer interface {
	Printf(string, ...any) string
	Print(...any) string
}

type RawResult

type RawResult struct {
	StatusCode  int
	ContentType string
	Response    []byte
	Err         error
}

RawResult is for when you just want to dump bytes.

func Raw

func Raw(contents []byte) *RawResult

Raw returns a new raw result.

func RawString

func RawString(contents string) *RawResult

RawString returns a new text result.

func RawWithContentType

func RawWithContentType(contentType string, body []byte) *RawResult

RawWithContentType returns a binary response with a given content type.

func RawWithErr

func RawWithErr(contentType string, body []byte, err error) *RawResult

RawWithErr returns a binary response with a given application error.

func (*RawResult) Render

func (rr *RawResult) Render(ctx Context) error

Render renders the result.

type RedirectResult

type RedirectResult struct {
	Method      string `json:"redirect_method"`
	RedirectURI string `json:"redirect_uri"`
	StatusCode  int    `json:"status_code"`
}

RedirectResult is a result that should cause the browser to redirect.

func Redirect

func Redirect(destination string) *RedirectResult

Redirect returns a redirect result to a given destination.

func RedirectStatus

func RedirectStatus(destination string, statusCode int) *RedirectResult

RedirectStatus returns a redirect result to a given destination with a given status code.

func RedirectWithMethod

func RedirectWithMethod(method, destination string) *RedirectResult

RedirectWithMethod returns a redirect result to a destination with a given method.

func RedirectWithMethodf

func RedirectWithMethodf(method, format string, args ...interface{}) *RedirectResult

RedirectWithMethodf returns a redirect result to a destination composed of a format and scan arguments with a given method.

func Redirectf

func Redirectf(format string, args ...interface{}) *RedirectResult

Redirectf returns a redirect result to a given destination specified by a given format and scan arguments.

func (*RedirectResult) Render

func (rr *RedirectResult) Render(ctx Context) error

Render writes the result to the response.

type RemoveSessionHandler

type RemoveSessionHandler interface {
	RemoveSession(context.Context, string) error
}

RemoveSessionHandler removes a session based on a session value.

type RequestEvent

type RequestEvent struct {
	RemoteAddr      string
	UserAgent       string
	Method          string
	URL             string
	Route           string
	ContentLength   int
	ContentType     string
	ContentEncoding string
	StatusCode      int
	Elapsed         time.Duration
	Locale          string
}

RequestEvent is an event type for http requests.

func NewRequestEvent

func NewRequestEvent(ctx Context) RequestEvent

NewRequestEvent returns a new request event.

func (RequestEvent) String

func (e RequestEvent) String() string

WriteText implements TextWritable.

type ResponseWriter

type ResponseWriter interface {
	http.Flusher
	http.ResponseWriter
	io.Closer
	StatusCode() int
	ContentLength() int
	InnerResponse() http.ResponseWriter
}

ResponseWriter is a super-type of http.ResponseWriter that includes the StatusCode and ContentLength for the request

type Result

type Result interface {
	Render(Context) error
}

Result is the type returned by actions.

func Static

func Static(ctx Context, fs http.FileSystem, path string) Result

Static serves a static file from a given filesystem.

It assumes views as the provider for failure conditions.

type ResultProvider

type ResultProvider interface {
	InternalError(error) Result
	BadRequest(error) Result
	NotFound() Result
	NotAuthorized() Result
	Result(int, any) Result
}

ResultProvider is the provider interface for status based results.

func AcceptedProvider

func AcceptedProvider(ctx Context) ResultProvider

AcceptedProvider returns a result provider by the Accept header value on the incoming request.

type RewriteRule

type RewriteRule interface {
	Apply(string) (string, bool)
}

RewriteRule is a type that modifies a request url path.

It should take the `url.Path` value, and return an updated value and true, or the value unchanged and false.

type RewriteRuleFunc

type RewriteRuleFunc func(string) (string, bool)

RewriteRuleFunc is a function that rewrites a url.

func (RewriteRuleFunc) Apply

func (rrf RewriteRuleFunc) Apply(path string) (string, bool)

Apply applies the rewrite rule.

type Route

type Route struct {
	Handler
	Method string
	Path   string
	Params []string
}

Route is an entry in the route tree.

func (Route) String

func (r Route) String() string

String returns the path.

func (Route) StringWithMethod

func (r Route) StringWithMethod() string

StringWithMethod returns a string representation of the route. Namely: Method_Path

type RouteNode

type RouteNode struct {
	RouteNodeType

	Path       string
	IsWildcard bool
	MaxParams  uint8
	Indices    string
	Children   []*RouteNode
	Route      *Route
	Priority   uint32
}

RouteNode is a node on the route tree.

func (*RouteNode) AddChildRoute

func (n *RouteNode) AddChildRoute(method, path string, handler Handler)

AddChildRoute adds a node with the given handle to the path.

func (*RouteNode) GetPath

func (n *RouteNode) GetPath(path string) (route *Route, p RouteParameters, tsr bool)

GetPath returns the node for a path, parameter values, and if there is a trailing slash redirect recommendation.

type RouteNodeType

type RouteNodeType uint8

RouteNodeType is a type of route node.

const (
	RouteNodeTypeStatic RouteNodeType = iota // default
	RouteNodeTypeRoot
	RouteNodeTypeParam
	RouteNodeTypeCatchAll
)

RouteNodeTypes

type RouteParameter

type RouteParameter struct {
	Key, Value string
}

RouteParameter is a parameter key and value for the route.

type RouteParameters

type RouteParameters []RouteParameter

RouteParameters are parameters sourced from parsing the request path (route).

func (RouteParameters) Get

func (rp RouteParameters) Get(key string) (string, bool)

Get gets a value for a key.

type RouteTree

type RouteTree struct {
	// Routes is a map between canonicalized http method
	// (i.e. `GET` vs. `get`) and individual method
	// route trees.
	Routes map[string]*RouteNode
	// SkipTrailingSlashRedirects disables matching
	// routes that are off by a trailing slash, either because
	// routes are registered with the '/' suffix, or because
	// the request has a '/' suffix and the
	// registered route does not.
	SkipTrailingSlashRedirects bool
	// SkipHandlingMethodOptions disables returning
	// a result with the `ALLOWED` header for method options,
	// and will instead 404 for `OPTIONS` methods.
	SkipHandlingMethodOptions bool
	// SkipMethodNotAllowed skips specific handling
	// for methods that do not have a route tree with
	// a specific 405 response, and will instead return a 404.
	SkipMethodNotAllowed bool
	// NotFoundHandler is an optional handler to set
	// to customize not found (404) results.
	NotFoundHandler Handler
	// MethodNotAllowedHandler is an optional handler
	// to set to customize method not allowed (405) results.
	MethodNotAllowedHandler Handler
}

RouteTree implements the basic logic of creating a route tree.

It is embedded in *App and handles the path to handler matching based on route trees per method.

A very simple example:

rt := new(web.RouteTree)
rt.Handle(http.MethodGet, "/", func(w http.ResponseWriter, req *http.Request, route *web.Route, params web.Params) {
    w.WriteHeader(http.StatusOK)
    fmt.Fprintf(w, "OK!")
})
(&http.Server{Addr: "127.0.0.1:8080", Handler: rt}).ListenAndServe()

func (*RouteTree) Handle

func (rt *RouteTree) Handle(method, path string, handler Handler)

Handle adds a handler at a given method and path.

func (RouteTree) Route

func (rt RouteTree) Route(req *http.Request) (*Route, RouteParameters)

Route gets the route and parameters for a given request if it matches a registered handler.

It will automatically resolve if a trailing slash should be appended for the input request url path, and will return the corresponding redirected route (and parameters) if there is one.

func (RouteTree) ServeHTTP

func (rt RouteTree) ServeHTTP(w http.ResponseWriter, req *http.Request)

ServeHTTP makes the router implement the http.Handler interface.

type SerializeSessionHandler

type SerializeSessionHandler interface {
	SerializeSession(context.Context, *Session) (string, error)
}

SerializeSessionHandler serializes a session as a string.

type Server

type Server struct {
	// Server is the entrypoint for the server.
	http.Server
	// Listener
	Listener net.Listener
	// GetListener is an optional function that will be
	// called if Listener is not set.
	// The Listener field will be set to the result of this
	// function.
	GetListener func() (net.Listener, error)
	// ShutdownGracePeriod is the amount of time we allow
	// connections to drain on Stop.
	ShutdownGracePeriod time.Duration
	// contains filtered or unexported fields
}

Server is a wrapper for an http server that implements the graceful interface.

It implements the graceful interface, allowing the server to be used with the graceful shutdown handler by signals.

On start, if the server does not have a Listener set, and the GetListener function is also not set, an http listener will be created on "srv.Server.Addr", and if that is unset, on ":http".

func (*Server) RegisterOnListen

func (gs *Server) RegisterOnListen(fn func())

RegisterOnListen registers an on-listen handler.

These listeners are called when the server is about to begin accepting connections.

func (*Server) RegisterOnStart

func (gs *Server) RegisterOnStart(fn func() error)

RegisterOnStart registers an on-start handler.

func (*Server) Restart

func (gs *Server) Restart(_ context.Context) error

Restart does nothing.

func (*Server) Start

func (gs *Server) Start(_ context.Context) (err error)

Start implements graceful.Graceful.Start. It is expected to block.

func (*Server) Stop

func (gs *Server) Stop(ctx context.Context) error

Stop implements graceful.Graceful.Stop.

type Session

type Session struct {
	UserID     string    `json:"userID,omitempty"`
	BaseURL    string    `json:"baseURL,omitempty"`
	SessionID  string    `json:"sessionID,omitempty"`
	CreatedUTC time.Time `json:"createdUTC,omitempty"`
	ExpiresUTC time.Time `json:"expiresUTC,omitempty"`
	UserAgent  string    `json:"userAgent,omitempty"`
	RemoteAddr string    `json:"remoteAddr,omitempty"`
	Locale     string    `json:"locale,omitempty"`
	State      any       `json:"state,omitempty"`
}

Session is an active session

func (*Session) IsExpired

func (s *Session) IsExpired(asOf time.Time) bool

IsExpired returns if the session is expired.

func (*Session) IsZero

func (s *Session) IsZero() bool

IsZero returns if the object is set or not. It will return true if either the userID or the sessionID are unset.

type SessionTimeoutProvider

type SessionTimeoutProvider interface {
	SessionTimeout(*Session) time.Time
}

SessionTimeoutProvider provides a new timeout for a session.

type StaticFileServer

type StaticFileServer struct {
	SearchPaths                  []http.FileSystem
	RewriteRules                 []RewriteRule
	Headers                      http.Header
	UseRouteFilepathAsRequestURL bool
	UseEmptyResponseIfNotFound   bool
}

StaticFileServer serves static results for `*filepath` suffix routes.

If you want to use a "cached" mode you should use embedding and http.FS(...) as a search path.

func (StaticFileServer) Action

func (sc StaticFileServer) Action(ctx Context) Result

Action implements an action handler.

func (*StaticFileServer) AddRegexPathRewrite

func (sc *StaticFileServer) AddRegexPathRewrite(match string, rewriteAction func(string, ...string) string) error

AddRegexPathRewrite adds a re-write rule that modifies the url path.

Typically these kinds of re-write rules are used for vanity forms or removing a cache busting string from a given path.

func (StaticFileServer) ResolveFile

func (sc StaticFileServer) ResolveFile(filePath string) (f http.File, finalPath string, err error)

ResolveFile resolves a file from rewrite rules and search paths.

First the file path is modified according to the rewrite rules. Then each search path is checked for the resolved file path.

func (StaticFileServer) ServeHTTP

func (sc StaticFileServer) ServeHTTP(rw http.ResponseWriter, req *http.Request)

ServeHTTP is the entrypoint for the static server.

It adds default headers if specified, and then serves the file from disk.

type StatusResponseWriter

type StatusResponseWriter struct {
	// contains filtered or unexported fields
}

StatusResponseWriter a better response writer

func NewStatusResponseWriter

func NewStatusResponseWriter(w http.ResponseWriter) *StatusResponseWriter

NewStatusResponseWriter creates a new response writer.

func (*StatusResponseWriter) Close

func (rw *StatusResponseWriter) Close() error

Close calls close on the inner response if it supports it.

func (*StatusResponseWriter) ContentLength

func (rw *StatusResponseWriter) ContentLength() int

ContentLength returns the content length

func (*StatusResponseWriter) Flush

func (rw *StatusResponseWriter) Flush()

Flush calls flush on the inner response writer if it is supported.

func (*StatusResponseWriter) Header

func (rw *StatusResponseWriter) Header() http.Header

Header accesses the response header collection.

func (*StatusResponseWriter) Hijack

func (rw *StatusResponseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error)

Hijack wraps response writer's Hijack function.

func (*StatusResponseWriter) InnerResponse

func (rw *StatusResponseWriter) InnerResponse() http.ResponseWriter

InnerResponse returns the backing writer.

func (*StatusResponseWriter) StatusCode

func (rw *StatusResponseWriter) StatusCode() int

StatusCode returns the status code.

func (*StatusResponseWriter) Write

func (rw *StatusResponseWriter) Write(b []byte) (int, error)

Write writes the data to the response.

func (*StatusResponseWriter) WriteHeader

func (rw *StatusResponseWriter) WriteHeader(code int)

WriteHeader writes the status code (it is a somewhat poorly chosen method name from the standard library).

type TextResultProvider

type TextResultProvider struct{}

TextResultProvider is the default response provider if none is specified.

func Text

func Text() TextResultProvider

Text returns a text result provider.

func (TextResultProvider) BadRequest

func (trp TextResultProvider) BadRequest(err error) Result

BadRequest returns a plaintext result.

func (TextResultProvider) InternalError

func (trp TextResultProvider) InternalError(err error) Result

InternalError returns a plainttext result.

func (TextResultProvider) NotAuthorized

func (trp TextResultProvider) NotAuthorized() Result

NotAuthorized returns a plaintext result.

func (TextResultProvider) NotFound

func (trp TextResultProvider) NotFound() Result

NotFound returns a plaintext result.

func (TextResultProvider) OK

func (trp TextResultProvider) OK() Result

OK returns an plaintext result.

func (TextResultProvider) Result

func (trp TextResultProvider) Result(statusCode int, result interface{}) Result

Result returns a plaintext result.

func (TextResultProvider) Status

func (trp TextResultProvider) Status(statusCode int, response interface{}) Result

Status returns a plaintext result.

type Translations

type Translations map[string]map[string]string

Translations are language => english => translated

type ValidateSessionHandler

type ValidateSessionHandler interface {
	ValidateSession(context.Context, *Session) error
}

ValidateSessionHandler validates a session.

type ViewFS

type ViewFS struct {
	// FS is the virtual filesystem reference.
	FS fs.FS
	// Patterns denotes glob patterns to match
	// within the filesystem itself (and can be empty!)
	Patterns []string
}

ViewFS is a fs reference for views.

type ViewResult

type ViewResult struct {
	ViewName   string
	StatusCode int
	ViewModel  any
	Views      Views
	Template   *template.Template
	Err        error
}

ViewResult is a result that renders a view.

func (*ViewResult) Render

func (vr *ViewResult) Render(ctx Context) (err error)

Render renders the result to the given response writer.

func (*ViewResult) RequestFuncs

func (vr *ViewResult) RequestFuncs(ctx Context) template.FuncMap

RequestFuncs returns the view funcs that are bound to the request specifically.

type Views

type Views struct {
	FuncMap template.FuncMap

	ViewPaths    []string
	ViewLiterals []string
	ViewFS       []ViewFS
	// contains filtered or unexported fields
}

Views is the cached views used in view results.

func (*Views) AddFS

func (vc *Views) AddFS(fs ...ViewFS)

AddFS adds view fs instances to the view collection.

func (*Views) AddLiterals

func (vc *Views) AddLiterals(views ...string)

AddLiterals adds view literal strings to the view collection.

func (*Views) AddPaths

func (vc *Views) AddPaths(paths ...string)

AddPaths adds paths to the view collection.

func (Views) BadRequest

func (vc Views) BadRequest(err error) Result

BadRequest returns a view result.

func (*Views) Initialize

func (vc *Views) Initialize() (err error)

Initialize caches templates by path.

func (Views) InternalError

func (vc Views) InternalError(err error) Result

InternalError returns a view result.

func (Views) Lookup

func (vc Views) Lookup(name string) *template.Template

Lookup looks up a view.

func (Views) NotAuthorized

func (vc Views) NotAuthorized() Result

NotAuthorized returns a view result.

func (Views) NotFound

func (vc Views) NotFound() Result

NotFound returns a view result.

func (Views) Parse

func (vc Views) Parse() (views *template.Template, err error)

Parse parses the view tree.

func (Views) Result

func (vc Views) Result(statusCode int, response any) Result

Result returns a status view result.

func (Views) View

func (vc Views) View(viewName string, viewModel any) Result

View returns a view result with an OK status code.

func (Views) ViewStatus

func (vc Views) ViewStatus(statusCode int, viewName string, viewModel any) Result

ViewStatus returns a view result with a given status code.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL