restserver

package
v0.22.0 Latest Latest
Warning

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

Go to latest
Published: Dec 31, 2023 License: MIT Imports: 22 Imported by: 4

Documentation

Index

Examples

Constants

View Source
const (
	// EvtSourceStatus specifies source for service Status
	EvtSourceStatus = "status"
	// EvtServiceStarted specifies Service Started event
	EvtServiceStarted = "service started"
	// EvtServiceStopped specifies Service Stopped event
	EvtServiceStopped = "service stopped"
)
View Source
const MaxRequestSize = 64 * 1024 * 1024

MaxRequestSize specifies max size of regular HTTP Post requests in bytes, 64 Mb

Variables

This section is empty.

Functions

func GetHostName

func GetHostName(bindAddr string) string

GetHostName returns Hostname from HTTP bind address, or OS Hostname, if it's not specified in the config

func GetPort

func GetPort(bindAddr string) string

GetPort returns the port from HTTP bind address, or standard HTTPS 443 port, if it's not specified in the config

func GetServerBaseURL

func GetServerBaseURL(s Server) *url.URL

GetServerBaseURL returns server base URL

func GetServerURL

func GetServerURL(s Server, r *http.Request, relativeEndpoint string) *url.URL

GetServerURL returns complete server URL for given relative end-point

Types

type CORSOptions

type CORSOptions struct {
	// AllowedOrigins is a list of origins a cross-domain request can be executed from.
	// If the special "*" value is present in the list, all origins will be allowed.
	// An origin may contain a wildcard (*) to replace 0 or more characters
	// (i.e.: http://*.domain.com). Usage of wildcards implies a small performance penalty.
	// Only one wildcard can be used per origin.
	// Default value is ["*"]
	AllowedOrigins []string
	// AllowOriginFunc is a custom function to validate the origin. It take the origin
	// as argument and returns true if allowed or false otherwise. If this option is
	// set, the content of AllowedOrigins is ignored.
	AllowOriginFunc func(origin string) bool
	// AllowOriginFunc is a custom function to validate the origin. It takes the HTTP Request object and the origin as
	// argument and returns true if allowed or false otherwise. If this option is set, the content of `AllowedOrigins`
	// and `AllowOriginFunc` is ignored.
	AllowOriginRequestFunc func(r *http.Request, origin string) bool
	// AllowedMethods is a list of methods the client is allowed to use with
	// cross-domain requests. Default value is simple methods (HEAD, GET and POST).
	AllowedMethods []string
	// AllowedHeaders is list of non simple headers the client is allowed to use with
	// cross-domain requests.
	// If the special "*" value is present in the list, all headers will be allowed.
	// Default value is [] but "Origin" is always appended to the list.
	AllowedHeaders []string
	// ExposedHeaders indicates which headers are safe to expose to the API of a CORS
	// API specification
	ExposedHeaders []string
	// MaxAge indicates how long (in seconds) the results of a preflight request
	// can be cached
	MaxAge int
	// AllowCredentials indicates whether the request can include user credentials like
	// cookies, HTTP authentication or client side SSL certificates.
	AllowCredentials bool
	// OptionsPassthrough instructs preflight to let other potential next handlers to
	// process the OPTIONS method. Turn this on if your application handles OPTIONS.
	OptionsPassthrough bool
	// Debugging flag adds additional output to debug server side CORS issues
	Debug bool
}

CORSOptions is a configuration container to setup the CORS middleware.

type Config

type Config interface {
	// GetServerName provides name of the server: WebAPI|Admin etc
	GetServerName() string
	// GetBindAddr provides the address that the HTTPS server should be listening on
	GetBindAddr() string
	// GetPublicURL is the FQ name of the VIP to the cluster that clients use to connect
	GetPublicURL() string
	// Services is a list of services to enable for this HTTP Service
	GetServices() []string
}

Config provides interface for the server configurarion

type HTTPServer

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

HTTPServer is responsible for exposing the collection of the services as a single HTTP server

func New

func New(
	version string,
	ipaddr string,
	httpConfig Config,
	tlsConfig *tls.Config,
) (*HTTPServer, error)

New creates a new instance of the server

func (*HTTPServer) AddService

func (server *HTTPServer) AddService(s Service)

AddService provides a service registration for the server

func (*HTTPServer) HTTPConfig

func (server *HTTPServer) HTTPConfig() Config

HTTPConfig returns HTTPServerConfig

func (*HTTPServer) HostName

func (server *HTTPServer) HostName() string

HostName returns the host name of the server

func (*HTTPServer) IsReady

func (server *HTTPServer) IsReady() bool

IsReady returns true when the server is ready to serve

func (*HTTPServer) LocalIP

func (server *HTTPServer) LocalIP() string

LocalIP returns the IP address of the server

func (*HTTPServer) Name

func (server *HTTPServer) Name() string

Name returns the server name

func (*HTTPServer) NewMux

func (server *HTTPServer) NewMux() http.Handler

NewMux creates a new http handler for the http server, typically you only need to call this directly for tests.

func (*HTTPServer) OnEvent

func (server *HTTPServer) OnEvent(evt ServerEvent, handler ServerEventFunc)

OnEvent accepts a callback to handle server events

func (*HTTPServer) Port

func (server *HTTPServer) Port() string

Port returns the port name of the server

func (*HTTPServer) Protocol

func (server *HTTPServer) Protocol() string

Protocol returns the protocol

func (*HTTPServer) PublicURL

func (server *HTTPServer) PublicURL() string

PublicURL returns the public URL of the server

func (*HTTPServer) ServeHTTP

func (server *HTTPServer) ServeHTTP(w http.ResponseWriter, r *http.Request)

ServeHTTP should write reply headers and data to the ResponseWriter and then return. Returning signals that the request is finished; it is not valid to use the ResponseWriter or read from the Request.Body after or concurrently with the completion of the ServeHTTP call.

func (*HTTPServer) Service

func (server *HTTPServer) Service(name string) Service

Service returns a registered server

func (*HTTPServer) StartHTTP

func (server *HTTPServer) StartHTTP() error

StartHTTP will verify all the TLS related files are present and start the actual HTTPS listener for the server

func (*HTTPServer) StartedAt

func (server *HTTPServer) StartedAt() time.Time

StartedAt returns the time when the server started

func (*HTTPServer) StopHTTP

func (server *HTTPServer) StopHTTP()

StopHTTP will perform a graceful shutdown of the serivce by

  1. signally to the Load Balancer to remove this instance from the pool by changing to response to /availability
  2. cause new responses to have their Connection closed when finished to force clients to re-connect [hopefully to a different instance]
  3. wait the minShutdownTime to ensure the LB has noticed the status change
  4. wait for existing requests to finish processing
  5. step 4 is capped by a overrall timeout where we'll give up waiting for the requests to complete and will exit.

it is expected that you don't try and use the server instance again after this. [i.e. if you want to start it again, create another server instance]

func (*HTTPServer) TLSConfig

func (server *HTTPServer) TLSConfig() *tls.Config

TLSConfig returns TLSConfig

func (*HTTPServer) Uptime

func (server *HTTPServer) Uptime() time.Duration

Uptime returns the duration the server was up

func (*HTTPServer) Version

func (server *HTTPServer) Version() string

Version returns the version of the server

func (*HTTPServer) WithAuthz

func (server *HTTPServer) WithAuthz(authz authz.HTTPAuthz) *HTTPServer

WithAuthz enables to use Authz

func (*HTTPServer) WithCORS

func (server *HTTPServer) WithCORS(cors *CORSOptions) *HTTPServer

WithCORS enables CORS options

func (*HTTPServer) WithIdentityProvider

func (server *HTTPServer) WithIdentityProvider(provider identity.ProviderFromRequest) *HTTPServer

WithIdentityProvider enables to set idenity on each request

func (*HTTPServer) WithMuxFactory

func (server *HTTPServer) WithMuxFactory(muxFactory MuxFactory)

WithMuxFactory requires the server to use `muxFactory` to create server handler.

func (*HTTPServer) WithShutdownTimeout

func (server *HTTPServer) WithShutdownTimeout(timeout time.Duration) *HTTPServer

WithShutdownTimeout sets the connection draining timeouts on server shutdown

type Handle

type Handle func(http.ResponseWriter, *http.Request, Params)

Handle is a function that can be registered to a route to handle HTTP requests. Like http.HandlerFunc, but has a third parameter for the values of wildcards (variables).

type MuxFactory

type MuxFactory interface {
	NewMux() http.Handler
}

MuxFactory creates http handlers.

type Params

type Params httprouter.Params

Params is a Param-slice, as returned by the router. The slice is ordered, the first URL parameter is also the first slice value. It is therefore safe to read values by the index.

func (Params) ByName

func (ps Params) ByName(name string) string

ByName returns the value of the first Param which key matches the given name. If no matching Param is found, an empty string is returned.

type Router

type Router interface {
	Handler() http.Handler
	GET(path string, handle Handle)
	HEAD(path string, handle Handle)
	OPTIONS(path string, handle Handle)
	POST(path string, handle Handle)
	PUT(path string, handle Handle)
	PATCH(path string, handle Handle)
	DELETE(path string, handle Handle)
	CONNECT(path string, handle Handle)
}

Router provides a router interface

func NewRouter

func NewRouter(notfoundhandler http.HandlerFunc) Router

NewRouter returns a new initialized Router.

func NewRouterWithCORS

func NewRouterWithCORS(notfoundhandler http.HandlerFunc, opt *CORSOptions) Router

NewRouterWithCORS returns a new initialized Router with CORS enabled

type Server

type Server interface {
	http.Handler
	Name() string
	Version() string
	HostName() string
	LocalIP() string
	Port() string
	Protocol() string
	PublicURL() string
	StartedAt() time.Time
	Service(name string) Service
	Config() Config
	TLSConfig() *tls.Config

	// IsReady indicates that all subservices are ready to serve
	IsReady() bool

	AddService(s Service)
	StartHTTP() error
	StopHTTP()

	OnEvent(evt ServerEvent, handler ServerEventFunc)
}

Server is an interface to provide server status

Example
package main

import (
	"fmt"
	"os"
	"os/signal"
	"syscall"
	"time"

	rest "github.com/effective-security/porto/restserver"
	"github.com/effective-security/xlog"
)

var logger = xlog.NewPackageLogger("github.com/effective-security/porto", "rest_test")

func main() {
	sigs := make(chan os.Signal, 2)

	tlsCfg := &tlsConfig{
		CertFile:       "testdata/test-server.pem",
		KeyFile:        "testdata/test-server-key.pem",
		TrustedCAFile:  "testdata/test-server-rootca.pem",
		WithClientAuth: false,
	}

	tlsInfo, tlsloader, err := createServerTLSInfo(tlsCfg)
	if err != nil {
		panic("unable to create TLS config")
	}
	defer tlsloader.Close()

	cfg := &serverConfig{
		BindAddr: ":8181",
	}

	server, err := rest.New("v1.0.123", "", cfg, tlsInfo)
	if err != nil {
		panic("unable to create the server")
	}

	svc := NewService(server)
	server.AddService(svc)

	fmt.Println("starting server")
	err = server.StartHTTP()
	if err != nil {
		logger.Panicf("unable to start the server: [%+v]", err)
	}

	go func() {
		// Send STOP signal after few seconds,
		// in production the service should listen to
		// os.Interrupt, os.Kill, syscall.SIGTERM, syscall.SIGUSR2, syscall.SIGABRT events
		time.Sleep(3 * time.Second)
		fmt.Println("sending syscall.SIGTERM signal")
		sigs <- syscall.SIGTERM
	}()

	// register for signals, and wait to be shutdown
	signal.Notify(sigs, os.Interrupt, os.Kill, syscall.SIGTERM, syscall.SIGUSR2, syscall.SIGABRT)
	// Block until a signal is received.
	sig := <-sigs

	server.StopHTTP()
	fmt.Println("stopped server")

	// SIGUSR2 is triggered by the upstart pre-stop script, we don't want
	// to actually exit the process in that case until upstart sends SIGTERM
	if sig == syscall.SIGUSR2 {
		select {
		case <-time.After(time.Second * 5):
			logger.KV(xlog.INFO, "status", "service shutdown from SIGUSR2 complete, waiting for SIGTERM to exit")
		case sig = <-sigs:
			logger.KV(xlog.INFO, "status", "exiting", "reason", "received_signal", "sig", sig)
		}
	}

}
Output:

starting server
sending syscall.SIGTERM signal
stopped server

type ServerEvent

type ServerEvent int

ServerEvent specifies server event type

const (
	// ServerStartedEvent is fired on server start
	ServerStartedEvent ServerEvent = iota
	// ServerStoppedEvent is fired after server stopped
	ServerStoppedEvent
	// ServerStoppingEvent is fired before server stopped
	ServerStoppingEvent
)

type ServerEventFunc

type ServerEventFunc func(evt ServerEvent)

ServerEventFunc is a callback to handle server events

type Service

type Service interface {
	Name() string
	Register(Router)
	Close()
	// IsReady indicates that service is ready to serve its end-points
	IsReady() bool
}

Service provides a way for subservices to be registered so they get added to the http API.

type TLSInfoConfig

type TLSInfoConfig interface {
	// GetCertFile returns location of the cert
	GetCertFile() string
	// GetKeyFile returns location of the key
	GetKeyFile() string
	// GetTrustedCAFile specifies location of the Trusted CA file
	GetTrustedCAFile() string
	// GetClientCertAuth controls client auth
	GetClientCertAuth() *bool
}

TLSInfoConfig contains configuration info for the TLS

Directories

Path Synopsis
Package authz provides an implemention of http authorization where specific URI (or URI's and their children) are allowed access by a set of roles
Package authz provides an implemention of http authorization where specific URI (or URI's and their children) are allowed access by a set of roles

Jump to

Keyboard shortcuts

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