fix(CuuTruyen): rewrite dead image hosts, fix DRM decode & add API he… - #440
fix(CuuTruyen): rewrite dead image hosts, fix DRM decode & add API he…#440thefirst632student wants to merge 2 commits into
Conversation
…ader - Fix dead image hosts: The API may return dead storage hosts such as `storage-ct.lrclib.net` and `storage-ct-riften.site`. Added `fixStorageHost()` to rewrite them to active hosts (`storage-bravo.cuutruyen.net` / `storage-charlie.cuutruyen.net`) directly when creating model URLs for covers, panorama covers, and page images. - Fix DRM decode: Some `drm_data` values contain whitespace/newline characters, which can break Base64 decoding. Strip whitespace before injecting DRM data into the image URL fragment so the decode -> XOR -> unscramble pipeline works correctly. - Add API header: Added `Cuutruyen-Client: OfficialWebApp-20250805` to `/api/` requests via `storageHostInterceptor`, while also keeping the interceptor as a fallback for host rewriting. Credit: Issue analysis and solution generated with the assistance of the Ox Alpha (max) AI model.
There was a problem hiding this comment.
Pull request overview
This PR updates the CuuTruyen (vi) parser to make image loading more resilient by rewriting known-dead storage hosts to active ones, and to improve DRM image decoding by sanitizing drm_data before Base64 decoding. It also attempts to add a required API client header for /api/ calls.
Changes:
- Rewrite cover, panorama, and page image URLs from known-dead storage hosts to active hosts via
fixStorageHost(). - Strip whitespace from
drm_databefore injecting it into the image URL fragment for the DRM decode pipeline. - Add a
storageHostInterceptor()intended to (a) rewrite dead storage hosts at request time and (b) attachCuutruyen-Clientheader for/api/requests.
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| override fun intercept(chain: Interceptor.Chain): Response { | ||
| val response = chain.proceed(chain.request()) | ||
| val fragment = response.request.url.fragment |
There was a problem hiding this comment.
Addressed. intercept() now routes the request through storageHostInterceptor(chain) before DRM fragment handling, so the dead-host fallback and Cuutruyen-Client API header are applied on this path as well.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 1 out of 1 changed files in this pull request and generated no new comments.
Suppressed comments (1)
Previously missed (1) — in code that hasn't changed since the last review.
src/main/kotlin/tsuki/site/vi/CuuTruyenParser.kt:266
fixStorageHost()currently does a plain string replacement across the entire URL. That can rewrite occurrences in the path/query/fragment too, even though the intent is to rewrite only the host. It’s safer (and matchesstorageHostInterceptorbehavior) to parse asHttpUrland replace the host when it matches a fallback entry, falling back to the current string replacement only if parsing fails.
private fun String.fixStorageHost(): String {
var result = this
for ((from, to) in STORAGE_HOST_FALLBACK) {
result = result.replace(from, to)
}
|
@thefirst632student please note that any PR or fixxes goes through now UMA and as well this source is already fixxed in this repo: https://github.com/dragonx943/manga-repo/blob/master/src%2Fmain%2Fkotlin%2Ftsuki%2Fsite%2Fvi%2FCuuTruyenParser.kt |
…ader
storage-ct.lrclib.netandstorage-ct-riften.site. AddedfixStorageHost()to rewrite them to active hosts (storage-bravo.cuutruyen.net/storage-charlie.cuutruyen.net) directly when creating model URLs for covers, panorama covers, and page images.drm_datavalues contain whitespace/newline characters, which can break Base64 decoding. Strip whitespace before injecting DRM data into the image URL fragment so the decode -> XOR -> unscramble pipeline works correctly.Cuutruyen-Client: OfficialWebApp-20250805to/api/requests viastorageHostInterceptor, while also keeping the interceptor as a fallback for host rewriting.Credit: Issue analysis and solution generated with the assistance of the Ox Alpha (max) AI model.
PLEASE READ THIS
I confirm that:
@Brokenannotation if the issue causing it to malfunction has been resolvedMangaSourceParserannotation if necessary (e.g., "type = ContentType.HENTAI")MangaSourceParserannotation if the source is not multilingual (e.g.,vi)availableSortOrders,filterCapabilities, andgetFilterOptionsare properly implemented ingetList()ORgetListPage()functionTESTING
I confirm that:
availableSortOrders,filterCapabilities, andgetFilterOptionswork correctly in the debug applicationgetList()ORgetListPage()andgetDetails()functions retrieve all necessary informationgetPages()function successfully retrieves all images from the sourceImportant
Source Name (Language)
CuuTruyen (vi)
Related Issues
N/A
Description
N/A