Documentation
¶
Overview ¶
Package hops bounds how far a request may travel between a shard and the virtual workspaces serving its virtual resources.
A shard serves a virtual resource by forwarding to the virtual workspace advertised for it, and a virtual workspace may serve a resource by delegating back to the shard. Both are legitimate, and chaining them is legitimate too:
APIExport VW -> shard -> Replication VW -> cache server terminates
But the same two moves also compose into a cycle, when the virtual workspace a request is forwarded to is the one that delegated it in the first place:
APIExport VW -> shard -> APIExport VW -> shard -> ... spins
Nothing static distinguishes the two. The export, the storage type and the endpoint URL are identical in both; only what the far end does with the request differs, and that is not knowable before sending it. So instead of trying to detect the cycle, this counts how deep a request has gone and refuses to go deeper than a legitimate chain ever needs.
Counting only works if every leg carries the count. An HTTP proxy forwards headers on its own, but a virtual workspace that delegates through a client-go client starts a fresh request, so the count has to survive as context: WithRequestHops puts an inbound header into the context, and WrapConfig puts the context value back onto outbound requests.
Index ¶
- Constants
- func Exceeded(hops int) bool
- func FromContext(ctx context.Context) int
- func FromHeader(h http.Header) int
- func SetHeader(h http.Header, hops int)
- func WithHops(ctx context.Context, hops int) context.Context
- func WithRequestHops(handler http.Handler) http.Handler
- func WrapConfig(cfg *rest.Config) *rest.Config
Constants ¶
const Header = "X-Kcp-Virtual-Resource-Hops"
Header carries how many times a request has been forwarded.
A client may set it, but only against itself: an inflated value fails that one request, which is why it is not stripped at the edge.
const Max = 4
Max is how deep forwarding may go before a request is refused.
The longest legitimate chain observed is two hops -- a client reaching an APIExport virtual workspace, which delegates to the shard, which forwards to the replication virtual workspace. The limit leaves room above that; a cycle exceeds any finite limit.
Variables ¶
This section is empty.
Functions ¶
func Exceeded ¶
Exceeded reports whether a request that has been forwarded this many times has reached the limit and must not be forwarded again.
func FromContext ¶
FromContext reports the hop count carried by a context, zero if none is.
func FromHeader ¶
FromHeader reports how many times the request carrying these headers has been forwarded. Anything unparsable counts as Max, so that a malformed header cannot buy more hops than a well-formed one.
func WithRequestHops ¶
WithRequestHops records the inbound hop count in the request context, so that work done on behalf of this request can carry it onwards.
func WrapConfig ¶
WrapConfig makes clients built from cfg carry the hop count of the request they are serving. Without it a virtual workspace that answers by delegating through a client-go client would restart the count at zero on every lap of a cycle, and the count would never reach its limit.
Types ¶
This section is empty.