Merge upstream/main into main#28
Merged
Merged
Conversation
… idle connection errors
fix: make badssl.com tests resilient to transient network failures
Danny-Dasilva#53) * ci(unit-tests): run macOS only for Python 3.13 to ease runner pressure Free-tier macOS runners are scarce; running the full 4-Python matrix on macOS queued 28+ jobs for 30+ minutes during a PR rebase storm. Linux covers the full Python matrix; macOS divergence (if any) surfaces on latest Python just as well as on older versions. * test(async-concurrent): mark large_concurrent_batch as live The 50-request burst against httpbin.org regularly trips the public service's rate limit / connection ceiling, producing context-deadline timeouts that aren't a cycletls bug. Move to the live-tests workflow so the blocking unit- tests pipeline isn't held hostage to httpbin.org reliability. * ci: re-trigger CI to clear stuck queue
…ny-Dasilva#47) * add build hint for codeql. * codeql did not detect the new workflow. * Add CodeQL analysis workflow configuration This file sets up a CodeQL workflow for analyzing code in multiple languages, including Go and Python, with scheduled runs and pull request checks. * update codeql build to manual. * add dependabot setting for golang. * update codeql buil.d * codeql fix v3 * build(deps): bump GitHub Actions to latest versions Consolidates all 4 dependabot PRs (#1-#4): - actions/setup-python: v5 → v6 (PR #1) - actions/upload-artifact: v4 → v7 (PR #2) - actions/setup-go: v5 → v6 (PR #3) - actions/download-artifact: v4 → v8 (PR #4) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * ci(codeql): pin setup-go to v6 for consistency with other workflows * ci: re-trigger after rebase on slim-matrix main --------- Co-authored-by: Stefan Meinecke <meinecke@greensec.de> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
…p-alives (Danny-Dasilva#51) * fix(transport): lower IdleConnTimeout 90s -> 60s to undercut peer keep-alives All four http.Transport literals in roundtripper.go declared IdleConnTimeout: 90 * time.Second. Most servers behind nginx idle-close at ~65-75s (and badssl in particular at ~70s), so the 90s window guaranteed that any second request after a brief pause checked out a peer-closed connection from the idle pool. The transport then surfaced bare 'EOF' or 'http: server closed idle connection' to the caller. Lower to 60s. This matches Go's net/http stdlib default and gives a 5-10s safety margin under typical peer keep-alive windows. Tests: golang/roundtripper_test.go - source-level invariants pin the 60s upper bound across all 4 transport sites and assert no IdleConnTimeout: 90 declarations regress. * ci: re-trigger after rebase on slim-matrix main
…lva#54) Bumps [softprops/action-gh-release](https://github.com/softprops/action-gh-release) from 2 to 3. - [Changelog](https://github.com/softprops/action-gh-release/blob/master/CHANGELOG.md) - [Commits](softprops/action-gh-release@v2...v3) --- updated-dependencies: - dependency-name: softprops/action-gh-release dependency-version: '3' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 6. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](actions/checkout@v4...v6) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: '6' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [actions/setup-python](https://github.com/actions/setup-python) from 5 to 6. - [Release notes](https://github.com/actions/setup-python/releases) - [Commits](actions/setup-python@v5...v6) --- updated-dependencies: - dependency-name: actions/setup-python dependency-version: '6' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [actions/setup-go](https://github.com/actions/setup-go) from 5 to 6. - [Release notes](https://github.com/actions/setup-go/releases) - [Commits](actions/setup-go@v5...v6) --- updated-dependencies: - dependency-name: actions/setup-go dependency-version: '6' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
The Linux wheel was compiled against glibc 2.32+ (ubuntu-latest), making it incompatible with Debian Bullseye (glibc 2.31) and similar older distros still in production. Use zig cc with `-target x86_64-linux-gnu.2.17` as the CGO compiler so the resulting libcycletls.so works on any Linux with glibc >= 2.17. Co-authored-by: Danny Dasilva <yahchayildasilva@gmail.com>
…anny-Dasilva#48) * fix(tests): mark badssl.com tests as live; fix CHANGELOG fetch-depth * ci: re-trigger after rebase on slim-matrix main
…pAlives=true (Danny-Dasilva#52) * ci: re-trigger after rebase on slim-matrix main * fix(transport): propagate enable_connection_reuse=False as DisableKeepAlives=true Previously enable_connection_reuse=False bypassed the global fhttp.Client cache (client.go:249) but every http.Transport literal in roundtripper.go hardcoded DisableKeepAlives: false. The inner transport therefore still pooled idle connections across requests on the same client instance — so the flag only avoided cross-test client reuse, not stale-conn races within a single test. Plumb the flag end-to-end: - Add Browser.DisableKeepAlives (client.go) — Browser is the boundary the flag flows through into newRoundTripper. - Add roundTripper.DisableKeepAlives, set in newRoundTripper from the Browser field. - Bind all 4 http.Transport literals in roundtripper.go to rt.DisableKeepAlives instead of the hardcoded false. - In getOrCreateClient: when enableConnectionReuse=false, set browser.DisableKeepAlives = true before constructing the client. Default behaviour is preserved: when the flag is absent or true, DisableKeepAlives ends up false on every transport, exactly as before. Tests: golang/roundtripper_test.go pins propagation through Browser → roundTripper, exercises the HTTP-scheme transport via getTransport, and asserts the source-level invariant that no DisableKeepAlives: false hard binding remains. * ci: re-trigger after rebase on slim-matrix main * ci: trigger after base change to main * ci: re-trigger after rebase on action-bumps main
…lva#62) Bumps [github.com/gorilla/websocket](https://github.com/gorilla/websocket) from 1.5.1 to 1.5.3. - [Release notes](https://github.com/gorilla/websocket/releases) - [Commits](gorilla/websocket@v1.5.1...v1.5.3) --- updated-dependencies: - dependency-name: github.com/gorilla/websocket dependency-version: 1.5.3 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…anny-Dasilva#59) Bumps [github.com/refraction-networking/utls](https://github.com/refraction-networking/utls) from 1.8.0 to 1.8.2. - [Release notes](https://github.com/refraction-networking/utls/releases) - [Commits](refraction-networking/utls@v1.8.0...v1.8.2) --- updated-dependencies: - dependency-name: github.com/refraction-networking/utls dependency-version: 1.8.2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…anny-Dasilva#66) Audit of utls 1.8.x parrot map (genMap) revealed three pre-existing gaps where dedicated utls extension types existed but genMap fell back to GenericExtension. Replacing them with the proper types lets utls own the wire encoding (including any future bugfixes) and removes hand-rolled byte payloads: - ID 17 (status_request_v2): GenericExtension -> StatusRequestV2Extension (proper RFC 6961 encoding instead of zero-length GenericExtension) - ID 17613 (TLS ALPS new codepoint): GenericExtension -> ApplicationSettingsExtensionNew Hand-rolled 5-byte payload {0x00,0x03,0x02,0x68,0x32} replaced by SupportedProtocols-driven encoding identical to ID 17513. - ID 30032 (Channel ID): GenericExtension(Id:0x7550, Data:{0}) -> FakeChannelIDExtension{}. Wire format also corrected: real Chrome ChannelID is a 4-byte zero-payload extension, the previous GenericExtension emitted 5 bytes (length=1). ID 51 (KeyShare), ID 43 (SupportedVersions), IDs 10/11 (curves/points) remain populated by callers because they depend on per-call inputs (version, GREASE flag, JA3 curves). ID 65037 (GREASE_ECH) is already correctly using utls.BoringGREASEECH(). IDs 22 (encrypt_then_mac) and 49 (post_handshake_auth) intentionally stay as GenericExtension because utls does not provide dedicated types for them. go build ./... and go test ./... -short pass.
…anny-Dasilva#63) Bumps [golang.org/x/net](https://github.com/golang/net) from 0.42.0 to 0.53.0. - [Commits](golang/net@v0.42.0...v0.53.0) --- updated-dependencies: - dependency-name: golang.org/x/net dependency-version: 0.53.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…a#60) Bumps [github.com/quic-go/quic-go](https://github.com/quic-go/quic-go) from 0.53.0 to 0.59.0. - [Release notes](https://github.com/quic-go/quic-go/releases) - [Commits](quic-go/quic-go@v0.53.0...v0.59.0) --- updated-dependencies: - dependency-name: github.com/quic-go/quic-go dependency-version: 0.59.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…asilva#64) Bumps [github.com/valyala/fasthttp](https://github.com/valyala/fasthttp) from 1.69.0 to 1.70.0. - [Release notes](https://github.com/valyala/fasthttp/releases) - [Commits](valyala/fasthttp@v1.69.0...v1.70.0) --- updated-dependencies: - dependency-name: github.com/valyala/fasthttp dependency-version: 1.70.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…ilva#61) Bumps [github.com/andybalholm/brotli](https://github.com/andybalholm/brotli) from 1.2.0 to 1.2.1. - [Commits](andybalholm/brotli@v1.2.0...v1.2.1) --- updated-dependencies: - dependency-name: github.com/andybalholm/brotli dependency-version: 1.2.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 6. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](actions/checkout@v4...v6) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: '6' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…nstance (Danny-Dasilva#49) * feat: use local TrackMe instance for TLS fingerprint tests Replace hardcoded tls.peet.ws URLs with a TRACKME_URL environment variable (defaulting to https://tls.peet.ws for backward compatibility) so CI and local tests can run against a local TrackMe Docker instance. - Add docker/trackme/Dockerfile + config.json: builds TrackMe from GitHub (golang:1.24-alpine, no pcap/QUIC, ports 8443/8080) - Add docker-compose.test.yml: runs local TrackMe - Add scripts/setup-trackme-certs.sh: generates self-signed certs; prints SSL_CERT_FILE hint for no-sudo local testing - Update all test files (20 files) to read TRACKME_URL from env - Update blocking-tests.yml and live-tests.yml: - Generate self-signed TLS certs; combine with system CA bundle - Start TrackMe via docker compose and wait for health - Set TRACKME_URL + SSL_CERT_FILE for the test run Tested locally: 22/22 blocking tests pass against https://localhost:8443 * fix: use function-scoped fixtures in tlsfingerprint tests to avoid stale connections TrackMe closes connections after each request; module-scoped CycleTLS clients reuse stale connections from the pool, causing "use of closed network connection" errors. * fix: disable connection reuse in live tests against local TrackMe TrackMe closes TCP connections after each request. The Go transport (loaded as a shared library) caches TLS connections in a global pool; the next test reuses the already-closed connection, causing "use of closed network connection". Setting enable_connection_reuse=False per request forces a fresh roundTripper with empty cachedConnections, matching how the blocking tests already work. * fix: handle TrackMe HTTP/2 POST rejection and unpatched clients in live tests - test_post_method: TrackMe rejects non-GET via HTTP/2 RST_STREAM causing timeout; skip gracefully instead of failing - test_multiple_clients: explicitly pass enable_connection_reuse=False since these clients are created directly in the test body, bypassing the fixture wrapper * test: mark external-resource tests as live; add Python matrix to live CI Move test files that hit tls.peet.ws / scrapfly.io to the live test suite by adding `pytestmark = pytest.mark.live`, so they no longer run in the unit-test workflow (which has no network access to those endpoints). Expand the live-tests workflow to a Python 3.10–3.13 matrix (ubuntu-only, since TrackMe requires Docker) matching the breadth of the unit-test matrix. Affected test files: - test_async_ja3.py - test_force_http1.py - test_frame_headers.py - test_http2.py - test_http2_fingerprint.py - test_integration.py - test_ja3_fingerprints.py - test_ja4_fingerprints.py * fix: apply _no_reuse pattern to all live test fixtures hitting TrackMe TrackMe closes the TLS connection after every response. The global Go transport caches the closed connection; the next test gets "use of closed network connection". Fix by injecting enable_connection_reuse=False via setdefault in: - conftest.py cycletls_client (covers test_integration, test_http2_fingerprint, test_tls13) - test_force_http1.py client fixture - test_http2.py cycle fixture - test_ja3_fingerprints.py cycle_client fixture - test_ja4_fingerprints.py cycle_client fixture - test_async_ja3.py: add enable_connection_reuse=False to 5 individual requests that were missing it (async tests can't use the wrapper pattern) * refactor(tests): rename TRACKME_URL env var to TLSFP_URL Tests now read the local-server endpoint from TLSFP_URL instead of the TrackMe-specific TRACKME_URL. Default remains https://tls.peet.ws so local devs without the local server still hit production. The renamed fixture (trackme_url -> tlsfp_url) and updated docstrings reflect that the local target is Danny-Dasilva/tlsfingerprint.com (the source of tls.peet.ws), not the third-party TrackMe image. * ci(tests): launch Danny-Dasilva/tlsfingerprint.com Docker container for live tests Replaces the third-party TrackMe Docker setup that this PR originally added with the user's own tlsfingerprint.com server (the open-source code that powers tls.peet.ws). Both blocking-tests and live-tests workflows now: 1. Check out Danny-Dasilva/tlsfingerprint.com@master into .tlsfingerprint-server/ 2. Generate a self-signed cert via openssl 3. Patch config.example.json to disable mongo/log_to_db 4. Build + start the container via the upstream docker-compose.yml (NET_ADMIN/NET_RAW caps, ports 80/443/443-udp) 5. Wait up to 90s for /api/clean to respond 6. Inject TLSFP_URL=https://localhost and SSL_CERT_FILE so tests trust the self-signed cert and target the local server 7. Tear the container down at the end of the run Tests still fall back to https://tls.peet.ws when TLSFP_URL is unset, so local developers without Docker keep working against production. Adds tests/README.md documenting the local-dev path and test markers. * ci: re-trigger after rebase on slim-matrix main * ci: re-trigger * ci: re-trigger after rebase on action-bumps main * test(ja4): match JA4_r structurally to handle production vs local server padding * test(blocking): apply JA4_r structural matcher to test_tlsfingerprint_blocking too The previous commit (7ad1723) only patched tests/test_ja4_fingerprints.py. The blocking test module (tests/test_tlsfingerprint_blocking.py) still contained 5 exact-equality JA4_r assertions, including test_ja4r_tls12_fingerprint_exact_match which was the actual CI failure (production tls.peet.ws emits 't12d128h2' for 12 ciphers + 8 extensions unpadded; the local tlsfingerprint.com Docker emits the spec-padded 't12d1208h2'; equality fails). Promote parse_ja4r and assert_ja4r_equivalent helpers from test_ja4_fingerprints.py into tests/conftest.py as public names so they can be reused. Both test files now import from conftest. Replace the five JA4_r equality assertions in test_tlsfingerprint_blocking.py with structural matcher calls. * test: scope _no_reuse to TLSFP_URL so httpbin tests keep keep-alive The session-wide `enable_connection_reuse=False` wrapper was forcing fresh TLS handshakes for *every* request, including ones against httpbin.org. httpbin closes idle HTTP/1.1 connections aggressively, so disabling reuse there causes "server closed idle connection" / EOF errors on multi-request flows like: - test_http1_with_cookies (set cookie -> get cookie) - test_http1_with_redirects (redirect chain) These two tests fail consistently across all 4 Python versions in the Live Tests workflow. Fix: only force `enable_connection_reuse=False` when the URL is the local tlsfingerprint.com server (TLSFP_URL). Public endpoints (httpbin.org) keep the default keep-alive behaviour. --------- Co-authored-by: Stefan Meinecke <meinecke@greensec.de>
… JA3 corruption (replaces #40) (Danny-Dasilva#65) * feat: add local_address parameter to bind outgoing TCP connections to a specific local IP - Add default_local_address to config mapping and validation - Add local_address field to Request schema with serialization - Thread localAddress through Go client pooling, key generation, and dialer creation - Apply local IP binding to both direct connections and proxy connections - Validate local_address is a valid IP address before use * fix: Do() drops ServerName/TLS13AutoRetry/DisableGrease; dispatchSSEAsync infinite loop on cancel/EOF 1. Do() silently dropped ServerName, TLS13AutoRetry, and DisableGrease when building the Browser struct. These fields were added to processRequest() in upstream commits 36f5171 (Draft Release #400, adds ServerName+TLS13AutoRetry) and a483b68 (Release 2.0.4 #390, adds DisableGrease) but were never propagated to Do(). 2. dispatchSSEAsync used bare `break` inside `for { select { ... } }`, which only breaks out of the select, not the outer loop — causing an infinite spin on context cancellation, EOF, or read errors. Introduced in upstream 5990fef (Major Release 2.0.0 #387). Fixed by adding a `sseLoop:` label and using `break sseLoop`. * fix(go): preserve JA3 supported_groups in TLS13AutoRetry proactive upgrade convertJA3ForTLS13 was hard-coding tokens[3] = "29-23", silently dropping P-384 (24), P-521 (25), FFDHE2048 (256), FFDHE3072 (257) and any other groups from the JA3 string before the first handshake attempt. This made TLS13AutoRetry (enabled by default) corrupt the fingerprint being applied. Fix: filter the groups field using isTLS13CompatibleCurve() instead of replacing it, preserving all RFC 8446 §4.2.7 compatible NamedGroups in their original order. Also extend isTLS13CompatibleCurve() to include FFDHE groups (256-260) which are valid TLS 1.3 NamedGroups per RFC 7919 and are advertised by Firefox/Safari in the supported_groups extension. * docs+test: document local_address in api.py kwargs; add schema, validation and live tests * docs(changelog): note Go core fixes from Danny-Dasilva#65 * fix(go-core): apply localAddress to SOCKS/HTTPS-proxy/HTTP3 dial paths The PR #40 / Danny-Dasilva#65 localAddress implementation silently dropped the local-IP bind on three proxy/transport paths. This change closes those gaps so the LocalAddr the user provided actually controls the kernel-level bind on the client->proxy socket on every supported scheme. Gaps addressed (identified in the code-trace and network-research reports at .claude/cache/agents/{code-trace,network-research}-localaddress-proxy): 1. SOCKS proxies (connect.go) The localAddress -> baseDialer block ran AFTER the scheme switch's socks5/socks5h/socks4 early returns, so the SOCKS dialers never saw LocalAddr. baseDialer is now built before the switch and: - socks5/socks5h: passed as the forward Dialer to proxy.SOCKS5, so the TCP-to-proxy connect honors LocalAddr. - socks4: when localAddress is set, h12.io/socks (which always uses net.DialTimeout internally with no LocalAddr hook) is bypassed via a small in-package socks4ContextDialer that performs the CONNECT handshake over a baseDialer.DialContext'd conn. With localAddress unset, the existing h12.io/socks path is preserved verbatim. 2. HTTPS proxies (connect.go) The default TLS-to-proxy step used tls.Dial(network, addr, &tlsConf), which bypasses any custom net.Dialer and silently dropped LocalAddr. Replaced with c.tlsDialer.DialContext (LocalAddr-aware) followed by tls.Client + HandshakeContext so the bind takes effect on the client->HTTPS-proxy TCP socket. 3. HTTP/3 / QUIC (http3.go) net.ListenPacket("udp", "") ignored localAddress entirely. Threaded LocalAddress through Browser -> roundTripper -> http3Dial; when set, the UDP socket is bound to <ip>:0. Empty localAddress preserves the prior kernel-chooses behavior. Also expands the cycleTLSRequestOptions.LocalAddress field comment to document that, when a Proxy is in the path, the bind applies to the client->proxy hop only — the proxy host always sees this IP, but the destination server never does. This is routing/interface control, not an anonymizer against the proxy itself. Verified: go build ./..., go vet ./... (only pre-existing index.go cancel warnings remain, line numbers shifted by docstring), go test ./... -short all pass on Go 1.26.0. --------- Co-authored-by: Stefan Meinecke <meinecke@greensec.de>
…asilva#68) Bumps [github.com/valyala/fasthttp](https://github.com/valyala/fasthttp) from 1.70.0 to 1.71.0. - [Release notes](https://github.com/valyala/fasthttp/releases) - [Commits](valyala/fasthttp@v1.70.0...v1.71.0) --- updated-dependencies: - dependency-name: github.com/valyala/fasthttp dependency-version: 1.71.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Upstream changes included: - fix(go-core): local_address binding, Do() field drops, TLS13AutoRetry JA3 corruption (Danny-Dasilva#65) - fix(transport): propagate enable_connection_reuse=False as DisableKeepAlives=true (Danny-Dasilva#52) - fix(transport): lower IdleConnTimeout 90s to 60s (Danny-Dasilva#51) - feat(extensions): expose proper utls types for IDs 17, 17613, 30032 (Danny-Dasilva#66) - feat(tests): run live tests against local tlsfingerprint.com Docker instance (Danny-Dasilva#49) - fix(release): build Linux .so targeting glibc 2.17 via zig cc (#41) - ci: add CodeQL analysis, expand dependabot, bump action versions (Danny-Dasilva#47) - ci: run macOS only for Python 3.13 to ease runner pressure (Danny-Dasilva#53) - Various dependency bumps (utls, quic-go, x/net, gorilla/websocket, etc.) Preserved fork features: - Windows CI support, Python 3.9 and 3.14 test matrix - Fingerprint registry and capture pipeline - TLS fingerprint test variants
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR syncs the latest changes from
Danny-Dasilva/CycleTLS(upstream/main) into our fork.Key upstream changes included
local_addressbinding now propagated through proxy dialers; Do() field drops fixed;TLS13AutoRetryJA3 corruption eliminated (Danny-Dasilva#65)enable_connection_reuse=Falsenow correctly setsDisableKeepAlives=trueon the Go transport (Danny-Dasilva#52); idle conn timeout lowered 90s → 60s (Danny-Dasilva#51)utlstypes for extension IDs 17, 17613, 30032 (Danny-Dasilva#66)tlsfingerprint.comDocker instance for CI live tests (Danny-Dasilva#49).sonow targets glibc 2.17 viazig ccfor broader compatibility (#41)fasthttp,gorilla/websocket,quic-go,utls,x/net,x/crypto, and othersFork-specific features preservedh
tlsfingerprint.comendpoints;httpbin.organd public endpoints still use normal HTTP/1.1 keep-alive to avoid EOF errors on redirect chains and cookie flowstest_*_tlsfingerprint.pymodules retainedMerge conflict resolution notes
Conflicts were resolved across:
local_addressstamping.github/workflows/— merged upstream CI improvements with our Windows + Python 3.9/3.14 matrix entriesTRACKME_URL→TLSFP_URLnaming, kept our smarter connection-reuse fixture behaviorTesting
tlsfingerprint.com