Documentation ¶
Overview ¶
Package server implements an environment for running LUCI servers.
It interprets command line flags and initializes the serving environment with the following core services:
- go.chromium.org/luci/common/logging: logging via Google Cloud Logging.
- go.opentelemetry.io/otel/trace: OpenTelemetry tracing with export to Google Cloud Trace.
- go.chromium.org/luci/server/tsmon: monitoring metrics via ProdX.
- go.chromium.org/luci/server/auth: sending and receiving RPCs authenticated with Google OAuth2 or OpenID tokens. Support for authorization via LUCI groups and LUCI realms.
- go.chromium.org/luci/server/caching: in-process caching.
- go.chromium.org/luci/server/warmup: allows other server components to register warmup callbacks that run before the server starts handling requests.
- go.chromium.org/luci/server/experiments: simple feature flags support.
- go.chromium.org/luci/grpc/prpc: pRPC server and RPC Explorer UI.
- Error reporting via Google Cloud Error Reporting.
- Continuous profiling via Google Cloud Profiler.
Other functionality is optional and provided by modules (objects implementing module.Module interface). They should be passed to the server when it starts (see the example below). Modules usually expose their configuration via command line flags, and provide functionality by injecting state into the server's global context.Context or by exposing gRPC endpoints.
Usage example:
import ( ... "go.chromium.org/luci/server" "go.chromium.org/luci/server/gaeemulation" "go.chromium.org/luci/server/module" "go.chromium.org/luci/server/redisconn" ) func main() { modules := []module.Module{ gaeemulation.NewModuleFromFlags(), redisconn.NewModuleFromFlags(), } server.Main(nil, modules, func(srv *server.Server) error { // Initialize global state, change root context (if necessary). if err := initializeGlobalStuff(srv.Context); err != nil { return err } srv.Context = injectGlobalStuff(srv.Context) // Install regular HTTP routes. srv.Routes.GET("/", nil, func(c *router.Context) { // ... }) // Install gRPC services. servicepb.RegisterSomeServer(srv, &SomeServer{}) return nil }) }
More examples can be found in the code search: https://source.chromium.org/search?q=%22server.Main%28nil%2C%20modules%2C%22
Known modules ¶
The following modules (in alphabetical order) are a part of the LUCI repository and can be used in any server binary:
- go.chromium.org/luci/config/server/cfgmodule: provides LUCI Config client, exposes config validation endpoints used by LUCI Config service.
- go.chromium.org/luci/server/analytics: generates Google Analytics js snippets for inclusion in a service's web pages.
- go.chromium.org/luci/server/bqlog: implements best effort low-overhead structured logging to BigQuery suitable for debug data like access logs.
- go.chromium.org/luci/server/cron: allows registering Cloud Scheduler (aka Appengine cron.yaml) handlers, with proper authentication and monitoring metrics.
- go.chromium.org/luci/server/encryptedcookies: implements an authentication scheme for HTTP routes based on encrypted cookies and user sessions in some session store.
- go.chromium.org/luci/server/dsmapper: provides a way to apply some function to all datastore entities of some particular kind, in parallel, distributing work via Cloud Tasks.
- go.chromium.org/luci/server/gaeemulation: implements go.chromium.org/luci/gae Datastore interface via Google Cloud Datastore API. Named so because because it enables migration of GAEv1 apps to GAEv2 without touching datastore-related code.
- go.chromium.org/luci/server/gerritauth: implements authentication using Gerrit JWTs. Useful if a service is used by a Gerrit frontend plugin.
- go.chromium.org/luci/server/limiter: a simple load shedding mechanism that puts a limit on a number of concurrent gRPC requests the server is handling.
- go.chromium.org/luci/server/mailer: sending simple emails.
- go.chromium.org/luci/server/redisconn: a Redis client. Also enables Redis as a caching backend for go.chromium.org/luci/server/caching and for go.chromium.org/luci/gae/filter/dscache.
- go.chromium.org/luci/server/secrets: enables generation and validation of HMAC-tagged tokens via go.chromium.org/luci/server/tokens.
- go.chromium.org/luci/server/span: a Cloud Spanner client. Wraps Spanner API a bit to improve interoperability with other modules (in particular the TQ module).
- go.chromium.org/luci/server/tq: implements a task queue mechanism on top of Cloud Tasks and Cloud PubSub. Also implements transactional task enqueuing when submitting tasks in a Cloud Datastore or a Cloud Spanner transaction.
Most of them need to be configured via corresponding CLI flags to be useful. See implementation of individual modules for details.
An up-to-date list of all known module implementations can be found here: https://source.chromium.org/search?q=%22NewModuleFromFlags()%20module.Module%22
gRPC services ¶
The server implements grpc.ServiceRegistrar interface which means it can be used to register gRPC service implementations in. The registered services will be exposed via gRPC protocol over the gRPC port (if the gRPC serving port is configured in options) and via pRPC protocol over the main HTTP port (if the main HTTP serving port is configured in options). The server is also pre-configured with a set of gRPC interceptors that collect performance metrics, catch panics and authenticate requests. More interceptors can be added via RegisterUnaryServerInterceptors.
Security considerations ¶
The expected deployment environments are Kubernetes, Google App Engine and Google Cloud Run. In all cases the server is expected to be behind a load balancer or proxy (or a series of load balancers and proxies) that terminate TLS and set `X-Forwarded-For` and `X-Forwarded-Proto` headers. In particular `X-Forwarded-For` header should look like:
[<untrusted part>,]<IP that connected to the LB>,<unimportant>[,<more>].
Where `<untrusted part>` may be present if the original request from the Internet comes with `X-Forwarded-For` header. The IP specified there is not trusted, but the server assumes the load balancer at least sanitizes the format of this field.
`<IP that connected to the LB>` is the end-client IP that can be used by the server for logs and for IP-allowlist checks.
`<unimportant>` is a "global forwarding rule external IP" for GKE or the constant "169.254.1.1" for GAE and Cloud Run. It is unused. See https://cloud.google.com/load-balancing/docs/https for more info.
`<more>` may be present if the request was proxied through more layers of load balancers while already inside the cluster. The server currently assumes this is not happening (i.e. `<more>` is absent, or, in other words, the client IP is the second to last in the `X-Forwarded-For` list). If you need to recognize more layers of load balancing, please file a feature request to add a CLI flag specifying how many layers of load balancers to skip to get to the original IP.
Index ¶
- func Main(opts *Options, mods []module.Module, init func(srv *Server) error)
- type Options
- type Port
- type PortOptions
- type Server
- func (s *Server) AddPort(opts PortOptions) (*Port, error)
- func (s *Server) ConfigurePRPC(cb func(srv *prpc.Server))
- func (s *Server) Fatal(err error)
- func (s *Server) RegisterCleanup(cb func(context.Context))
- func (s *Server) RegisterService(desc *grpc.ServiceDesc, impl any)
- func (s *Server) RegisterStreamServerInterceptors(intr ...grpc.StreamServerInterceptor)
- func (s *Server) RegisterUnaryServerInterceptors(intr ...grpc.UnaryServerInterceptor)
- func (s *Server) RegisterUnifiedServerInterceptors(intr ...grpcutil.UnifiedServerInterceptor)
- func (s *Server) RegisterWarmup(cb func(context.Context))
- func (s *Server) RunInBackground(activity string, f func(context.Context))
- func (s *Server) Serve() error
- func (s *Server) SetRPCAuthMethods(methods []auth.Method)
- func (s *Server) Shutdown()
- func (s *Server) UserAgent() string
- func (s *Server) VirtualHost(host string) *router.Router
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Main ¶
Main initializes the server and runs its serving loop until SIGTERM.
Registers all options in the default flag set and uses `flag.Parse` to parse them. If 'opts' is nil, the default options will be used. Only flags are allowed in the command line (no positional arguments).
Additionally recognizes GAE_* and K_* env vars as an indicator that the server is running in the corresponding serverless runtime. This slightly tweaks its behavior to match what these runtimes expects from servers.
On errors, logs them and aborts the process with non-zero exit code.
Types ¶
type Options ¶
type Options struct { Prod bool // set when running in production (not on a dev workstation) Serverless module.Serverless // set when running in a serverless environment, implies Prod Hostname string // used for logging and metric fields, default is os.Hostname HTTPAddr string // address to bind the main listening socket to GRPCAddr string // address to bind the gRPC listening socket to AdminAddr string // address to bind the admin socket to, ignored on GAE and Cloud Run AllowH2C bool // if true, allow HTTP/2 Cleartext traffic on non-gRPC HTTP ports DefaultRequestTimeout time.Duration // how long non-internal HTTP handlers are allowed to run, 1 min by default InternalRequestTimeout time.Duration // how long "/internal/*" HTTP handlers are allowed to run, 10 min by default ShutdownDelay time.Duration // how long to wait after SIGTERM before shutting down ClientAuth clientauth.Options // base settings for client auth options TokenCacheDir string // where to cache auth tokens (optional) AuthDBProvider auth.DBProvider // source of the AuthDB: if set all Auth* options below are ignored AuthDBPath string // if set, load AuthDB from a file AuthServiceHost string // hostname of an Auth Service to use AuthDBDump string // Google Storage path to fetch AuthDB dumps from AuthDBSigner string // service account that signs AuthDB dumps FrontendClientID string // OAuth2 ClientID for frontend (e.g. user sign in) FrontendOAuthScopes stringlistflag.Flag // OAuth2 Scopes for frontend (e.g. user sign in) OpenIDRPCAuthEnable bool // if true, use OIDC identity tokens for RPC authentication OpenIDRPCAuthAudience stringlistflag.Flag // additional allowed OIDC token audiences CloudProject string // name of the hosting Google Cloud Project CloudRegion string // name of the hosting Google Cloud region TraceSampling string // what portion of traces to upload to Cloud Trace (ignored on GAE and Cloud Run) TsMonAccount string // service account to flush metrics as TsMonServiceName string // service name of tsmon target TsMonJobName string // job name of tsmon target TsMonFlushInterval time.Duration // how often to flush metrics TsMonFlushTimeout time.Duration // timeout for flushing ProfilingProbability float64 // an [0; 1.0] float with a chance to enable Cloud Profiler in the process ProfilingServiceID string // service name to associated with profiles in Cloud Profiler ContainerImageID string // ID of the container image with this binary, for logs (optional) EnableExperiments []string // names of go.chromium.org/luci/server/experiments to enable CloudErrorReporting bool // set to true to enable Cloud Error Reporting // contains filtered or unexported fields }
Options are used to configure the server.
Most of them are exposed as command line flags (see Register implementation). Some (specific to serverless runtimes) are only settable through code or are derived from the environment.
func OptionsFromEnv ¶
OptionsFromEnv prepopulates options based on the runtime environment.
It detects if the process is running on GAE or Cloud Run and adjust options accordingly. See FromGAEEnv and FromCloudRunEnv for exact details of how it happens.
Either mutates give `opts`, returning it in the end, or (if `opts` is nil) create new Options.
func (*Options) FromCloudRunEnv ¶
FromCloudRunEnv recognized K_SERVICE environment variable and configures some options based on what it discovers in the environment.
Does nothing if K_SERVICE is not set.
Equivalent to passing the following flags:
-prod -http-addr - -grpc-addr - -admin-addr - -allow-h2c -shutdown-delay 1s -cloud-project <cloud project Cloud Run container is running in> -cloud-region <cloud region Cloud Run container is running in> -service-account-json :gce -open-id-rpc-auth-enable -ts-mon-service-name <cloud project Cloud Run container is running in> -ts-mon-job-name ${K_SERVICE}
Flags passed via the actual command line in the Cloud Run manifest override these prefilled defaults. In particular pass either `-http-addr` or `-grpc-addr` (or both) to enable corresponding ports.
Additionally the hostname (used in metric and trace fields) is derived from environment to be semantically similar to what it looks like in the GKE environment.
func (*Options) FromGAEEnv ¶
func (o *Options) FromGAEEnv()
FromGAEEnv uses the GAE_* env vars to configure the server for the GAE environment.
Does nothing if GAE_VERSION is not set.
Equivalent to passing the following flags:
-prod -http-addr 0.0.0.0:${PORT} -admin-addr - -shutdown-delay 1s -cloud-project ${GOOGLE_CLOUD_PROJECT} -cloud-region <derived from the region code in GAE_APPLICATION> -service-account-json :gce -ts-mon-service-name ${GOOGLE_CLOUD_PROJECT} -ts-mon-job-name ${GAE_SERVICE}
Additionally the hostname and -container-image-id (used in metric and trace fields) are derived from available GAE_* env vars to be semantically similar to what they represent in the GKE environment.
Note that a mapping between a region code in GAE_APPLICATION and the corresponding cloud region is not documented anywhere, so if you see warnings when your app starts up either update the code to recognize your region code or pass '-cloud-region' argument explicitly in app.yaml.
See https://cloud.google.com/appengine/docs/standard/go/runtime.
func (*Options) ImageName ¶
ImageName extracts image name from ContainerImageID.
This is the part of ContainerImageID before ':' or '@'.
func (*Options) ImageVersion ¶
ImageVersion extracts image tag or digest from ContainerImageID.
This is eventually reported as a value of 'server/version' metric.
On GAE it would return the service version name based on GAE_VERSION env var, since ContainerImageID is artificially constructed to look like "appengine/${CLOUD_PROJECT}/${GAE_SERVICE}:${GAE_VERSION}".
On Cloud Run it is responsibility of the deployment layer to correctly populate -container-image-id command line flag.
Returns "unknown" if ContainerImageID is empty or malformed.
type Port ¶
type Port struct { // Routes is a router for requests hitting this port. // // This router is used for all requests whose Host header does not match any // specially registered per-host routers (see VirtualHost). Normally, there // are no such per-host routers, so usually Routes is used for all requests. // // Should be populated before Server's Serve loop. Routes *router.Router // contains filtered or unexported fields }
Port is returned by Server's AddPort and used to setup the request routing.
It represents an HTTP port with a request router.
func (*Port) VirtualHost ¶
VirtualHost returns a router (registering it if necessary) used for requests that have the given Host header.
Note that requests that match some registered virtual host router won't reach the default router (port.Routes), even if the virtual host router doesn't have a route for them. Such requests finish with HTTP 404.
Should be called before Server's Serve loop (panics otherwise).
type PortOptions ¶
type PortOptions struct { Name string // optional logical name of the port for logs ListenAddr string // local address to bind to or "-" for a dummy port Listener net.Listener // already bound listener to use instead of ListenAddr (optional) DisableMetrics bool // do not collect HTTP metrics for requests on this port }
PortOptions is a configuration of a single serving HTTP port.
See Server's AddPort.
type Server ¶
type Server struct { // Context is the root context used by all requests and background activities. // // Can be replaced (by a derived context) before Serve call, for example to // inject values accessible to all request handlers. Context context.Context // Routes is a router for requests hitting HTTPAddr port. // // This router is used for all requests whose Host header does not match any // specially registered per-host routers (see VirtualHost). Normally, there // are no such per-host routers, so usually Routes is used for all requests. // // This router is also accessible to the server modules and they can install // routes into it. // // Should be populated before Serve call. Routes *router.Router // CookieAuth is an authentication method implemented via cookies. // // It is initialized only if the server has a module implementing such scheme // (e.g. "go.chromium.org/luci/server/encryptedcookies"). CookieAuth auth.Method // Options is a copy of options passed to New. Options Options // contains filtered or unexported fields }
Server is responsible for initializing and launching the serving environment.
Generally assumed to be a singleton: do not launch multiple Server instances within the same process, use AddPort instead if you want to expose multiple HTTP ports with different routers.
Server can serve plain HTTP endpoints, routing them trough a router.Router, and gRPC APIs (exposing them over gRPC and pRPC protocols). Use an instance of Server as a grpc.ServiceRegistrar when registering gRPC services. Services registered that way will be available via gRPC protocol over the gRPC port and via pRPC protocol over the main HTTP port. Interceptors can be added via RegisterUnaryServerInterceptors. RPC authentication can be configured via SetRPCAuthMethods.
pRPC protocol is served on the same port as the main HTTP router, making it possible to expose just a single HTTP port for everything (which is a requirement on Appengine).
Native gRPC protocol is always served though a dedicated gRPC h2c port since the gRPC library has its own HTTP/2 server implementation not compatible with net/http package used everywhere else. There's an assortments of hacks to workaround this, but many ultimately depend on experimental and slow grpc.Server.ServeHTTP method. See https://github.com/grpc/grpc-go/issues/586 and https://github.com/grpc/grpc-go/issues/4620. Another often recommended workaround is https://github.com/soheilhy/cmux, which decides if a new connection is a gRPC one or a regular HTTP/2 one. It doesn't work when the server is running behind a load balancer that understand HTTP/2, since it just opens a **single** backend connection and sends both gRPC and regular HTTP/2 requests over it. This happens on Cloud Run, for example. See e.g. https://ahmet.im/blog/grpc-http-mux-go/.
If you want to serve HTTP and gRPC over the same public port, configure your HTTP load balancer (e.g. https://cloud.google.com/load-balancing/docs/https) to route requests into appropriate containers and ports. Another alternative is to put an HTTP/2 proxy (e.g. Envoy) right into the pod with the server process and route traffic "locally" there. This option would also allow to add local grpc-web proxy into the mix if necessary.
The server doesn't do TLS termination (even for gRPC traffic). It must be sitting behind a load balancer or a proxy that terminates TLS and sends clear text (HTTP/1 or HTTP/2 for gRPC) requests to corresponding ports, injecting `X-Forwarded-*` headers. See "Security considerations" section above for more details.
func New ¶
New constructs a new server instance.
It hosts one or more HTTP servers and starts and stops them in unison. It is also responsible for preparing contexts for incoming requests.
The given context will become the root context of the server and will be inherited by all handlers.
On errors returns partially initialized server (always non-nil). At least its logging will be configured and can be used to report the error. Trying to use such partially initialized server for anything else is undefined behavior.
func (*Server) AddPort ¶
func (s *Server) AddPort(opts PortOptions) (*Port, error)
AddPort prepares and binds an additional serving HTTP port.
Can be used to open more listening HTTP ports (in addition to opts.HTTPAddr and opts.AdminAddr). The returned Port object can be used to populate the router that serves requests hitting the added port.
If opts.ListenAddr is empty or literal '-', a dummy port will be added: it is a valid *Port object, but it is not actually exposed as a listening TCP socket. This is useful to disable listening ports without changing any other code (like the code that populates routes).
If opts.Listener is not nil, it will be used instead of a new TCP listener. In that case opts.ListenAddr is completely ignored (even if it is '-' or empty).
Must be called before Serve (panics otherwise).
func (*Server) ConfigurePRPC ¶
ConfigurePRPC allows tweaking pRPC-specific server configuration.
Use it only for changing pRPC-specific options (usually ones that are related to HTTP protocol in some way). This method **must not be used** for registering interceptors or setting authentication options (changes to them done here will cause a panic). Instead use RegisterUnaryServerInterceptors to register interceptors or SetRPCAuthMethods to change how the server authenticates RPC requests. Changes done through these methods will apply to both gRPC and pRPC servers.
Must be called before Serve (panics otherwise).
func (*Server) Fatal ¶
Fatal logs the error and immediately shuts down the process with exit code 3.
No cleanup is performed. Deferred statements are not run. Not recoverable.
func (*Server) RegisterCleanup ¶
RegisterCleanup registers a callback that is run in Serve after the server has exited the serving loop.
Registering a new cleanup callback from within a cleanup causes a deadlock, don't do that.
func (*Server) RegisterService ¶
func (s *Server) RegisterService(desc *grpc.ServiceDesc, impl any)
RegisterService is part of grpc.ServiceRegistrar interface.
The registered service will be exposed through both gRPC and pRPC protocols on corresponding ports. See Server doc.
Must be called before Serve (panics otherwise).
func (*Server) RegisterStreamServerInterceptors ¶
func (s *Server) RegisterStreamServerInterceptors(intr ...grpc.StreamServerInterceptor)
RegisterStreamServerInterceptors registers grpc.StreamServerInterceptor's applied to all streaming RPCs that hit the server.
Interceptors are chained in order they are registered, i.e. the first registered interceptor becomes the outermost. The initial chain already contains some base interceptors (e.g. for monitoring) and all interceptors registered by server modules. RegisterStreamServerInterceptors extends this chain. Subsequent calls to RegisterStreamServerInterceptors adds more interceptors into the chain.
Must be called before Serve (panics otherwise).
func (*Server) RegisterUnaryServerInterceptors ¶
func (s *Server) RegisterUnaryServerInterceptors(intr ...grpc.UnaryServerInterceptor)
RegisterUnaryServerInterceptors registers grpc.UnaryServerInterceptor's applied to all unary RPCs that hit the server.
Interceptors are chained in order they are registered, i.e. the first registered interceptor becomes the outermost. The initial chain already contains some base interceptors (e.g. for monitoring) and all interceptors registered by server modules. RegisterUnaryServerInterceptors extends this chain. Subsequent calls to RegisterUnaryServerInterceptors adds more interceptors into the chain.
Must be called before Serve (panics otherwise).
func (*Server) RegisterUnifiedServerInterceptors ¶
func (s *Server) RegisterUnifiedServerInterceptors(intr ...grpcutil.UnifiedServerInterceptor)
RegisterUnifiedServerInterceptors registers given interceptors into both unary and stream interceptor chains.
It is just a convenience helper for UnifiedServerInterceptor's that usually need to be registered in both unary and stream interceptor chains. This method is equivalent to calling RegisterUnaryServerInterceptors and RegisterStreamServerInterceptors, passing corresponding flavors of interceptors to them.
Must be called before Serve (panics otherwise).
func (*Server) RegisterWarmup ¶
RegisterWarmup registers a callback that is run in server's Serve right before the serving loop.
It receives the global server context (including all customizations made by the user code in server.Main). Intended for best-effort warmups: there's no way to gracefully abort the server startup from a warmup callback.
Registering a new warmup callback from within a warmup causes a deadlock, don't do that.
func (*Server) RunInBackground ¶
RunInBackground launches the given callback in a separate goroutine right before starting the serving loop.
If the server is already running, launches it right away. If the server fails to start, the goroutines will never be launched.
Should be used for background asynchronous activities like reloading configs.
All logs lines emitted by the callback are annotated with "activity" field which can be arbitrary, but by convention has format "<namespace>.<name>", where "luci" namespace is reserved for internal activities.
The context passed to the callback is canceled when the server is shutting down. It is expected the goroutine will exit soon after the context is canceled.
func (*Server) Serve ¶
Serve launches the serving loop.
Blocks forever or until the server is stopped via Shutdown (from another goroutine or from a SIGTERM handler). Returns nil if the server was shutdown correctly or an error if it failed to start or unexpectedly died. The error is logged inside.
Should be called only once. Panics otherwise.
func (*Server) SetRPCAuthMethods ¶
SetRPCAuthMethods overrides how the server authenticates incoming gRPC and pRPC requests.
It receives a list of auth.Method implementations which will be applied one after another to try to authenticate the request until the first successful hit. If all methods end up to be non-applicable (i.e. none of the methods notice any headers they recognize), the request will be passed through to the handler as anonymous (coming from an "anonymous identity"). Rejecting anonymous requests (if necessary) is the job of an authorization layer, often implemented as a gRPC interceptor. For simple cases use go.chromium.org/luci/server/auth/rpcacl interceptor.
By default (if SetRPCAuthMethods is never called) the server will check incoming requests have an `Authorization` header with a Google OAuth2 access token that has `https://www.googleapis.com/auth/userinfo.email` scope (see auth.GoogleOAuth2Method). Requests without `Authorization` header will be considered anonymous.
If OpenIDRPCAuthEnable option is set (matching `-open-id-rpc-auth-enable` flag), the service will recognize ID tokens as well. This is important for e.g. Cloud Run where this is the only authentication method supported natively by the platform. ID tokens are also generally faster to check than access tokens.
Note that this call completely overrides the previously configured list of methods instead of appending to it, since chaining auth methods is often tricky and it is safer to just always provide the whole list at once.
Passing an empty list of methods is allowed. All requests will be considered anonymous in that case.
Note that this call **doesn't affect** how plain HTTP requests (hitting the main HTTP port and routed through s.Router) are authenticated. Very often RPC requests and plain HTTP requests need different authentication methods and using an RPC authentication for everything is incorrect. To authenticate plain HTTP requests use auth.Authenticate(...) HTTP router middleware, perhaps in combination with s.CookieAuth (which is non-nil if there is a server module installed that provides a cookie-based authentication scheme).
Must be called before Serve (panics otherwise).
func (*Server) Shutdown ¶
func (s *Server) Shutdown()
Shutdown gracefully stops the server if it was running.
Blocks until the server is stopped. Can be called multiple times.
func (*Server) UserAgent ¶
UserAgent can be put into "User-Agent" header when calling other servers.
It includes some public details about the server (like its name and version). Placing them into "User-Agent" header is useful since it is exposed in the logs of the server being called. It allows to identify at a glance what software is making calls. This is similar to how e.g. "curl" places its version into "User-Agent" header.
Note that HTTP clients obtained through go.chromium.org/luci/server/auth are already setup to report this header. Thus this method is primarily useful for manually constructed http.Client and for gRPC clients.
func (*Server) VirtualHost ¶
VirtualHost returns a router (registering it if necessary) used for requests that hit the main port (opts.HTTPAddr) and have the given Host header.
Should be used in rare cases when the server is exposed through multiple domain names and requests should be routed differently based on what domain was used. If your server is serving only one domain name, or you don't care what domain name is used to access it, do not use VirtualHost.
Note that requests that match some registered virtual host router won't reach the default router (server.Routes), even if the virtual host router doesn't have a route for them. Such requests finish with HTTP 404.
Also the router created by VirtualHost is initially completely empty: the server and its modules don't install anything into it (there's intentionally no mechanism to do this). For that reason VirtualHost should never by used to register a router for the "main" domain name: it will make the default server.Routes (and all handlers installed there by server modules) useless, probably breaking the server. Put routes for the main server functionality directly into server.Routes instead, using VirtualHost only for routes that critically depend on Host header.
Must be called before Serve (panics otherwise).
Directories ¶
Path | Synopsis |
---|---|
Package analytics provides a way to generate google analytics snippets.
|
Package analytics provides a way to generate google analytics snippets. |
Package auth implements authentication and authorization framework for HTTP servers.
|
Package auth implements authentication and authorization framework for HTTP servers. |
authdb
Package authdb contains definition of Authentication Database (aka AuthDB).
|
Package authdb contains definition of Authentication Database (aka AuthDB). |
authdb/dump
Package dump implements loading AuthDB from dumps in Google Storage.
|
Package dump implements loading AuthDB from dumps in Google Storage. |
authdb/internal/certs
Package certs knows how to fetch certificate bundles of trusted services.
|
Package certs knows how to fetch certificate bundles of trusted services. |
authdb/internal/conds
Package conds contains supporting code for conditional bindings.
|
Package conds contains supporting code for conditional bindings. |
authdb/internal/globset
Package globset preprocesses []identity.Glob for faster querying.
|
Package globset preprocesses []identity.Glob for faster querying. |
authdb/internal/graph
Package graph implements handling of the groups graph.
|
Package graph implements handling of the groups graph. |
authdb/internal/ipaddr
Package ipaddr implements IP allowlist check.
|
Package ipaddr implements IP allowlist check. |
authdb/internal/legacy
Package legacy contains older implementation of IsMember check.
|
Package legacy contains older implementation of IsMember check. |
authdb/internal/oauthid
Package oauthid implements OAuth client ID allowlist check.
|
Package oauthid implements OAuth client ID allowlist check. |
authdb/internal/realmset
Package realmset provides queryable representation of LUCI Realms DB.
|
Package realmset provides queryable representation of LUCI Realms DB. |
authdb/internal/seccfg
Package seccfg interprets SecurityConfig proto message.
|
Package seccfg interprets SecurityConfig proto message. |
authtest
Package authtest implements some interfaces used by auth package to simplify unit testing.
|
Package authtest implements some interfaces used by auth package to simplify unit testing. |
delegation
Package delegation contains low-level API for working with delegation tokens.
|
Package delegation contains low-level API for working with delegation tokens. |
deprecated
Package deprecated contains code that should not be used in new applications.
|
Package deprecated contains code that should not be used in new applications. |
iap
Package iap implements auth.Method for GCP's Identity Aware Proxy.
|
Package iap implements auth.Method for GCP's Identity Aware Proxy. |
internal
Package internal contains internal functions used by server/auth package.
|
Package internal contains internal functions used by server/auth package. |
internal/tracing
Package tracing contains helper for reporting OpenTelemetry tracing spans.
|
Package tracing contains helper for reporting OpenTelemetry tracing spans. |
openid
Package openid contains functionality related to OpenID Connect protocol.
|
Package openid contains functionality related to OpenID Connect protocol. |
realms
Package realms contains functionality related to LUCI Realms.
|
Package realms contains functionality related to LUCI Realms. |
rpcacl
Package rpcacl implements a gRPC interceptor that checks per-RPC ACLs.
|
Package rpcacl implements a gRPC interceptor that checks per-RPC ACLs. |
service
Package service implements a wrapper around API exposed by auth_service: https://github.com/luci/luci-py/tree/master/appengine/auth_service
|
Package service implements a wrapper around API exposed by auth_service: https://github.com/luci/luci-py/tree/master/appengine/auth_service |
service/protocol
Package protocol defines the data structures used in AuthDB replication.
|
Package protocol defines the data structures used in AuthDB replication. |
signing
Package signing provides interfaces to sign arbitrary small blobs with RSA-SHA256 signature (PKCS1v15) and verify such signatures.
|
Package signing provides interfaces to sign arbitrary small blobs with RSA-SHA256 signature (PKCS1v15) and verify such signatures. |
signing/signingtest
Package signingtest implements signing.Signer interface using small random keys.
|
Package signingtest implements signing.Signer interface using small random keys. |
xsrf
Package xsrf provides Cross Site Request Forgery prevention middleware.
|
Package xsrf provides Cross Site Request Forgery prevention middleware. |
Package bqlog implements best effort low-overhead structured logging to BigQuery.
|
Package bqlog implements best effort low-overhead structured logging to BigQuery. |
Package caching implements common server object caches.
|
Package caching implements common server object caches. |
cachingtest
Package cachingtest contains helpers for testing code that uses caching package.
|
Package cachingtest contains helpers for testing code that uses caching package. |
layered
Package layered provides a two-layer cache for serializable objects.
|
Package layered provides a two-layer cache for serializable objects. |
cmd
|
|
cookieserver
Executable cookieserver is a LUCI Server that hosts encryptedcookies module using Cloud Datastore as the session storage backend.
|
Executable cookieserver is a LUCI Server that hosts encryptedcookies module using Cloud Datastore as the session storage backend. |
datastore-delete
Executable datastore-delete deletes all data of a specified kind in a Datastore database.
|
Executable datastore-delete deletes all data of a specified kind in a Datastore database. |
encryptedcookies-session-backfill
Executable encryptedcookies-session-backfill backfills ExpireAt field in session datastore entities used by encryptedcookies module.
|
Executable encryptedcookies-session-backfill backfills ExpireAt field in session datastore entities used by encryptedcookies module. |
secret-tool
Executable secret-tool allows to generate and rotate secrets stored in Google Secret Manager and consumed by go.chromium.org/luci/server/secrets module.
|
Executable secret-tool allows to generate and rotate secrets stored in Google Secret Manager and consumed by go.chromium.org/luci/server/secrets module. |
selfsigned-cert
Executable selfsigned-cert generates a self-signed TLS certificate.
|
Executable selfsigned-cert generates a self-signed TLS certificate. |
statsd-to-tsmon
Executable statsd-to-tsmon implements a statsd sink that sends aggregated metrics to tsmon.
|
Executable statsd-to-tsmon implements a statsd sink that sends aggregated metrics to tsmon. |
tq-sweeper-spanner
Executable tq-sweeper-spanner runs an inproc sweeping driver that scans Spanner database for TQ transactional tasks reminders.
|
Executable tq-sweeper-spanner runs an inproc sweeping driver that scans Spanner database for TQ transactional tasks reminders. |
Package cron allows to register handlers called by Cloud Scheduler.
|
Package cron allows to register handlers called by Cloud Scheduler. |
Package dsmapper implements a simple Datastore mapper.
|
Package dsmapper implements a simple Datastore mapper. |
dsmapperlite
Package dsmapperlite implements an in-process datastore mapper.
|
Package dsmapperlite implements an in-process datastore mapper. |
internal/splitter
Package splitter implements SplitIntoRanges function useful when splitting large datastore queries into a bunch of smaller queries with approximately evenly-sized result sets.
|
Package splitter implements SplitIntoRanges function useful when splitting large datastore queries into a bunch of smaller queries with approximately evenly-sized result sets. |
internal/tasks
Package tasks contains definition of task queue tasks used by the mapper.
|
Package tasks contains definition of task queue tasks used by the mapper. |
Package encryptedcookies implements authentication using encrypted cookies.
|
Package encryptedcookies implements authentication using encrypted cookies. |
internal/fakecookies
Package fakecookies implements a cookie-based fake authentication method.
|
Package fakecookies implements a cookie-based fake authentication method. |
session
Package session defines API for the session storage.
|
Package session defines API for the session storage. |
session/datastore
Package datastore implements session storage over Cloud Datastore.
|
Package datastore implements session storage over Cloud Datastore. |
Package experiments allow servers to use experimental code paths.
|
Package experiments allow servers to use experimental code paths. |
Package gaeemulation provides a server module that adds implementation of some https://godoc.org/go.chromium.org/luci/gae APIs to the global server context.
|
Package gaeemulation provides a server module that adds implementation of some https://godoc.org/go.chromium.org/luci/gae APIs to the global server context. |
Package gerritauth implements authentication using Gerrit JWTs.
|
Package gerritauth implements authentication using Gerrit JWTs. |
Package internal is supporting code used by server.go.
|
Package internal is supporting code used by server.go. |
gae
Package gae implements minimal support for using some bundled GAE APIs.
|
Package gae implements minimal support for using some bundled GAE APIs. |
testpb
Package testpb contains protobufs used by server's unit tests.
|
Package testpb contains protobufs used by server's unit tests. |
Package limiter implements load shedding for servers.
|
Package limiter implements load shedding for servers. |
Package loginsessions implements Login Sessions backend that is used to perform interactive logins in LUCI CLI tools.
|
Package loginsessions implements Login Sessions backend that is used to perform interactive logins in LUCI CLI tools. |
internal
Package internal contains implementation details of loginsessions module.
|
Package internal contains implementation details of loginsessions module. |
internal/assets
Package assets is generated by go.chromium.org/luci/tools/cmd/assets.
|
Package assets is generated by go.chromium.org/luci/tools/cmd/assets. |
internal/statepb
Package statepb contains protos used internally by loginsessions.
|
Package statepb contains protos used internally by loginsessions. |
Package mailer can be used to send mails through a mailer service.
|
Package mailer can be used to send mails through a mailer service. |
Package middleware contains some basic middlewares.
|
Package middleware contains some basic middlewares. |
Package module defines a framework for extending server.Server with optional reusable bundles of functionality (called "modules", naturally).
|
Package module defines a framework for extending server.Server with optional reusable bundles of functionality (called "modules", naturally). |
Package portal implements HTTP routes for portal pages.
|
Package portal implements HTTP routes for portal pages. |
internal/assets
Package assets is generated by go.chromium.org/luci/tools/cmd/assets.
|
Package assets is generated by go.chromium.org/luci/tools/cmd/assets. |
Package pprof is similar to net/http/pprof, except it supports auth.
|
Package pprof is similar to net/http/pprof, except it supports auth. |
Package pubsub allows to register handlers called by Cloud Pub/Sub.
|
Package pubsub allows to register handlers called by Cloud Pub/Sub. |
Package quota provides an implementation for server quotas which are backed by Redis.
|
Package quota provides an implementation for server quotas which are backed by Redis. |
examples/ratelimit
Package main contains a binary demonstrating how to use the server/quota module to implement rate limiting for requests.
|
Package main contains a binary demonstrating how to use the server/quota module to implement rate limiting for requests. |
internal/datatool
Datatool is a program which allows you to encode/decode quotapb protobuf messages to/from a variety of codecs.
|
Datatool is a program which allows you to encode/decode quotapb protobuf messages to/from a variety of codecs. |
internal/lua
Package lua is generated by go.chromium.org/luci/tools/cmd/assets.
|
Package lua is generated by go.chromium.org/luci/tools/cmd/assets. |
internal/quotakeys
Package quotakeys has utility functions for generating internal quota Redis keys.
|
Package quotakeys has utility functions for generating internal quota Redis keys. |
quotapb
Package quotapb exports proto definitions required by the quota library.
|
Package quotapb exports proto definitions required by the quota library. |
quotatestmonkeypatch
Package quotatestmonkeypatch should be imported for its side-effects in tests.
|
Package quotatestmonkeypatch should be imported for its side-effects in tests. |
Package quota provides a LUCI Quota Library implementation.
|
Package quota provides a LUCI Quota Library implementation. |
examples/ratelimit
Package main contains a binary demonstrating how to use the server/quota module to implement rate limiting for requests.
|
Package main contains a binary demonstrating how to use the server/quota module to implement rate limiting for requests. |
proto
Package proto exports proto definitions required by the quota library.
|
Package proto exports proto definitions required by the quota library. |
quotaconfig
Package quotaconfig exports the interface required by the quota library to read *pb.Policy configs.
|
Package quotaconfig exports the interface required by the quota library to read *pb.Policy configs. |
quotaconfig/configservice
Package configservice provides an implementation of quotaconfig.Interface which fetches *pb.Policy configs stored with the LUCI Config service.
|
Package configservice provides an implementation of quotaconfig.Interface which fetches *pb.Policy configs stored with the LUCI Config service. |
Package redisconn implements integration with a Redis connection pool.
|
Package redisconn implements integration with a Redis connection pool. |
adminpb
Package adminpb contains API with Redis-related administrative endpoints.
|
Package adminpb contains API with Redis-related administrative endpoints. |
Package router provides an HTTP router.
|
Package router provides an HTTP router. |
Package secrets provides a secrets store based on Google Secret Manager.
|
Package secrets provides a secrets store based on Google Secret Manager. |
testsecrets
Package testsecrets provides a dumb in-memory secret store to use in unit tests.
|
Package testsecrets provides a dumb in-memory secret store to use in unit tests. |
Package servertest contains helpers for running server integration tests.
|
Package servertest contains helpers for running server integration tests. |
Package settings implements storage for infrequently changing global settings.
|
Package settings implements storage for infrequently changing global settings. |
Package span implements a server module for communicating with Cloud Spanner.
|
Package span implements a server module for communicating with Cloud Spanner. |
Package templates implements wrapper around html/template to provide lazy loading of templates and better integration with HTTP middleware framework.
|
Package templates implements wrapper around html/template to provide lazy loading of templates and better integration with HTTP middleware framework. |
Package tokens provides means to generate and validate base64 encoded tokens compatible with luci-py's components.auth implementation.
|
Package tokens provides means to generate and validate base64 encoded tokens compatible with luci-py's components.auth implementation. |
Package tq provides a task queue implementation on top of Cloud Tasks.
|
Package tq provides a task queue implementation on top of Cloud Tasks. |
internal/db
Package db defines common database interface.
|
Package db defines common database interface. |
internal/lessor
Package lessor defines common lessor interface.
|
Package lessor defines common lessor interface. |
internal/loopbacktest
Package loopbacktest is an integration test for TQ loopback dispatcher.
|
Package loopbacktest is an integration test for TQ loopback dispatcher. |
internal/metrics
Package metrics contains definition of metrics exposed by server/tq.
|
Package metrics contains definition of metrics exposed by server/tq. |
internal/partition
Package partition encapsulates partitioning and querying large keyspace which can't be expressed even as uint64.
|
Package partition encapsulates partitioning and querying large keyspace which can't be expressed even as uint64. |
internal/reminder
Package reminder holds Reminder to avoid circular dependencies.
|
Package reminder holds Reminder to avoid circular dependencies. |
internal/testutil
Package testutil provides fakes for testing TQ guts.
|
Package testutil provides fakes for testing TQ guts. |
internal/workset
Package workset contains a synchronized work queue implementation used by inproc sweeper.
|
Package workset contains a synchronized work queue implementation used by inproc sweeper. |
tqtesting
Package tqtesting contains helpers for running server/tq in tests and on localhost.
|
Package tqtesting contains helpers for running server/tq in tests and on localhost. |
txn/datastore
Datastore contains Transactional Enqueue support for Cloud Datastore.
|
Datastore contains Transactional Enqueue support for Cloud Datastore. |
txn/spanner
Spanner contains Transactional Enqueue support for Cloud Spanner.
|
Spanner contains Transactional Enqueue support for Cloud Spanner. |
Package tsmon adapts common/tsmon library to a server-side environment.
|
Package tsmon adapts common/tsmon library to a server-side environment. |
Package warmup allows to register hooks executed during the server warmup.
|
Package warmup allows to register hooks executed during the server warmup. |