2054 Commits

Author SHA1 Message Date
yusing 2160bdae3a chore(deps): bump golang.org/x chain, quic-go, and refresh module pins
Raise golang.org/x/crypto, x/net, x/text, x/mod, and x/tools across the
root and nested Go modules, bump quic-go to v0.59.1 in agent and bench
binaries, and align socket-proxy on the newer x/net and x/text releases.

Refresh local replace pins for godoxy/agent and internal/dnsproviders and
advance goutils/http, goutils/server, and goutils/cache pseudoversions;
advance the goutils and webui git submodules.

Submodule goutils:
   dd3d03787386d8d3993a7eab312649fea94a81e1
Submodule webui:
   f121ebbca59004edac0decdecd4a38ba522ad80f
2026-05-11 13:34:22 +08:00
yusing 7bc5b561cb chore(deps): bump Go modules to 1.26.3 and refresh dependency pins
Update root and nested module `go.mod`/`go.sum` files to Go 1.26.3 and
align shared dependency versions, including docker/cli, fasthttp, and x/sys.
Sync internal references to latest godoxy/goutils revisions and advance the
`goutils` submodule pointer.

Bump all Dockerfile to use Go 1.26.3

Submodule goutils:

  c11edd03d3b1bcc1e61d0ae6b011042234ca3d58 chore(deps): bump module Go and golang.org/x dependency versions
  Raise all module `go` directives from 1.26.2 to 1.26.3 and upgrade
  `golang.org/x/sys` to v0.44.0 across root, cache, http, and server
  modules.
2026-05-08 22:40:16 +08:00
yusing 344a6dba93 feat(route): add do command option blocks and ordered help
Replace command help arg maps with ordered helpArgs/helpArg definitions so
positional order matches validation and cheatsheet extraction.

Extend parseDoWithBlocks to accept `{ name: value }` bodies that flatten to the
same positional arguments as CLI form, with validation for missing keys,
unknown keys, duplicates, and scalar values only. Teach rules-cheatsheet-gen to
extract helpArgs() from AST; update README and tests.

Update webui submodule:

  d58bdde52a992f323e865d5002a3f6dac043068b feat(webui): add RuleDo option-block typing and pass/bypass variants
  Introduce RuleDoCommandName and RuleDoOptionBlock so `do` commands can be
  typed as named braced option blocks with positional option lines. Wire
  RuleDoOptionBlock, RuleDoPass, and RuleDoBypass into RuleDo and extend the
  RuleDo examples with a multiline notify block.

  Update wiki submodule:

    47623f9b2a899c2c7eedf521e4b875fdf14a8d01 docs(wiki): document named option blocks for route rule actions
    Expand the Actions reference and routing guide with YAML option-block
    syntax (keys mirror positional arguments), rules forbidding mixing inline
    and named forms, scalar-only values, and rejection of unknown or duplicate
    keys. Clarify that braced YAML maps after actions are option blocks whereas
    logical headers introduce nested conditional chains.

    Extend impl/internal-route-rules `do_stmt` productions with command_block
    and explain flattening named options into positional arguments before normal
    validation.
2026-05-06 17:31:37 +08:00
yusing ed5c0abe81 chore: refresh screenshots 2026-05-05 23:36:59 +08:00
yusing f8d0257011 refactor(route): remove path_patterns; sync OpenAPI and webui submodule
Drop PathPatterns from the Route model and remove FileServer path-pattern
mux wiring. Strip path_patterns from provider examples and docker label
tests.

Refresh Swagger (max_conns_per_host, remove path_patterns; reorder
load_avg fields) and bump webui to 77af2589.

submodule webui:

  77af25899ff4c4de7de5bb81b9bf4ac7d276e4aa chore(types,ui): remove path_patterns from types and ui
  Regenerated json schema

  f64b2e8f85eec683b8e9258c23e3398c4ba828ed chore: update wiki
  2e5ea789845032b4ad99325e824db8d6dc351fd0 chore(godoxy): sync impl docs and swagger

  ec840613ae7a9a5fb0e3c79caf2aa88ee1cef202 docs(godoxy): inline docker stats in benchmarks and refresh gallery images
  Replace the resource usage screenshot with a fenced `docker stats` excerpt
  and drop `docker-stats.png`. Update gallery assets for idlesleeper, routes,
  servers, and webui.
v0.29.1
2026-05-05 17:53:27 +08:00
yusing 93d526bd63 fix(route): wrap FileServer handlers with middleware after rules
Reorder FileServer.prepareHandler so Rules.BuildHandler runs before the
middleware chain. Middleware now sees responses from rule handlers (e.g.
embedded WebUI API routes), not only the static file handler.

Run header-only middleware via LazyResponseModifier SetModifyResponse and
body rewriting separately (modifyResponseHeadersOnly /
modifyResponseBodyOnly). Update rewrite-gate expectations and add a webui
smoke test for themed HTML plus response headers on SPA and /api paths.

submodule goutils:

  a4fd3da67a05a570d17cd4fddae1f436ec8059ad feat(http): run ModifyResponse before lazy buffering decision
  Add SetModifyRequest wiring plus optional ModifyResponseFunc on LazyResponseModifier.
  Invoke it in decide() with a synthetic Response (status, headers, request) before
  shouldBuffer chooses buffering vs passthrough. Propagate the resulting status into
  WriteHeader/Write and gate passthrough headers with headerSent so implicit writes
  still send headers once.
2026-05-05 17:52:08 +08:00
yusing 17f486cfe0 chore(scripts): add idlesleeper WebP recorder and shrink screenshot
Add Bun script that drives headless Chromium via CDP, captures JPEG frames,
encodes an animated WebP with ffmpeg, and copies into the wiki gallery path.
Regenerate screenshots/idlesleeper.webp for updated loading page visuals.
2026-05-05 17:37:47 +08:00
yusing e8de6912f0 chore(scripts): portable setup.sh and README curl invoke sh
Rewrite scripts/setup.sh for POSIX sh: replace bash arrays and sed -i with
portable loops and a temp-file sed helper; use id/read patterns that work on
dash, busybox, and BSD shells.

Point README install curls at /bin/sh -c; ensure_benchmark_cert.sh now uses a
bash shebang and [[ ]] for existence checks.
2026-05-05 15:14:52 +08:00
yusing 232e7fad41 feat(rules): add serve_file terminating command
Add serve_file to validate an existing non-directory path and respond with
http.ServeFile. README distinguishes serve (directory) from serve_file
(single file) and adds a favicon example.

Extend parse/block/YAML HTTP-flow tests for the new action. Bump webui
submodule to 2a937ccf.
v0.29.0
2026-05-05 12:52:59 +08:00
yusing 5fd9b01006 fix(deps): bump goutils for gRPC/SSE flush; add regression tests
Bump the goutils submodule to f91a3042: flush after WriteHeader for
gRPC/SSE, passthrough ResponseModifier Flush support, and treat
unsupported Flush as non-fatal during copy.

Add integration tests: h2c reverse proxy with rules surfaces grpc headers
before the body; middleware and rules paths accept buffered writers that
reject Flush.
2026-05-05 12:52:59 +08:00
yusing 3feb3e44b4 chore(deps): bump goutils submodule and refresh Go module pins
Bump the goutils submodule and align root goutils/* and godoxy sub-module
pseudo-versions. Refresh agent and internal/dnsproviders for grpc, docker/cli,
fsnotify, gopsutil, and related transitive updates. In agent, list sonic as an
indirect dependency.
2026-05-05 12:52:58 +08:00
yusing 22d648800e feat(webui): assemble Web UI route rules from presets and config
Wire `newWebUIRoute` to use `rules.Rules` built by `loadWebUIRules`, which clones
preset rules from `webui.yml`/`webui_dev.yml` and appends `WebUI.rules`. Add
`WebUIConfig.Rules`, merge coverage in `webui_rules_test.go`, adjust the dev
server readiness non-2xx case to HTTP 500, and drop `webui_route_test.go`.

---

webui submodule @ 9bf564c2dcbe904d409b4f58514c9b6e7071b926
feat(webui): add rules section to Web UI server route form

Extend WebUIConfig with optional rules and reuse RouteRulesSection in the
settings form. Update the route card copy to mention extra rules.

Update config schema
2026-05-05 12:52:58 +08:00
yusing 2fea900dca refactor(gphttp): drop CIDR whitelist RemoteAddr cache and add benchmark
Remove the xsync per-address cache and resolve allow/deny via ipInCIDRs
after a successful SplitHostPort of RemoteAddr.

Add BenchmarkCIDRWhitelist sub-benchmarks for matching and non-matching
IPs with a noop ResponseWriter.
2026-05-05 12:52:58 +08:00
yusing 29b103d588 fix(route): align unexpected-error filter with HTTP/2 cancel and closed body
Bump goutils submodule.

Link `errClosedResponseBody` and ignore `http2.ErrCodeCancel` alongside stream
closed in `isUnexpectedError`.
2026-05-05 12:52:34 +08:00
yusing 403ce09d57 perf(homepage): parallel icon updates and xsync-backed icon cache
Replace the icon list map with xsync.Map stored behind atomic.Pointer, and
clear the map on test teardown instead of mutating a shared Go map.

Fetch WalkxCode and SelfhSt icon manifests concurrently under one timeout;
thread context through httpGet and reuse a 5s-timeout http.Client.
2026-05-05 12:52:34 +08:00
yusing 9ae7fe9cd9 chore: cleanup .gitignore 2026-05-05 12:52:34 +08:00
yusing 482f344814 feat(bench): add benchmark profiles and repeatable throughput summaries
Introduce BENCH_PROFILE (smoke/stable/stress) with presets for duration,
concurrency, streams, requests, latency samples, startup wait, and RUNS.

Add --profile and smoke/stable/stress aliases; RUNS and REPEAT_DELAY repeat
h2load/h3bench runs and print median/CV stats. Parse throughput and failed
counts from captured output; extend h2load noise filtering. Default HOST via
HOST when unset.
2026-05-05 12:52:33 +08:00
yusing 5995e02587 feat(route): add max_conns_per_host for proxy HTTP transport
Add HTTPConfig.max_conns_per_host and set the reverse proxy transport’s
MaxConnsPerHost when non-zero. Extend JSON deserialization tests and bump
the webui submodule.
2026-05-05 12:52:33 +08:00
yusing a6de9060e2 feat(rules): add rules-cheatsheet-gen, webui build hook, and richer Help
Add cmd/rules-cheatsheet-gen to parse internal/route/rules with go/ast and emit
indented JSON for the webui cheatsheet. Require -out; Makefile adds
gen-rules-cheatsheet and runs it from build-webui before gen-schema. Include
generator tests; bump webui submodule.

Enrich Help on matchers, mutation fields, and variables for cheatsheet
extraction (descriptions, examples, clearer arg labels). Static var maps wrap
getters in reqVar/respVar; dynamic var keys are const with Help on each entry.
Clarify log and notify action help intros in do.go.

Update WebUI submodule to include quick reference card in rules playground
2026-05-05 12:52:33 +08:00
yusing 8b80944531 fix(metrics): ignore context.Canceled in period poller errors
Skip appending poll failures when the error is cancellation, so timeouts
and shutdown do not inflate the poller error history.
2026-05-05 12:52:33 +08:00
yusing 938d8cd255 fix(update-wiki): tolerate READMEs without ## and omit webui from impl docs
md2mdx no longer exits when no level-two heading is present; the whole file
feeds frontmatter and the synthesized body stays empty.

Add webui/ to excluded readme roots alongside other vendored trees. Extend
tests for md2mdx without H2 and for syncImplDocs ignoring webui/README.md.
2026-05-05 12:52:33 +08:00
yusing 0e4dfcdc7d feat(webui): submodule build, Dockerfile targets, embedded SPA routes
Add godoxy-webui submodule and Dockerfile stages that install Bun/Node,
run schema generation, produce a production Vite build, copy dist into the
main image, and publish separate scratch targets for agent and
socket-proxy. Makefile defaults WEBUI_DIR to ./webui, adds build-webui
and ensure-webui-dist for embedded builds/tests, introduces dev=1 and
updates `dev`/`dev-build`; docker-build-test pins build targets and the
workflow forwards targets to buildx.

Load `webui` YAML aliases (fallback to legacy frontend env aliases when
unset). Serve production UI from embedded `fs.FS` fileservers with SPA
routing and presets; in non-production, when `./webui` is present,
register a localhost Vite dev proxy (`webui_dev.yml`) and optionally
auto-start bun dev server. Attach webui compose volume; switch dev base
image to Bun; drop the standalone frontend service and related env hints.

Extend static-provider handling, preset rules/metadata, fileserver SPA
behavior for RootFS roots, README/examples, smoke/config tests; bump
the webui submodule pin.
2026-05-05 12:52:33 +08:00
yusing cf8ce25097 docs(agents): note Swagger ignores, Bun in webui, PrependSubject subject
Extend the AGENTS repo map: point agents at generated Swagger under
internal/api/v1/docs as ignored in broad searches, list Bun with Vite for
webui tooling, and clarify PrependSubject is for object-identifying
context—not the error title.
2026-05-05 12:52:33 +08:00
yusing bb6ce9f049 feat(agent): optional config persist on verify with reload suppression
Add add_to_config to append verified hosts under providers.agents via YAML round-
trip, suppress one matching config-file watcher reload while active, clear
suppression when persist fails, and return VerifyNewAgentResponse listing current
agents instead of SuccessResponse.

Introduce reload suppression helpers under internal/config/types; OnConfigChange
ignores empty event batches and consumes suppression before reloading. Add
injectable reloadConfig plus tests.

Regenerate Swagger for verify request/response; includes related definition tweaks.
2026-05-05 12:52:33 +08:00
yusing 8085fca2b4 fix(agent): POSIX root check and strict release timestamp parsing
Replace EUID with id -u for non-bash shells. Require the cached release epoch
to be a non-negative integer string before comparing to the API timestamp, so
invalid version file contents do not trigger a false up-to-date match.
2026-05-05 12:52:33 +08:00
yusing 9d0c3a2d2e feat(agent): OpenRC installs, POSIX sh, and portable release checks
Add systemd vs OpenRC detection, openrc-run service generation, and
/etc/conf.d env layout on Alpine; abstract enable/start/stop/disable.

Switch shebang to sh, fix bashisms (read, redirects); compare release
timestamps with jq fromdateiso8601 instead of GNU date -d for
Alpine/BusyBox.

Record the installed release epoch in the agent data directory and
compare updates portably via GNU or BSD stat fallbacks; stop using
touch -d on the binary. Document dual init and sh invocations in
README, README_CHT, and the bare_metal template.
2026-05-05 12:52:33 +08:00
yusing 43dc25b125 ci(docker): fold nightly image CI into docker-image-nightly; drop compat workflow
Remove docker-image-compat.yml. Extend docker-image-nightly.yml with the gated
push/pull_request triggers, nightly tags for main and agent, GraphQL-based open
PR skipping (with reason output), and logging/reporting for gate decisions.

Stops building compat-tagged images from Actions for the compat branch; compat
workflow file is deleted.
2026-05-05 12:52:33 +08:00
yusing 240c7f59ba feat(serialization): gate Sonic JSON behind USE_SONIC_JSON
Register Sonic in init only when USE_SONIC_JSON is true (default); set
false to avoid SIGILL on hardware Sonic does not support.

Remove Makefile BRANCH-based sonic build tag; document the variable in
.env.example, rootless.env.example, agent compose template, and
install-agent.sh. Log enabled state and a troubleshooting tip in the
agent; refresh agent README bare-metal install link to install-agent.sh.
Expand internal/serialization README with behavior table and pointers.
2026-05-05 12:52:33 +08:00
yusing 32170509dc refactor(json): centralize marshal/unmarshal via goutils/strings
Replace direct sonic calls with `strutils` helpers (`MarshalJSON`, `UnmarshalJSON`,
`NewJSONEncoder`/`Decoder`, `MarshalJSONIndent`) across agent and internal packages;
blank-import `internal/serialization` where the sonic backend must register.
Bump `goutils` for the helpers; align entrypoint benchmark listener with `:18080` and
set `Listening` on the synthetic route.

Refresh package README examples and dependency notes accordingly.
2026-05-05 12:52:33 +08:00
yusing 85def6a893 fix(accesslog): harden ResponseRecorder hijack/status; bench tolerates loader exit
Track wroteHeader and hijacked; use ResponseController for Hijack and FlushError;
record 101 on hijack and suppress duplicate informational status lines (except 101).
Write and Flush imply 200 before delegating when no header yet; hijacked callers get
ErrHijacked.

benchmark.sh: run_h2load/run_h3bench capture PIPESTATUS/status, warn on failure, and
continue so non-2xx or stream failures still show in output while keeping h2load
noise filtering inside the wrapper.

- goutils: 63f33445338651cd359b5aa4a013cb72aa8daa54

  fix(http): skip WriteHeader and access error logging on ErrHijacked

  When errors.Is matches http.ErrHijacked, trace-log only and return from
  errorHandler so we do not emit error-level logs, WriteHeader(500), or
  AccessLogger.LogError after the connection is hijacked.
2026-05-05 12:52:33 +08:00
yusing 5fa5b51b29 perf(bench): add h2load warm-up for reused runs and per-restart readiness
Introduce H2LOAD_WARM_UP_TIME (default 3s, 0 disables) with h2load-style
validation and pass --warm-up-time to reused h2load HTTP/1.1, HTTP/2, and
HTTP/3 runs; log it in the config summary and reused benchmark header.

Drop the global connection-test loop before benchmarks; run the probe only
after restart_bench for the service being benchmarked and exit on failure.
2026-05-05 12:52:32 +08:00
yusing d3d9b6b34f perf(bench): serve bench_server over raw TCP HTTP/1.1
Replace net/http with a TCP listener, manual HTTP/1.1 parsing, prebuilt
responses for static routes, chunked stream/SSE, and minimal WebSocket
handling without gorilla/websocket.

benchmark.sh brings up bench plus any paired compose service, uses
BENCH_STARTUP_WAIT after restart, probes readiness before reused HTTP/1.1,
HTTP/2, and HTTP/3 runs, and passes -t 0 to compose down. Un-ignore
dev.compose.yml under the *.compose.yml rule and refresh the bench service
comment in dev.compose.yml.
2026-05-05 12:52:32 +08:00
yusing 40d681f717 fix(route): guard nil routes during provider load
When iterating routes in loadRoutes, ensure each alias maps to a non-nil
Route before setting Alias, provider, and Validate. Avoids panics or
skipped validation if the route map contains nil entries.
2026-05-05 12:52:32 +08:00
yusing fcc3219f72 test(gphttp): stabilize bypass middleware entrypoint listener tests
Replace the magic listening port with a dedicated high test port and look up the
entrypoint server using the route’s ListenURL port so tests stay aligned with
the route configuration.
2026-05-05 12:52:32 +08:00
yusing 6d0c83fae3 docs(agents): expand repo map for wiki/webui and condense lists
Restructure Repo Map into proxy, Wiki, and web frontend subsections
with anchor paths for documentation and UI tooling.

Shorten the module-boundaries note, documentation reminder, Go Patterns
list, and Testing section for quicker scanning.
2026-05-05 12:52:32 +08:00
yusing b389d84bf8 perf(entrypoint): direct HTTPS accept until first TCP SNI route registers
Before any TCP SNI route exists for a shared HTTPS listener, sniListener.Accept
delegates straight to the wrapped net.Listener so normal HTTPS skips ClientHello
sniffing, background accepts, and replay queueing.

After the first registration, flip to a sniffing accept loop with per-listener
copy-on-write route tables behind atomic.Pointer; replay non-matching handshakes
to HTTPS through an unbounded lock-free MPSC queue using eventfd/Poll wakeups.

Promote golang.org/x/sys to a direct dependency for unix; add SNI router benchmarks
and fast-path coverage; expand entrypoint and stream README notes on shared HTTPS
SNI handoff.
2026-05-05 12:52:32 +08:00
yusing f02568b8e6 feat(bench): expand bench_server, add h3bench, and compose benchmark tooling
Extend bench_server with JSON, upload, streaming, SSE, and WebSocket routes;
add optional probe mode for http, sse, and ws over HTTP/1.1, HTTP/2, and
HTTP/3 with dial/TTFB/total timing.

Add cmd/h3bench, ensure_benchmark_cert.sh, and dev.compose wiring; drive
benchmarks through scripts/benchmark.sh. Makefile adds help, uses /bin/sh,
fixes gomod_paths discovery, and delegates the benchmark target to the
script.
2026-05-05 12:52:32 +08:00
yusing 971d968a63 feat(entrypoint): gate shared-HTTPS TCP SNI routing behind env toggle
Add SNI_ROUTING_FOR_TCP_ROUTES (default true). Document GODOXY_SNI_ROUTING_
FOR_TCP_ROUTES in .env.example. When disabled, HTTPS skips the SNI
passthrough listener and adding TCP/stream routes bound to that listener
errors.

Bump the HTTPS forward queue to 4096. Extend sni_passthrough tests for
burst queuing, plain HTTPS listen, and rejected TCP routes when disabled.

This commit is an continuation of 5c7838bbfe.
2026-05-05 12:52:32 +08:00
yusing 1269a8aaaf chore(examples): refine netbird compose proxy rules and embedded config
Tighten gRPC and API path globs, route `application/grpc*` to
netbird-grpc, and drop the default pass rule. Replace the host
`config.yaml` bind mount with a compose `configs` entry and inlined
server settings. Append commented dashboard env notes for OIDC.
2026-05-05 12:52:32 +08:00
yusing a94c23a1d5 docs(agents): add proxy/route repo map and refresh agent guidance
Replace the old Principles section with concrete entry points for route and
proxy debugging, and note that root, agent, and goutils are separate modules
for tests.

Expand the documentation reminder to wiki and webui types. Rename Go
Guidelines to Go Patterns, drop the golang-best-practices skill bullet, and
renumber the remaining items.
2026-05-01 17:54:35 +08:00
yusing 6b786aee33 fix(route): use passthrough ResponseModifier for rule sets without post-phase work
When no rule installs post matchers or post commands, initialize the outbound
modifier with NewPassthroughResponseModifier so upstream writes and flushes reach
clients without waiting for buffering to complete.

Otherwise use GetInitResponseModifier rather than unconditionally calling
NewResponseModifier.

Add PhaseFlag.IsPreOnly, extend the README upstream-phase section, and add an
HTTP flow test that asserts early streamed write and flush with pre-only rules.
2026-05-01 17:50:22 +08:00
yusing f6fbfc1512 chore(goutils): update submodule
57176206f02e4c195d93826edaa1bee31762e70c fix(http): flush passthrough ResponseModifier writes and finalize modified bodies
Add NewPassthroughResponseModifier for direct forwarding when buffering would
break streaming. After successful passthrough writes, flush via
ResponseController when supported; append errors except ErrNotSupported.

FlushRelease in passthrough mode now commits headers and writes buffered
content when the body was modified. LazyResponseModifier obtains its buffered
modifier via GetInitResponseModifier instead of NewResponseModifier. Document
why ResponseModifier keeps Unwrap/Flush unavailable without buffering.

39d1e79dbedab541152a4b6add67fa959576f359 fix(http): skip error WriteHeader on upgrade response write/flush failures

After the proxied upgrade response is written, write or flush errors are
still reported via errorHandler but must not call WriteHeader(500).
Headers may already be committed; pass writeHeader false so we only log.
2026-05-01 17:49:30 +08:00
yusing 47d5bc2102 chore(dev,compose): use .env, add dev test services, quieter Makefile go targets
Use `.env` instead of `dev.env` on the main dev proxy; drop DEBUG there and
enable it on host-network `app-test`. Add `app-test`, `idlewatcher-test`
(idle/wake labels), `stash` (issue 222 themed middleware css), and `bentopdf`.

Prefix the multi-module Makefile loops with `@`, echo each module path before
`cd`, and trim trailing blank lines in the embedded bench nginx config.
2026-05-01 13:21:21 +08:00
Yuzerion 5c7838bbfe Feat/tls passthrough (#230)
* feat(entrypoint): multiplex HTTPS TCP routes by TLS SNI with tls_termination

Add an SNI router on the shared HTTPS listener that inspects TLS ClientHello
SNI, matches TCP routes by alias while honoring domain filters, and either
forwards TLS end-to-end without termination or terminates with autocert before
plaintext upstream relay when tls_termination is enabled.

Wire TCPTCPStream and idlewatcher through ConnProxy.ProxyConn instead of inline
handlers. Validate tls_termination for TCP schemes only and refresh README and
config examples. Bump internal/go-oidc submodule.

* fix(entrypoint,route): align SNI shared HTTPS listen addrs and gate tls_termination

Compare listen addresses with SplitHostPort so empty, 0.0.0.0, and ::
wildcard hosts on the HTTPS port match the proxy’s shared HTTPS address
for SNI route registration, keys, and passthrough eligibility.

Require tls_termination TCP routes to listen on that shared HTTPS
listener; add tests for address equality and validation.

* refactor(net,entrypoint,route): centralize shared HTTPS listener matching helpers

Move equivalence logic next to ProxyHTTPSAddr into internal/net/listen_addr.go and use it from SNI passthrough and tls_termination validation, dropping duplicated helpers.

Close the SNI listener and finish the http_server task when StartServer fails after SNI Listen. Update README examples for autocert-gated tls_termination and HTTPS_ADDR-relative ports.

* feat(entrypoint,net): open SNI HTTPS listener without autocert; widen wildcard host checks

Remove the autocert guard so the shared HTTPS listener still starts the SNI
multiplexer for passthrough when no certificate provider is configured.

Extend IsWildcardListenHost for trimmed input, host:port and bracketed IPv6,
using net.ParseIP and IsUnspecified for IPv4/IPv6. Add listen_addr tests,
README detail, and align SNI passthrough tests with ProxyHTTPSAddr.

* fix: apply CodeRabbit auto-fixes

Fixed 2 file(s) based on 2 unresolved review comments.

Co-authored-by: CodeRabbit <noreply@coderabbit.ai>

* test(dev,compose): add TCP echo fixture and SNI passthrough smoke test

Wire `cmd/tcp_echo_server` with plaintext and self-signed TLS listeners,
dev.compose labels for passthrough and `tls_termination` aliases, and
`scripts/tcp_echo_test.ts` invoked by `make tcp-echo-test` via bun.

---------

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: CodeRabbit <noreply@coderabbit.ai>
2026-05-01 13:20:38 +08:00
yusing 87890a4159 test(route,agent): cover h2c grpc proxying in handler, docker labels, and rules
Add ProxyHTTP integration test with h2c backend asserting HTTP/2 and grpc
trailers. Extend docker label fixture for parallel http and h2c proxies on
the same container.

Add reverse-proxy tests for rules-selected h2c upstreams and for agent proxy
config headers: legacy agents map h2c to http; modern agents pass scheme h2c.
2026-05-01 12:21:15 +08:00
yusing 0d33016101 fix(agent): proxy HTTP with goutils reverseproxy and decode HTTPConfig only
Unmarshal header JSON into `cfg.HTTPConfig` so it matches the JSON payload.

Resolve scheme/host into a synthetic upstream URL, build TLS from that
target instead of the stripped client path, and replace
`httputil.ReverseProxy` with `reverseproxy.NewReverseProxy`. Pull
`goutils/http/reverseproxy` and `golang.org/x/net` in as direct agent
dependencies.
2026-05-01 12:19:17 +08:00
yusing ab36b5de8a chore(goutils): update submodule
- 0fad3ec0071e825cc55e3438cd3140727e3cd516 fix(http): preserve announced trailers when flushing a modified body

    When the modifier rewrote the body, FlushRelease always forced
    Content-Length and dropped Trailer before WriteHeader. Collect keys from
    Trailer first; with none, behavior stays length-based. With announced
    trailers, skip Content-Length so the response can use chunked framing,
    then move those header values onto trailer-prefixed headers after the
    body is written
2026-05-01 12:18:04 +08:00
yusing 6875525e9f fix(route): select agent proxy headers by agent version and type h2c as HTTP
Default to legacy `SetAgentProxyConfigHeadersLegacy` for agents below 0.18.6; use
`SetAgentProxyConfigHeaders` for newer agents (the assignments were swapped).

Treat `route.SchemeH2C` like HTTP/HTTPS in `Route.Type()` so it reports HTTP route
kind consistently.
2026-05-01 12:13:16 +08:00
yusing c34ef8160c chore(go-oidc): update submodule go-oidc bcfa54222d4092e054d351eb23cd8edb748188d1
Advance `internal/go-oidc` to include upstream dependency upgrades from that
submodule tip (`chore(deps): upgrade dependencies`).
2026-05-01 02:32:33 +08:00
yusing 95233e9352 chore(goutils): update submodule goutils
9a3a071cc6fa95b010a0625f5e6120fbba26bdbc chore(deps): bump go-isatty and websocket transitive pins
Bump github.com/mattn/go-isatty to v0.0.22 in the root module, http/
reverseproxy, integrationtest, websocket, and server.

In http/websocket, also bump bytedance/sonic, cloudwego/base64x, and
go.mongodb.org/mongo-driver/v2 alongside the tidied sums.

42e6b2fc1dde7c8bb33791912918a6a7ca51d976 chore(cache): add standalone cache module and refresh workspace go.mod files
Add `cache/go.mod` and `cache/go.sum` for `github.com/yusing/goutils/cache`
(backoff, xsync, zerolog, testify). Remove `cenkalti/backoff` from the root
module. Drop redundant indirect `xsync` lines from reverseproxy,
integrationtest, and websocket after tidying.

4018ae830107550c9509c10990083c2f00a7c9fc refactor(synk): drop sizedFullCaps xsync tracker and rewrite README
Remove the sizedFullCaps map initialization and import from synk pooling.

Rewrite synk/README for current getter names (GetSizedBytesPool, etc.),
GetAtLeast helpers, weakBuf/details, tier/index/split semantics, Put
routing, usage patterns, and the GetSized no-append caveat.

b5ed70b7e5cba5969336c8dabedf0da48be9c908 Merge pull request #2 from yusing/fix/proper-h2c-upgrade
- fix(http,io): h2c prior-knowledge gRPC proxying and streaming flush/copy

    Treat `h2c://` as cleartext HTTP/2 prior knowledge: normalize the outbound URL,
    strip bogus h2c upgrade headers while preserving `TE: trailers`, propagate
    `CloseIdleConnections` from the layered round tripper, and omit Connection
    Upgrade spoofing when already on h2c. Enable response full-duplex when the
    upstream request carries a body so half-close gRPC traffic can flow.

    Broaden flush heuristics so `CopyClose`/HTTP copying flushes `application/grpc`
    and unknown-length replies; add tests alongside reverseproxy grpc/h2c cases.

    Adds a sibling `integrationtest` module exercising real unary and bidi gRPC over
    proxied h2c without pulling grpc into the reverseproxy package.

- fix(http): propagate Transport.DisableCompression to h2c round tripper

    When the base round tripper is *http.Transport, copy DisableCompression into
    the inner http2.Transport used for cleartext HTTP/2. DialContext behavior is
    unchanged; only compression alignment with the HTTP/1 path is added.

8b871e11769fd9d8f399bd509b0875cf05e01436 docs(http): use DefaultTransport in README example and non-empty HTTP2-Settings in h2c test
Align the snippet with a concrete outbound transport instead of passing nil.

Use a sentinel HTTP2-Settings value so header stripping is exercised reliably.

b065e910fde6a03be4252c3bd01372825b882ae5 fix(http,io): h2c prior-knowledge gRPC proxying and streaming flush/copy
Treat `h2c://` as cleartext HTTP/2 prior knowledge: normalize the outbound URL,
strip bogus h2c upgrade headers while preserving `TE: trailers`, propagate
`CloseIdleConnections` from the layered round tripper, and omit Connection
Upgrade spoofing when already on h2c. Enable response full-duplex when the
upstream request carries a body so half-close gRPC traffic can flow.

Broaden flush heuristics so `CopyClose`/HTTP copying flushes `application/grpc`
and unknown-length replies; add tests alongside reverseproxy grpc/h2c cases.

Adds a sibling `integrationtest` module exercising real unary and bidi gRPC over
proxied h2c without pulling grpc into the reverseproxy package.

44b1950caf32ecd32f37e3922bf635fefcd9b15d fix(http): propagate Transport.DisableCompression to h2c round tripper
When the base round tripper is *http.Transport, copy DisableCompression into
the inner http2.Transport used for cleartext HTTP/2. DialContext behavior is
unchanged; only compression alignment with the HTTP/1 path is added.

b26a278d9e5224d62559924bab9cd68b6300c26a test(cache): remove redundant loop-variable shadowing in concurrent tests
Go 1.22 gives range loop variables per-iteration scope, so wg.Go closures can safely
capture the index and worker IDs without shadowing assignments like `i := i`.
2026-05-01 02:31:22 +08:00