HTTP Router
HTTP Router
HTTP Router is the service that determines which cell should serve the incoming requests inside the cluster. This is generally determined by the resources the request is asking for.
For example, a request looking for a project inside cell-2 will be routed to cell-2.
To learn more about HTTP Router, check out the design document and the project repository.
Routing Rules
Routing rules define how to decode requests and make routing decisions.
Rules are organized in rulesets (e.g. session_token). Rules are static and selected (by ruleset) prior to the HTTP Router deployment.
Routing decision is evaluated from top to bottom. It short circuits upon first match.
For more in-depth explanation of rules and running examples of incoming requests being matched to routing rules, check out the http-router documentation on rules.
Routing based on routable tokens
A routable token encodes routing information directly in the token. When a request carries a routable token, the HTTP Router decodes the token and routes the request to the correct cell. The router does not need to query another service to find the cell that owns the resource.
This follows the Routable Tokens design document.
Routing based on routable tokens has two sides:
- GitLab encodes the routing information when it generates the token.
- The HTTP Router decodes that information and routes the request.
Encode routing information in a token
Introduce a routable_token as soon as possible. This ensures tokens are
generated with routable information from the start.
The HTTP Router decoder changes can happen later. If the router does not know where to
route the request, it falls back to the legacy cell.
GitLab encodes routing information in a token through the routable_token: option of the
TokenAuthenticatable concern. For details, see
Using the TokenAuthenticatable concern.
For example, Ci::Runner#token is routable.
The runner token encodes the organization, group,
project, and user keys for group type, and project type runners:
add_authentication_token_field :token,
encrypted: :optional,
expires_at: :compute_token_expiration,
format_with_prefix: :prefix_for_new_and_legacy_runner,
routable_token: {
if: ->(token_owner_record) {
(token_owner_record.group_type? || token_owner_record.project_type?) &&
token_owner_record.owner &&
Feature.enabled?(:routable_runner_token, token_owner_record.owner)
},
payload: {
o: ->(token_owner_record) { token_owner_record.owner.organization_id },
g: ->(token_owner_record) { token_owner_record.group_type? ? token_owner_record.sharding_key_id : nil },
p: ->(token_owner_record) { token_owner_record.project_type? ? token_owner_record.sharding_key_id : nil },
u: ->(token_owner_record) { token_owner_record.creator_id }
}
}Decode a token and route the request
The HTTP Router matches the token against a rule, decodes the payload, and classifies the request by cell.
Each token type needs a new rule in the HTTP Router.
A rule that routes runner tokens looks like this:
{
"id": "session_token_header_runner_token",
"match": {
"type": "header",
"name": "runner-token",
"regexValue": "^glrtr?-(?<payload>[0-9A-Za-z_-]{27,300})\\.01\\.(?<payload_length>[0-9a-z]{2})[0-9a-z]{7}$"
},
"transform": {
"type": "routable-token-payload",
"input": [
"${payload}",
"${payload_length}"
],
"output": "decoded"
},
"action": "classify",
"classify": {
"type": "CELL_ID",
"value": "${decoded.c}"
},
"validate": {
"exist": [
"${decoded.c}"
]
}
}The router processes the rule in these phases:
- Match: the
match.regexValuecaptures thepayloadandpayload_lengthfrom the token. Thepayload_lengthtells the decoder how much of the payload to read, which avoids decoding the whole token. - Transform: the
routable-token-payloadtransform decodes the Base64 payload and attaches the result underdecoded. For example,decoded.cholds the cell. - Validate: the router checks that
decoded.cexists. - Classify: the router sends a
CELL_IDclassify request to the Topology Service with the value ofdecoded.c, then proxies the request to the cell that the Topology Service returns.
For a step-by-step walkthrough of this rule with a sample request, see the runner token example in the http-router documentation.
Routing based on resource path
Coming soon
Routing based on resource ID
Coming soon