Documentation
¶
Overview ¶
Package qinetic is a Fiber-style web framework built on the qilat HTTP engine, serving HTTP/1.1, HTTP/2, and HTTP/3 from one App.
Index ¶
- Constants
- Variables
- func DefaultErrorHandler(c *Ctx, err error) error
- type App
- func (app *App) Add(methods []string, path string, handler Handler, handlers ...Handler) Router
- func (app *App) All(path string, handler Handler, handlers ...Handler) Router
- func (app *App) Connect(path string, handler Handler, handlers ...Handler) Router
- func (app *App) Delete(path string, handler Handler, handlers ...Handler) Router
- func (app *App) Get(path string, handler Handler, handlers ...Handler) Router
- func (app *App) Group(prefix string, handlers ...Handler) Router
- func (app *App) Handler() qilat.Handler
- func (app *App) Head(path string, handler Handler, handlers ...Handler) Router
- func (app *App) Listen(addr string) error
- func (app *App) ListenQUIC(pc net.PacketConn) error
- func (app *App) ListenTLS(addr, certFile, keyFile string) error
- func (app *App) ListenTLSWithCertificate(addr string, cert tls.Certificate) error
- func (app *App) Listener(ln net.Listener) error
- func (app *App) ListenerTLS(ln net.Listener) error
- func (app *App) OnShutdown(fn func(ctx context.Context) error)
- func (app *App) Options(path string, handler Handler, handlers ...Handler) Router
- func (app *App) Patch(path string, handler Handler, handlers ...Handler) Router
- func (app *App) Post(path string, handler Handler, handlers ...Handler) Router
- func (app *App) Put(path string, handler Handler, handlers ...Handler) Router
- func (app *App) Route(prefix string, fn func(Router)) Router
- func (app *App) ServeHTTP(w qilat.ResponseWriter, r *qilat.Request)
- func (app *App) Shutdown(ctx context.Context) error
- func (app *App) ShutdownWithTimeout(d time.Duration) error
- func (app *App) Test(req *http.Request) (*http.Response, error)
- func (app *App) Trace(path string, handler Handler, handlers ...Handler) Router
- func (app *App) Use(args ...any) Router
- type Bind
- type Config
- type Cookie
- type Ctx
- func (c *Ctx) Append(field string, values ...string)
- func (c *Ctx) Attachment(filename ...string)
- func (c *Ctx) Bind() *Bind
- func (c *Ctx) Body() ([]byte, error)
- func (c *Ctx) BodyReader() io.Reader
- func (c *Ctx) ClearCookie(names ...string)
- func (c *Ctx) Committed() bool
- func (c *Ctx) Context() context.Context
- func (c *Ctx) Cookie(ck *Cookie)
- func (c *Ctx) Cookies(key string, def ...string) string
- func (c *Ctx) Download(file string, filename ...string) error
- func (c *Ctx) Flush() error
- func (c *Ctx) FormFile(key string) (*multipart.FileHeader, error)
- func (c *Ctx) FormValue(key string, def ...string) string
- func (c *Ctx) Get(key string, def ...string) string
- func (c *Ctx) GetRespHeader(key string, def ...string) string
- func (c *Ctx) HandleError(err error)
- func (c *Ctx) Host() string
- func (c *Ctx) Hostname() string
- func (c *Ctx) IP() string
- func (c *Ctx) IPs() []string
- func (c *Ctx) JSON(v any) error
- func (c *Ctx) Locals(key any, value ...any) any
- func (c *Ctx) Method() string
- func (c *Ctx) MultipartForm() (*multipart.Form, error)
- func (c *Ctx) Next() error
- func (c *Ctx) OriginalURL() string
- func (c *Ctx) Params(key string, def ...string) string
- func (c *Ctx) ParamsInt(key string) (int, error)
- func (c *Ctx) Path() string
- func (c *Ctx) PeekHeader(key string) []byte
- func (c *Ctx) PeekParam(key string) []byte
- func (c *Ctx) PeekQuery(key string) []byte
- func (c *Ctx) Protocol() string
- func (c *Ctx) Queries() map[string]string
- func (c *Ctx) Query(key string, def ...string) string
- func (c *Ctx) QueryBool(key string, def ...bool) bool
- func (c *Ctx) QueryInt(key string, def ...int) int
- func (c *Ctx) Redirect(location string, code ...int) error
- func (c *Ctx) Request() *qilat.Request
- func (c *Ctx) ResponseBody() []byte
- func (c *Ctx) ResponseHeader() *qilat.Header
- func (c *Ctx) ResponseSize() int64
- func (c *Ctx) Route() Route
- func (c *Ctx) Secure() bool
- func (c *Ctx) Send(body []byte) error
- func (c *Ctx) SendFile(file string) error
- func (c *Ctx) SendStatus(code int) error
- func (c *Ctx) SendStream(r io.Reader, size ...int) error
- func (c *Ctx) SendString(s string) error
- func (c *Ctx) Set(key, val string)
- func (c *Ctx) Status(code int) *Ctx
- func (c *Ctx) StatusCode() int
- func (c *Ctx) Trailer() *qilat.Header
- func (c *Ctx) Type(ext string, charset ...string) *Ctx
- func (c *Ctx) Vary(fields ...string)
- func (c *Ctx) Writer() io.Writer
- func (c *Ctx) XML(v any) error
- type Error
- type ErrorHandler
- type Group
- func (g *Group) Add(methods []string, path string, handler Handler, handlers ...Handler) Router
- func (g *Group) All(path string, handler Handler, handlers ...Handler) Router
- func (g *Group) Connect(path string, handler Handler, handlers ...Handler) Router
- func (g *Group) Delete(path string, handler Handler, handlers ...Handler) Router
- func (g *Group) Get(path string, handler Handler, handlers ...Handler) Router
- func (g *Group) Group(prefix string, handlers ...Handler) Router
- func (g *Group) Head(path string, handler Handler, handlers ...Handler) Router
- func (g *Group) Options(path string, handler Handler, handlers ...Handler) Router
- func (g *Group) Patch(path string, handler Handler, handlers ...Handler) Router
- func (g *Group) Post(path string, handler Handler, handlers ...Handler) Router
- func (g *Group) Put(path string, handler Handler, handlers ...Handler) Router
- func (g *Group) Route(prefix string, fn func(Router)) Router
- func (g *Group) Trace(path string, handler Handler, handlers ...Handler) Router
- func (g *Group) Use(args ...any) Router
- type Handler
- type Incrementer
- type Route
- type Router
- type Storage
Constants ¶
const ( CookieSameSiteLax = "Lax" CookieSameSiteStrict = "Strict" CookieSameSiteNone = "None" )
SameSite values for Cookie.SameSite.
const DefaultBodyLimit = 4 << 20
DefaultBodyLimit is the request body size c.Body reads when Config.BodyLimit is zero.
Variables ¶
var ( ErrBadRequest = NewError(http.StatusBadRequest) ErrForbidden = NewError(http.StatusForbidden) ErrNotFound = NewError(http.StatusNotFound) ErrMethodNotAllowed = NewError(http.StatusMethodNotAllowed) ErrNotAcceptable = NewError(http.StatusNotAcceptable) ErrRequestTimeout = NewError(http.StatusRequestTimeout) ErrConflict = NewError(http.StatusConflict) ErrRequestEntityTooLarge = NewError(http.StatusRequestEntityTooLarge) ErrUnsupportedMediaType = NewError(http.StatusUnsupportedMediaType) ErrUnprocessableEntity = NewError(http.StatusUnprocessableEntity) ErrTooManyRequests = NewError(http.StatusTooManyRequests) ErrInternalServerError = NewError(http.StatusInternalServerError) ErrNotImplemented = NewError(http.StatusNotImplemented) )
Errors for common client and server failures, sent as is by DefaultErrorHandler.
var ErrCertificateAfterStart = errors.New("qinetic: ListenTLSWithCertificate called while the app is already serving")
ErrCertificateAfterStart is returned by ListenTLSWithCertificate when another Listen call already started the App's server, whose TLS configuration can no longer change. Use Config.TLSConfig for both instead.
var ErrResponseSent = errors.New("qinetic: response already sent by a qilat handler")
ErrResponseSent is returned when writing a body after a qilat handler or middleware, run through FromQilat or FromQilatMiddleware, has finished the response: the bytes would land after a body framed or encoded by that handler, corrupting it, so they are not sent.
Functions ¶
func DefaultErrorHandler ¶
DefaultErrorHandler sends an *Error's code and message. Any other error becomes a 500 with a generic message, so internal details never reach the client; the error itself goes to Config.Logger.
Types ¶
type App ¶
type App struct {
// contains filtered or unexported fields
}
App is a qinetic application. It is a qilat.Handler; routes must be registered before it serves its first request, after which registering panics.
func (*App) Handler ¶
Handler returns app as a qilat.Handler, for a custom qilat.Server or qilat middleware.
func (*App) Listen ¶
Listen serves HTTP/1.1 on the TCP address addr, and cleartext HTTP/2 when Config.H2C is set. It blocks until the server stops; after Shutdown it returns qilat.ErrServerClosed once Shutdown has finished.
The Listen methods may run concurrently on one App, for example Listener for TCP and ListenQUIC for UDP: they share one qilat.Server and one Shutdown.
func (*App) ListenQUIC ¶
func (app *App) ListenQUIC(pc net.PacketConn) error
ListenQUIC serves HTTP/3 on pc with the certificates of Config.TLSConfig. Responses from a ListenerTLS on the same port advertise it with Alt-Svc.
func (*App) ListenTLS ¶
ListenTLS serves HTTPS on addr: HTTP/2 and HTTP/1.1 over TCP and, unless Config.DisableHTTP3 is set, HTTP/3 over UDP on the same port, advertised to TCP clients with Alt-Svc. The certificate files may be empty when Config.TLSConfig holds certificates.
func (*App) ListenTLSWithCertificate ¶
func (app *App) ListenTLSWithCertificate(addr string, cert tls.Certificate) error
ListenTLSWithCertificate is like ListenTLS with a certificate already loaded, such as one from qilat.GenerateDevCert, added to Config.TLSConfig. It must start the App's server: while another Listen call is running it returns ErrCertificateAfterStart.
func (*App) Listener ¶
Listener serves HTTP/1.1, and cleartext HTTP/2 with Config.H2C, on ln. A listener from tls.NewListener offers HTTP/2 only if its config lists "h2" in NextProtos; ListenerTLS does that for you.
func (*App) ListenerTLS ¶
ListenerTLS serves HTTPS, HTTP/2 and HTTP/1.1, on ln with the certificates of Config.TLSConfig. Run ListenQUIC alongside it on a UDP socket to add HTTP/3.
func (*App) OnShutdown ¶
OnShutdown registers fn to run, in registration order, after Shutdown has stopped the server. It receives Shutdown's context.
func (*App) ServeHTTP ¶
func (app *App) ServeHTTP(w qilat.ResponseWriter, r *qilat.Request)
ServeHTTP runs the handler chain for r. A panic propagates to qilat and its Ctx is not reused.
func (*App) Shutdown ¶
Shutdown stops accepting connections, waits for in-flight requests until ctx is done, then runs the OnShutdown hooks. Running Listen calls return qilat.ErrServerClosed once Shutdown has finished, and later ones at once. The hooks run once; the errors of the server and every hook are joined.
func (*App) ShutdownWithTimeout ¶
ShutdownWithTimeout is Shutdown with a context that expires after d.
func (*App) Test ¶
Test serves req in memory and returns the response, without a network or a qilat.Server. Server settings such as its body size limit and DebugPoison therefore do not apply; Config.DebugPoison does. A handler panic propagates to the caller.
type Bind ¶
type Bind struct {
// contains filtered or unexported fields
}
Bind decodes request data into a struct, returned by c.Bind. Malformed input fails with a 400 *Error whose message names at most the offending field; the decoder's own error is kept only for logs.
func (*Bind) Body ¶
Body decodes the body according to its Content-Type: JSON, XML, or a form. Other types fail with ErrUnsupportedMediaType.
func (*Bind) Form ¶
Form decodes an application/x-www-form-urlencoded or multipart/form-data body into the fields of the struct v points to, named by `form` tags or else by field name, matched case-insensitively as in Fiber. Supported field types are string, bool, integers, floats, and slices of them.
type Config ¶
type Config struct {
// ErrorHandler handles errors returned by handlers. If nil, DefaultErrorHandler is used.
ErrorHandler ErrorHandler
// Logger receives errors that are not sent to the client. If nil, slog.Default is used.
Logger *slog.Logger
// CaseSensitive makes "/Users" and "/users" different routes.
CaseSensitive bool
// StrictRouting makes "/users" and "/users/" different routes.
StrictRouting bool
// DebugPoison makes any use of a Ctx after its handler returned panic, instead of reusing it, and sets
// qilat.Server.DebugPoison for the Listen methods. It helps find handlers that keep c in a goroutine;
// it disables pooling.
DebugPoison bool
// BodyLimit is the largest request body, in bytes, that c.Body and form parsing read; larger bodies
// fail with ErrRequestEntityTooLarge. Zero means DefaultBodyLimit and a negative value means no limit.
BodyLimit int64
// ProxyHeader names the header holding the client IP set by a reverse proxy, such as X-Forwarded-For.
// It is used by c.IP only when the connection comes from one of TrustedProxies.
ProxyHeader string
// TrustedProxies lists the IPs or CIDR prefixes of reverse proxies whose ProxyHeader and
// X-Forwarded-Proto are believed. New panics on an invalid entry.
TrustedProxies []string
// JSONEncoder and JSONDecoder replace encoding/json for c.JSON and c.Bind().JSON.
JSONEncoder func(v any) ([]byte, error)
JSONDecoder func(data []byte, v any) error
// ReadTimeout and WriteTimeout bound reading a whole request and writing a response. Zero means no
// limit, as in qilat; slow clients are still cut off by qilat's header and stall timeouts.
ReadTimeout time.Duration
WriteTimeout time.Duration
// IdleTimeout bounds the wait for the next keep-alive request. Zero means qilat.DefaultIdleTimeout.
IdleTimeout time.Duration
// TLSConfig holds the certificates and settings for ListenTLS, ListenerTLS, and ListenQUIC. It is cloned,
// never modified.
TLSConfig *tls.Config
// H2C makes Listen and Listener serve cleartext HTTP/2 to clients with prior knowledge.
H2C bool
// DisableHTTP3 makes ListenTLS serve TCP only.
DisableHTTP3 bool
// Server, if set, adjusts the qilat.Server built by the Listen methods before it starts, for options
// Config does not cover, such as TLSConfig, MaxConcurrentConns, or HTTP2 and HTTP3 settings.
Server func(srv *qilat.Server)
}
Config configures an App. The zero value is ready to use.
type Cookie ¶
type Cookie struct {
Name string
Value string
Path string
Domain string
MaxAge int // seconds; zero omits Max-Age, negative deletes the cookie now
Expires time.Time
Secure bool
HTTPOnly bool
SameSite string // CookieSameSiteLax, CookieSameSiteStrict, CookieSameSiteNone, or "" to omit
Partitioned bool
}
Cookie is a response cookie, serialized with net/http.
type Ctx ¶
type Ctx struct {
// contains filtered or unexported fields
}
Ctx carries one request through its handlers. Like the qilat request it wraps, a Ctx and every []byte returned from it are valid only until the handler chain returns; strings are copies and c.Context() may be kept.
The response body is buffered and written once the chain and any ErrorHandler are done, so an ErrorHandler can still replace it. Headers go straight to the qilat ResponseWriter.
func (*Ctx) Append ¶
Append adds values to the comma-separated response header field, skipping values already listed.
func (*Ctx) Attachment ¶
Attachment sets Content-Disposition to attachment and, given a file name, sets Content-Type from its extension and offers its base name to the client.
func (*Ctx) Body ¶
Body reads the whole request body, once; later calls return the same bytes. It fails with ErrRequestEntityTooLarge past Config.BodyLimit and with a 400 *Error when reading fails. The result is valid only until the handler chain returns.
func (*Ctx) BodyReader ¶
BodyReader returns the request body as a stream, limited like Body. After Body it reads the bytes Body returned. Do not mix it with Body otherwise.
func (*Ctx) ClearCookie ¶
ClearCookie expires the named cookies in the client, or every cookie of the request when no name is given. Cookies set with a Path or Domain are cleared only by a Cookie call with the same Path and Domain.
func (*Ctx) Committed ¶
Committed reports whether the response has been sent, at least in part, so it can no longer be replaced.
func (*Ctx) Context ¶
Context returns the request context. It is canceled when the client disconnects or the request finishes, and unlike the Ctx it may be kept after the handler returns.
func (*Ctx) Cookie ¶
Cookie adds a Set-Cookie header. A cookie net/http considers invalid, such as one whose name or value has characters that could inject attributes, is not sent; the reason goes to Config.Logger.
func (*Ctx) Cookies ¶
Cookies returns the value of the request cookie key, or def[0] (or "") when it is absent or empty.
func (*Ctx) Flush ¶
Flush commits the response and sends what has been written so far to the client.
func (*Ctx) FormFile ¶
func (c *Ctx) FormFile(key string) (*multipart.FileHeader, error)
FormFile returns the first file uploaded in the multipart form field key.
func (*Ctx) FormValue ¶
FormValue returns a copy of the first value of the form field key from an application/x-www-form-urlencoded or multipart/form-data body, or def[0] (or "") when it is absent, empty, or the body cannot be read. The query string is not consulted; use Query for it.
func (*Ctx) Get ¶
Get returns a copy of the request header key, or def[0] (or "") when it is absent or empty.
func (*Ctx) GetRespHeader ¶
GetRespHeader returns a copy of the response header key, or def[0] (or "") when it is absent or empty.
func (*Ctx) HandleError ¶
HandleError runs the App's error handling for err now, as it would after the chain: the body is discarded and Config.ErrorHandler writes the response. Middleware such as a logger use it to see the final status; the handler should then return nil.
func (*Ctx) Host ¶
Host returns the host the client asked for, including any port: the Host header (:authority on HTTP/2 and HTTP/3), or, when the connection comes from one of Config.TrustedProxies, the last X-Forwarded-Host value, which the nearest proxy set. Earlier values could have come from the client.
func (*Ctx) Hostname ¶
Hostname returns Host without its port, and without brackets for an IPv6 address.
func (*Ctx) IP ¶
IP returns the client IP. It is the connection's remote address unless that address is one of Config.TrustedProxies: then it is the rightmost address in Config.ProxyHeader that is not a trusted proxy, so a client cannot spoof it by sending the header itself.
func (*Ctx) IPs ¶
IPs returns the comma-separated entries of the proxy header (Config.ProxyHeader, or X-Forwarded-For), as sent. They come from the client or proxies and must not be trusted.
func (*Ctx) JSON ¶
JSON encodes v with Config.JSONEncoder (encoding/json by default) as the body, with Content-Type application/json.
func (*Ctx) Locals ¶
Locals stores value under key for later handlers of the same request, or returns the stored value when value is omitted.
func (*Ctx) MultipartForm ¶
MultipartForm parses a multipart/form-data body. It is read in memory, bounded by Config.BodyLimit.
func (*Ctx) Next ¶
Next runs the next handler of the current route, or else the first handler of the next route that matches. When no route is left it returns ErrNotFound, or ErrMethodNotAllowed with an Allow header when the path matches routes of other methods.
func (*Ctx) OriginalURL ¶
OriginalURL returns a copy of the request-target as received, with its query.
func (*Ctx) Params ¶
Params returns a decoded copy of the route parameter key, or def[0] (or "") when it is absent or empty. Wildcards are named "*" (or "*1"), "*2", "+", and so on.
func (*Ctx) Path ¶
Path returns a copy of the percent-decoded request path. Routing uses the raw path, where an encoded slash (%2F) does not separate segments; here it is decoded to '/'.
func (*Ctx) PeekHeader ¶
PeekHeader is like Get but returns the value without copying it, or nil when it is absent. The result is valid only until the handler chain returns.
func (*Ctx) PeekParam ¶
PeekParam is like Params but returns the decoded value without copying it, or nil when it is absent. The result is valid only until the handler chain returns.
func (*Ctx) PeekQuery ¶
PeekQuery is like Query but returns the value without copying it, or nil when it is absent. The result is valid only until the handler chain returns.
func (*Ctx) Protocol ¶
Protocol returns the request protocol: "HTTP/1.0", "HTTP/1.1", "HTTP/2.0", or "HTTP/3.0".
func (*Ctx) Queries ¶
Queries returns copies of all query arguments, keeping the first value of repeated keys.
func (*Ctx) Query ¶
Query returns a copy of the first query argument key, or def[0] (or "") when it is absent or empty.
func (*Ctx) QueryBool ¶
QueryBool parses the query argument key with strconv.ParseBool, returning def[0] (or false) when it is absent or invalid.
func (*Ctx) QueryInt ¶
QueryInt parses the query argument key as an int, returning def[0] (or 0) when it is absent or invalid.
func (*Ctx) Redirect ¶
Redirect responds with a redirect to location, 303 See Other unless code is given. A location with control characters, such as CR or LF from an unchecked request value, is refused with an error.
func (*Ctx) Request ¶
Request returns the underlying qilat request, valid until the handler chain returns.
func (*Ctx) ResponseBody ¶
ResponseBody returns the buffered response body, or nil once the response is committed, when it has been sent. It is valid only until the body changes or the handler chain returns.
func (*Ctx) ResponseHeader ¶
ResponseHeader returns the response header, for middleware that inspect or copy it. It is valid only until the handler chain returns.
func (*Ctx) ResponseSize ¶
ResponseSize returns the size of the response body: what is buffered, plus what has already been sent once the response is committed. Bytes compressed by middleware count before compression.
func (*Ctx) Route ¶
Route returns a copy of the route being run, or the zero Route before any route matched. Changing it does not change the route; its Params slice is shared and must not be modified.
func (*Ctx) Secure ¶
Secure reports whether the request came over TLS, directly or, from a trusted proxy, as declared by X-Forwarded-Proto: https.
func (*Ctx) SendFile ¶
SendFile sends the named file with qilat.ServeFile, which handles Range and conditional requests and sets Content-Type. A name with a ".." element, as a decoded parameter like "a%2F..%2Fb" can produce, fails with ErrBadRequest; a missing file or directory with ErrNotFound. On success the response is committed and the file server picks the status, ignoring c.Status.
func (*Ctx) SendStatus ¶
SendStatus sets the status code and, if the body is empty, sends the status text.
func (*Ctx) SendStream ¶
SendStream commits the response and copies r to it, closing r if it is an io.Closer. With size, it is sent as the Content-Length. The body set before is discarded.
func (*Ctx) SendString ¶
SendString replaces the response body with s, with Content-Type text/plain; charset=utf-8 unless one is set.
func (*Ctx) Set ¶
Set sets the response header key to val. qilat replaces CR, LF, and NUL in val, so a value taken from the request cannot inject header fields, and panics on an invalid key.
func (*Ctx) Status ¶
Status sets the response status code. It has no effect once the response is committed.
func (*Ctx) StatusCode ¶
StatusCode returns the response status: the one set so far, or 200.
func (*Ctx) Trailer ¶
Trailer returns the header whose fields are sent as trailers after the body. Using it drops the Content-Length the response would otherwise get, since HTTP/1.1 needs a chunked body for trailers.
func (*Ctx) Type ¶
Type sets Content-Type from a file extension such as "json" or ".html", or from a full media type. A charset, if given, replaces the type's own. Unknown extensions give application/octet-stream.
type Error ¶
Error is an error with an HTTP status code. DefaultErrorHandler sends its Code and Message to the client.
type ErrorHandler ¶
ErrorHandler handles an error returned by a handler. It may write a new response; the body written before the error has already been discarded.
type Group ¶
type Group struct {
// contains filtered or unexported fields
}
Group is a set of routes under a common prefix, created by Router.Group.
func (*Group) Add ¶
Add registers a route for each of methods. A route matches the whole path; its handlers run in order when each calls c.Next.
func (*Group) Group ¶
Group returns a Router for routes under prefix. handlers, if any, run as middleware for that prefix.
type Handler ¶
Handler handles a request. A returned error goes to the App's ErrorHandler.
func FromQilat ¶
FromQilat runs a qilat handler, such as qilat.FileServer, as the response. The handler writes to the client directly, so the response is committed and an ErrorHandler cannot replace it; its status and size are still recorded for c.StatusCode and c.ResponseSize.
func FromQilatMiddleware ¶
FromQilatMiddleware runs qilat middleware, such as qilat.CompressWith, around the rest of the chain. Inside it the Ctx writes to the middleware's writer and reads the request the middleware passes on, which may differ, as with qilat.StripPrefix. Since qilat finishes that writer when its handler returns, the rest of the chain, any ErrorHandler, and the buffered response all complete inside the middleware: the response is then committed, and handlers registered before the adapter see it as sent. When the middleware answers without calling next, the rest of the chain does not run.
type Incrementer ¶
type Incrementer interface {
// Incr adds delta, which may be negative, to the integer at key and returns the new value and when the
// key expires. A missing or expired key starts at zero and gets ttl; an existing key keeps its expiry.
// Get on the key returns the value in decimal.
Incr(ctx context.Context, key string, delta int64, ttl time.Duration) (int64, time.Time, error)
}
Incrementer is implemented by a Storage with atomic counters, such as Redis INCRBY. Middleware use it when available, so counts are exact even across instances sharing the storage.
type Route ¶
type Route struct {
// Method is the request method, or "USE" for middleware.
Method string
// Path is the pattern as registered, including group prefixes.
Path string
// Params are the parameter names in order; wildcards are named "*1", "+1", and so on.
Params []string
}
Route describes a registered route, as returned by c.Route.
type Router ¶
type Router interface {
Use(args ...any) Router
Get(path string, handler Handler, handlers ...Handler) Router
Head(path string, handler Handler, handlers ...Handler) Router
Post(path string, handler Handler, handlers ...Handler) Router
Put(path string, handler Handler, handlers ...Handler) Router
Patch(path string, handler Handler, handlers ...Handler) Router
Delete(path string, handler Handler, handlers ...Handler) Router
Options(path string, handler Handler, handlers ...Handler) Router
Connect(path string, handler Handler, handlers ...Handler) Router
Trace(path string, handler Handler, handlers ...Handler) Router
All(path string, handler Handler, handlers ...Handler) Router
Add(methods []string, path string, handler Handler, handlers ...Handler) Router
Group(prefix string, handlers ...Handler) Router
Route(prefix string, fn func(Router)) Router
}
Router registers routes. *App and *Group implement it.
type Storage ¶
type Storage interface {
// Get returns the value of key, or nil and no error when the key is missing or expired.
Get(ctx context.Context, key string) ([]byte, error)
// Set stores val under key. A ttl of zero or less means the entry does not expire.
Set(ctx context.Context, key string, val []byte, ttl time.Duration) error
// Delete removes key. Deleting a missing key is not an error.
Delete(ctx context.Context, key string) error
// Close releases the storage's resources.
Close() error
}
Storage is a key-value store with expiry, used by middleware such as limiter, csrf, and cache. Implementations must be safe for concurrent use. The default, used when a middleware is given none, keeps entries in the process's memory, so state is not shared between instances; plug in an external store, such as Redis, to share it.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
internal
|
|
|
leaktest
Package leaktest checks that tests leave no goroutines behind, without a dependency outside qilat's.
|
Package leaktest checks that tests leave no goroutines behind, without a dependency outside qilat's. |
|
memory
Package memory is the in-process qinetic.Storage used by middleware when none is configured.
|
Package memory is the in-process qinetic.Storage used by middleware when none is configured. |
|
middleware
|
|
|
cache
Package cache stores responses and serves them again, keeping a separate copy per value of each header the response varies on, so a response for one Origin or language is never served to another.
|
Package cache stores responses and serves them again, keeping a separate copy per value of each header the response varies on, so a response for one Origin or language is never served to another. |
|
compress
Package compress compresses response bodies with qilat.CompressWith.
|
Package compress compresses response bodies with qilat.CompressWith. |
|
cors
Package cors implements Cross-Origin Resource Sharing: it answers preflight requests and adds Access-Control-* headers for allowed origins.
|
Package cors implements Cross-Origin Resource Sharing: it answers preflight requests and adds Access-Control-* headers for allowed origins. |
|
csrf
Package csrf protects state-changing requests from cross-site request forgery with two checks: the request's origin, from Sec-Fetch-Site or Origin, and a token stored server side that the client must send back in both a cookie and a header or form field.
|
Package csrf protects state-changing requests from cross-site request forgery with two checks: the request's origin, from Sec-Fetch-Site or Origin, and a token stored server side that the client must send back in both a cookie and a header or form field. |
|
limiter
Package limiter limits how many requests a client makes per time window.
|
Package limiter limits how many requests a client makes per time window. |
|
logger
Package logger writes one slog record per request.
|
Package logger writes one slog record per request. |
|
recovery
Package recovery turns panics in later handlers into a 500 handled by the App's ErrorHandler.
|
Package recovery turns panics in later handlers into a 500 handled by the App's ErrorHandler. |
|
requestid
Package requestid gives each request an ID, kept from the client when valid, and returns it in a header.
|
Package requestid gives each request an ID, kept from the client when valid, and returns it in a header. |
|
static
Package static serves files from a directory or an fs.FS.
|
Package static serves files from a directory or an fs.FS. |