bhttp

package module
v0.3.0 Latest Latest
Warning

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

Go to latest
Published: Jan 26, 2025 License: MIT Imports: 11 Imported by: 3

README

bhttpv2

Predecessor of bhttp, ideas features

  • The middleware will have different signature as "leaf" http handlers
  • "leaf" http handlers take a custom (typed) context, a bhttp.ResponseWriter, a http.request and return an error
  • the custom "leaf" handler context is constructed from the regular context.Context just before the leaf handler is called, share this logic and error handling
  • middleware only take the bhttp.ResponseWriter, a http.request (that carries the regular context.Context) and can handle the error
  • named routes and route reversing

Documentation

Overview

Package bhttp provides buffered HTTP response handling.

Index

Constants

This section is empty.

Variables

View Source
var ErrBufferFull = errors.New("buffer is full")

ErrBufferFull is returned when the write call will cause the buffer to be filled beyond its limit.

Functions

func ToStd added in v0.3.0

func ToStd(h BareHandler, bufLimit int, logs Logger) http.Handler

ToStd converts a bare handler into a standard library http.Handler. The implementation creates a buffered response writer and flushes it implicitly after serving the request.

Types

type BareHandler added in v0.3.0

type BareHandler interface {
	ServeBareBHTTP(w ResponseWriter, r *http.Request) error
}

BareHandler describes how middleware servers HTTP requests. In this library the signature for handling middleware BareHandler is different from the signature of "leaf" handlers: Handler.

func ToBare added in v0.3.0

func ToBare[C Context](h Handler[C], contextInit ContextInitFunc[C]) BareHandler

ToBare converts a typed context handler 'h' into a bare buffered handler.

func Wrap added in v0.3.0

func Wrap[C Context](h Handler[C], contextInit ContextInitFunc[C], m ...Middleware) BareHandler

Wrap takes the inner handler h and wraps it with middleware. The order is that of the Gorilla and Chi router. That is: the middleware provided first is called first and is the "outer" most wrapping, the middleware provided last will be the "inner most" wrapping (closest to the handler).

type BareHandlerFunc added in v0.3.0

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

BareHandlerFunc allow casting a function to an implementation of Handler.

func (BareHandlerFunc) ServeBareBHTTP added in v0.3.0

func (f BareHandlerFunc) ServeBareBHTTP(w ResponseWriter, r *http.Request) error

ServeBareBHTTP implements the Handler interface.

type Context

type Context interface{ context.Context }

Context constraint for "leaf" nodes.

type ContextInitFunc added in v0.2.0

type ContextInitFunc[C Context] func(*http.Request) (C, error)

ContextInitFunc describe functions that turn requests into a typed context for our "leaf" handlers.

type Handler

type Handler[C Context] interface {
	ServeBHTTP(ctx C, w ResponseWriter, r *http.Request) error
}

Handler mirrors http.Handler but it supports typed context values and a buffered response allow returning error.

type HandlerFunc

type HandlerFunc[C Context] func(C, ResponseWriter, *http.Request) error

HandlerFunc allow casting a function to imple Handler.

func (HandlerFunc[C]) ServeBHTTP

func (f HandlerFunc[C]) ServeBHTTP(ctx C, w ResponseWriter, r *http.Request) error

ServeBHTTP implements the Handler interface.

type Logger

type Logger interface {
	LogUnhandledServeError(err error)
	LogImplicitFlushError(err error)
}

Logger can be implemented to get informed about important states.

func NewStdLogger added in v0.3.0

func NewStdLogger(l *log.Logger) Logger

type Middleware

type Middleware func(BareHandler) BareHandler

Middleware for cross-cutting concerns with buffered responses.

type ResponseBuffer

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

ResponseBuffer is a http.ResponseWriter implementation that buffers writes up to configurable amount of bytes. This allows the implementation of handlers that can error halfway and return a completely different response instead of what was written before the error occurred.

func (*ResponseBuffer) FlushBuffer added in v0.3.0

func (w *ResponseBuffer) FlushBuffer() error

FlushBuffer flushes data to the underlying writer without calling .Flush on it by proxy. This is provided separately from FlushError to allow for emulating the original ResponseWriter behaviour more correctly.

func (*ResponseBuffer) FlushError

func (w *ResponseBuffer) FlushError() error

FlushError any buffered bytes to the underlying response writer and resets the buffer. After flush has been called the response data should be considered sent and in-transport to the client.

func (*ResponseBuffer) Free

func (w *ResponseBuffer) Free()

Free resets all members of the ResponseBuffer and puts it back in the sync pool to allow it to be re-used for a possible next initilization. It should be called after the handling has completed and the buffer should not be used after.

func (*ResponseBuffer) Header

func (w *ResponseBuffer) Header() http.Header

Header allows users to modify the headers (and trailers) sent to the client. The headers are not actually flushed to the underlying writer until a write or flush is being triggered.

func (*ResponseBuffer) Reset

func (w *ResponseBuffer) Reset()

Reset provides the differentiating feature from a regular ResponseWriter: it allows changing the response completely even if some data has been written already. This behaviour cannot be guaranteed if flush has been called explicitly so in that case it will panic.

func (*ResponseBuffer) Unwrap

func (w *ResponseBuffer) Unwrap() http.ResponseWriter

Unwrap returns the underlying response writer. This is expected by the http.ResponseController to allow it to call appropriate optional interface implementations.

func (*ResponseBuffer) Write

func (w *ResponseBuffer) Write(buf []byte) (int, error)

Write appends the contents of p to the buffered response, growing the internal buffer as needed. If the write will cause the buffer be larger then the configure limit it will return ErrBufferFull.

func (*ResponseBuffer) WriteHeader

func (w *ResponseBuffer) WriteHeader(statusCode int)

WriteHeader will cause headers to be flushed to the underlying writer while calling WriteHeader on the underlying writer with the given status code.

type ResponseWriter

type ResponseWriter interface {
	http.ResponseWriter
	Reset()
	Free()
	FlushBuffer() error
}

ResponseWriter implements the http.ResponseWriter but the underlying bytes are buffered. This allows middleware to reset the writer and formulate a completely new response.

func NewResponseWriter added in v0.3.0

func NewResponseWriter(resp http.ResponseWriter, limit int) ResponseWriter

NewResponseWriter inits a buffered response writer. It has a configurable limit after which the writing will return an error. This is to protect unchecked handlers from claiming too much memory. Limit can be set to -1 to disable this check.

type Reverser

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

Reverser keeps track of named patterns and allows building URLS.

func NewReverser

func NewReverser() *Reverser

NewReverser inits the reverser.

func (Reverser) Named

func (r Reverser) Named(name, str string) string

Named is a convenience method that panics if naming the pattern fails.

func (Reverser) NamedPattern

func (r Reverser) NamedPattern(name, str string) (string, error)

NamedPattern will parse 's' as a path pattern while returning it as well.

func (Reverser) Reverse

func (r Reverser) Reverse(name string, vals ...string) (string, error)

Reverse reverses the named pattern into a url.

type ServeMux

type ServeMux[C Context] struct {
	// contains filtered or unexported fields
}

func NewCustomServeMux added in v0.3.0

func NewCustomServeMux[C Context](
	contextInit ContextInitFunc[C],
	bufLimit int,
	logger Logger,
	baseMux *http.ServeMux,
	reverser *Reverser,
) *ServeMux[C]

NewCustomServeMux creates a mux that allows full customization of the context type and how it is initialized for each handler from the request.

func NewServeMux

func NewServeMux() *ServeMux[context.Context]

NewServeMux creates a http.Handler implementation that is akin to the http.ServeMux but allows named routes and buffered responses. It does no use a custom (typed) context, see NewCustomServeMux for that.

func (*ServeMux[C]) Handle

func (m *ServeMux[C]) Handle(pattern string, handler Handler[C], name ...string)

Handle handles the request given a handler.

func (*ServeMux[C]) HandleFunc

func (m *ServeMux[C]) HandleFunc(pattern string, handler HandlerFunc[C], name ...string)

HandleFunc handles the request given the pattern using a function.

func (*ServeMux[C]) Reverse

func (m *ServeMux[C]) Reverse(name string, vals ...string) (string, error)

Reverse returns the url based on the name and parameter values.

func (*ServeMux[C]) ServeHTTP

func (m *ServeMux[C]) ServeHTTP(w http.ResponseWriter, r *http.Request)

ServeHTTP makes the server mux implement the http.Handler interface.

func (*ServeMux[C]) Use

func (m *ServeMux[C]) Use(mw ...Middleware)

Use allows providing of middleware.

type TestLogger added in v0.3.0

type TestLogger struct {
	NumLogUnhandledServeError int64
	NumLogImplicitFlushError  int64
	// contains filtered or unexported fields
}

func NewTestLogger added in v0.3.0

func NewTestLogger(tb testing.TB) *TestLogger

func (*TestLogger) LogImplicitFlushError added in v0.3.0

func (l *TestLogger) LogImplicitFlushError(err error)

func (*TestLogger) LogUnhandledServeError added in v0.3.0

func (l *TestLogger) LogUnhandledServeError(err error)

Directories

Path Synopsis
internal
Package main provides development automation.
Package main provides development automation.

Jump to

Keyboard shortcuts

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