From d1e415926a8ebd3b13d469dbdb29e328e81c41f8 Mon Sep 17 00:00:00 2001 From: Arc <90333108+lastarc@users.noreply.github.com> Date: Sun, 4 Oct 2026 20:43:25 +0200 Subject: [PATCH 1/3] fix(en.comix): images not loading Image hosts now return 403 when the request carries a comix Referer, so send image requests without it. --- sources/en.comix/res/source.json | 2 +- sources/en.comix/src/lib.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sources/en.comix/res/source.json b/sources/en.comix/res/source.json index 2775cdb90..a4390b916 100644 --- a/sources/en.comix/res/source.json +++ b/sources/en.comix/res/source.json @@ -2,7 +2,7 @@ "info": { "id": "en.comix", "name": "Comix", - "version": 24, + "version": 25, "url": "https://comix.to", "contentRating": 1, "languages": ["en"], diff --git a/sources/en.comix/src/lib.rs b/sources/en.comix/src/lib.rs index e7beb5e48..0d42d1ae0 100644 --- a/sources/en.comix/src/lib.rs +++ b/sources/en.comix/src/lib.rs @@ -20,7 +20,6 @@ mod models; mod settings; mod web; -use crate::helpers::create_request_get; use crate::settings::VERIFY_KEY; use models::*; use web::*; @@ -507,7 +506,8 @@ impl ListingProvider for Comix { impl ImageRequestProvider for Comix { fn get_image_request(&self, url: String, _context: Option) -> Result { - Ok(create_request_get(&url)?.header("Referer", &format!("{BASE_URL}/"))) + // images are served from third-party hosts that reject requests with a comix Referer + Ok(Request::get(url)?) } } From a0d93910cd1a1e6b270c179a3c259838edf53f81 Mon Sep 17 00:00:00 2001 From: Arc <90333108+lastarc@users.noreply.github.com> Date: Sun, 4 Oct 2026 23:13:00 +0200 Subject: [PATCH 2/3] fix(en.comix): failed to find installer function The site's scripts don't reliably run in the webview, so evaluate the secure chunk directly instead. --- sources/en.comix/src/web.rs | 40 +++++++++++++++++++++++++++---------- 1 file changed, 29 insertions(+), 11 deletions(-) diff --git a/sources/en.comix/src/web.rs b/sources/en.comix/src/web.rs index 9376d4ecb..161ec5aad 100644 --- a/sources/en.comix/src/web.rs +++ b/sources/en.comix/src/web.rs @@ -93,24 +93,42 @@ impl ComixWebView { let js_asset_path = &main_module_src[0..js_asset_path_index + 1]; let secure_script_regex = Regex::new("(secure-[A-Za-z0-9-_]+?\\.js)").unwrap(); let main_module_contents = - Request::get(format!("{BASE_URL}{main_module_src}"))?.string()?; + create_request_get(&format!("{BASE_URL}{main_module_src}"))?.string()?; if let Some(secure_script_path) = secure_script_regex .captures(main_module_contents.as_str()) .and_then(|captures| captures.get(1).map(|m| m.as_str())) { - self.web_view.eval(&format!( + // the site's own scripts don't reliably run in the webview, so fetch the + // secure chunk natively and evaluate it as a classic script. it registers + // its own `vm` global, so only the trailing `export{...}` needs removing + let secure_module_contents = + create_request_get(&format!("{BASE_URL}{js_asset_path}{secure_script_path}"))? + .string()?; + let Some(module_body) = secure_module_contents + .rfind("export") + .filter(|&index| { + secure_module_contents[index + "export".len()..] + .trim_start() + .starts_with('{') + }) + .map(|index| &secure_module_contents[..index]) + else { + bail!("Secure module exports not found"); + }; + let result = self.web_view.eval(&format!( "(() => {{ - import('{BASE_URL}{js_asset_path}{secure_script_path}') - .then((m) => window['vm'] = m) - .catch((e) => window['vm'] = {{}}); - return ''; + 'use strict'; + try {{ + {module_body} + return 'ok'; + }} catch (e) {{ + return 'error: ' + e; + }} }})()" ))?; - while self - .web_view - .eval("(() => { return window['vm'] == null ? 'true' : 'false'; })()")? - == "true" - {} + if result != "ok" { + bail!("Failed to load secure module: {result}"); + } Ok(()) } else { bail!("Secure module not found"); From 147199b28dd3a042e206a7efc8beda829deae38c Mon Sep 17 00:00:00 2001 From: Arc <90333108+lastarc@users.noreply.github.com> Date: Mon, 5 Oct 2026 23:56:24 +0200 Subject: [PATCH 3/3] refactor(en.comix): address review feedback --- sources/en.comix/src/lib.rs | 14 +++----------- sources/en.comix/src/web.rs | 4 ---- 2 files changed, 3 insertions(+), 15 deletions(-) diff --git a/sources/en.comix/src/lib.rs b/sources/en.comix/src/lib.rs index 0d42d1ae0..0d47b5ad7 100644 --- a/sources/en.comix/src/lib.rs +++ b/sources/en.comix/src/lib.rs @@ -1,9 +1,9 @@ #![no_std] use aidoku::{ Chapter, DeepLinkHandler, DeepLinkResult, FilterValue, HashMap, Home, HomeComponent, - HomeLayout, HomePartialResult, ImageRequestProvider, Link, LinkValue, Listing, ListingProvider, - Manga, MangaPageResult, MangaWithChapter, NotificationHandler, Page, PageContent, PageContext, - Result, Source, WebLoginHandler, + HomeLayout, HomePartialResult, Link, LinkValue, Listing, ListingProvider, Manga, + MangaPageResult, MangaWithChapter, NotificationHandler, Page, PageContent, Result, Source, + WebLoginHandler, alloc::{String, Vec, string::ToString, vec}, helpers::uri::{QueryParameters, encode_uri_component}, imports::{ @@ -504,13 +504,6 @@ impl ListingProvider for Comix { } } -impl ImageRequestProvider for Comix { - fn get_image_request(&self, url: String, _context: Option) -> Result { - // images are served from third-party hosts that reject requests with a comix Referer - Ok(Request::get(url)?) - } -} - impl NotificationHandler for Comix { fn handle_notification(&self, notification: String) { if notification == "resetFilters" { @@ -577,7 +570,6 @@ register_source!( Comix, Home, ListingProvider, - ImageRequestProvider, NotificationHandler, DeepLinkHandler, WebLoginHandler diff --git a/sources/en.comix/src/web.rs b/sources/en.comix/src/web.rs index 161ec5aad..db14066d2 100644 --- a/sources/en.comix/src/web.rs +++ b/sources/en.comix/src/web.rs @@ -98,9 +98,6 @@ impl ComixWebView { .captures(main_module_contents.as_str()) .and_then(|captures| captures.get(1).map(|m| m.as_str())) { - // the site's own scripts don't reliably run in the webview, so fetch the - // secure chunk natively and evaluate it as a classic script. it registers - // its own `vm` global, so only the trailing `export{...}` needs removing let secure_module_contents = create_request_get(&format!("{BASE_URL}{js_asset_path}{secure_script_path}"))? .string()?; @@ -117,7 +114,6 @@ impl ComixWebView { }; let result = self.web_view.eval(&format!( "(() => {{ - 'use strict'; try {{ {module_body} return 'ok';