http

package module
v0.0.0-...-b87209e Latest Latest
Warning

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

Go to latest
Published: Dec 7, 2023 License: Apache-2.0 Imports: 33 Imported by: 4

README

HTTP Server Plugin

An HTTP server provider with HTTP3 support build in (not enabled by default).

Default router used is Chi. You can use another router if you want, but you will need to write a plugin for it to support the router interface used.

Documentation

Overview

Package http provides an HTTP server implementation. It provides an HTTP1, HTTP2, and HTTP3 server, the first two enabled by default.

One server contains multiple entrypoints, with one entrypoint being one address to listen on. Each entrypoint with start its own HTTP2 server, and optionally also an HTTP3 server. Each entrypoint can be customized individually, but default options are provided, and can be tweaked.

The architecture is based on the Traefik server implementation.

Index

Constants

View Source
const (
	// DefaultAddress to use for new HTTP servers.
	// If set to "random", the default, a random address will be selected,
	// preferably on a private interface (XX subet). TODO: implement.
	// TODO(davincible): revisit default address, probably use random addr.
	DefaultAddress = "0.0.0.0:42069"

	// DefaultInsecure will create an HTTP server without TLS, for insecure connections.
	// Note: as a result you can only make insecure HTTP requests, and no HTTP2
	// unless you set WithH2C.
	//
	// WARNING: don't use this in production, unless you really know what you are
	// doing. this will result in unencrypted traffic. Really, it is even advised
	// against using this in testing environments.
	DefaultInsecure = false

	// DefaultAllowH2C allows insecure, unencrypted traffic to HTTP2 servers.
	// Don't use this, see the notes at DefaultInsecure for more details.
	DefaultAllowH2C = false

	// DefaultMaxConcurrentStreams for HTTP2.
	DefaultMaxConcurrentStreams = 512

	// DefaultHTTP2 dicates whether to also allow HTTP/2 and HTTP/3 connections.
	DefaultHTTP2 = true

	// DefaultHTTP3 dicates whether to also start an HTTP/3.0 server.
	DefaultHTTP3 = false

	// DefaultRouter to use as serve mux. There's not really a reason to change this
	// but if you really wanted to, you could.
	DefaultRouter = "chi"

	// DefaultReadTimeout see net/http pkg for more details.
	DefaultReadTimeout = 5 * time.Second

	// DefaultWriteTimeout see net/http pkg for more details.
	DefaultWriteTimeout = 5 * time.Second

	// DefaultIdleTimeout see net/http pkg for more details.
	DefaultIdleTimeout = 5 * time.Second

	// DefaultEnableGzip enables gzip response compression server wide onall responses.
	// Only use this if your messages are sufficiently large. For small messages
	// the compute overhead is not worth the reduction in transport time.
	//
	// Alternatively, you can send a gzip compressed request, and the server
	// will send back a gzip compressed respponse.
	DefaultEnableGzip = false

	// DefaultConfigSection is the section key used in config files used to
	// configure the server options.
	DefaultConfigSection = Plugin

	// DefaultMaxHeaderBytes is the maximum size to parse from a client's
	// HTTP request headers.
	DefaultMaxHeaderBytes = 1024 * 64
)
View Source
const Plugin = "http"

Plugin is the plugin name.

Variables

View Source
var (
	ErrNoRouter            = errors.New("no router plugin name set in config")
	ErrRouterNotFound      = errors.New("router plugin not found, did you register it?")
	ErrEmptyCodecWhitelist = errors.New("codec whitelist is empty")
	ErrNoMatchingCodecs    = errors.New("no matching codecs found, did you register the codec plugins?")
)

Errors.

View Source
var (
	// ErrContentTypeNotSupported is returned when there is no matching codec.
	ErrContentTypeNotSupported = errors.New("content type not supported")
	ErrInvalidConfigType       = errors.New("http server: invalid config type provided, not of type http.Config")
)

Errors.

View Source
var (
	ErrRouterHandlerInterface = errors.New("router does not implement http.Handler interface")
	ErrNoTLS                  = errors.New("no TLS config provided")
)

Errors.

View Source
var (
	ErrNoTLSConfig = errors.New("no tls config")
)

Errors returned by the HTTP3 server.

View Source
var (
	ErrNotHTTPServer = errors.New("server provider is not of type *http.Server")
)

Errors.

Functions

func DefaultCodecWhitelist

func DefaultCodecWhitelist() []string

DefaultCodecWhitelist is the default allowed list of codecs to be used for HTTP request encoding/decoding. This means that if any of these plugins are registered, they will be included in the server's available codecs. If they are not registered, the server will not be able to handle these formats.

func NewGRPCHandler

func NewGRPCHandler[Tin any, Tout any](srv *ServerHTTP, f func(context.Context, *Tin) (*Tout, error)) http.HandlerFunc

NewGRPCHandler will wrap a gRPC function with a HTTP handler.

func WithDefaults

func WithDefaults(options ...Option) server.Option

WithDefaults sets default options to use on the creation of new HTTP entrypoints.

func WithEntrypoint

func WithEntrypoint(options ...Option) server.Option

WithEntrypoint adds an HTTP entrypoint with the provided options.

func WriteError

func WriteError(w http.ResponseWriter, err error)

WriteError returns an error response to the HTTP request.

Types

type Config

type Config struct {
	// Name is the entrypoint name.
	//
	// The default name is 'http-<random uuid>'
	Name string `json:"name" yaml:"name"`

	// Address to listen on.
	// TODO(davincible): implement this, and the address method.
	// If no IP is provided, an interface will be selected automatically. Private
	// interfaces are preferred, if none are found a public interface will be used.
	//
	// If no port is provided, a random port will be selected. To listen on a
	// specific interface, but with a random port, you can use '<IP>:0'.
	Address string `json:"address" yaml:"address"`

	// Insecure will create an HTTP server without TLS, for insecure connections.
	// Note: as a result you can only make insecure HTTP1 requests, no HTTP2
	// unless you set WithH2C.
	//
	// WARNING: don't use this in production, unless you really know what you are
	// doing. this will result in unencrypted traffic. Really, it is even advised
	// against using this in testing environments.
	Insecure bool `json:"insecure" yaml:"insecure"`

	// TLS config, if none is provided a self-signed certificates will be generated.
	//
	// You can load a tls config from yaml/json with the following options:
	//
	// “`yaml
	// rootCAFiles:
	//    - xxx
	// clientCAFiles:
	//    - xxx
	// clientAuth: "none" | "request" | "require" |  "verify" | "require+verify"
	// certificates:
	//   - certFile: xxx
	//     keyFile: xxx
	// “`
	TLS *mtls.Config `json:"tls,omitempty" yaml:"tls,omitempty"`

	// H2C allows h2c connections; HTTP2 without TLS.
	H2C bool `json:"h2c" yaml:"h2c"`

	// HTTP2 dicates whether to also allow HTTP/2 connections. Defaults to true.
	HTTP2 bool `json:"http2" yaml:"http2"`

	// HTTP3 dicates whether to also start an HTTP/3.0 server. Defaults to false.
	HTTP3 bool `json:"http3" yaml:"http3"`

	// Gzip enables gzip response compression server wide onall responses.
	// Only use this if your messages are sufficiently large. For small messages
	// the compute overhead is not worth the reduction in transport time.
	//
	// Alternatively, you can send a gzip compressed request, and the server
	// will send back a gzip compressed respponse.
	Gzip bool `json:"gzip" yaml:"gzip"`

	// MaxConcurrentStreams for HTTP2.
	MaxConcurrentStreams int `json:"maxConcurrentStreams" yaml:"maxConcurrentStreams"`

	// MaxHeaderBytes is the maximum size to parse from a client's
	// HTTP request headers.
	MaxHeaderBytes int `json:"maxHeaderBytes" yaml:"maxHeaderBytes"`

	// CodecWhitelist is the list of codec names that are allowed to be used
	// with the HTTP server. This means that if registered, codecs in this list
	// will be added to the server, allowing you to make RPC requests in that format.
	// If any of the codecs in this list are not registred nothing will happen.
	//
	// We explicitly whitelist codecs, as we don't
	// want to add every codec plugin that has been registered to be automaically
	// added to the server.
	CodecWhitelist []string `json:"codecWhitelist" yaml:"codecWhitelist"`

	// Router is the router plugin to use. Default is chi.
	Router string `json:"router" yaml:"router"`

	// ReadTimeout is the maximum duration for reading the entire
	// request, including the body. A zero or negative value means
	// there will be no timeout.
	ReadTimeout time.Duration `json:"readTimeout" yaml:"readTimeout"`

	// WriteTimeout is the maximum duration before timing out
	// writes of the response. It is reset whenever a new
	// request's header is read. Like ReadTimeout, it does not
	// let Handlers make decisions on a per-request basis.
	// A zero or negative value means there will be no timeout.
	WriteTimeout time.Duration `json:"writeTimeout" yaml:"writeTimeout"`

	// IdleTimeout is the maximum amount of time to wait for the
	// next request when keep-alives are enabled. If IdleTimeout
	// is zero, the value of ReadTimeout is used. If both are
	// zero, there is no timeout.
	IdleTimeout time.Duration `json:"idleTimeout" yaml:"idleTimeout"`

	// HandlerRegistrations are all handler registration functions that will be
	// registered to the server upon startup.
	//
	// You can statically add handlers by using the fuctional server options.
	// Optionally, you can dynamically add handlers by registering them to the
	// Handlers global, and setting them explicitly in the config.
	HandlerRegistrations server.HandlerRegistrations `json:"handlers" yaml:"handlers"`

	// Middleware is a list of middleware to use.
	Middleware router.Middlewares `json:"middleware" yaml:"middleware"`

	// Logger allows you to dynamically change the log level and plugin for a
	// specific entrypoint.
	Logger struct {
		Level  slog.Level `json:"level,omitempty" yaml:"level,omitempty"` // TODO(davincible): change with custom level
		Plugin string     `json:"plugin,omitempty" yaml:"plugin,omitempty"`
	} `json:"logger" yaml:"logger"`
}

Config provides options to the entrypoint.

func NewConfig

func NewConfig(options ...Option) *Config

NewConfig will create a new default config for the entrypoint.

func (*Config) ApplyOptions

func (c *Config) ApplyOptions(options ...Option)

ApplyOptions applies a set of options to the config.

func (Config) Copy

func (c Config) Copy() server.EntrypointConfig

Copy creates a copy of the entrypoint config.

func (Config) GetAddress

func (c Config) GetAddress() string

GetAddress returns the entrypoint address.

func (*Config) NewCodecMap

func (c *Config) NewCodecMap() (codecs.Map, error)

NewCodecMap fetches the whitelisted codec plugins from the registered codecs if present.

func (*Config) NewRouter

func (c *Config) NewRouter() (router.Router, error)

NewRouter uses the config.Router to craete a new router. It fetches the factory from the registered router plugins.

type Option

type Option func(*Config)

Option is a functional option to provide custom values to the config.

func WithAddress

func WithAddress(address string) Option

WithAddress specifies the address to listen on. If you want to listen on all interfaces use the format ":8080" If you want to listen on a specific interface/address use the full IP.

func WithAllowH2C

func WithAllowH2C() Option

WithAllowH2C will allow H2C connections on the entrypoint. H2C is HTTP2 without TLS. It is not recommended to turn this on.

func WithCodecWhitelist

func WithCodecWhitelist(list []string) Option

WithCodecWhitelist sets the list of codecs allowed in the HTTP entrypoint. If registered, any codecs set here will be imported into the server. You still need to register the codec plugins by importing them.

func WithConfig

func WithConfig(config Config) Option

WithConfig will set replace the server config with config provided as argument. Warning: any options applied previous to this option will be overwritten by the contents of the config provided here.

func WithDisableHTTP2

func WithDisableHTTP2() Option

WithDisableHTTP2 will prevent the creation of an HTTP2 server on the entrypoint.

func WithGzip

func WithGzip() Option

WithGzip enables gzip response compression server wide onall responses. Only use this if your messages are sufficiently large. For small messages the compute overhead is not worth the reduction in transport time.

Alternatively, you can send a gzip compressed request, and the server will send back a gzip compressed respponse.

func WithHTTP3

func WithHTTP3() Option

WithHTTP3 will additionally enable an HTTP3 server on the entrypoint.

func WithIdleTimeout

func WithIdleTimeout(timeout time.Duration) Option

WithIdleTimeout is the maximum amount of time to wait for the next request when keep-alives are enabled. If IdleTimeout is zero, the value of ReadTimeout is used. If both are zero, there is no timeout.

func WithInsecure

func WithInsecure() Option

WithInsecure will create the entrypoint without using TLS. Note: as a result you can only make insecure HTTP requests, and no HTTP2 unless you set WithH2C.

WARNING: don't use this in production, unless you really know what you are doing. this will result in unencrypted traffic. Really, it is even advised against using this in testing environments.

func WithLogLevel

func WithLogLevel(level slog.Level) Option

WithLogLevel changes the log level from the inherited logger.

func WithLogPlugin

func WithLogPlugin(plugin string) Option

WithLogPlugin changes the log level from the inherited logger.

func WithMaxConcurrentStreams

func WithMaxConcurrentStreams(value int) Option

WithMaxConcurrentStreams sets the concurrent streams limit for HTTP2.

func WithMiddleware

func WithMiddleware(name string, middleware func(http.Handler) http.Handler) Option

WithMiddleware appends middlewares to the server. You can use any standard Go HTTP middleware.

Each middlware is uniquely identified with a name. The name provided here can be used to dynamically add middlware to an entrypoint in a config.

func WithName

func WithName(name string) Option

WithName sets the entrypoint name. The default name is in the format of 'http-<uuid>'.

Setting a custom name allows you to dynamically reference the entrypoint in the file config, and makes it easier to attribute the logs.

func WithReadTimeout

func WithReadTimeout(timeout time.Duration) Option

WithReadTimeout sets the maximum duration for reading the entire request, including the body. A zero or negative value means there will be no timeout.

func WithRegistration

func WithRegistration(name string, registration server.RegistrationFunc) Option

WithRegistration adds a named registration function to the config. The name set here allows you to dynamically add this handler to entrypoints through a config.

Registration functions are used to register handlers to a server.

func WithRouter

func WithRouter(router string) Option

WithRouter sets the router plguin name.

func WithTLS

func WithTLS(tlsConfig *tls.Config) Option

WithTLS sets a tls config.

func WithWriteTimeout

func WithWriteTimeout(timeout time.Duration) Option

WithWriteTimeout sets the maximum duration before timing out writes of the response. It is reset whenever a new request's header is read. Like ReadTimeout, it does not let Handlers make decisions on a per-request basis. A zero or negative value means there will be no timeout.

type ServerHTTP

type ServerHTTP struct {
	Config   Config
	Logger   log.Logger
	Registry registry.Type
	// contains filtered or unexported fields
}

ServerHTTP represents a listener on one address. You can create multiple entrypoints for multiple addresses and ports. This is e.g. useful if you want to listen on multiple interfaces, or multiple ports in parallel, even with the same handler.

func ProvideServerHTTP

func ProvideServerHTTP(
	_ types.ServiceName,
	logger log.Logger,
	reg registry.Type,
	cfg Config,
	options ...Option,
) (*ServerHTTP, error)

ProvideServerHTTP creates a new entrypoint for a single address. You can create multiple entrypoints for multiple addresses and ports. One entrypoint can serve a HTTP1, HTTP2 and HTTP3 server. If you enable HTTP3 it will listen on both TCP and UDP on the same port.

func (*ServerHTTP) Address

func (s *ServerHTTP) Address() string

Address returns the address the entrypoint is listening on.

func (*ServerHTTP) EntrypointID

func (s *ServerHTTP) EntrypointID() string

EntrypointID returns the id (uuid) of this entrypoint in the registry.

func (*ServerHTTP) Name

func (s *ServerHTTP) Name() string

Name returns the entrypoint name.

func (*ServerHTTP) Register

func (s *ServerHTTP) Register(register server.RegistrationFunc)

Register executes a registration function on the entrypoint.

func (*ServerHTTP) Router

func (s *ServerHTTP) Router() router.Router

Router returns the router used by the HTTP server. You can use this to register extra handlers, or mount additional routers.

func (*ServerHTTP) ServeHTTP

func (s *ServerHTTP) ServeHTTP(resp http.ResponseWriter, req *http.Request)

func (*ServerHTTP) Start

func (s *ServerHTTP) Start() error

Start will create the listeners and start the server on the entrypoint.

func (*ServerHTTP) Stop

func (s *ServerHTTP) Stop(ctx context.Context) error

Stop will stop the HTTP server(s).

func (*ServerHTTP) String

func (s *ServerHTTP) String() string

String returns the entrypoint type; http.

func (*ServerHTTP) Transport

func (s *ServerHTTP) Transport() string

Transport returns the client transport to use.

func (*ServerHTTP) Type

func (s *ServerHTTP) Type() string

Type returns the component type.

Directories

Path Synopsis
cmd
Package headers contains common headers
Package headers contains common headers
Package router provides an interface for the HTTP router (serve mux).
Package router provides an interface for the HTTP router (serve mux).
chi
Package chi provides a Chi implementation of the router interface.
Package chi provides a Chi implementation of the router interface.
tests
handler
Package handler provdes a test handler.
Package handler provdes a test handler.
proto
Package proto ...
Package proto ...
util/http
Package http provides testing utilities.
Package http provides testing utilities.
utils
header
Package header implements header manipulation utilities
Package header implements header manipulation utilities
ip
Package ip provides validation and parsing utilities.
Package ip provides validation and parsing utilities.
tcp
Package tcp offers tcp utilities.
Package tcp offers tcp utilities.
tls
Package tls provides a function to create a self signed certificate.
Package tls provides a function to create a self signed certificate.
udp
Package udp offers UDP utilities.
Package udp offers UDP utilities.

Jump to

Keyboard shortcuts

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