Skip to content

Latest commit

 

History

History
224 lines (148 loc) · 7.14 KB

README.md

File metadata and controls

224 lines (148 loc) · 7.14 KB

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:

  1. appkit/server default middleware:

    1. HTTP status memoisation
    2. Taggin request with UUID
    3. Adding logger to request context
    4. Logging request/response
    5. recovering from panic, and returning 500 Internal Server Error if no other HTTP status has been "sent" from a later handler.
  2. Request tracing via Opentracing/Jaeger

  3. Notification of panics to Airbrake

  4. Logging request metrics in InfluxDB

  5. Add clickjacking countermeasure header

  6. Add HSTS header

  7. Sending request information to New Relic

  8. CORS handling

  9. HTTP Basic Authentication

  10. Adding AWS session 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 Session

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_MaxAge: the time in seconds value for max-age .

  • HSTS_IncludeSubDomains: boolean-ish value for includeSubDomains .

HSTS header will only be added when the value of HSTS_MaxAge is greater than 0

Add clickjacking countermeasure header

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.

  1. Create and configure service background context (including starting background goroutines used by some middleware).

  2. Set up common middleware using background context.

  3. Hand over to app-side code (passed function) to do app-specific configuration.

  4. App-side code hands back to the service harness (by returning from the passed function).

  5. Start HTTP server in background goroutine.

  6. Wait for signal to terminate.

  7. Ask HTTP server to shut down, and wait.

  8. 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.

  9. 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.