Documentation ¶
Overview ¶
Package httpserver provides the HTTPServer facility which defines a configurable HTTP server for processing web-service requests.
The HTTPServer facility provides a server that will listen for HTTP web-service requests and map them to the web-service endpoints defined by your application. A full description of how to configure this facility can be found at https://granitic.io/ref/http-server
This package defines two main types HTTPServer and AccessLogWriter. HTTPServer is a layer over Go's built-in http.Server adding runtime control (suspension, resumption) and mapping of requests to instances of ws.Handler. AccessLogWriter supports Apache/Tomcat style access log formatting and writing.
Most applications will only need to enable this facility (probably changing the listen Port) and define mappings between incoming paths and application logic in their component definition files. See handler.WsHandler for more details.
Index ¶
- Constants
- func ValidateJSONFields(fields []*AccessLogJSONField) error
- type AccessLogJSONConfig
- type AccessLogJSONField
- type AccessLogMapBuilder
- type AccessLogValueGenerator
- type AccessLogWriter
- func (alw *AccessLogWriter) LogRequest(ctx context.Context, req *http.Request, res *httpendpoint.HTTPResponseWriter, ...)
- func (alw *AccessLogWriter) PrepareToStop()
- func (alw *AccessLogWriter) ReadyToStop() (bool, error)
- func (alw *AccessLogWriter) RegisterInstanceID(i *instance.Identifier)
- func (alw *AccessLogWriter) StartComponent() error
- func (alw *AccessLogWriter) Stop() error
- type FacilityBuilder
- type HTTPServer
- func (h *HTTPServer) AllowAccess() error
- func (h *HTTPServer) Container(container *ioc.ComponentContainer)
- func (h *HTTPServer) PrepareToStop()
- func (h *HTTPServer) ReadyToStop() (bool, error)
- func (h *HTTPServer) Resume() error
- func (h *HTTPServer) SetProvidersManually(p map[string]httpendpoint.Provider)
- func (h *HTTPServer) StartComponent() error
- func (h *HTTPServer) Stop() error
- func (h *HTTPServer) Suspend() error
- type IdentifiedRequestContextBuilder
- type JSONLineBuilder
- func (jlb *JSONLineBuilder) BuildLine(ctx context.Context, req *http.Request, res *httpendpoint.HTTPResponseWriter, ...) string
- func (jlb *JSONLineBuilder) Init() error
- func (jlb *JSONLineBuilder) SetContextFilter(cf logging.ContextFilter)
- func (jlb *JSONLineBuilder) SetInstanceID(i *instance.Identifier)
- type LineBuilder
- type UnstructuredLineBuilder
- func (ulb *UnstructuredLineBuilder) BuildLine(ctx context.Context, req *http.Request, res *httpendpoint.HTTPResponseWriter, ...) string
- func (ulb *UnstructuredLineBuilder) Init() error
- func (ulb *UnstructuredLineBuilder) SetContextFilter(cf logging.ContextFilter)
- func (ulb *UnstructuredLineBuilder) SetInstanceID(i *instance.Identifier)
Constants ¶
const HTTPServerAbnormalStatusFieldName = "AbnormalStatusWriter"
HTTPServerAbnormalStatusFieldName is the field on the HTTPServer component into which a ws.AbnormalStatusWriter can be injected. Most applications will use either the JSONWs or XMLWs facility, in which case a AbnormalStatusWriter that will respond to requests with an abnormal result (404, 503 etc) by sending a JSON or XML response respectively.
If this behaviour is undesirable, an alternative AbnormalStatusWriter can set by using the frameworkModifiers mechanism (see https://granitic.io/ref/component-definition-files )
const HTTPServerComponentName = instance.FrameworkPrefix + "HTTPServer"
HTTPServerComponentName is the name of the HTTPServer component as stored in the IoC framework.
const PresetCombinedFormat = "%h %l %u %t \"%r\" %s %b \"%{Referer}i\" \"%{User-agent}i\""
PresetCombinedFormat is the log format used when AccessLogWriter.LogLinePreset is set to combined. Similar to the Apache HTTP preset of the same name.
const PresetFrameworkFormat = "%h XFF[%{X-Forwarded-For}i] %l %u [%{02/Jan/2006:15:04:05 Z0700}t] \"%m %U%q\" %s %bB %{us}Tμs"
PresetFrameworkFormat is the log format used when AccessLogWriter.LogLinePreset is set to framework. Uses the X-Forwarded-For header to show all IP addresses that the request has been proxied for (useful for services that sit behind multiple load-balancers and proxies) and logs processing time in microseconds.
Variables ¶
This section is empty.
Functions ¶
func ValidateJSONFields ¶ added in v2.2.0
func ValidateJSONFields(fields []*AccessLogJSONField) error
ValidateJSONFields checks that the configuration of a JSON application log entry is correct
Types ¶
type AccessLogJSONConfig ¶ added in v2.2.0
type AccessLogJSONConfig struct { Prefix string Fields [][]string ParsedFields []*AccessLogJSONField Suffix string UTC bool }
AccessLogJSONConfig defines the fields to be included in a JSON-formatted application log entry
type AccessLogJSONField ¶ added in v2.2.0
type AccessLogJSONField struct { Name string Content string Arg string // contains filtered or unexported fields }
A AccessLogJSONField defines the rules for outputting a single field in a JSON-formatted application log entry
func ConvertFields ¶ added in v2.2.0
func ConvertFields(unparsed [][]string) []*AccessLogJSONField
ConvertFields converts from the config representation of a field list to the internal version
type AccessLogMapBuilder ¶ added in v2.2.0
type AccessLogMapBuilder struct { RequiresContextFilter bool // contains filtered or unexported fields }
AccessLogMapBuilder creates a map[string]interface{} representing a log entry, ready for JSON encoding
func CreateMapBuilder ¶ added in v2.2.0
func CreateMapBuilder(cfg *AccessLogJSONConfig) (*AccessLogMapBuilder, error)
CreateMapBuilder builds a component able to generate a log entry based on the rules in the supplied fields.
func (*AccessLogMapBuilder) BuildLine ¶ added in v2.2.0
func (mb *AccessLogMapBuilder) BuildLine(ctx context.Context, req *http.Request, res *httpendpoint.HTTPResponseWriter, rec *time.Time, fin *time.Time) map[string]interface{}
BuildLine creates a map and populates it
type AccessLogValueGenerator ¶ added in v2.2.0
type AccessLogValueGenerator func(lineContext *lineContext, field *AccessLogJSONField) interface{}
AccessLogValueGenerator functions are able to generate a value for a field in a JSON formatted log entry
type AccessLogWriter ¶
type AccessLogWriter struct { // The path of the log file to be written to (and created if required) LogPath string // The format of each log line. See the top of this GoDoc page for supported formats. Mutually exclusive with LogLinePreset. LogLineFormat string // A pre-defined format. Supported values are framework or combined. Mutually exclusive with LogLineFormat. LogLinePreset string //The number of lines that can be buffered for asynchronous writing to the log file before calls to LogRequest block. //Setting to zero or less makes calls to LogRequest synchronous LineBufferSize int // Whether or not timestamps should be converted to UTC before they are written to the access log. UtcTimes bool // A component able to extract information from a context.Context into a loggable format ContextFilter logging.ContextFilter // contains filtered or unexported fields }
AccessLogWriter is a component able to asynchronously write an Apache HTTPD style access log. See the top of this GoDoc page for more information.
func (*AccessLogWriter) LogRequest ¶
func (alw *AccessLogWriter) LogRequest(ctx context.Context, req *http.Request, res *httpendpoint.HTTPResponseWriter, rec *time.Time, fin *time.Time)
LogRequest generates an access log line according the configured format. As long as the number of log lines waiting to be written to the file does not exceed the value of AccessLogWriter.LineBufferSize, this method will return immediately.
func (*AccessLogWriter) PrepareToStop ¶
func (alw *AccessLogWriter) PrepareToStop()
PrepareToStop settings state to 'Stopping'
func (*AccessLogWriter) ReadyToStop ¶
func (alw *AccessLogWriter) ReadyToStop() (bool, error)
ReadyToStop returns true if the log line buffer is empty
func (*AccessLogWriter) RegisterInstanceID ¶ added in v2.2.0
func (alw *AccessLogWriter) RegisterInstanceID(i *instance.Identifier)
RegisterInstanceID receives the instance ID of the current application and passes it down to the LineBuilder
func (*AccessLogWriter) StartComponent ¶
func (alw *AccessLogWriter) StartComponent() error
StartComponent parses the specified log format, sets up a channel to buffer lines for asynchrnous writing and opens the log file. An error is returned if any of these steps fails.
func (*AccessLogWriter) Stop ¶
func (alw *AccessLogWriter) Stop() error
Stop closes the log file and message channel
type FacilityBuilder ¶
type FacilityBuilder struct { }
FacilityBuilder creates the components that make up the HTTPServer facility (the server and an access log writer).
func (*FacilityBuilder) BuildAndRegister ¶
func (hsfb *FacilityBuilder) BuildAndRegister(lm *logging.ComponentLoggerManager, ca *config.Accessor, cn *ioc.ComponentContainer) error
BuildAndRegister implements FacilityBuilder.BuildAndRegister
func (*FacilityBuilder) DependsOnFacilities ¶
func (hsfb *FacilityBuilder) DependsOnFacilities() []string
DependsOnFacilities implements FacilityBuilder.DependsOnFacilities
func (*FacilityBuilder) FacilityName ¶
func (hsfb *FacilityBuilder) FacilityName() string
FacilityName implements FacilityBuilder.FacilityName
type HTTPServer ¶
type HTTPServer struct { // Logger used by Granitic framework components. Automatically injected. FrameworkLogger logging.Logger // A component able to write an access log. Automatically added by this facility's builder, is access log support is enabled. AccessLogWriter *AccessLogWriter // Whether or not access logging should be enabled. AccessLogging bool // Whether or not instances of httpendpoint.Provider found in the IoC container should be automatically // registered with this server AutoFindHandlers bool // The TCP port on which the HTTP server should listen for requests. Port int // The IP/hostname this server should listen on, follows standard Go net package syntax. Empty string means listen on all. Address string // A component able to write valid HTTP responses in the event a user request results in an abnormal result // (not found, server too busy, panic in application logic). If you use the JSONWs or XMLWs facility, this is automatically injected. AbnormalStatusWriter ws.AbnormalStatusWriter // The number of HTTP requests currently being handled by the server. ActiveRequests int64 // Allow request instrumentation to begin BEFORE too-busy/suspended checks. Allows instrumentation of requests that would be trivially // rejected, but potentially increases risk of denial-of-service if instrumentation setup causes load or consumes memory. AllowEarlyInstrumentation bool // Prevents this server from finding and using RequestInstrumentationManager components DisableInstrumentationAutoWire bool // A component able to instrument a web service request in some way InstrumentationManager instrument.RequestInstrumentationManager // How many concurrent requests the server should allow before returning 'too busy' responses to subsequent requests. MaxConcurrent int64 // The HTTP status code returned with 'too busy responses'. Normally 503 TooBusyStatus int // A component able to examine an incoming request and determine which version of functionality is being requested. VersionExtractor httpendpoint.RequestedVersionExtractor // A component able to use data in an HTTP request's headers to populate a context IDContextBuilder IdentifiedRequestContextBuilder // contains filtered or unexported fields }
HTTPServer is the server that accepts incoming HTTP requests and maps them to handlers to process them.
func (*HTTPServer) AllowAccess ¶
func (h *HTTPServer) AllowAccess() error
AllowAccess starts the server listening on the configured address and port. Returns an error if the port is already in use.
func (*HTTPServer) Container ¶
func (h *HTTPServer) Container(container *ioc.ComponentContainer)
Container allows Granitic to inject a reference to the IOC container
func (*HTTPServer) PrepareToStop ¶
func (h *HTTPServer) PrepareToStop()
PrepareToStop sets state to Stopping. Any subsequent requests will receive a 'too busy response'
func (*HTTPServer) ReadyToStop ¶
func (h *HTTPServer) ReadyToStop() (bool, error)
ReadyToStop returns false is the server is currently handling any requests.
func (*HTTPServer) Resume ¶
func (h *HTTPServer) Resume() error
Resume allows subsequent requests to be processed normally (reverses the effect of calling Suspend).
func (*HTTPServer) SetProvidersManually ¶
func (h *HTTPServer) SetProvidersManually(p map[string]httpendpoint.Provider)
SetProvidersManually manually injects a set of httpendpoint.HTTPEndpointProviders when auto finding is disabled.
func (*HTTPServer) StartComponent ¶
func (h *HTTPServer) StartComponent() error
StartComponent Finds and registers any available components that implement httpendpoint.Provider (normally instances of handler.WsHandler) unless auto finding of handlers is disabled. The server does not actually start listening for requests until the IoC container calls AllowAccess.
func (*HTTPServer) Stop ¶
func (h *HTTPServer) Stop() error
Stop sets state to Stopped. Any subsequent requests will receive a 'too busy response'. Note that the HTTP server is still listening on its configured port and address.
func (*HTTPServer) Suspend ¶
func (h *HTTPServer) Suspend() error
Suspend causes all subsequent new HTTP requests to receive a 'too busy' response until Resume is called.
type IdentifiedRequestContextBuilder ¶
type IdentifiedRequestContextBuilder interface { // WithIdentity uses information in the supplied request to assign an ID to this context WithIdentity(ctx context.Context, req *http.Request) (context.Context, error) //Extract an ID string from a previously populated context ID(ctx context.Context) string }
IdentifiedRequestContextBuilder is implemented by a component that should be called by the HTTPServer facility before a request is matched to a handler. It is an opportunity to extract information from the HTTP request to add an ID for this request to the context that will be passed to the handler.
It is the responsibility of the implementor to control the uniqueness of the allocated ID ¶
It is recommended that only the request meta data (headers, path, parameters) are accessed by implementations, as loading the request body will interfere with later phases of the request processing.
type JSONLineBuilder ¶ added in v2.2.0
type JSONLineBuilder struct { Config *AccessLogJSONConfig MapBuilder *AccessLogMapBuilder }
A JSONLineBuilder is a component able to take a message to be written to a log file and format it as JSON document
func (*JSONLineBuilder) BuildLine ¶ added in v2.2.0
func (jlb *JSONLineBuilder) BuildLine(ctx context.Context, req *http.Request, res *httpendpoint.HTTPResponseWriter, rec *time.Time, fin *time.Time) string
BuildLine takes the message and prefixes it according the the rule specified in PrefixFormat or PrefixPreset
func (*JSONLineBuilder) Init ¶ added in v2.2.0
func (jlb *JSONLineBuilder) Init() error
Init checks that a context filter has been injected (if the field configuration needs one)
func (*JSONLineBuilder) SetContextFilter ¶ added in v2.2.0
func (jlb *JSONLineBuilder) SetContextFilter(cf logging.ContextFilter)
SetContextFilter provides the formatter with access selected data from a context
func (*JSONLineBuilder) SetInstanceID ¶ added in v2.2.0
func (jlb *JSONLineBuilder) SetInstanceID(i *instance.Identifier)
SetInstanceID makes the ID of the current instance available to the map builder
type LineBuilder ¶ added in v2.2.0
type LineBuilder interface { BuildLine(ctx context.Context, req *http.Request, res *httpendpoint.HTTPResponseWriter, rec *time.Time, fin *time.Time) string SetContextFilter(cf logging.ContextFilter) Init() error SetInstanceID(i *instance.Identifier) }
LineBuilder is a component able to generate an access log entry ready to be written to a file or stream
type UnstructuredLineBuilder ¶ added in v2.2.0
type UnstructuredLineBuilder struct { // The format of each log line. See the top of this GoDoc page for supported formats. Mutually exclusive with LogLinePreset. LogLineFormat string // A pre-defined format. Supported values are framework or combined. Mutually exclusive with LogLineFormat. LogLinePreset string // contains filtered or unexported fields }
UnstructuredLineBuilder creates strings that correspond to traditional line-based entries in an accesss log, where the meaning is inferred by position of each field in the line
func (*UnstructuredLineBuilder) BuildLine ¶ added in v2.2.0
func (ulb *UnstructuredLineBuilder) BuildLine(ctx context.Context, req *http.Request, res *httpendpoint.HTTPResponseWriter, rec *time.Time, fin *time.Time) string
BuildLine creates a text representation of an access log entry ready to log to a file or stream
func (*UnstructuredLineBuilder) Init ¶ added in v2.2.0
func (ulb *UnstructuredLineBuilder) Init() error
Init checks that a valid format for access log lines has been provided
func (*UnstructuredLineBuilder) SetContextFilter ¶ added in v2.2.0
func (ulb *UnstructuredLineBuilder) SetContextFilter(cf logging.ContextFilter)
SetContextFilter provides access to a component that has limited access to data stored in a context.Context
func (*UnstructuredLineBuilder) SetInstanceID ¶ added in v2.2.0
func (ulb *UnstructuredLineBuilder) SetInstanceID(i *instance.Identifier)
SetInstanceID records the ID of the current instance