serverhttp

package
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: Aug 26, 2026 License: MIT Imports: 9 Imported by: 0

Documentation

Overview

Package serverhttp provides an owned standard-library HTTP server runtime.

Index

Examples

Constants

This section is empty.

Variables

View Source
var ErrInvalidConfig = errors.New("invalid HTTP server configuration")

ErrInvalidConfig identifies invalid HTTP runtime configuration.

View Source
var ErrInvalidState = errors.New("invalid HTTP server state")

ErrInvalidState identifies an HTTP runtime operation rejected by its state.

Functions

func Chain

func Chain(handler http.Handler, middleware ...Middleware) (http.Handler, error)

Chain composes middleware around handler in listed order.

Example
package main

import (
	"fmt"
	"net/http"
	"net/http/httptest"

	"github.com/faustbrian/go-correlation"
	httpcorrelation "github.com/faustbrian/go-correlation/http"
	"github.com/faustbrian/go-service/serverhttp"
)

func main() {
	factory, err := correlation.NewFactory(correlation.FactoryOptions{})
	if err != nil {
		panic(err)
	}
	identity, err := httpcorrelation.New(factory, httpcorrelation.Options{})
	if err != nil {
		panic(err)
	}
	handler, err := serverhttp.Chain(
		http.HandlerFunc(func(_ http.ResponseWriter, request *http.Request) {
			values, _ := correlation.FromContext(request.Context())
			fmt.Println(values.RequestID != "")
		}),
		serverhttp.Recover(),
		identity.Wrap,
	)
	if err != nil {
		panic(err)
	}

	handler.ServeHTTP(
		httptest.NewRecorder(),
		httptest.NewRequest(http.MethodGet, "/", nil),
	)
}
Output:
true
Example (AuthenticationAndAuthorization)
package main

import (
	"context"
	"fmt"
	"net/http"
	"net/http/httptest"

	"github.com/faustbrian/go-service/serverhttp"
)

type principalKey struct{}

func main() {
	authentication := serverhttp.Middleware(func(next http.Handler) http.Handler {
		return http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
			fmt.Println("authenticate")
			if request.Header.Get("Authorization") != "Bearer example" {
				http.Error(writer, "unauthorized", http.StatusUnauthorized)

				return
			}
			ctx := context.WithValue(request.Context(), principalKey{}, "user-1")
			next.ServeHTTP(writer, request.WithContext(ctx))
		})
	})
	authorization := serverhttp.Middleware(func(next http.Handler) http.Handler {
		return http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
			fmt.Println("authorize")
			if request.Context().Value(principalKey{}) == nil {
				http.Error(writer, "forbidden", http.StatusForbidden)

				return
			}
			next.ServeHTTP(writer, request)
		})
	})
	handler, err := serverhttp.Chain(
		http.HandlerFunc(func(writer http.ResponseWriter, _ *http.Request) {
			writer.WriteHeader(http.StatusNoContent)
		}),
		authentication,
		authorization,
	)
	if err != nil {
		panic(err)
	}
	request := httptest.NewRequest(http.MethodGet, "/", nil)
	request.Header.Set("Authorization", "Bearer example")
	recorder := httptest.NewRecorder()
	handler.ServeHTTP(recorder, request)
	fmt.Println(recorder.Code)
}
Output:
authenticate
authorize
204

Types

type ConfigError

type ConfigError struct {
	// Field identifies the rejected configuration path.
	Field string
	// Reason describes why Field was rejected.
	Reason string
}

ConfigError identifies one invalid HTTP runtime field.

func (*ConfigError) Error

func (err *ConfigError) Error() string

Error implements error.

func (*ConfigError) Unwrap

func (err *ConfigError) Unwrap() error

Unwrap makes ConfigError inspectable with errors.Is.

type Middleware

type Middleware func(http.Handler) http.Handler

Middleware wraps an http.Handler. In Chain, the first middleware is the outermost and observes the request first and response last.

func LimitBody

func LimitBody(limit int64) (Middleware, error)

LimitBody rejects a known oversized request before the handler and limits streaming or chunked bodies before their first read. Zero disables it.

func Recover

func Recover() Middleware

Recover contains handler panics. If no response was committed, it removes prepared headers and sends a generic HTTP 500 response.

type Option

type Option func(*config) error

Option configures a Server. A nil Option is invalid.

func WithBaseContext

func WithBaseContext(base func(net.Listener) context.Context) Option

WithBaseContext sets the base context for accepted connections. The callback must return a non-nil context.

func WithBodyLimit

func WithBodyLimit(limit int64) Option

WithBodyLimit configures the maximum request body size. Zero disables the limit.

func WithConnContext

func WithConnContext(connection func(context.Context, net.Conn) context.Context) Option

WithConnContext derives a context for each accepted connection. The callback must return a non-nil context.

func WithCorrelation

func WithCorrelation(
	factory *correlation.Factory,
	options httpcorrelation.Options,
) Option

WithCorrelation installs correlation-owned HTTP identity immediately after panic recovery and before ingress middleware or body limits.

func WithIdleTimeout

func WithIdleTimeout(timeout time.Duration) Option

WithIdleTimeout configures the keep-alive idle timeout. Zero disables it.

func WithIngressMiddleware

func WithIngressMiddleware(middleware ...Middleware) Option

WithIngressMiddleware appends middleware after request identity and before request body limits.

func WithMaxHeaderBytes

func WithMaxHeaderBytes(limit int) Option

WithMaxHeaderBytes configures the maximum request-header size.

func WithMiddleware

func WithMiddleware(middleware ...Middleware) Option

WithMiddleware appends user middleware in visible listed order.

func WithReadHeaderTimeout

func WithReadHeaderTimeout(timeout time.Duration) Option

WithReadHeaderTimeout configures the request-header read timeout. Zero disables it.

func WithReadTimeout

func WithReadTimeout(timeout time.Duration) Option

WithReadTimeout configures the full request read timeout. Zero disables it.

func WithShutdownTimeout

func WithShutdownTimeout(timeout time.Duration) Option

WithShutdownTimeout configures the graceful-shutdown bound. Zero is invalid because Run always owns a finite shutdown bound.

func WithWriteTimeout

func WithWriteTimeout(timeout time.Duration) Option

WithWriteTimeout configures the response write timeout. Zero disables it.

type RunError

type RunError struct {
	// Failures contains graceful-shutdown and forced-close failures.
	Failures []error
}

RunError aggregates failures observed while stopping an HTTP server.

func (*RunError) Error

func (err *RunError) Error() string

Error implements error.

func (*RunError) Unwrap

func (err *RunError) Unwrap() []error

Unwrap exposes every runtime failure.

type ServeError

type ServeError struct {
	// Err is the unexpected listener or serving failure.
	Err error
}

ServeError reports an unexpected listener or serving failure.

func (*ServeError) Error

func (err *ServeError) Error() string

Error implements error.

func (*ServeError) Unwrap

func (err *ServeError) Unwrap() error

Unwrap returns the serving failure.

type Server

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

Server owns one listener and its standard-library HTTP server.

func New

func New(
	listener net.Listener,
	handler http.Handler,
	options ...Option,
) (*Server, error)

New constructs a server without accepting connections or starting goroutines. Ownership of listener transfers to Server after success.

func (*Server) Close

func (server *Server) Close() error

Close releases the owned listener before Run or force-closes an active server. Concurrent and repeated calls return the same result. A closed server cannot be run.

func (*Server) HTTPServer

func (server *Server) HTTPServer() *http.Server

HTTPServer returns the configured server. Callers must not mutate it after Run begins.

func (*Server) Run

func (server *Server) Run(ctx context.Context) error

Run serves until ctx is canceled or serving fails. It owns and joins the Serve goroutine before returning and may be called only once.

type StateError

type StateError struct {
	// Operation is the rejected runtime operation.
	Operation string
	// State describes the runtime state in which Operation was rejected.
	State string
}

StateError reports an invalid HTTP runtime operation.

func (*StateError) Error

func (err *StateError) Error() string

Error implements error.

func (*StateError) Unwrap

func (err *StateError) Unwrap() error

Unwrap makes StateError inspectable with errors.Is.

Jump to

Keyboard shortcuts

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