server

package
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Oct 15, 2026 License: Apache-2.0 Imports: 48 Imported by: 0

Documentation

Overview

Package server is Backyard's HTTP layer (SPEC §2–§6): host/path routing, static site serving, the site API (identity, db, files, ai, warehouse, websocket), the hub (UI, docs, llms.txt, site list, tokens), the embedded deploy gateway mount, health checks, rate limiting and metrics.

Routing

The request host (Host, or X-Forwarded-Host from server.trusted_proxies) is classified as the hub (server.base_domain or the public URL's host), a site (a single DNS label under base_domain, host mode only) or an unknown host (404). With server.dev, IP-literal and localhost host names also reach the hub (other names stay unknown, which defeats DNS rebinding against a local dev server). In path mode sites live under /s/<site>/ on the hub host. The path prefix /__backyard/ is reserved on every host: site files can never shadow it. /__backyard/healthz and /__backyard/readyz answer on any host without authentication.

Security

Every other request is authenticated with the configured auth.Authenticator, except the SDK files, the auth endpoints, the deploy gateway (which authenticates by itself) and the machine paths of the Claude connector. Unauthenticated browser page loads are redirected to the login URL; API calls get 401 JSON with "login_url". State-changing API calls must carry "X-Backyard: 1" and, when present, an Origin equal to the request's own origin (path mode: the hub origin). Site API calls are rate limited per user (anonymous: per client IP).

Claude connector

With mcp.enabled (SPEC §8.4, §14.1) the hub also serves the remote MCP endpoint /__backyard/mcp, the OAuth endpoints /__backyard/oauth/{register,token,revoke} and the discovery documents /.well-known/oauth-authorization-server and /.well-known/oauth-protected-resource/__backyard/mcp. These machine paths authenticate by themselves (the endpoint accepts only MCP access tokens) and never read cookies or identity-proxy headers; they exist on the canonical hub host only and answer 404 while the connector is off. The sign-in and consent page /__backyard/auth/authorize is an auth endpoint like the others, and /__backyard/api/mcp/grants a hub API. Registration and revocation are rate limited per client IP; authorize, the token endpoint and the MCP endpoint per user (authorize and token: per client IP for requests that identify no one).

Timeouts

No http.TimeoutHandler is used: streaming responses (AI server-sent events, websockets, large downloads and uploads) extend or clear the connection deadlines themselves, and backend calls are bounded by contexts.

Large responses on Cloud Run

Cloud Run rejects HTTP/1 responses that declare a Content-Length above 32 MiB. When K_SERVICE is set, static files and uploads above that size are streamed without a Content-Length (chunked), and byte ranges above it are shortened to 32 MiB (see serveObject).

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ClientIP added in v0.2.0

func ClientIP(r *http.Request) string

ClientIP returns the client address of r (X-Forwarded-For from server.trusted_proxies honoured), as access logs and audit records show it. For a request that did not pass through the server's handler it is the address of r.RemoteAddr.

func RequestOrigin added in v0.2.0

func RequestOrigin(r *http.Request) string

RequestOrigin returns the client-visible origin of r (lowercase scheme://host[:port], default port removed), honouring X-Forwarded-Host and X-Forwarded-Proto from server.trusted_proxies as the router does. For a request that did not pass through the server's handler it falls back to r.TLS and r.Host.

Types

type Deps

type Deps struct {
	Config    *config.Config
	Logger    *slog.Logger
	Blob      blob.Store
	Docs      docstore.Store
	Sites     *sites.Registry
	Auth      auth.Authenticator
	Tokens    *auth.Tokens
	Users     *identity.UserCache
	Realtime  realtime.Hub
	AI        ai.Service
	Warehouse warehouse.Service
	// Gateway is the embedded deploy gateway, mounted at /__backyard/api/deploy
	// on the hub host with that prefix stripped. GET /__backyard/api/info is
	// served by forwarding to the gateway's /info.
	Gateway http.Handler
	// MCP is the Claude connector's authorization server (auth.MCPOf(Auth));
	// nil while mcp.enabled is false. It serves the discovery documents and
	// /__backyard/oauth/*, and backs the grants API.
	MCP *auth.MCP
	// MCPEndpoint serves POST /__backyard/mcp (internal/mcpremote); nil
	// answers the disabled 404.
	MCPEndpoint http.Handler
	// DevSites maps site names to local directories served live (backyard dev).
	// Like deploys, they never expose hidden paths (a segment starting with
	// "." other than ".well-known").
	DevSites map[string]string
	// Version string reported by /__backyard/api/info.
	Version string
}

Deps are the components the server needs. AI, Warehouse, Realtime and Gateway may be nil (feature disabled → 404/unsupported responses).

type Server

type Server struct {
	// contains filtered or unexported fields
}

Server is the assembled HTTP application.

func New

func New(d Deps) (*Server, error)

New validates deps and builds the server.

Deps.Docs is wrapped with docstore.WithLimits(database.max_doc_bytes, database.max_docs_per_site) unless it already exposes an Unwrap method (i.e. the caller wrapped it). The embedded deploy gateway is mounted only when deploy.embedded_gateway is not false; GET /__backyard/api/info is forwarded to Deps.Gateway whenever it is set.

func (*Server) AllowAPI added in v0.2.0

func (s *Server) AllowAPI(key string) (bool, time.Duration)

AllowAPI consumes one request of the general API limit (ratelimit.api_per_minute) for key, e.g. "user:<id>" for the MCP endpoint. On refusal it counts rate_limited_total{category="api"} and returns how long to wait. A nil Server allows everything.

func (*Server) Close

func (s *Server) Close(ctx context.Context) error

Close waits (bounded by ctx) for background work such as user-cache writes and audit records to finish. The handler keeps working after Close (work started meanwhile is waited for too); call it after the HTTP server has shut down and before closing Deps.Docs.

func (*Server) Handler

func (s *Server) Handler() http.Handler

Handler returns the root http.Handler.

func (*Server) MetricsHandler

func (s *Server) MetricsHandler() http.Handler

MetricsHandler returns the Prometheus handler (for telemetry.metrics_listen).

func (*Server) ObserveDeploy

func (s *Server) ObserveDeploy(method, result string)

ObserveDeploy counts a deploy for the deploys_total metric. Deploys through the embedded gateway are counted automatically; this is for other paths (the Claude connector's publishes, method "mcp"; a standalone gateway sharing the process).

func (*Server) OnWSFrame

func (s *Server) OnWSFrame(dir string)

OnWSFrame counts one websocket frame received from (dir "in") or written to (dir "out") a client. Pass it as realtime.Options.OnFrame (it is safe to call before New returns through a closure, and concurrently).

func (*Server) PurgeSite

func (s *Server) PurgeSite(site string)

PurgeSite drops cached static files and the cached existence of a site, so a deploy is visible immediately instead of after storage.cache_ttl. Deploys through the embedded gateway purge automatically.

Directories

Path Synopsis
Package servertest holds end-to-end tests that run the HTTP server against real components: the filesystem blob store, the SQLite (and, when BACKYARD_TEST_POSTGRES_DSN is set, PostgreSQL) document store, the realtime hub over in-memory (and, when BACKYARD_TEST_REDIS_URL is set, Redis) pub/sub, the auth package in mode "none" and the embedded deploy gateway.
Package servertest holds end-to-end tests that run the HTTP server against real components: the filesystem blob store, the SQLite (and, when BACKYARD_TEST_POSTGRES_DSN is set, PostgreSQL) document store, the realtime hub over in-memory (and, when BACKYARD_TEST_REDIS_URL is set, Redis) pub/sub, the auth package in mode "none" and the embedded deploy gateway.

Jump to

Keyboard shortcuts

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