web

package module
v0.8.1 Latest Latest
Warning

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

Go to latest
Published: Sep 17, 2024 License: MIT Imports: 9 Imported by: 1

README

Helpers for implementing http.Handlers

Requests Handling

Middleware

To facilitate the implementation of standard func(http.Handler) http.Handler middleware the MiddlewareFunc interface and the NewMiddleware() factory were created.

type MiddlewareFunc func(rw http.ResponseWriter, req *http.Request, next http.Handler)

The next argument is never nil, and a do-nothing NoMiddleware middleware was introduced. When NoMiddleware() is called without a handler, it will return a 404 handler.

Alternatively there is MiddlewareErrorFunc and NewMiddlewareError() that allows the handler to return an error that is then passed to HandleError() and then to the registered ErrorHandler.

Resolver

We call Resolver a function that will give us the Path our resource should be handling, and for this task darvaza.org/x/web provides four helpers.

  • WithResolver() to attach a dedicated Resolver to the request's context.
  • NewResolverMiddleware() to attach one to every request.
  • Resolver(), to retrieve a previously attached Resolver from the request's context.
  • and a Resolve() helper that will use the above and call the specified Resolver, or take the request's URL.Path, and then clean it to make sure its safe to use.
  • CleanPath() cleans and validates the path for URL.Path handling.
RESTful Handlers

The darvaza.org/x/web/resource sub-package offers a Resource[T] wrapper to implement a RESTful interface to a particular resource.

Response Handlers

Using respond.WithRequest() we compute our options and PreferredContentType() tells one how to encode the data.

Content Negotiation

QualityList

The QualityList parser allows choosing the best option during Content Negotiation, e.g. accepted Content-Types.

BestQuality

qlist offers two helpers to choose the best option from a QualityList and a list of supported options, BestQuality() and BestQualityWithIdentity(). Identity is an special option we consider unless it's explicitly forbidden.

BestEncoding

qlist.BestEncoding() is a special case of BestQualityWithIdentity() using the Accept header, and falling back to "identity" as magic type.

See also

HTTP Errors

HTTPError

HTTPError{} is an http.Handler that is also an error and can be used to build HTTP errors.

Error Handlers

darvaza.org/x/web provides a mechanism to hook an HTTP error handler to the request Context.

  • WithErrorHandler() to attach a func(http.ResponseWriter, *http.Request, error)
  • NewErrorHandlerMiddleware() to attach it to every request,
  • and ErrorHandler() to read it back.

We also provide a basic implementation called HandleError which will first attempt to get a better handler for the context, via ErrorHandler(req.Context()) and hand it over. If there is no ErrorHandlerFunc in the context it will test if the error itself via the http.Handler interface and invoke it.

As last resort HandleError() will check if the error provides an HTTPStatus() int method to infer the HTTP status code of the error, and if negative or undefined it will assume it's a 500, compose a web.HTTPError and serve it.

Error Factories
  • AsError() that will do the same as HandleError() to ensure the given error, if any, error is http.Handler-able
  • and AsErrorWithCode() to suggest an HTTP status code to be used instead of 500 when it can't be determined.

There are also web.HTTPError factories to create new errors, from a generic:

  • NewHTTPError() and NewHTTPErrorf() and a companion ErrorText(code) helper.

to redirect factories from formatted strings:

  • NewStatusMovedPermanently(loc, ...) (301)
  • NewStatusFound(loc, ...) (302)
  • NewStatusSeeOther(loc, ...) (303)
  • NewStatusTemporaryRedirect(loc, ...) (307)
  • NewStatusPermanentRedirect(loc, ...) (308)

error wrappers:

  • NewStatusBadRequest(err) (400)

and simple responses:

  • NewStatusNotModified() (304)
  • NewStatusBadRequest(err) (400)
  • NewStatusNotFound() (404)
  • NewStatusMethodNotAllowed(allowed...) (405)
  • NewStatusNotAcceptable() (406)

Documentation

Overview

Package web contains helpers for web handlers

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func AsError added in v0.5.0

func AsError(err error) error

AsError converts a given error into an HTTP-aware one. A nil argument will be treated as no error. If the status code can't be inferred, a 500 will be assumed.

func AsErrorWithCode added in v0.5.0

func AsErrorWithCode(err error, code int) error

AsErrorWithCode converts a given error into an HTTP-aware one using the given status code when none could be inferred. If a non-positive code is provided, a 500 will be assumed.

func CleanPath added in v0.5.3

func CleanPath(path string) (string, bool)

CleanPath cleans and validates a URL.Path

func ErrorText

func ErrorText(code int) string

ErrorText returns the title corresponding to a given HTTP Status code

func HandleError added in v0.4.3

func HandleError(rw http.ResponseWriter, req *http.Request, err error)

HandleError attempts to call the ErrorHandler set for the content, otherwise it serves the error directly using its own ServeHTTP if defined or HTTPError if not.

func NewErrorHandlerMiddleware added in v0.6.1

func NewErrorHandlerMiddleware(h ErrorHandlerFunc) func(http.Handler) http.Handler

NewErrorHandlerMiddleware creates a middleware that will attach a ErrorHandlerFunc to all requests.

func NewMiddleware added in v0.6.1

func NewMiddleware(h MiddlewareFunc) func(http.Handler) http.Handler

NewMiddleware adds a MiddlewareFunc in a HTTP handling chain.

func NewMiddlewareWithError added in v0.6.1

func NewMiddlewareWithError(h MiddlewareWithErrorFunc) func(http.Handler) http.Handler

NewMiddlewareWithError adds a MiddlewareWithErrorFunc in a HTTP handling chain.

func NewResolverMiddleware added in v0.6.1

func NewResolverMiddleware(h ResolverFunc) func(http.Handler) http.Handler

NewResolverMiddleware creates a middleware that will attach a ResolverFunc to all requests.

func NoMiddleware added in v0.6.1

func NoMiddleware(next http.Handler) http.Handler

NoMiddleware is a middleware handler that does nothing.

func Resolve added in v0.5.3

func Resolve(req *http.Request) (path string, err error)

Resolve extracts the routing path from the request using the Resolver in the context when available.

The resulting path is cleaned and validated before returning it.

The Resolver either returns the route path, or a web.HTTPError usually of one one of the following codes: * 30x (Redirects) * 400 (Bad request) * 401 (Login Required) * 403 (Permission Denied) * 404 (Resource Not Found), * or 500 (Server Error)

func SetCache added in v0.7.0

func SetCache(hdr http.Header, d time.Duration)

SetCache sets the Cache-Control header. a Negative value is translated in "private", values of a second or longer translated to "max-age", and otherwise "no-cache"

func SetHeader added in v0.7.0

func SetHeader(hdr http.Header, key, value string, args ...any)

SetHeader sets a header value, optionally formatted.

func SetHeaderUnlessExists added in v0.7.0

func SetHeaderUnlessExists(hdr http.Header, key, value string, args ...any)

SetHeaderUnlessExists sets a header value if it's not already set. Optional value formatting supported.

func SetNoCache added in v0.7.0

func SetNoCache(hdr http.Header)

SetNoCache sets the Cache-Control header to "no-cache"

func WithErrorHandler

func WithErrorHandler(ctx context.Context, h ErrorHandlerFunc) context.Context

WithErrorHandler attaches an ErrorHandler function to a context for later retrieval

func WithResolver added in v0.5.3

func WithResolver(ctx context.Context, h ResolverFunc) context.Context

WithResolver attaches a ResolverFunc to a context for later retrieval

Types

type Error

type Error interface {
	Error() string
	HTTPStatus() int
}

Error is an error that knows its HTTP Status Code

type ErrorHandlerFunc

type ErrorHandlerFunc func(http.ResponseWriter, *http.Request, error)

ErrorHandlerFunc is the signature of a function used as ErrorHandler

func ErrorHandler

func ErrorHandler(ctx context.Context) (ErrorHandlerFunc, bool)

ErrorHandler attempts to pull an ErrorHandler from the context.Context

type HTTPError

type HTTPError struct {
	Err  error
	Code int
	Hdr  http.Header
}

HTTPError extends core.WrappedError with HTTP Status Code

func NewHTTPError

func NewHTTPError(code int, err error, note string) *HTTPError

NewHTTPError creates a new HTTPError with a given StatusCode and optional cause and annotation

func NewHTTPErrorf

func NewHTTPErrorf(code int, err error, format string, args ...any) *HTTPError

NewHTTPErrorf creates a new HTTPError with a given StatusCode and optional cause and formatted annotation

func NewStatusBadRequest added in v0.5.2

func NewStatusBadRequest(err error) *HTTPError

NewStatusBadRequest returns a 400 HTTP error, unless the given error is already qualified.

func NewStatusForbidden added in v0.7.2

func NewStatusForbidden() *HTTPError

NewStatusForbidden returns a 403 HTTP error.

func NewStatusFound added in v0.5.1

func NewStatusFound(dest string, args ...any) *HTTPError

NewStatusFound returns a 302 redirect error.

func NewStatusInternalServerError added in v0.7.2

func NewStatusInternalServerError(err error) *HTTPError

NewStatusInternalServerError returns a 500 HTTP error, unless the given error is already qualified.

func NewStatusMethodNotAllowed added in v0.5.2

func NewStatusMethodNotAllowed(allowed ...string) *HTTPError

NewStatusMethodNotAllowed returns a 405 HTTP error

func NewStatusMovedPermanently added in v0.5.1

func NewStatusMovedPermanently(dest string, args ...any) *HTTPError

NewStatusMovedPermanently returns a 301 redirect error.

func NewStatusNotAcceptable added in v0.5.2

func NewStatusNotAcceptable() *HTTPError

NewStatusNotAcceptable returns a 406 HTTP error.

func NewStatusNotFound added in v0.5.2

func NewStatusNotFound() *HTTPError

NewStatusNotFound returns a 404 HTTP error.

func NewStatusNotModified added in v0.5.1

func NewStatusNotModified() *HTTPError

NewStatusNotModified returns a 304 HTTP error.

func NewStatusPermanentRedirect added in v0.5.1

func NewStatusPermanentRedirect(dest string, args ...any) *HTTPError

NewStatusPermanentRedirect returns a 308 redirect error.

func NewStatusSeeOther added in v0.5.1

func NewStatusSeeOther(dest string, args ...any) *HTTPError

NewStatusSeeOther returns a 303 redirect error.

func NewStatusTemporaryRedirect added in v0.5.1

func NewStatusTemporaryRedirect(dest string, args ...any) *HTTPError

NewStatusTemporaryRedirect returns a 307 redirect error.

func NewStatusUnauthorized added in v0.7.2

func NewStatusUnauthorized() *HTTPError

NewStatusUnauthorized returns a 401 HTTP error.

func (*HTTPError) AddHeader

func (err *HTTPError) AddHeader(key, value string)

AddHeader appends a value to an HTTP header entry of the HTTPError

func (*HTTPError) DeleteHeader

func (err *HTTPError) DeleteHeader(key string)

DeleteHeader removes a header key from the HTTPError if present

func (*HTTPError) Error

func (err *HTTPError) Error() string

func (*HTTPError) HTTPStatus added in v0.5.0

func (err *HTTPError) HTTPStatus() int

HTTPStatus returns the HTTP status code associated with the Error

func (*HTTPError) Header

func (err *HTTPError) Header() http.Header

Header returns a http.Header attached to this error for custom fields

func (*HTTPError) Render added in v0.6.3

func (err *HTTPError) Render(rw http.ResponseWriter, req *http.Request)

Render will serve the error ignoring the ErrorHandler.

func (*HTTPError) ServeHTTP

func (err *HTTPError) ServeHTTP(rw http.ResponseWriter, req *http.Request)

ServeHTTP is a very primitive handler that will try to pass the error to a [middleware.ErrorHandlerFunc] provided via the request's context.Context. if it exists, otherwise it will invoke the [Render] method to serve it.

func (*HTTPError) SetHeader

func (err *HTTPError) SetHeader(key, value string)

SetHeader sets the value of a header key of the HTTPError

func (*HTTPError) Unwrap

func (err *HTTPError) Unwrap() error

type Handler added in v0.4.3

type Handler interface {
	TryServeHTTP(http.ResponseWriter, *http.Request) error
}

A Handler is like http.Handler but doesn't render or handle errors by itself.

type HandlerFunc added in v0.4.3

type HandlerFunc func(http.ResponseWriter, *http.Request) error

HandlerFunc is a function that implements http.Handler and our Handler. HandleError will be called when using the http.Handler interface and the function returns an error.

func (HandlerFunc) ServeHTTP added in v0.4.3

func (fn HandlerFunc) ServeHTTP(rw http.ResponseWriter, req *http.Request)

func (HandlerFunc) TryServeHTTP added in v0.4.3

func (fn HandlerFunc) TryServeHTTP(rw http.ResponseWriter, req *http.Request) error

TryServeHTTP implements the Handler interface.

type MiddlewareFunc added in v0.6.1

type MiddlewareFunc func(rw http.ResponseWriter, req *http.Request, next http.Handler)

MiddlewareFunc is a middleware handler that is introduced into an HTTP handling chain via NewMiddleware.

type MiddlewareWithErrorFunc added in v0.6.1

type MiddlewareWithErrorFunc func(rw http.ResponseWriter, req *http.Request, next http.Handler) error

MiddlewareWithErrorFunc is a middleware handler that is introduced into an HTTP handling chain via [NewMiddlewareError].

type ResolverFunc added in v0.5.3

type ResolverFunc func(*http.Request) (string, error)

A ResolverFunc attempts to extract the path from a http.Request.

func Resolver added in v0.5.3

func Resolver(ctx context.Context) (ResolverFunc, bool)

Resolver attempts to get a ResolverFunc from the given context

Directories

Path Synopsis
Package assets assists serving embedded assets via HTTP
Package assets assists serving embedded assets via HTTP
Package consts contains constant strings used on HTTP handlers
Package consts contains constant strings used on HTTP handlers
Package forms assists working with web forms and Request.Form
Package forms assists working with web forms and Request.Form
Package html facilitates use of html/template.Template
Package html facilitates use of html/template.Template
Package qlist provides a processor for HTTP Quality Lists
Package qlist provides a processor for HTTP Quality Lists
Package resource implements a RESTful resource handler
Package resource implements a RESTful resource handler
Package respond assists handlers to produce reponses
Package respond assists handlers to produce reponses

Jump to

Keyboard shortcuts

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