Skip to content

Commit da691a7

Browse files
committed
Merge remote-tracking branch 'upstream/main' into feat/toml-config-migration
Merge remote-tracking branch 'upstream/main' into feat/toml-config-migration
2 parents f32d916 + de62874 commit da691a7

28 files changed

Lines changed: 110 additions & 54 deletions

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "mhrv-rs"
3-
version = "1.9.28"
3+
version = "1.9.31"
44
edition = "2021"
55
description = "Rust port of MasterHttpRelayVPN -- DPI bypass via Google Apps Script relay with domain fronting"
66
license = "MIT"

android/app/build.gradle.kts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ android {
1414
applicationId = "com.therealaleph.mhrv"
1515
minSdk = 24 // Android 7.0 — covers 99%+ of live devices.
1616
targetSdk = 34
17-
versionCode = 160
18-
versionName = "1.9.28"
17+
versionCode = 163
18+
versionName = "1.9.31"
1919

2020
// Ship all four mainstream Android ABIs:
2121
// - arm64-v8a — 95%+ of real-world Android phones since 2019

assets/apps_script/Code.gs

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -203,14 +203,6 @@ function _doSingle(req) {
203203
var opts = _buildOpts(req);
204204
var resp = UrlFetchApp.fetch(req.u, opts);
205205

206-
// Raw-return mode for exit-node path.
207-
// r:true = return destination body verbatim so Rust gets {s,h,b} unwrapped.
208-
if (req.r === true) {
209-
return ContentService
210-
.createTextOutput(resp.getContentText())
211-
.setMimeType(ContentService.MimeType.JSON);
212-
}
213-
214206
return _json({
215207
s: resp.getResponseCode(),
216208
h: _respHeaders(resp),
@@ -316,7 +308,7 @@ function _buildOpts(req) {
316308
var opts = {
317309
method: (req.m || "GET").toLowerCase(),
318310
muteHttpExceptions: true,
319-
followRedirects: true, // ← always true; r flag now has different meaning
311+
followRedirects: req.r !== false,
320312
validateHttpsCertificates: true,
321313
escaping: false,
322314
};

assets/apps_script/CodeFull.gs

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -395,15 +395,8 @@ function _doBatch(items) {
395395
}
396396
var fallbackReq = fetchArgs[j];
397397
var fallbackUrl = fallbackReq.url;
398-
var fallbackOpts = {};
399-
for (var key in fallbackReq) {
400-
if (
401-
Object.prototype.hasOwnProperty.call(fallbackReq, key) &&
402-
key !== "url"
403-
) {
404-
fallbackOpts[key] = fallbackReq[key];
405-
}
406-
}
398+
var fallbackOpts = Object.assign({}, fallbackReq);
399+
delete fallbackOpts.url;
407400
responses[j] = UrlFetchApp.fetch(fallbackUrl, fallbackOpts);
408401
} catch (singleErr) {
409402
errorMap[fetchIndex[j]] = String(singleErr);
@@ -608,12 +601,12 @@ function _edgeDnsResolve(prep, cachedReplyB64, cache, localMap) {
608601
function _sha256Hex(s) {
609602
var d = Utilities.computeDigest(
610603
Utilities.DigestAlgorithm.SHA_256, s, Utilities.Charset.UTF_8);
611-
var hex = "";
604+
var parts = [];
612605
for (var i = 0; i < d.length; i++) {
613606
var b = d[i] & 0xFF;
614-
hex += (b < 16 ? "0" : "") + b.toString(16);
607+
parts.push((b < 16 ? "0" : "") + b.toString(16));
615608
}
616-
return hex;
609+
return parts.join("");
617610
}
618611

619612
// Single DoH GET against `url`. Returns the reply as a byte array, or null
@@ -656,13 +649,13 @@ function _dnsParseQuestion(bytes) {
656649
if (len > 63) return null;
657650
off++;
658651
if (off + len > bytes.length) return null;
659-
var label = "";
652+
var labelChars = [];
660653
for (var i = 0; i < len; i++) {
661654
var c = bytes[off + i] & 0xFF;
662655
if (c >= 0x41 && c <= 0x5A) c += 0x20; // ASCII lowercase
663-
label += String.fromCharCode(c);
656+
labelChars.push(String.fromCharCode(c));
664657
}
665-
labels.push(label);
658+
labels.push(labelChars.join(""));
666659
off += len;
667660
nameLen += len + 1;
668661
if (nameLen > 255) return null;
@@ -743,8 +736,7 @@ function _dnsSkipName(bytes, off) {
743736
// cheap (~100 bytes for a typical DNS reply) compared to the surrounding
744737
// base64 encode/decode work.
745738
function _dnsRewriteTxid(bytes, txid) {
746-
var out = [];
747-
for (var i = 0; i < bytes.length; i++) out.push(bytes[i]);
739+
var out = Array.prototype.slice.call(bytes);
748740
var hi = (txid >> 8) & 0xFF;
749741
var lo = txid & 0xFF;
750742
out[0] = hi > 127 ? hi - 256 : hi;

docs/changelog/v1.9.29.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<!-- see docs/changelog/v1.1.0.md for the file format: Persian, then `---`, then English. -->
2+
<div dir="rtl">
3+
4+
• **رفع خطای JSON در `Code.gs` نسخه 1.9.28** ([PR #1265](https://github.com/therealaleph/MasterHttpRelayVPN-RUST/pull/1265)، [#1245](https://github.com/therealaleph/MasterHttpRelayVPN-RUST/issues/1245)، [#1253](https://github.com/therealaleph/MasterHttpRelayVPN-RUST/issues/1253)، [#1261](https://github.com/therealaleph/MasterHttpRelayVPN-RUST/issues/1261)). مسیر ساده `Code.gs` در بعضی درخواست‌ها پاسخ مقصد را خام برمی‌گرداند و کلاینت Rust آن را به‌جای envelope داخلی relay به عنوان JSON parse می‌کرد؛ نتیجه خطاهایی مثل `json: key must be a string` یا `no json in` بود. حالا `Code.gs` مثل `CodeFull.gs` پاسخ‌ها را داخل envelope `{s,h,b}` نگه می‌دارد و `req.r` فقط برای کنترل follow-redirect استفاده می‌شود. برای گرفتن این fix، فایل جدید `assets/apps_script/Code.gs` را در Apps Script جایگزین کنید و یک New version deploy بسازید.
5+
6+
</div>
7+
8+
---
9+
**Fix the v1.9.28 `Code.gs` JSON parse regression** ([PR #1265](https://github.com/therealaleph/MasterHttpRelayVPN-RUST/pull/1265), [#1245](https://github.com/therealaleph/MasterHttpRelayVPN-RUST/issues/1245), [#1253](https://github.com/therealaleph/MasterHttpRelayVPN-RUST/issues/1253), [#1261](https://github.com/therealaleph/MasterHttpRelayVPN-RUST/issues/1261)). The simple `Code.gs` path could return the destination body verbatim for some requests, so the Rust client tried to parse arbitrary site HTML/JSON as the relay envelope and surfaced errors such as `json: key must be a string` or `no json in`. `Code.gs` now matches `CodeFull.gs`: normal relay responses stay wrapped as `{s,h,b}`, and `req.r` only controls redirect following. To get this fix, replace your Apps Script with the new `assets/apps_script/Code.gs` and deploy a New version.

docs/changelog/v1.9.30.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<!-- see docs/changelog/v1.1.0.md for the file format: Persian, then `---`, then English. -->
2+
• مسیر `CodeFull.gs` برای Full mode کمی سبک‌تر شد: چند hot path در Apps Script با ساختن رشته‌ها و آرایه‌های کمتر اجرا می‌شوند تا فشار CPU/GC در batchهای پرترافیک کمتر شود. با تشکر از @brightening-eyes برای PR #1254.
3+
---
4+
• Make the Full mode `CodeFull.gs` path a little lighter: several Apps Script hot paths now allocate fewer strings/arrays, reducing CPU/GC pressure during high-traffic batches. Thanks @brightening-eyes for PR #1254.

docs/changelog/v1.9.31.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<!-- see docs/changelog/v1.1.0.md for the file format: Persian, then `---`, then English. -->
2+
• رگرسیون pipeline در Full mode که بعد از v1.9.28 می‌توانست روی sessionهای idle درخواست‌های خالی زیادی بسازد و quota چند deployment را سریع مصرف کند، اصلاح شد. مسیر keepalive دوباره backoff مرحله‌ای دارد و timer refill در حالت idle کمتر poll خالی می‌فرستد.
3+
• جریان داده در Full mode پایدارتر شد: پاسخ‌های خالی قدیمی که قبل از شروع جریان داده queue شده بودند دیگر streak داده را قطع نمی‌کنند، بنابراین افت زودهنگام عمق pipeline و گیر کردن ویدیوها، مخصوصاً Instagram، کمتر می‌شود.
4+
• default گزینه `block_stun` از این نسخه `false` است تا STUN/TURN به صورت پیش‌فرض اجازه داشته باشد؛ اگر می‌خواهید آن ترافیک را مسدود کنید، `block_stun: true` را صریحاً در config بگذارید. با تشکر از @yyoyoian-pixel برای PR #1309.
5+
---
6+
• Fix a Full mode pipeline regression introduced after v1.9.28 where idle sessions could generate too many empty polls and burn quota across multi-deployment setups. Keepalive polling now has staged backoff again, and idle refill timers schedule fewer empty polls.
7+
• Make Full mode data flow steadier: stale empty-poll replies queued before data starts no longer break active data streaks, reducing premature pipeline-depth drops and video stalls, especially on Instagram.
8+
• Change the `block_stun` default to `false`, so STUN/TURN traffic is allowed by default; set `block_stun: true` explicitly if you want to block that traffic. Thanks @yyoyoian-pixel for PR #1309.

0 commit comments

Comments
 (0)