Documentation ¶
Overview ¶
Package http provides a usrv transport over HTTP/HTTPS.
Index ¶
- func Factory() transport.Provider
- func SingletonFactory() transport.Provider
- type ServiceURLBuilder
- type Transport
- func (t *Transport) Bind(version, service, endpoint string, handler transport.Handler) error
- func (t *Transport) Close(mode transport.Mode) error
- func (t *Transport) Dial(mode transport.Mode) error
- func (t *Transport) Request(reqMsg transport.Message) <-chan transport.ImmutableMessage
- func (t *Transport) Unbind(version, service, endpoint string)
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Factory ¶
Factory is a factory for creating usrv transport instances whose concrete implementation is the HTTP transport. This function behaves exactly the same as New() but returns back a Transport interface allowing it to be used as usrv.DefaultTransportFactory.
func SingletonFactory ¶
SingletonFactory is a factory for creating singleton HTTP transport instances. This function returns back a Transport interface allowing it to be used as usrv.DefaultTransportFactory.
Types ¶
type ServiceURLBuilder ¶
ServiceURLBuilder defines an interface for mapping a version, service and endpoint tuple into a remote path URL.
URL receives the service and endpoint name as input and returns back a URL.
type Transport ¶
type Transport struct { // URLBuilder can be overridden to implement custom service discovery rules. URLBuilder ServiceURLBuilder // contains filtered or unexported fields }
Transport implements a usrv transport over HTTP/HTTPS.
Bindings for this transport must be defined before a call to Dial(). Any attempt to define a binding after the transport has been dialed will result in a n error. If new bindings need to be defined after the transport has been dialed, the Close() method must be invoked before defining the new binidngs.
When operating as a server, the transport provides a simple mux that dispatches incoming POST requests to the bound endpoints. Each endpoint is mapped to a route with pattern "service_name/endpoint_name". Non-POST requests or requests not matching the above pattern will fail with http.StatusNotFound (404).
The transport returns http.StatusOK if the incoming request is handled by a defined binding and maps common errors to HTTP status codes using the following rules:
- 404 = Unknown binding or non-POST request
- 408 = If the binding handler returns transport.ErrTimeout
- 401 = If the binding handler returns transport.ErrNotAuthorized
- 500 = If the binding handler returns any other error; it that case the error message gets encoded as a response header
The transport uses prefixed HTTP headers (Usrv-) to decode message headers from HTTP requests and encode them into HTTP responses.
The transport server adds watches to the global configuration store for the following configuration parameters:
- transport/http/protocol (default: http). The protocol to use; either "http" or "https".
- transport/http/port (default: ""). The port to listen for incoming connections; if unspecified, the default port for the protocol will be used.
- transport/http/tls/certificate (default: ""). The path to a SSL certificate; used only if protocol is "https".
- transport/http/tls/key (default: ""). The path to the key for the certificate; used only if protocol is "https".
- transport/http/tls/strict (default: "true"). Enables strict TLS configuration to achieve a perfect SSL labs score (see https://blog.bracebin.com/achieving-perfect-ssl-labs-score-with-go); used only if protocol is "https".
The following configuration parameter is used by the transport in client mode when the protocol is set to "https":
- transport/http/client/verifycert (default: "cert_pool"). Defines how the http client verifies self-signed SSL certificates. Supported values are either "cert_pool" (append certificate to the system's certificate pool) or "skip" which sets the "InsecureSkipVerify" flag in the client's TLS configuration.
If any of the above values changes, the transport will automatically trigger a redial while gracefully closing the existing listener.
When operating as a client, the transport needs to be able to generate a remote URL for outgoing requests. For this purpose it uses a ServiceURLBuilder (URLBuilder field) which maps the outgoing service name and endpoint into an HTTP URL.
If no URLBuilder is defined when the transport is dialed it will automatically use a default implementation that watches the following configuration fields:
- transport/http/protocol.
- transport/http/port.
- transport/http/client/hostsuffix. A suffix to append to the service name when building the remote URL (default: .service)
Using the above configuration values, the default ServiceURLBuilder generates remote URLs using the pattern: "$protocol://service_name(-$version)$suffix(:$port)/service_name/endpoint_name". The port is only included if the "transport/http/port" parameter is defined. If the outgoing message requests a particular service version then that version value will also be included in the generated URL.
The built-in ServiceURLBuilder implementation is designed to enable DNS-based service discovery. In case that the default implementation is not sufficient or you want to test against a locally running server, you can override the URLBuilder field with a custom ServiceURLBuilder implementation prior to calling Dial().
func (*Transport) Bind ¶
Bind listens for messages send to a particular service and endpoint tuple and invokes the supplied handler to process them.
The HTTP transport ignores the version argument as it assumes that routing to a service with a particular version is handled at the DNS level. Attempting to define multiple versions for the same service and endpoint tuple will cause an error to be returned.
func (*Transport) Dial ¶
Dial connects to the transport using the specified dial mode. When the dial mode is set to DialModeServer the transport will start relaying messages to registered bindings.