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
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.
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.
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.
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.
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.
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.
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.
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.
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.
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
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.
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.
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.
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.
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
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
* 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>
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.
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.
- 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
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.
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`.