Skip to content

fix(CuuTruyen): rewrite dead image hosts, fix DRM decode & add API he… - #440

Closed
thefirst632student wants to merge 2 commits into
Gekkoushi:masterfrom
thefirst632student:cuutruyen-patch
Closed

fix(CuuTruyen): rewrite dead image hosts, fix DRM decode & add API he…#440
thefirst632student wants to merge 2 commits into
Gekkoushi:masterfrom
thefirst632student:cuutruyen-patch

Conversation

@thefirst632student

Copy link
Copy Markdown

…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.

PLEASE READ THIS

I confirm that:

  • All relevant issues have been mentioned in the PR description (e.g., "Closes #???")
  • I have built the library with these changes to update the number of available sources in the Summary file
  • I have removed @Broken annotation if the issue causing it to malfunction has been resolved
  • I have added a special type to MangaSourceParser annotation if necessary (e.g., "type = ContentType.HENTAI")
  • I have added a specific language code to MangaSourceParser annotation if the source is not multilingual (e.g., vi)
  • I have not changed the parser class name and ensured it does not conflict with any existing class
  • All declared sort orders and filters in availableSortOrders, filterCapabilities, and getFilterOptions are properly implemented in getList() OR getListPage() function
  • I have followed the instructions and parser class skeleton provided in this CONTRIBUTING guide
  • This PR only creates / edits to a single source; any more than that will be automatically rejected by reviewers

TESTING

I confirm that:

  • I have tested the parser for syntax errors by compiling the class with the library
  • I have tested the parser by compiling, building, and packaging it with the debug application
  • All sort orders and filters declared in availableSortOrders, filterCapabilities, and getFilterOptions work correctly in the debug application
  • getList() OR getListPage() and getDetails() functions retrieve all necessary information
  • getPages() function successfully retrieves all images from the source

Important

  • You must provide accurate information before creating a pull request
  • Select only the tasks you have completed and leave blank if you haven't done them
  • This information will be verified against data retrieved from that source by the reviewers.

Source Name (Language)

CuuTruyen (vi)

Related Issues

N/A

Description

N/A

…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.
Copilot AI lite review requested due to automatic review settings August 25, 2026 19:57

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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_data before 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) attach Cuutruyen-Client header for /api/ requests.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines 283 to 285
override fun intercept(chain: Interceptor.Chain): Response {
val response = chain.proceed(chain.request())
val fragment = response.request.url.fragment

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copilot AI review requested due to automatic review settings August 26, 2026 17:03

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 matches storageHostInterceptor behavior) to parse as HttpUrl and 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)
		}

@InvalidDavid

Copy link
Copy Markdown
Contributor

@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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants