This package provides a common harness for running HTTP apps, that
configures middleware that we use nearly all the time, and provides a
standard way to configure the different parts of the service.
Basic usage is to call service.ListenAndServe
, and pass a function
that registers your HTTP handlers on the *http.ServeMux
parameter
passed to your function.
There are some pre-configured common things available in the background context
passed to the function:
Most of these are also made available via middleware, and should be
accessed via the HTTP request context instead.
Middleware
In request-processing order:
-
appkit/server
default middleware:
- HTTP status memoisation
- Taggin request with UUID
- Adding logger to request context
- Logging request/response
recover
ing from panic
, and returning 500 Internal Server Error
if no other HTTP status has been "sent" from a later
handler.
-
Request tracing via Opentracing/Jaeger
-
Notification of panic
s to Airbrake
-
Logging request metrics in InfluxDB
-
Add clickjacking countermeasure header
-
Add HSTS header
-
Sending request information to New Relic
-
CORS handling
-
HTTP Basic Authentication
-
Adding AWS config to request context
Configuration
General Configuration
SERVICE_NAME
can be set in the environment, this will be used by:
-
Loggger: as svc
field.
-
Vault+AWS client credentials sourcing: as default role for Vault
authn, and default AWS credentials path.
-
Request Tracing (Opentracing/Jaeger): As service name for traced
requests.
-
New Relic Middleware: Application name reported to New Relic.
HTTP Basic Authentication
Environment variables:
BASICAUTH_Username
BASICAUTH_Password
BASICAUTH_UserAgentWhitelistRegexp
: Regexp matched against HTTP
User-Agent header to bypass HTTP Basic Authentication.
BASICAUTH_PathWhitelistRegexp
: Regexp matched against request path
to bypass HTTP Basic Authentication.
CORS
CORS
configuration of https://github.com/rs/cors
Environment variables:
Vault/AWS Config
Environment variables:
-
VAULT_AUTHN_ADDRESS
: base URL of Vault server.
-
VAULT_AUTH_PATH
: path to Vault K8s auth backend. By default this
is set to auth/kubernetes/login
.
-
VAULT_AUTH_ROLE
: role used when authenticating with Vault. By
default this is set to $SERVICE_NAME
.
-
VAULT_AUTH_AUTORENEW
: flag to enable/disable automatic renewal of
Vault lease in background goroutine. Defaults to true
.
-
VAULT_AWSPATH
: When using AWS credentials sourced from Vault, the
Vault path of the credentials secret. By default this is set to
aws/sts/<$SERVICE_NAME>
.
-
VAULT_AUTHN_DISABLED
: flag to enable/disable Vault authentication
completely. Use this when the service does not need any access to
Vault.
HTTP Server
PORT
: port number for HTTP server to bind to, defaults to 9800
. If
required, ADDR
can be set instead to allow binding to a specific
interface/IP address using [interface]:port
syntax.
Monitor
INFLUXDB_URL
: Set to URL of InfluxDB server. If blank, a logging
(via appkit/log
monitor will be used instead of sending data to
InfluxDB.
If INFLUXDB_URL
's scheme is vault
(vs http
or https
), then the
client will source InfluxDB credentials from Vault. In this case,
INFLUXDB_URL
does not need any credentials. See the Vault+InfluxDB
client documentation in the credentials
README for information about configuration
constraints.
If INFLUXDB_URL
has no (or blank) service-name
query parameter,
the parameter will be set to SERVICE_NAME
.
Error Notifier
AIRBRAKE_PROJECTID
AIRBRAKE_TOKEN
AIRBRAKE_ENVIRONMENT
AIRBRAKE_FILTERS
If notifier can't be created due to blank project ID or token, a
logging notifier will be used instead.
New Relic
NEWRELIC_APIKey
NEWRELIC_AppName
: If this is blank, $SERVICE_NAME
will be used.
Tracer
Configured as for Jaeger Go
client.
If JAEGER_SERVICE_NAME
is blank, $SERVICE_NAME
will be used.
HSTS
HSTS
Environment variables:
HSTS header will only be added when the value of HSTS_MaxAge
is greater than 0
X-Frame-Options
Content-Security-Policy
Default:
the page cannot be displayed in a frame.
Environment variables:
-
DISPLAY_IN_FRAME_NoLimit
: Bool type. If true
, no headers added, the page should be able to be displayed in a frame without limit(depend on browser's default behavior).
-
DISPLAY_IN_FRAME_SameOrigin
: Bool type. If true
, the page can only be displayed in a frame on the same origin as the page itself.
-
DISPLAY_IN_FRAME_AllowURIs
: A string contains URIs separated by spaces. If it has value, the page can only be displayed in a frame on specified URIs.
Design Background
Design is implemented via a configuration callback because the
lifecycle of the app is controlled by the serivce harness.
-
Create and configure service background context (including starting
background goroutines used by some middleware).
-
Set up common middleware using background context.
-
Hand over to app-side code (passed function) to do app-specific
configuration.
-
App-side code hands back to the service harness (by returning from
the passed function).
-
Start HTTP server in background goroutine.
-
Wait for signal to terminate.
-
Ask HTTP server to shut down, and wait.
-
Once HTTP server has shut down (=> all requests have been handled
or rejected, no more HTTP requests will be accepted), shut down
background context goroutines.
-
Exit
The reason for this structure is that step 7 needs to finish before
step 8 is started, and managing this lifecycle is somewhat complex,
and tedious. So we don't want to implement it in every service.