Skip to content

Routing Rules Reference

Routes belong to listeners and are evaluated only for traffic received by that listener.

In the management UI, choose Proxy -> Routes. The Routes tab presents compact rows for route and match, action and targets, priority and state, and actions. Choose Add Route to open the route drawer; existing rows expose edit, clone, and delete actions. Choose Proxy -> Listeners to manage the incoming endpoints those routes belong to.

Route Fields And Defaults

A non-default route requires at least one of:

  • host pattern,
  • path prefix.
FieldRule
listener_idRequired. Route is scoped to this listener.
priorityLower numbers evaluate first.
host_patternExact host or wildcard subdomain.
path_prefixMust start with / when set.
path_security_modeDefaults to strict. Use allow_encoded_separators only for upstreams that require encoded / or \ path identifiers.
access_policy_idOptional reusable identity policy. Requests fail closed when its provider or policy is unavailable.
actionforward or redirect; defaults to forward when unspecified.
target_load_balancingDefaults to round-robin for forward target pools.
is_defaultMarks the listener default route. One default route is allowed per listener.
redirect_status_codeDefaults to 302 when unset.
redirect_preserve_path_suffixDefaults enabled.
redirect_preserve_queryDefaults enabled.

Target Fields

Forward routes require at least one enabled target.

FieldRule
target_typeproxy or static.
urlRequired for proxy targets. Must be an HTTP or HTTPS origin.
transportdirect or agent for proxy targets.
agent_selector.match_labelsRequired for agent targets. All labels must match the same enabled agent.
priority_groupLowest available group is selected; higher groups are failover.
weight1 to 1000000; defaults to 100.
agent_load_balancingAgent selection policy for agent targets.
tls_skip_verifyDisables upstream certificate verification for this target; use only for a deliberately trusted private origin.
upstream_response_header_timeout_millisDefaults to 60000.
upstream_request_headersOrdered headers added to upstream requests. Sensitive values are write-only and returned as saved-state metadata.
upstream_basic_authOptional upstream username and write-only password.
health_checkOptional method, path, interval, timeout, thresholds, and expected status range.
static_status_codeLocal status returned by a static target.
static_response_headersHeaders returned by a static target.
static_response_body_modeInline body or generic response template.
static_response_template_idGeneric template selected when template mode is active.

Static targets use static_status_code, static_response_headers, and either inline body text or a generic response template.

Agent labels are configured in the Edit Agent drawer. Labels under p2pstream.io/ are system-owned. Use p2pstream.io/agent-id=<agent public ID> for exact-agent targeting. Empty selector values are allowed and match only agents with the same empty label value.

Current Management UI Coverage

The route drawer currently exposes route matching, path security, route-level target balancing, redirects, and these target controls:

  • target name, type, priority group, weight, and enabled state;
  • proxy URL, Direct or Agent transport, response-header timeout, and TLS verification;
  • exact-agent or label selectors for Agent transport;
  • status and inline body for Static targets.

The management API and runtime also support upstream request headers, upstream basic authentication, health checks, per-target agent load balancing, static response headers, and template-backed static bodies. Those fields are loaded and preserved during an ordinary edit but are not currently rendered by the route drawer, so use the management API to review saved-state metadata or configure them. Secret values remain write-only. Do not infer from the drawer that an existing hidden setting is absent. Cloning a route cannot carry forward redacted header or basic-auth secrets; set new secrets through the API.

Validation Rules

PatternMatches
app.example.comexactly app.example.com
*.example.comapp.example.com, media.example.com

Wildcard patterns do not match the apex example.com.

Redirect routes require target mode, target, and status code 301, 302, 307, or 308.

Path Security

Every route has a path security mode:

ModeBehavior
strictRejects request targets containing encoded path separators such as %2F or %5C before WAF, rate limits, traffic shaping, cache, or forwarding.
allow_encoded_separatorsAllows encoded separators for compatibility with upstreams that use encoded path IDs, such as GitLab project paths. Shared cache bypasses encoded-separator requests on these routes.

Decoded . and .. path segments and raw literal backslashes are always rejected on public listeners. Encoded dots inside ordinary segment names, such as /files/v1%2e2/readme, are allowed; encoded dots that decode to a whole . or .. segment are rejected.

The compatibility mode is route-scoped so only the backend that needs encoded separators receives them. WAF, rate-limit, and traffic-shaper path matching still use p2pstream's decoded request path model, so avoid relying on decoded slash boundaries for routes that enable encoded separators.

p2pstream route drawer showing listener, host pattern, path prefix, path security, action, targets, and priority
The route drawer defines the listener-scoped match, path security, action, priority, and forward target pool or redirect settings.
p2pstream route drawer showing a direct upstream target
Direct proxy targets are used when the p2pstream server itself can reach the upstream origin.
p2pstream route drawer showing an agent-selected proxy target with label selectors
Agent proxy targets select a connected agent by labels and dial the origin from that agent's network.
p2pstream route drawer showing redirect action, destination, status, path-suffix, and query-preservation settings
Redirect routes return a local redirect response without selecting a route target.
p2pstream route drawer showing the currently available static target controls for status and inline body
Static response targets can return a local status, headers, and inline or template-backed body without forwarding upstream. The current drawer exposes status and inline body; configure response headers or a generic response template through the management API.

Runtime Effects

Routes are sorted by priority ascending, then route ID ascending. If no enabled non-default route matches, the listener default route handles the request.

p2pstream performs a lightweight route match before WAF, rate limits, access control, and traffic shapers to determine the matched route's path security mode and access policy. Target selection and load-balancer accounting still happen after those policy layers.

An assigned access policy applies to forward, static, and redirect routes. Protected routes bypass shared cache. See Identity-Aware Access.

At request time, disabled targets, unhealthy targets, invalid target configs, and unavailable agent selector matches are skipped. p2pstream selects from the lowest available priority group. If no target is usable, the response is 503.

When target health checks are enabled, connection and timeout failures mark the selected target or target-agent path temporarily unhealthy for later requests. The original request is not replayed to another target.

After a route and target are selected, cache rules may serve eligible proxy GET or HEAD requests. Redirect routes and static targets are not cached.

Example

Specific route before broad fallback:

PriorityHostPathTarget
10app.example.com/apiapi-direct
20app.example.com/app-agent
defaultempty/welcome-static

Operations documentation for self-hosted p2pstream deployments.