Skip to content

Implement HTTP relay proxy with upstream load balancing (round-robin/best/priority), captive-style health checking, domain blacklist/whitelist routing with domain-expression matching, and hot reload#1

Merged
MejiroRina merged 13 commits intomainfrom
copilot/http-relay-implementation
Mar 22, 2026

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Mar 21, 2026

Greenfield implementation of an HTTP relay proxy that listens on a local port and forwards traffic through a configurable upstream proxy pool with high-availability guarantees.

Core architecture

  • src/config.rs — YAML config structs (yaml_serde); mtime-based hot-reload detection; domain routing policy config
  • src/upstream.rsUpstreamEntry (atomic state machine, latency EMA α=0.25, active-conn counter) + UpstreamPool (selection, reload)
  • src/health.rs — Background task; probes offline upstreams using captive-style HTTP generate_204 requests through the proxy, marks online on HTTP 204
  • src/proxy.rs — HTTP/1.x handler: CONNECT tunnel + plain HTTP forwarding; Content-Length and chunked body; client keep-alive; domain-policy based direct/proxy routing with domain-expression matching
  • src/main.rs — Tokio accept loop; spawns health checker and hot-reload watcher

Load balancing

Three modes via mode: in config:

Mode Behavior
round_robin Weighted round-robin across online upstreams
best Picks upstream with lowest latency_ema_ms + active_conns × 50
priority Picks the online upstream with the lowest priority value (higher priority), and automatically falls back to the next online priority level when the current one is offline

Each upstream now supports a priority field (default: 100) for priority mode.

Domain routing policy (blacklist / whitelist)

Adds optional domain-based direct/proxy selection:

domain_policy:
  mode: off        # off | blacklist | whitelist
  domains: []      # supports domain/suffix expressions

Behavior:

  • off (default): all domains use upstream proxy
  • blacklist: listed domains connect directly (bypass upstream proxy); others use upstream proxy
  • whitelist: listed domains use upstream proxy; others connect directly

This policy is applied to both:

  • CONNECT requests (HTTPS tunneling)
  • Plain HTTP forwarding

For direct HTTP routing, absolute-form proxy request targets are rewritten to origin-form before sending to origin servers.

Domain expression formats

domain_policy.domains supports:

  • domain:example.com — exact domain match
  • suffix:example.com — domain suffix match
  • *.example.com / .example.com — suffix shorthand
  • example.com — backward-compatible exact-or-suffix matching

Health checking

Passive — any TCP connect failure immediately marks the upstream offline; the in-flight request is retried on the next available upstream (up to min(pool_size, 3) attempts, then 502).

Active — background task probes each offline upstream every health_check.interval_secs seconds by sending a captive-style HTTP proxy request to:

  • GET http://connectivitycheck.gstatic.com/generate_204

Only an HTTP 204 response marks the upstream back online; non-204/timeout/error keeps it offline.

health_check:
  interval_secs: 30
  timeout_secs: 5

Hot reload

Config file mtime is polled every reload_interval_secs seconds. On change, the upstream list is reconciled: existing entries (matched by URL) retain their online/offline state and stats; new entries start online; removed entries are dropped — no restart required.

For existing URL-matched upstreams, hot reload now refreshes mutable config values (including priority, weight, and auth settings) while preserving runtime state/statistics, so priority changes take effect without restart.

Documentation additions

  • Added AGENTS.md at repository root
  • Added copilot-Instructions.md at repository root

Tests and validation

  • Added unit tests for:
    • priority-mode primary selection
    • priority-mode failover to next online upstream
    • hot-reload priority update behavior
    • captive 204 probe marks upstream online
    • non-204 probe keeps upstream offline
    • domain policy parsing (off/blacklist/whitelist)
    • blacklist and whitelist domain matching behavior
    • domain-expression matching behavior (domain:, suffix:, *. / . shorthand, legacy plain form, empty-expression guards)
    • direct HTTP request-line rewrite to origin-form
  • Full test suite passes (cargo test)
  • Lint/checks pass (cargo clippy -- -D warnings)
  • Security scan passes (CodeQL: 0 alerts)
Original prompt

我需要这个项目做成http relay,本地监听一个http proxy端口,然后配置上游代理池
需要支持以下功能:
· 上游负载均衡模式
· 择优模式
· 主动与被动上游链路存活检测
· 正在使用的上游代理如果无法连通则需标记为离线,除非主动探测其已恢复,并且把流量转发到其他可用的上游代理
· 热更新配置
我需要确保连接到这个http proxy server的客户端能在上述需求中尽可能保证高连通性高可用性


📱 Kick off Copilot coding agent tasks wherever you are with GitHub Mobile, available on iOS and Android.

Copilot AI and others added 2 commits March 21, 2026 15:33
Copilot AI changed the title [WIP] Add HTTP relay proxy server with upstream features Implement HTTP relay proxy with upstream load balancing, health checking, and hot reload Mar 21, 2026
Copilot AI requested a review from MejiroRina March 21, 2026 15:37
@MejiroRina
Copy link
Copy Markdown
Member

MejiroRina commented Mar 21, 2026

@copilot 再加一个优先级模式,为每个上游节点做优先级标记,根据节点存活状态切换

Copy link
Copy Markdown
Contributor Author

Copilot AI commented Mar 21, 2026

@MejiroRina The model claude-sonnet-4.6 is not available for your account. This can happen if the model was disabled by your organization's policy or if your Copilot plan doesn't include access to it.

You can try again without specifying a model (just @copilot) to use the default, or choose a different model from the model picker.

If you want to contact GitHub about this error, please mention the following identifier so they can better serve you: 78cd1b2d-bfe6-4179-aac7-a1aa78e9e9b2

5 similar comments
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Mar 21, 2026

@MejiroRina The model claude-sonnet-4.6 is not available for your account. This can happen if the model was disabled by your organization's policy or if your Copilot plan doesn't include access to it.

You can try again without specifying a model (just @copilot) to use the default, or choose a different model from the model picker.

If you want to contact GitHub about this error, please mention the following identifier so they can better serve you: 78cd1b2d-bfe6-4179-aac7-a1aa78e9e9b2

Copy link
Copy Markdown
Contributor Author

Copilot AI commented Mar 21, 2026

@MejiroRina The model claude-sonnet-4.6 is not available for your account. This can happen if the model was disabled by your organization's policy or if your Copilot plan doesn't include access to it.

You can try again without specifying a model (just @copilot) to use the default, or choose a different model from the model picker.

If you want to contact GitHub about this error, please mention the following identifier so they can better serve you: 78cd1b2d-bfe6-4179-aac7-a1aa78e9e9b2

Copy link
Copy Markdown
Contributor Author

Copilot AI commented Mar 21, 2026

@MejiroRina The model claude-sonnet-4.6 is not available for your account. This can happen if the model was disabled by your organization's policy or if your Copilot plan doesn't include access to it.

You can try again without specifying a model (just @copilot) to use the default, or choose a different model from the model picker.

If you want to contact GitHub about this error, please mention the following identifier so they can better serve you: 78cd1b2d-bfe6-4179-aac7-a1aa78e9e9b2

Copy link
Copy Markdown
Contributor Author

Copilot AI commented Mar 21, 2026

@MejiroRina The model claude-sonnet-4.6 is not available for your account. This can happen if the model was disabled by your organization's policy or if your Copilot plan doesn't include access to it.

You can try again without specifying a model (just @copilot) to use the default, or choose a different model from the model picker.

If you want to contact GitHub about this error, please mention the following identifier so they can better serve you: 78cd1b2d-bfe6-4179-aac7-a1aa78e9e9b2

Copy link
Copy Markdown
Contributor Author

Copilot AI commented Mar 21, 2026

@MejiroRina The model claude-sonnet-4.6 is not available for your account. This can happen if the model was disabled by your organization's policy or if your Copilot plan doesn't include access to it.

You can try again without specifying a model (just @copilot) to use the default, or choose a different model from the model picker.

If you want to contact GitHub about this error, please mention the following identifier so they can better serve you: 78cd1b2d-bfe6-4179-aac7-a1aa78e9e9b2

@MejiroRina
Copy link
Copy Markdown
Member

@copilot 再加一个优先级模式,为每个上游节点做优先级标记,根据节点存活状态切换

Copy link
Copy Markdown
Contributor Author

Copilot AI commented Mar 21, 2026

@MejiroRina The model claude-opus-4.5 is not available for your account. This can happen if the model was disabled by your organization's policy or if your Copilot plan doesn't include access to it.

You can try again without specifying a model (just @copilot) to use the default, or choose a different model from the model picker.

If you want to contact GitHub about this error, please mention the following identifier so they can better serve you: 155a1824-21ff-4955-a99b-ad0df32b2e83

2 similar comments
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Mar 21, 2026

@MejiroRina The model claude-opus-4.5 is not available for your account. This can happen if the model was disabled by your organization's policy or if your Copilot plan doesn't include access to it.

You can try again without specifying a model (just @copilot) to use the default, or choose a different model from the model picker.

If you want to contact GitHub about this error, please mention the following identifier so they can better serve you: 155a1824-21ff-4955-a99b-ad0df32b2e83

Copy link
Copy Markdown
Contributor Author

Copilot AI commented Mar 21, 2026

@MejiroRina The model claude-opus-4.5 is not available for your account. This can happen if the model was disabled by your organization's policy or if your Copilot plan doesn't include access to it.

You can try again without specifying a model (just @copilot) to use the default, or choose a different model from the model picker.

If you want to contact GitHub about this error, please mention the following identifier so they can better serve you: 155a1824-21ff-4955-a99b-ad0df32b2e83

@MejiroRina
Copy link
Copy Markdown
Member

@copilot 再加一个优先级模式,为每个上游节点做优先级标记,根据节点存活状态切换

Copy link
Copy Markdown
Contributor Author

Copilot AI commented Mar 21, 2026

@MejiroRina The model claude-opus-4.5 is not available for your account. This can happen if the model was disabled by your organization's policy or if your Copilot plan doesn't include access to it.

You can try again without specifying a model (just @copilot) to use the default, or choose a different model from the model picker.

If you want to contact GitHub about this error, please mention the following identifier so they can better serve you: 155a1824-21ff-4955-a99b-ad0df32b2e83

Copy link
Copy Markdown
Contributor Author

Copilot AI commented Mar 21, 2026

@MejiroRina The model claude-opus-4.5 is not available for your account. This can happen if the model was disabled by your organization's policy or if your Copilot plan doesn't include access to it.

You can try again without specifying a model (just @copilot) to use the default, or choose a different model from the model picker.

If you want to contact GitHub about this error, please mention the following identifier so they can better serve you: 155a1824-21ff-4955-a99b-ad0df32b2e83

1 similar comment
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Mar 21, 2026

@MejiroRina The model claude-opus-4.5 is not available for your account. This can happen if the model was disabled by your organization's policy or if your Copilot plan doesn't include access to it.

You can try again without specifying a model (just @copilot) to use the default, or choose a different model from the model picker.

If you want to contact GitHub about this error, please mention the following identifier so they can better serve you: 155a1824-21ff-4955-a99b-ad0df32b2e83

Copy link
Copy Markdown
Contributor Author

Copilot AI commented Mar 21, 2026

@copilot 再加一个优先级模式,为每个上游节点做优先级标记,根据节点存活状态切换

已实现 priority 模式并支持按上游节点优先级自动切换(节点离线时切到下一优先级在线节点,恢复后可自动回切)。对应提交:be4ff1e。

@copilot 再加一个优先级模式,为每个上游节点做优先级标记,根据节点存活状态切换

已实现 priority 模式并支持按上游节点优先级自动切换(节点离线时切到下一优先级在线节点,恢复后可自动回切)。对应提交:be4ff1e。

@copilot 再加一个优先级模式,为每个上游节点做优先级标记,根据节点存活状态切换

已实现 priority 模式并支持按上游节点优先级自动切换(节点离线时切到下一优先级在线节点,恢复后可自动回切)。对应提交:be4ff1e。

Copilot AI changed the title Implement HTTP relay proxy with upstream load balancing, health checking, and hot reload Implement HTTP relay proxy with upstream load balancing (round-robin/best/priority), health checking, and hot reload Mar 21, 2026
@MejiroRina
Copy link
Copy Markdown
Member

@copilot 连通性测试用类似gstatic generate 204之类的captive来检测代理是否存活

Copy link
Copy Markdown
Contributor Author

Copilot AI commented Mar 21, 2026

@copilot 连通性测试用类似gstatic generate 204之类的captive来检测代理是否存活

已按建议改为 captive 风格连通性检测:对离线上游发起 GET http://connectivitycheck.gstatic.com/generate_204,仅在返回 HTTP 204 时标记恢复在线;非 204/超时/异常保持离线。对应提交:c1ddd51。该改动为后端逻辑,无 UI 变更(截图不适用)。

Copilot AI changed the title Implement HTTP relay proxy with upstream load balancing (round-robin/best/priority), health checking, and hot reload Implement HTTP relay proxy with upstream load balancing (round-robin/best/priority), captive-style health checking, and hot reload Mar 21, 2026
@MejiroRina
Copy link
Copy Markdown
Member

@copilot 需要支持黑白名单,比如黑名单模式下特定域名直接连接不走代理,白名单模式下特定域名走代理不走直连

Copy link
Copy Markdown
Contributor Author

Copilot AI commented Mar 21, 2026

@copilot 需要支持黑白名单,比如黑名单模式下特定域名直接连接不走代理,白名单模式下特定域名走代理不走直连

已支持黑白名单路由策略:新增 domain_policy.modeoff|blacklist|whitelist)和 domain_policy.domainsblacklist 下名单域名直连不走上游代理,whitelist 下仅名单域名走上游代理其余直连;同时覆盖了 CONNECT 与普通 HTTP 路径。对应提交:8c8b8cc。该改动为后端逻辑,无 UI 变更(截图不适用)。

Copilot AI changed the title Implement HTTP relay proxy with upstream load balancing (round-robin/best/priority), captive-style health checking, and hot reload Implement HTTP relay proxy with upstream load balancing (round-robin/best/priority), captive-style health checking, domain blacklist/whitelist routing, and hot reload Mar 21, 2026
@MejiroRina
Copy link
Copy Markdown
Member

@copilot 忘了说了,域名要支持domain和domain suffix之类的表达方法,并且最后为这个项目添加AGENTS.md和copilot-Instructions.md

Copy link
Copy Markdown
Contributor Author

Copilot AI commented Mar 21, 2026

@copilot 忘了说了,域名要支持domain和domain suffix之类的表达方法,并且最后为这个项目添加AGENTS.md和copilot-Instructions.md

已补充域名表达方式支持:domain:example.com(精确)、suffix:example.com(后缀)、*.example.com/.example.com(后缀简写),并保持 example.com 的兼容匹配;同时已新增项目根目录 AGENTS.mdcopilot-Instructions.md。对应提交:cabf28a。该改动为后端与文档变更,无 UI 变更(截图不适用)。

Copilot AI changed the title Implement HTTP relay proxy with upstream load balancing (round-robin/best/priority), captive-style health checking, domain blacklist/whitelist routing, and hot reload Implement HTTP relay proxy with upstream load balancing (round-robin/best/priority), captive-style health checking, domain blacklist/whitelist routing with domain-expression matching, and hot reload Mar 21, 2026
@MejiroRina MejiroRina marked this pull request as ready for review March 22, 2026 23:03
@MejiroRina MejiroRina merged commit 46cb774 into main Mar 22, 2026
10 checks passed
@MejiroRina MejiroRina deleted the copilot/http-relay-implementation branch March 22, 2026 23:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants