Rolls up the four post-v1.2.14 commits on main into a single tagged
release. Highlights:
- Per-deployment concurrency (#142): each deployment ID gets its own
30-permit semaphore, so setups with deployments across multiple
Google accounts get a genuine 30×N throughput ceiling. Single-account
setups still cap at Google's per-account 30-simultaneous limit —
docs (EN + FA) updated to call that out.
- Android app-splitting ONLY-mode bug fix (#143): the previous code
called both addAllowedApplication and addDisallowedApplication,
which Android documents as mutually exclusive. ONLY mode was
silently failing establish(). Now fixed.
- Per-ABI Android APKs (#136): ships four split APKs (arm64-v8a ~21 MB,
armeabi-v7a ~18 MB, x86_64 ~23 MB, x86 ~22 MB) alongside the ~53 MB
universal. Huge distribution win for users on unreliable
censorship-tunnel paths — the 21 MB arm64-v8a download succeeds
where the universal doesn't.
- Honest IP-exposure note in Security Posture (#148): clarified that
v1.2.9's forwarded-header stripping only covers the client-side leg;
what Google's own infrastructure may add on the UrlFetchApp.fetch()
second leg is outside this client's control. Full Tunnel mode is
the recommendation for threat models where that matters.
- Telegram release-post format: added Persian preambles above both
links (GitHub repo + full Persian guide; release page + desktop/
router builds) so channel readers see the intent at a glance.
82 tests pass. Desktop + Android builds both verified clean locally
across the v1.2.15+ commit series.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Contains the three safety fixes from PRs #48/#49/#50 and the Persian
README RTL polishing from #58, all squashed into main. Merge details
already in their individual PR comments; summary:
#48: reject truncated Content-Length relay responses (previously
silently accepted whatever bytes arrived before EOF)
#49: reject truncated or malformed (missing CRLF) chunked-encoding
relay responses (same class of silent-acceptance bug)
#50: restrict the SNI-rewrite tunnel dispatch to port 443. Plain
HTTP (:80) targets that happened to match google.com / hosts
override were being steered into the TLS tunnel and blocking
waiting for a ClientHello that would never arrive.
#58: trailing-whitespace line-breaks on Persian bullet lists in
README so the RTL rendering doesn't collapse consecutive
items into a single paragraph.
Test suite grew from 54 to 58 passing (three new negative tests for
the relay-reader correctness fixes + one SNI-rewrite port filter).
Telegram CI notify default switched to file-plus-link:
- script gains a `--with-changelog` flag; default OFF
- workflow only passes it when `vars.TELEGRAM_INCLUDE_CHANGELOG=true`
- every routine release now posts just the APK + short caption
(title + SHA-256 + repo URL + release URL) with no long body
To include bullets for a given release again:
gh variable set TELEGRAM_INCLUDE_CHANGELOG --body true
The existing `vars.TELEGRAM_NOTIFY_ENABLED` job-level gate remains —
changelog toggle is orthogonal to enable/disable.
Also closes PR #55 without merging; ads/analytics domains were being
lumped under a YouTube-specific toggle, and the PR committed per-
machine \`.cargo/config.toml\` + zig-cc cross-compile helpers that
would have broken CI on actual Windows / macOS runners.
The v1.1.0 CI telegram job failed with curl exit 26 "Failed to
open/read local data from file/application" because:
-F "caption=<b>mhrv-rs Android v1.1.0</b>..."
curl's -F treats a value starting with `<` as "read from file
named ..." (the canonical way to put file CONTENTS into a text
form field). Our HTML captions start with `<b>`, so curl tried
to open a file named `b>mhrv-rs Android v1.1.0</b>...`, failed,
and the whole job went red.
Rewrote the step in Python (`.github/scripts/telegram_release_notify.py`).
stdlib urllib + http.client have no such value-interpretation
wart. Also:
- uses `application/vnd.android.package-archive` content-type
so Telegram shows the APK with an Android-package label, not
generic octet-stream
- proper sha256 hash (streaming, not shell-piped)
- consolidated the two shell-script HEREDOCs that were parsing
the changelog into one place
- clean exit codes: "no changelog file" and "no secrets" both
exit 0, a broken Telegram response exits non-zero
No behaviour change for callers — the workflow just calls the
script with the same four inputs.