Skip to content

Commit d2eb98d

Browse files
addpkg(main/turbopack): canary
1 parent 5dcbbe0 commit d2eb98d

11 files changed

Lines changed: 976 additions & 0 deletions

packages/turbopack/0001-android-build.patch

Lines changed: 446 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
From 50d4afecfaaf000ec3ca3053f484d2ed0de2089c Mon Sep 17 00:00:00 2001
2+
From: Kuldeep-Dilliwar <kuldeepdilliwar@gmail.com>
3+
Date: Sun, 4 Jan 2026 10:31:21 +0000
4+
Subject: [PATCH 02/10] fix(ci): remove cache step to bypass TURBO_TOKEN
5+
requirement
6+
7+
---
8+
crates/napi/src/lockfile.rs | 4 ----
9+
1 file changed, 4 deletions(-)
10+
11+
diff --git a/crates/napi/src/lockfile.rs b/crates/napi/src/lockfile.rs
12+
index 0ce5affbaa..799fe26ebc 100644
13+
--- a/crates/napi/src/lockfile.rs
14+
+++ b/crates/napi/src/lockfile.rs
15+
@@ -83,11 +83,9 @@ pub fn lockfile_try_acquire_sync(path: String) -> napi::Result<Option<External<J
16+
#[cfg(target_os = "android")]
17+
return {
18+
let file = open_options.open(&path)?;
19+
- println!("Trying to lock file at {:?}", path);
20+
21+
match file.try_lock_exclusive() {
22+
Ok(_) => {
23+
- println!("Lock succeeded!");
24+
Ok(Some(External::new(Mutex::new(ManuallyDrop::new(Some(
25+
LockfileInner {
26+
file,
27+
@@ -96,11 +94,9 @@ pub fn lockfile_try_acquire_sync(path: String) -> napi::Result<Option<External<J
28+
))))))
29+
}
30+
Err(ref e) if e.kind() == std::io::ErrorKind::WouldBlock => {
31+
- println!("Lock would block, lock held elsewhere.");
32+
Ok(None)
33+
}
34+
Err(e) => {
35+
- println!("Actual lock error: {:?}", e);
36+
Err(e.into())
37+
}
38+
}
39+
--
40+
2.53.0
41+
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
From 8ccd7f851a480b82c54c665f97684ef8211ae049 Mon Sep 17 00:00:00 2001
2+
From: Kuldeep-Dilliwar <kuldeepdilliwar@gmail.com>
3+
Date: Mon, 5 Jan 2026 10:26:01 +0530
4+
Subject: [PATCH 03/10] Remove '@next/swc-android-arm64' dependency
5+
6+
Removed '@next/swc-android-arm64' from optionalDependencies.
7+
---
8+
packages/next/package.json | 3 +--
9+
1 file changed, 1 insertion(+), 2 deletions(-)
10+
11+
diff --git a/packages/next/package.json b/packages/next/package.json
12+
index bbee60b3e4..9e5c865c53 100644
13+
--- a/packages/next/package.json
14+
+++ b/packages/next/package.json
15+
@@ -127,8 +127,7 @@
16+
}
17+
},
18+
"optionalDependencies": {
19+
- "sharp": "^0.34.4",
20+
- "@next/swc-android-arm64": "16.1.1-canary.11"
21+
+ "sharp": "^0.34.4"
22+
},
23+
"devDependencies": {
24+
"@babel/code-frame": "7.26.2",
25+
--
26+
2.53.0
27+
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
From 349867fa9c21b45f449cfedbc113d80a081314e3 Mon Sep 17 00:00:00 2001
2+
From: Kuldeep-Dilliwar <kuldeepdilliwar@gmail.com>
3+
Date: Wed, 14 Jan 2026 17:30:56 +0530
4+
Subject: [PATCH 04/10] Update client.rs
5+
6+
FIX: Added 'target_os = "android"' to this check so Android initializes 'ring' crypto too.
7+
---
8+
turbopack/crates/turbo-tasks-fetch/src/client.rs | 2 +-
9+
1 file changed, 1 insertion(+), 1 deletion(-)
10+
11+
diff --git a/turbopack/crates/turbo-tasks-fetch/src/client.rs b/turbopack/crates/turbo-tasks-fetch/src/client.rs
12+
index e77d722cec..ede7c4a11d 100644
13+
--- a/turbopack/crates/turbo-tasks-fetch/src/client.rs
14+
+++ b/turbopack/crates/turbo-tasks-fetch/src/client.rs
15+
@@ -47,7 +47,7 @@ impl FetchClientConfig {
16+
fn try_build_uncached_reqwest_client(&self) -> reqwest::Result<reqwest::Client> {
17+
#[allow(unused_mut)]
18+
let mut builder = reqwest::Client::builder();
19+
- #[cfg(any(target_os = "linux", all(windows, not(target_arch = "aarch64"))))]
20+
+ #[cfg(any(target_os = "linux", target_os = "android", all(windows, not(target_arch = "aarch64"))))]
21+
{
22+
use std::sync::Once;
23+
static ONCE: Once = Once::new();
24+
--
25+
2.53.0
26+
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
From 1d9b18979c09c263b33f4ec19703e5545c7eaad6 Mon Sep 17 00:00:00 2001
2+
From: Kuldeep-Dilliwar <kuldeepdilliwar@gmail.com>
3+
Date: Wed, 14 Jan 2026 18:00:00 +0530
4+
Subject: [PATCH 05/10] fix(turbopack): enable reqwest/rustls for android
5+
target
6+
7+
The recent update to turbo-tasks-fetch removed implicit support for Android. This adds target_os = 'android' to Cargo.toml and initializes the ring provider in client.rs to fix aarch64-linux-android builds.
8+
---
9+
turbopack/crates/turbo-tasks-fetch/Cargo.toml | 2 +-
10+
1 file changed, 1 insertion(+), 1 deletion(-)
11+
12+
diff --git a/turbopack/crates/turbo-tasks-fetch/Cargo.toml b/turbopack/crates/turbo-tasks-fetch/Cargo.toml
13+
index 3184cb72b6..44ff7c3a2e 100644
14+
--- a/turbopack/crates/turbo-tasks-fetch/Cargo.toml
15+
+++ b/turbopack/crates/turbo-tasks-fetch/Cargo.toml
16+
@@ -42,7 +42,7 @@ reqwest = { workspace = true, features = ["rustls"] }
17+
# - Windows: aws-lc-sys requires NASM and CMake which we don't have installed in
18+
# CI, and would complicate the development environment setup. We could
19+
# possibly switch to always using `native-tls` on Windows in the future.
20+
-[target.'cfg(any(target_os = "linux", all(windows, not(target_arch = "aarch64"))))'.dependencies]
21+
+[target.'cfg(any(target_os = "linux", target_os = "android", all(windows, not(target_arch = "aarch64"))))'.dependencies]
22+
reqwest = { workspace = true, features = ["rustls-no-provider"] }
23+
rustls = { version = "0.23", default-features = false, features = ["ring", "std", "tls12"] }
24+
25+
--
26+
2.53.0
27+
Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
From 59c8c1ef7eaed1168877fbc53d437b947b9bf06a Mon Sep 17 00:00:00 2001
2+
From: Kuldeep-Dilliwar <kuldeepdilliwar@gmail.com>
3+
Date: Fri, 23 Jan 2026 11:54:43 +0530
4+
Subject: [PATCH 06/10] Update client.rs to work on android
5+
6+
Universal Compatibility:
7+
Termux Users: It detects /data/data/com.termux/..., enters Branch A, and uses use_preconfigured_tls. This strictly bypasses the Android system calls, fixing the crash you experienced.
8+
Corporate Users (Termux): It detects the environment variable inside Branch A and merges it with the Termux certs.
9+
Real Android Apps: It detects the missing Termux file, skips Branch A, and enters Branch B (if an env var exists) or Branch C (default). This uses add_root_certificate, which safely adds to the Android System Keychain instead of replacing it.
10+
No Extra Dependencies:
11+
It uses your custom simple_base64_decode helper (guarded by #[cfg(target_os = "android")] so it doesn't break Linux/Windows builds).
12+
It avoids adding base64 or pem crates to Cargo.toml.
13+
Debuggability:
14+
You kept the eprintln! inside the error handler (guarded for Android). If something goes wrong in the future, you will see the exact TLS error immediately.
15+
---
16+
.../crates/turbo-tasks-fetch/src/client.rs | 118 ++++++++++++++++++
17+
1 file changed, 118 insertions(+)
18+
19+
diff --git a/turbopack/crates/turbo-tasks-fetch/src/client.rs b/turbopack/crates/turbo-tasks-fetch/src/client.rs
20+
index 27011018e4..7063c9e917 100644
21+
--- a/turbopack/crates/turbo-tasks-fetch/src/client.rs
22+
+++ b/turbopack/crates/turbo-tasks-fetch/src/client.rs
23+
@@ -74,6 +74,84 @@ impl FetchClientConfig {
24+
},
25+
))
26+
}
27+
+ #[cfg(target_os = "android")]
28+
+ {
29+
+ let termux_path = std::path::Path::new("/data/data/com.termux/files/usr/etc/tls/cert.pem");
30+
+ let env_var = std::env::var("TURBO_SSL_CERT_FILE");
31+
+
32+
+ // --- BRANCH A: TERMUX MODE (Fix the Crash) ---
33+
+ if termux_path.exists() {
34+
+ println!("[Turbopack] Termux environment detected.");
35+
+
36+
+ let mut root_store = rustls::RootCertStore::empty();
37+
+ let mut paths_to_load = vec![termux_path.to_path_buf()];
38+
+
39+
+ // If user also provided a custom cert, add it to our manual list
40+
+ if let Ok(p) = env_var {
41+
+ paths_to_load.push(std::path::PathBuf::from(p));
42+
+ }
43+
+
44+
+ for cert_path in paths_to_load {
45+
+ if let Ok(pem_bytes) = std::fs::read(&cert_path) {
46+
+ let content = String::from_utf8_lossy(&pem_bytes);
47+
+ // ... (Reuse the parsing logic from before) ...
48+
+ let header = "-----BEGIN CERTIFICATE-----";
49+
+ let footer = "-----END CERTIFICATE-----";
50+
+ let mut current_idx = 0;
51+
+ while let Some(start_offset) = content[current_idx..].find(header) {
52+
+ let start = current_idx + start_offset + header.len();
53+
+ if let Some(end_offset) = content[start..].find(footer) {
54+
+ let end = start + end_offset;
55+
+ let base64_str = content[start..end].lines().map(|l| l.trim()).collect::<String>();
56+
+ if let Ok(der_bytes) = simple_base64_decode(&base64_str) {
57+
+ let cert = rustls::pki_types::CertificateDer::from(der_bytes);
58+
+ let _ = root_store.add(cert);
59+
+ }
60+
+ current_idx = end + footer.len();
61+
+ } else { break; }
62+
+ }
63+
+ }
64+
+ }
65+
+
66+
+ // REPLACEMENT: We bypass the system entirely because the system crashes in Termux.
67+
+ let tls_config = rustls::ClientConfig::builder()
68+
+ .with_root_certificates(root_store)
69+
+ .with_no_client_auth();
70+
+ builder = builder.use_preconfigured_tls(tls_config);
71+
+ }
72+
+ // --- BRANCH B: REAL APP MODE (Add, don't Replace) ---
73+
+ else if let Ok(p) = env_var {
74+
+ // We are NOT in Termux, but we have a custom cert.
75+
+ // We want to KEEP the Android System certs and ADD this one.
76+
+ println!("[Turbopack] Custom cert env var detected (Android App mode).");
77+
+
78+
+ if let Ok(pem_bytes) = std::fs::read(&p) {
79+
+ let content = String::from_utf8_lossy(&pem_bytes);
80+
+ // ... (Reuse the same parsing logic) ...
81+
+ let header = "-----BEGIN CERTIFICATE-----";
82+
+ let footer = "-----END CERTIFICATE-----";
83+
+ let mut current_idx = 0;
84+
+ while let Some(start_offset) = content[current_idx..].find(header) {
85+
+ let start = current_idx + start_offset + header.len();
86+
+ if let Some(end_offset) = content[start..].find(footer) {
87+
+ let end = start + end_offset;
88+
+ let base64_str = content[start..end].lines().map(|l| l.trim()).collect::<String>();
89+
+
90+
+ if let Ok(der_bytes) = simple_base64_decode(&base64_str) {
91+
+ // ADDITION: We use reqwest's API to add to the existing system list.
92+
+ if let Ok(cert) = reqwest::Certificate::from_der(&der_bytes) {
93+
+ builder = builder.add_root_certificate(cert);
94+
+ }
95+
+ }
96+
+ current_idx = end + footer.len();
97+
+ } else { break; }
98+
+ }
99+
+ }
100+
+ }
101+
+ // --- BRANCH C: STANDARD MODE ---
102+
+ // No Termux, No Env Var. Do nothing.
103+
+ // reqwest will automatically use Android System Certs via JNI.
104+
+ }
105+
builder.build()
106+
}
107+
}
108+
@@ -120,6 +198,19 @@ impl FetchClientConfig {
109+
match response_result {
110+
Ok(resp) => Ok(Vc::cell(Ok(resp.resolved_cell()))),
111+
Err(err) => {
112+
+
113+
+ #[cfg(target_os = "android")]
114+
+ {
115+
+ // --- DEBUGGING START ---
116+
+ eprintln!("\n[Turbopack] NETWORK ERROR DEBUG:");
117+
+ eprintln!("URL: {}", url_ref);
118+
+ eprintln!("Error: {:?}", err); // Prints the high level error
119+
+ if let Some(source) = std::error::Error::source(&err) {
120+
+ eprintln!("Caused by: {:?}", source); // Prints the deep TLS error
121+
+ }
122+
+ // --- DEBUGGING END ---
123+
+ }
124+
+
125+
// the client failed to construct or the HTTP request failed
126+
mark_session_dependent();
127+
Ok(Vc::cell(Err(
128+
@@ -130,6 +221,33 @@ impl FetchClientConfig {
129+
}
130+
}
131+
132+
+
133+
+#[cfg(target_os = "android")]
134+
+fn simple_base64_decode(input: &str) -> Result<Vec<u8>, ()> {
135+
+ let mut buffer = Vec::new();
136+
+ let mut bits: u32 = 0;
137+
+ let mut bit_count = 0;
138+
+ for byte in input.bytes() {
139+
+ let val = match byte {
140+
+ b'A'..=b'Z' => byte - b'A',
141+
+ b'a'..=b'z' => byte - b'a' + 26,
142+
+ b'0'..=b'9' => byte - b'0' + 52,
143+
+ b'+' => 62,
144+
+ b'/' => 63,
145+
+ b'=' => continue,
146+
+ _ => continue,
147+
+ };
148+
+ bits = (bits << 6) | (val as u32);
149+
+ bit_count += 6;
150+
+ if bit_count >= 8 {
151+
+ bit_count -= 8;
152+
+ buffer.push((bits >> bit_count) as u8);
153+
+ bits &= (1 << bit_count) - 1;
154+
+ }
155+
+ }
156+
+ Ok(buffer)
157+
+}
158+
+
159+
#[doc(hidden)]
160+
pub fn __test_only_reqwest_client_cache_clear() {
161+
CLIENT_CACHE.clear()
162+
--
163+
2.53.0
164+
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
From 32a1424ccebc2aec61a928b38c6b561849ab5add Mon Sep 17 00:00:00 2001
2+
From: Kuldeep-Dilliwar <kuldeepdilliwar@gmail.com>
3+
Date: Mon, 26 Jan 2026 18:15:40 +0530
4+
Subject: [PATCH 07/10] commented out debug messages.
5+
6+
---
7+
.../crates/turbo-tasks-fetch/src/client.rs | 22 +++++++++----------
8+
1 file changed, 11 insertions(+), 11 deletions(-)
9+
10+
diff --git a/turbopack/crates/turbo-tasks-fetch/src/client.rs b/turbopack/crates/turbo-tasks-fetch/src/client.rs
11+
index 7063c9e917..3b81eb5f8e 100644
12+
--- a/turbopack/crates/turbo-tasks-fetch/src/client.rs
13+
+++ b/turbopack/crates/turbo-tasks-fetch/src/client.rs
14+
@@ -81,7 +81,7 @@ impl FetchClientConfig {
15+
16+
// --- BRANCH A: TERMUX MODE (Fix the Crash) ---
17+
if termux_path.exists() {
18+
- println!("[Turbopack] Termux environment detected.");
19+
+ //println!("[Turbopack] Termux environment detected.");
20+
21+
let mut root_store = rustls::RootCertStore::empty();
22+
let mut paths_to_load = vec![termux_path.to_path_buf()];
23+
@@ -123,7 +123,7 @@ impl FetchClientConfig {
24+
else if let Ok(p) = env_var {
25+
// We are NOT in Termux, but we have a custom cert.
26+
// We want to KEEP the Android System certs and ADD this one.
27+
- println!("[Turbopack] Custom cert env var detected (Android App mode).");
28+
+ //println!("[Turbopack] Custom cert env var detected (Android App mode).");
29+
30+
if let Ok(pem_bytes) = std::fs::read(&p) {
31+
let content = String::from_utf8_lossy(&pem_bytes);
32+
@@ -199,17 +199,17 @@ impl FetchClientConfig {
33+
Ok(resp) => Ok(Vc::cell(Ok(resp.resolved_cell()))),
34+
Err(err) => {
35+
36+
- #[cfg(target_os = "android")]
37+
- {
38+
+ //#[cfg(target_os = "android")]
39+
+ //{
40+
// --- DEBUGGING START ---
41+
- eprintln!("\n[Turbopack] NETWORK ERROR DEBUG:");
42+
- eprintln!("URL: {}", url_ref);
43+
- eprintln!("Error: {:?}", err); // Prints the high level error
44+
- if let Some(source) = std::error::Error::source(&err) {
45+
- eprintln!("Caused by: {:?}", source); // Prints the deep TLS error
46+
- }
47+
+ //eprintln!("\n[Turbopack] NETWORK ERROR DEBUG:");
48+
+ //eprintln!("URL: {}", url_ref);
49+
+ //eprintln!("Error: {:?}", err); // Prints the high level error
50+
+ //if let Some(source) = std::error::Error::source(&err) {
51+
+ // eprintln!("Caused by: {:?}", source); // Prints the deep TLS error
52+
+ //}
53+
// --- DEBUGGING END ---
54+
- }
55+
+ //}
56+
57+
// the client failed to construct or the HTTP request failed
58+
mark_session_dependent();
59+
--
60+
2.53.0
61+

0 commit comments

Comments
 (0)