handler

package
v0.20.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 12, 2026 License: Apache-2.0 Imports: 32 Imported by: 0

Documentation

Overview

Package handler provides a client and handlers for responding to locate requests.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Client

type Client struct {
	Signer

	LocatorV2
	ClientLocator
	PrometheusClient
	// contains filtered or unexported fields
}

Client handles HTTP requests for the locate service, including nearest server lookups, heartbeat processing, and monitoring endpoints. It maintains dependencies for geolocation, rate limiting, access token signing, and metrics collection. TODO: This should probably be a Handler, not a Client.

func NewClient

func NewClient(project string, private Signer, locatorV2 LocatorV2, client ClientLocator,
	promClient PrometheusClient, lmts limits.Agents, tierLmts limits.TierLimits, limiter TierLimiter, earlyExitClients []string, jwtVerifier Verifier) *Client

NewClient creates a new client.

func (*Client) Heartbeat

func (c *Client) Heartbeat(rw http.ResponseWriter, req *http.Request)

Heartbeat implements /v2/platform/heartbeat requests. It starts a new persistent connection and a new goroutine to read incoming messages. This endpoint is protected by API key authentication.

func (*Client) HeartbeatJWT added in v0.18.0

func (c *Client) HeartbeatJWT(rw http.ResponseWriter, req *http.Request)

HeartbeatJWT implements /v2/platform/heartbeat-jwt requests. It starts a new persistent connection and a new goroutine to read incoming messages. This endpoint is protected by JWT authentication with organization validation.

func (*Client) Live added in v0.14.10

func (c *Client) Live(rw http.ResponseWriter, req *http.Request)

Live is a minimal handler to indicate that the server is operating at all.

func (*Client) MLabNSCompat added in v0.20.0

func (c *Client) MLabNSCompat(rw http.ResponseWriter, outerReq *http.Request)

MLabNSCompat handles mlab-ns `/ndt` and returns a compatible response.

Motivation

According to https://www.measurementlab.net/blog/retiring-ndt5-raw/ ndt5 should have discontinued in January, 2024 along with mlab-ns. However, for technical reasons, there are still known mlab-ns integrators that needs a minimal amount of mlab-ns backward compatibility to finish their migrations.

What they specifically need is for these URLs:

https://mlab-ns.appspot.com/ndt?format=json&policy=metro&metro={metro}
https://mlab-ns.appspot.com/ndt?format=json

to return a correctly formatted response refererring to ndt7 servers on either the bare-metal or the auto-joined platform.

Traffic from mlab-ns.appspot.com is routed to locate via dispatch.yaml.

Implementation

We accept without erroring out the following query parameters:

  1. format="" and format="json"
  2. policy="", policy="geo", and policy="metro"
  3. metro with any non-empty value

However, the policy="metro" is silently ignored and remapped to the "geo" policy. This is acceptable because the only requirement is that the output does not break existing clients.

The returned status code is as follows:

  1. http.StatusNotImplemented if the method is not GET.
  2. http.StatusBadRequet if we do not support the URL options.
  3. http.StatusBadGateway if the inner call to `/v2/nearest/ndt/ndt7` fails.
  4. http.StatusNoContent if no servers are available.
  5. http.StatusOK on success.

On success, we return the following JSON structure:

{
  "city": "",
  "country": "",
  "fqdn": "",
  "ip": ["127.0.0.1", "::1"],
  "site": "",
  "url": "",
}

where:

  • "city" is set to the *actual* city of the ndt7 server.
  • "country" is set to the *actual* country of the ndt7 server.
  • "fqdn" is set to the *actual* hostname of the ndt7 server.
  • "ip" is set to contain specific sentinel values.
  • "site" is set to the *actual* site of the ndt7 server.
  • "url" is set to the *actual* HTTPS URL of the ndt7 server.

This output response has been constructed to avoid breaking parsing of the existing consumer who need the output for documentational purposes.

CAVEAT: the returned URL is not actionable to run ndt7 tests.

Metrics

This handler emits metrics.RequestsTotal with type="mlabns". Because the implementation internally calls *Client.Nearest via httptest.NewRecorder, the inner call also emits its own "nearest" metrics. Therefore, each successful mlab-ns compat request produces two metrics.RequestsTotal increments: one for "mlabns" and one for "nearest". This double-counting is intentional: it allows monitoring mlab-ns compat traffic independently while the "nearest" counter reflects the actual load on that code path.

Impact

This API endpoint implements the required functionality and effectively cripples all the other existing users of mlab-ns and ndt5. This is completely fine since the support has been extended for two years beyond EOL.

Removal

TODO(https://github.com/m-lab/locate/issues/185): this endpoint should not be removed until the affected integrators confirm that it is fine.

func (*Client) Monitoring

func (c *Client) Monitoring(rw http.ResponseWriter, req *http.Request)

Monitoring issues access tokens for end to end monitoring requests.

func (*Client) Nearest added in v0.11.0

func (c *Client) Nearest(rw http.ResponseWriter, req *http.Request)

Nearest uses an implementation of the LocatorV2 interface to look up nearest servers.

func (*Client) PriorityNearest added in v0.19.0

func (c *Client) PriorityNearest(rw http.ResponseWriter, req *http.Request)

PriorityNearest handles requests to /v2/priority/nearest with tier-based rate limiting. It requires a valid integration JWT with an int_id claim. Requests without valid credentials receive a 401 Unauthorized response.

func (*Client) Prometheus added in v0.13.0

func (c *Client) Prometheus(rw http.ResponseWriter, req *http.Request)

Prometheus is a handler that collects Prometheus health signals.

func (*Client) Ready added in v0.14.10

func (c *Client) Ready(rw http.ResponseWriter, req *http.Request)

Ready reports whether the server is working as expected and ready to serve requests.

func (*Client) Registrations added in v0.16.0

func (c *Client) Registrations(rw http.ResponseWriter, req *http.Request)

Registrations returns information about registered machines. There are 3 supported query parameters:

* format - defines the format of the returned JSON * org - limits results to only records for the given organization * exp - limits results to only records for the given experiment (e.g., ndt)

The "org" and "exp" query parameters are currently only supported by the default or "machines" format.

func (*Client) UpdatePrometheusForMachine added in v0.15.6

func (c *Client) UpdatePrometheusForMachine(ctx context.Context, hostname string) error

UpdatePrometheusForMachine updates the Prometheus signals for a single machine hostname.

type ClientLocator added in v0.7.0

type ClientLocator interface {
	Locate(req *http.Request) (*clientgeo.Location, error)
}

ClientLocator defines the interface for looking up the client geolocation.

type IntegrationClaims added in v0.20.0

type IntegrationClaims struct {
	IntegrationID string `json:"int_id,omitempty"`
	KeyID         string `json:"key_id,omitempty"`
}

IntegrationClaims holds M-Lab integration-specific claims that are embedded into access tokens issued for priority requests. The JSON tags are the wire-level claim names in the resulting JWT payload.

type Limiter added in v0.17.1

type Limiter interface {
	IsLimited(ip, ua string) (limits.LimitStatus, error)
}

type LocatorV2 added in v0.11.0

type LocatorV2 interface {
	Nearest(service string, lat, lon float64, opts *heartbeat.NearestOptions) (*heartbeat.TargetInfo, error)
	heartbeat.StatusTracker
}

LocatorV2 defines how the Nearest handler requests machines nearest to the client.

type PrometheusClient added in v0.13.0

type PrometheusClient interface {
	Query(ctx context.Context, query string, ts time.Time, opts ...prom.Option) (model.Value, prom.Warnings, error)
}

PrometheusClient defines the interface to query Prometheus.

type Signer

type Signer interface {
	Sign(cl jwt.Claims, extra ...any) (string, error)
}

Signer defines how access tokens are signed. Extra claim objects are merged into the JWT payload via go-jose's variadic Claims support (see token.Signer.Sign).

type TierLimiter added in v0.19.0

type TierLimiter interface {
	Limiter
	IsLimitedWithTier(org, ip string, tierConfig limits.LimitConfig) (limits.LimitStatus, error)
}

TierLimiter extends Limiter with tier-based limits for priority endpoints.

type Verifier added in v0.19.0

type Verifier interface {
	// ExtractClaims extracts and optionally validates JWT claims from the request.
	// Returns the claims as a map, or an error if extraction/validation fails.
	ExtractClaims(req *http.Request) (map[string]interface{}, error)

	// Mode returns the name of the verification mode (for logging/debugging).
	Mode() string
}

Verifier defines the interface for extracting JWT claims from HTTP requests. Different implementations support different verification modes.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL