Documentation ¶
Index ¶
- Constants
- func GetHostName(bindAddr string) string
- func GetPort(bindAddr string) string
- func GetServerBaseURL(s Server) *url.URL
- func GetServerURL(s Server, r *http.Request, relativeEndpoint string) *url.URL
- type Auditor
- type CORSOptions
- type HTTPServer
- func (server *HTTPServer) AddService(s Service)
- func (server *HTTPServer) Audit(source string, eventType string, identity string, contextID string, ...)
- func (server *HTTPServer) HTTPConfig() HTTPServerConfig
- func (server *HTTPServer) HostName() string
- func (server *HTTPServer) IsReady() bool
- func (server *HTTPServer) LocalIP() string
- func (server *HTTPServer) Name() string
- func (server *HTTPServer) NewMux() http.Handler
- func (server *HTTPServer) OnEvent(evt ServerEvent, handler ServerEventFunc)
- func (server *HTTPServer) Port() string
- func (server *HTTPServer) Protocol() string
- func (server *HTTPServer) Scheduler() tasks.Scheduler
- func (server *HTTPServer) ServeHTTP(w http.ResponseWriter, r *http.Request)
- func (server *HTTPServer) Service(name string) Service
- func (server *HTTPServer) StartHTTP() error
- func (server *HTTPServer) StartedAt() time.Time
- func (server *HTTPServer) StopHTTP()
- func (server *HTTPServer) TLSConfig() *tls.Config
- func (server *HTTPServer) Uptime() time.Duration
- func (server *HTTPServer) Version() string
- func (server *HTTPServer) WithAuditor(auditor Auditor) *HTTPServer
- func (server *HTTPServer) WithAuthz(authz authz.HTTPAuthz) *HTTPServer
- func (server *HTTPServer) WithCORS(cors *CORSOptions) *HTTPServer
- func (server *HTTPServer) WithIdentityProvider(provider identity.ProviderFromRequest) *HTTPServer
- func (server *HTTPServer) WithMuxFactory(muxFactory MuxFactory)
- func (server *HTTPServer) WithScheduler(scheduler tasks.Scheduler) *HTTPServer
- func (server *HTTPServer) WithShutdownTimeout(timeout time.Duration) *HTTPServer
- type HTTPServerConfig
- type Handle
- type MuxFactory
- type Params
- type Router
- type Server
- type ServerEvent
- type ServerEventFunc
- type Service
- type TLSInfoConfig
Examples ¶
Constants ¶
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" )
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 ¶
GetHostName returns Hostname from HTTP bind address, or OS Hostname, if it's not specified in the config
func GetPort ¶
GetPort returns the port from HTTP bind address, or standard HTTPS 443 port, if it's not specified in the config
func GetServerBaseURL ¶
GetServerBaseURL returns server base URL
Types ¶
type Auditor ¶
type Auditor interface { // Call at shutdown to cleanly close the audit destination io.Closer // Call Event to record a new Auditable event // Audit event // source indicates the area that the event was triggered by // eventType indicates the specific event that occured // identity specifies the identity of the user that triggered this event, typically this is <role>/<cn> // contextID specifies the request ContextID that the event was triggered in [this can be used for cross service correlation of logs] // raftIndex indicates the index# of the raft log in RAFT that the event occured in [if applicable] // message contains any additional information about this event that is eventType specific Audit(source string, eventType string, identity string, contextID string, raftIndex uint64, message string) }
Auditor defines an interface that can receive information about audit events
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 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 HTTPServerConfig, 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) Audit ¶
func (server *HTTPServer) Audit(source string, eventType string, identity string, contextID string, raftIndex uint64, message string)
Audit create an audit event
func (*HTTPServer) HTTPConfig ¶
func (server *HTTPServer) HTTPConfig() HTTPServerConfig
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) 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) Scheduler ¶
func (server *HTTPServer) Scheduler() tasks.Scheduler
Scheduler returns task scheduler for 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
- signally to the Load Balancer to remove this instance from the pool by changing to response to /availability
- cause new responses to have their Connection closed when finished to force clients to re-connect [hopefully to a different instance]
- wait the minShutdownTime to ensure the LB has noticed the status change
- wait for existing requests to finish processing
- 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) WithAuditor ¶ added in v0.5.0
func (server *HTTPServer) WithAuditor(auditor Auditor) *HTTPServer
WithAuditor enables to use auditor
func (*HTTPServer) WithAuthz ¶ added in v0.5.0
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 ¶ added in v0.7.0
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) WithScheduler ¶ added in v0.5.0
func (server *HTTPServer) WithScheduler(scheduler tasks.Scheduler) *HTTPServer
WithScheduler enables to schedule tasks, such as heartbeat, uptime etc If a scheduler is not provided, then tasks will not be schedduled.
func (*HTTPServer) WithShutdownTimeout ¶ added in v0.5.0
func (server *HTTPServer) WithShutdownTimeout(timeout time.Duration) *HTTPServer
WithShutdownTimeout sets the connection draining timeouts on server shutdown
type HTTPServerConfig ¶
type HTTPServerConfig interface { // ServiceName specifies name of the service: HTTP|HTTPS|WebAPI GetServiceName() string // Disabled specifies if the service is disabled GetDisabled() bool // VIPName is the FQ name of the VIP to the cluster [this is used when building the cert requests] GetVIPName() string // BindAddr is the address that the HTTPS service should be exposed on GetBindAddr() string // PackageLogger if set, specifies name of the package logger GetPackageLogger() string // AllowProfiling if set, will allow for per request CPU/Memory profiling triggered by the URI QueryString GetAllowProfiling() bool // ProfilerDir specifies the directories where per-request profile information is written, if not set will write to a TMP dir GetProfilerDir() string // Services is a list of services to enable for this HTTP Service GetServices() []string // HeartbeatSecs specifies heartbeat GetHeartbeatSecserval in seconds [30 secs is a minimum] GetHeartbeatSecs() int }
HTTPServerConfig contains the configuration of the HTTPS API Service
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 ¶
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.
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 StartedAt() time.Time Uptime() time.Duration Service(name string) Service HTTPConfig() HTTPServerConfig TLSConfig() *tls.Config // IsReady indicates that all subservices are ready to serve IsReady() bool // Audit records an auditable event. // source indicates the area that the event was triggered by // eventType indicates the specific event that occured // identity specifies the identity of the user that triggered this event, typically this is <role>/<cn> // contextID specifies the request ContextID that the event was triggered in [this can be used for cross service correlation of logs] // raftIndex indicates the index# of the raft log in RAFT that the event occured in [if applicable] // message contains any additional information about this event that is eventType specific Audit(source string, eventType string, identity string, contextID string, raftIndex uint64, message string) AddService(s Service) StartHTTP() error StopHTTP() Scheduler() tasks.Scheduler OnEvent(evt ServerEvent, handler ServerEventFunc) }
Server is an interface to provide server status
Example ¶
package main import ( "crypto/x509" "fmt" "os" "os/signal" "syscall" "time" metricsutil "github.com/go-phorce/dolly/metrics/util" "github.com/go-phorce/dolly/rest" "github.com/go-phorce/dolly/rest/tlsconfig" "github.com/go-phorce/dolly/tasks" "github.com/go-phorce/dolly/testify/auditor" "github.com/go-phorce/dolly/xlog" "github.com/pkg/errors" ) var logger = xlog.NewPackageLogger("github.com/go-phorce/dolly", "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", } scheduler := tasks.NewScheduler() server, err := rest.New("v1.0.123", "", cfg, tlsInfo) if err != nil { panic("unable to create the server") } server.WithAuditor(auditor.NewInMemory()). WithScheduler(scheduler) // execute and schedule go certExpirationPublisherTask(tlsloader) server.Scheduler().Add(tasks.NewTaskAtIntervals(1, tasks.Hours).Do("servertls", certExpirationPublisherTask, tlsloader)) svc := NewService(server) server.AddService(svc) fmt.Println("starting server") err = server.StartHTTP() if err != nil { panic("unable to start the server: " + fmt.Sprintf("%+v", err)) } scheduler.Start() 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 scheduler.Stop() 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.Info("status='service shutdown from SIGUSR2 complete, waiting for SIGTERM to exit'") case sig = <-sigs: logger.Infof("status=exiting, reason=received_signal, sig=%v", sig) } } } func certExpirationPublisherTask(tlsloader *tlsconfig.KeypairReloader) { certFile, keyFile := tlsloader.CertAndKeyFiles() logger.Tracef("cert=%q, key=%q", certFile, keyFile) tlsloader.Reload() pair := tlsloader.Keypair() if pair != nil { cert, err := x509.ParseCertificate(pair.Certificate[0]) if err != nil { errors.WithMessagef(err, "reason=unable_parse_tls_cert, file=%q", certFile) } else { metricsutil.PublishCertExpirationInDays(cert, "server") } } else { logger.Warningf("reason=Keypair, cert=%q, key=%q", certFile, keyFile) } }
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 // TrustedCAFile specifies location of the Trusted CA file GetTrustedCAFile() string // ClientCertAuth controls client auth GetClientCertAuth() *bool }
TLSInfoConfig contains configuration info for the TLS