Documentation
¶
Overview ¶
Package server provides HTTP server implementation for Starport.
Index ¶
- Constants
- Variables
- func CORS(cfg CORSConfig) func(http.Handler) http.Handler
- func LoggingMiddleware(next http.Handler) http.Handler
- func SecurityHeaders(next http.Handler) http.Handler
- func SizeLimiter(maxSize int64, exempt func(*http.Request) bool) func(http.Handler) http.Handler
- func Timeout(timeout time.Duration) func(http.Handler) http.Handler
- func TracingMiddleware(tracing *telemetry.Tracing) func(http.Handler) http.Handler
- type AccountReader
- type AuthMiddleware
- func (m *AuthMiddleware) AcceptSessions(gate *localauth.Gate)
- func (m *AuthMiddleware) Govern(policy *authmode.Policy, scopes []string)
- func (m *AuthMiddleware) RequireAPIKey(next http.Handler) http.Handler
- func (m *AuthMiddleware) RequireAccountAccess(next http.Handler) http.Handler
- func (m *AuthMiddleware) RequireAdmin(next http.Handler) http.Handler
- func (m *AuthMiddleware) RequireAnyScope(scopes ...string) func(http.Handler) http.Handler
- type CORSConfig
- type Config
- type Dependencies
- type Server
Constants ¶
const ( // MetricsModeOn serves GET /metrics to every caller. MetricsModeOn = "on" // MetricsModeAdmin serves GET /metrics only to the admin scope. MetricsModeAdmin = "admin" // MetricsModeOff removes the route. MetricsModeOff = "off" )
Metrics modes name who may read the Prometheus scrape.
const ( ContextKeyAPIKey contextKey = requestctx.APIKey ContextKeyAPIKeyID contextKey = requestctx.APIKeyID ContextKeyAPIKeyModel contextKey = requestctx.APIKeyModel )
Context keys for middleware
Variables ¶
var ( // ErrModelRequired is returned when neither model nor models array is provided ErrModelRequired = errors.New("model or models array is required") // ErrMessagesRequired is returned when messages are not provided ErrMessagesRequired = errors.New("messages are required") // ErrInvalidTemperature is returned when temperature is out of valid range ErrInvalidTemperature = errors.New("temperature must be between 0 and 2") // ErrInvalidTopP is returned when top_p is out of valid range ErrInvalidTopP = errors.New("top_p must be between 0 and 1") // ErrInvalidMaxTokens is returned when max_tokens is less than 1 ErrInvalidMaxTokens = errors.New("max_tokens must be at least 1") // ErrInvalidN is returned when n is less than 1 ErrInvalidN = errors.New("n must be at least 1") // ErrInvalidPresencePenalty is returned when presence_penalty is out of valid range ErrInvalidPresencePenalty = errors.New("presence_penalty must be between -2 and 2") // ErrInvalidFrequencyPenalty is returned when frequency_penalty is out of valid range ErrInvalidFrequencyPenalty = errors.New("frequency_penalty must be between -2 and 2") // ErrInvalidMinP is returned when min_p is out of valid range ErrInvalidMinP = errors.New("min_p must be between 0 and 1") // ErrInvalidTopA is returned when top_a is out of valid range ErrInvalidTopA = errors.New("top_a must be between 0 and 1") // ErrInvalidRepetitionPenalty is returned when repetition_penalty is out of valid range ErrInvalidRepetitionPenalty = errors.New("repetition_penalty must be greater than 0") // Embeddings validation errors // ErrEmbeddingsModelRequired is returned when model is not provided for embeddings ErrEmbeddingsModelRequired = errors.New("model is required") // ErrInputRequired is returned when input is not provided ErrInputRequired = errors.New("input is required") // ErrInvalidEncodingFormat is returned when encoding format is invalid ErrInvalidEncodingFormat = errors.New("encoding_format must be 'float' or 'base64'") )
Request validation errors
var ( RequestID = middleware.RequestID ClientIP = middleware.ClientIPFromRemoteAddr Recoverer = middleware.Recoverer Compress = middleware.Compress )
Middleware aliases for chi middleware.
var ( // ErrConfigRequired reports an absent HTTP server configuration. ErrConfigRequired = errors.New("server config is required") // ErrServiceRequired reports an absent gateway use-case service. ErrServiceRequired = errors.New("gateway service is required") // ErrAPIKeysRequired reports an absent API key repository. ErrAPIKeysRequired = errors.New("API key repository is required") // ErrAccountsRequired reports an absent account repository. ErrAccountsRequired = errors.New("account repository is required") // ErrProviderKeysRequired reports an absent provider-key service. ErrProviderKeysRequired = errors.New("provider key service is required") // ErrRateLimitsRequired reports an absent rate-limit repository. ErrRateLimitsRequired = errors.New("rate-limit repository is required") // ErrProviderOperationsRequired reports an absent provider operations port. ErrProviderOperationsRequired = errors.New("provider operations are required") )
Functions ¶
func CORS ¶
func CORS(cfg CORSConfig) func(http.Handler) http.Handler
CORS returns a configured CORS handler
func LoggingMiddleware ¶
LoggingMiddleware creates a custom logging middleware using zerolog
func SecurityHeaders ¶
SecurityHeaders adds security headers to responses
func SizeLimiter ¶
SizeLimiter limits the size of request bodies. A caller that states its size in Content-Length is refused before the gateway reads a byte of it, which matters most for the case this limit exists to catch: a request that carries attached media is large, and reading it only to discard it costs the memory the limit is there to protect.
A body whose size the caller does not state is cut while it is read. The decode path answers that one, because only the reader learns the body was too long.
The exempt predicate names the routes that carry their own bound. A file upload is one of them: this limit exists to stop a caller from making the gateway hold and decode a huge document, and an upload streams to a store instead. Its own bound is the operator's file setting, which is usually larger, so the general limit steps aside rather than clamping it lower.
func Timeout ¶
Timeout bounds one request and hands the handler the release of that bound.
Route timing is route-specific. An ordinary JSON route writes its body at the end, so the bound covers it from end to end. A route that commits to a long response releases the bound and then runs as long as its provider sends bytes. The middleware owns the bound, because clearing the write deadline alone leaves the parent context deadline in place and still cuts a healthy stream in half.
func TracingMiddleware ¶ added in v1.2.0
TracingMiddleware starts the request span and carries the tracer into the request context, where the routing and execution seams start their children. It continues the caller's W3C trace context when the inbound headers carry one. A nil tracer leaves the handler chain untouched.
Types ¶
type AccountReader ¶ added in v1.1.0
AccountReader reads one account by ID. The middleware holds this single method rather than the account repository, so the HTTP seam never learns how an account is stored or gains the power to write one.
type AuthMiddleware ¶
type AuthMiddleware struct {
// contains filtered or unexported fields
}
AuthMiddleware provides authentication functionality
func NewAuthMiddleware ¶
func NewAuthMiddleware(apiKeys apikey.Repository, accounts ...AccountReader) *AuthMiddleware
NewAuthMiddleware creates a new authentication middleware. The account reader is optional: without it a request still authenticates and runs under the default credential policy, because a key is a valid caller whether or not the deployment can read the account behind it.
func (*AuthMiddleware) AcceptSessions ¶ added in v1.1.0
func (m *AuthMiddleware) AcceptSessions(gate *localauth.Gate)
AcceptSessions binds the gate that verifies console sessions.
It is separate from Govern because the two answer different questions. The policy decides whether a credential is required at all; the gate decides whether one particular kind of credential is genuine. A deployment can have either without the other.
func (*AuthMiddleware) Govern ¶ added in v1.1.0
func (m *AuthMiddleware) Govern(policy *authmode.Policy, scopes []string)
Govern binds the live authentication policy and the key a request runs as while that policy is disabled. An empty scope list means apikey.DefaultAnonymousScopes.
The operator decides both; nothing in a request can. Passing them together is the point: a policy without an anonymous key would disable the key check and leave every downstream seam without a subject to meter.
func (*AuthMiddleware) RequireAPIKey ¶
func (m *AuthMiddleware) RequireAPIKey(next http.Handler) http.Handler
RequireAPIKey validates API key authentication
func (*AuthMiddleware) RequireAccountAccess ¶ added in v1.1.0
func (m *AuthMiddleware) RequireAccountAccess(next http.Handler) http.Handler
RequireAccountAccess guards a route addressed by account. A caller reaches its own account, and an operator holding admin reaches any account, because applying a credential on an account's behalf is a support operation an operator has to be able to perform. Nothing else passes.
An operator naming an account that does not exist gets 404 rather than a silent write into a scope no account owns.
func (*AuthMiddleware) RequireAdmin ¶
func (m *AuthMiddleware) RequireAdmin(next http.Handler) http.Handler
RequireAdmin validates admin privileges
func (*AuthMiddleware) RequireAnyScope ¶
RequireAnyScope validates that the authenticated API key has at least one accepted scope. The wildcard "*" grants access to all scopes.
type CORSConfig ¶
type CORSConfig struct {
// AllowedOrigins is a list of origins a cross-domain request can be executed from
AllowedOrigins []string `env:"CORS_ALLOWED_ORIGINS,default=*"`
// AllowedMethods is a list of methods the client is allowed to use with cross-domain requests
AllowedMethods []string `env:"CORS_ALLOWED_METHODS,default=GET,POST,PUT,DELETE,OPTIONS"`
// AllowedHeaders is list of non simple headers the client is allowed to use with cross-domain requests
AllowedHeaders []string `env:"CORS_ALLOWED_HEADERS,default=Accept,Authorization,Content-Type,X-CSRF-Token"`
// ExposedHeaders indicates which headers are safe to expose to the API of a CORS API specification
ExposedHeaders []string `env:"CORS_EXPOSED_HEADERS,default="`
// AllowCredentials indicates whether the request can include user credentials
AllowCredentials bool `env:"CORS_ALLOW_CREDENTIALS,default=true"`
// MaxAge indicates how long (in seconds) the results of a preflight request can be cached
MaxAge int `env:"CORS_MAX_AGE,default=300"`
}
CORSConfig holds CORS configuration
type Config ¶
type Config struct {
// Port to listen on
Port int `env:"PORT,default=8080"`
// Host to bind to
Host string `env:"HOST,default=0.0.0.0"`
// Read and write timeouts
ReadTimeout time.Duration `env:"READ_TIMEOUT,default=10s"`
WriteTimeout time.Duration `env:"WRITE_TIMEOUT,default=10s"`
IdleTimeout time.Duration `env:"IDLE_TIMEOUT,default=120s"`
// Request timeout for middleware
RequestTimeout time.Duration `env:"REQUEST_TIMEOUT,default=60s"`
// Shutdown timeout
ShutdownTimeout time.Duration `env:"SHUTDOWN_TIMEOUT,default=30s"`
// MaxRequestSize is the largest request body the gateway reads, in bytes.
// Application composition supplies it from the loaded configuration, so
// this field carries no environment tag: a tag here would state a default
// that never reads the environment and would drift from the real one.
MaxRequestSize int64
// MaxFileUploadSize is the largest file upload the gateway accepts, in
// bytes. It carries no environment tag for the same reason MaxRequestSize
// does not: application composition supplies it from the loaded file
// configuration, and a tag here would state a second default that never
// reads the environment.
MaxFileUploadSize int64
// Maximum aggregate size of HTTP request headers.
MaxHeaderBytes int `env:"MAX_HEADER_BYTES,default=1048576"`
// Rate limiting configuration. Enforcement happens after API key
// authentication and uses the authenticated API key ID, not the raw secret.
EnableRateLimiting bool `env:"ENABLE_RATE_LIMITING,default=false"`
RateLimitRequestsPerWindow int64 `env:"RATE_LIMIT_REQUESTS_PER_WINDOW,default=0"`
RateLimitWindow time.Duration `env:"RATE_LIMIT_WINDOW,default=1m"`
// AuthMode selects whether a request must carry a gateway API key. It is
// the mode the gateway starts under; the console can change the running
// mode afterwards, and the middleware reads the live policy rather than
// this field.
AuthMode authmode.Mode
// AuthModeSource names where AuthMode came from, so the startup banner and
// the console can say which thing an operator has to change.
AuthModeSource authmode.Source
// AuthModeStore persists a mode the console sets, so the change outlives
// the process that accepted it. A nil store means the mode cannot be
// changed at runtime, and the switch reports that rather than accepting a
// change it would forget.
AuthModeStore authmode.Repository
// UnauthenticatedScopes lists the scopes a request holds while the running
// mode is disabled. An empty list means apikey.DefaultAnonymousScopes.
UnauthenticatedScopes []string
// AllowRemoteNoAuth is the operator's acknowledgment that an
// unauthenticated gateway may bind an address the network can reach. It is
// the same acknowledgment startup validation reads, and the runtime switch
// reads it for the same reason.
AllowRemoteNoAuth bool
// MetricsMode states who may read GET /metrics: MetricsModeOn serves
// every caller, MetricsModeAdmin requires the admin scope, and
// MetricsModeOff removes the route. Application composition supplies it
// from the loaded telemetry configuration; an empty value reads as on,
// so a hand-built server serves the scrape the way a deployment does by
// default.
MetricsMode string
// Build is the provenance of the running binary, which the health and
// admin surfaces report. Application composition supplies it from the
// linker-stamped values; a hand-built server reports an unstamped build.
Build controllers.BuildInfo
// CORS configuration
CORS CORSConfig
}
Config holds server configuration
type Dependencies ¶
type Dependencies struct {
Service proxy.Proxy
APIKeys apikey.Repository
Accounts account.Repository
ProviderKeys keyring.ProviderKeys
RateLimits ratelimit.Repository
ProviderOperations controllers.ProviderOperations
Console console.PageServer
// Usage serves recorded request activity. A nil repository degrades
// the activity and metrics endpoints to 503, loudly.
Usage usage.Repository
// Catalog serves snapshot freshness, diffs, and forced acquisition. A
// nil port degrades the catalog endpoints to 503, loudly.
Catalog controllers.CatalogOperations
// Presets serves stored preset management. A nil repository degrades
// the preset endpoints to 503, loudly.
Presets presets.Repository
// Templates serves account templates: the named creation defaults an
// account can be stamped from. A nil repository degrades the template
// endpoints to 503, loudly.
Templates account.TemplateRepository
// Files serves the stored file surface. A nil service degrades the file
// endpoints to 503, loudly: the routes stay registered so a caller reads
// that this deployment configured no file storage rather than that the
// gateway has no files API.
Files *files.Service
// Jobs serves work that outlives its request. A nil service degrades the
// video endpoints to 503, loudly, for the same reason a nil file service
// does: the routes stay registered so a caller reads that this deployment
// configured no job store rather than that the gateway has no video API.
Jobs *jobs.Service
// Batches serves the batch surface. A nil service degrades the batch
// endpoints to 503, loudly, for the same reason a nil job service does.
Batches *jobs.BatchService
// FileBackend names the blob backend behind that service, for the admin
// surface to report. An empty name reads as no file storage at all.
FileBackend string
// LocalGate redeems console launch tickets and verifies console sessions
// against this machine's local admin token. A nil gate refuses every
// launch and every session cookie, which is the right answer for a
// gateway assembled without one: the bearer key path is unaffected.
LocalGate *localauth.Gate
// IdentityAuth is the OAuth acquisition path, or nil when this
// deployment configured no identity provider. The identity routes stay
// mounted either way and refuse with the operator's answer when nil.
IdentityAuth controllers.IdentityAuthenticator
// Identity holds the durable people plane: users, teams, memberships,
// and account grants. Zero repositories — no identity provider configured —
// degrade the members and teams endpoints to 503, loudly, so the
// console reads "not configured" rather than "nobody is here".
Identity identity.Repositories
// Telemetry serves the Prometheus scrape and counts budget refusals. A
// nil surface removes the /metrics route and observes nothing, which is
// what a deployment that turned metrics off gets.
Telemetry *telemetry.Metrics
// Tracing starts the request span and hands the tracer to the routing and
// execution seams. A nil tracer disables tracing without a guard anywhere
// else.
Tracing *telemetry.Tracing
// Audit records admin mutations and serves the trail back. A nil trail
// records nothing and degrades the audit listing to 503, loudly.
Audit controllers.AuditTrail
// Events pushes budget and key lifecycle events to the configured
// webhook endpoints. A nil emitter pushes nothing, which is the
// deployment with no endpoint configured.
Events controllers.EventEmitter
// Webhooks reports the delivery state of that surface for the admin
// summary. A nil reporter reads as webhooks off.
Webhooks controllers.WebhookReporter
// Deployment is what the admin surface states about the configured
// storage, telemetry, guardrail, and retention settings.
Deployment controllers.Deployment
}
Dependencies contains ready application ports for the HTTP adapter.
type Server ¶
type Server struct {
// contains filtered or unexported fields
}
Server represents the HTTP server with new handler organization
func New ¶
func New(config *Config, dependencies Dependencies) (*Server, error)
New creates an HTTP adapter from ready application dependencies.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package controllers contains HTTP handlers for the Starport API.
|
Package controllers contains HTTP handlers for the Starport API. |
|
Package dto owns shared administrative HTTP response values.
|
Package dto owns shared administrative HTTP response values. |
|
Package requestctx defines typed request context values shared by the server middleware and HTTP controllers.
|
Package requestctx defines typed request context values shared by the server middleware and HTTP controllers. |