Skip to content

Migrate WebView platforms to WebView2 (fix Snapchat crash, FetLife Cloudflare bypass, OnlyFans reliability) #1

Description

@jasmeralia

Summary

Three WebView-based platforms have fundamental reliability problems caused by GaleFling's embedded Chromium (Qt WebEngine, Chromium 134). The fix is to migrate all four WebView platforms (Snapchat, OnlyFans, FetLife, Fansly) from QWebEngine to the system Edge WebView2 runtime.

Problems

Snapchat — Renderer crash (blocker)

Snapchat's web app (www.snapchat.com/web/) crashes Qt's embedded Chromium renderer with STATUS_ACCESS_VIOLATION (exit code -1073741819) ~1,200 ms after the page loads. Root cause: the 8.3 MB Next.js bundle spawns a Web Worker and instantiates WASM from a blob: URL in a way that is incompatible with Chromium 134's renderer sandbox in the Qt embedding context. The same page works in system Chrome/Edge.

Current workaround: URL interception redirects away from the crashing page before the bundle executes. This prevents the crash but also prevents the full Snapchat web app from loading, which means the posting flow cannot be completed normally.

There is no newer PyQt6-WebEngine release to upgrade to — 6.10.0 (Chromium 134) is the latest on PyPI.

FetLife — Cloudflare fingerprinting (session test always fails)

Cloudflare fingerprints the headless QWebEnginePage user-agent/TLS context and rejects it even when valid session cookies are present, redirecting to /login. As a result, GaleFling's connection test for FetLife always reports an expired session, even when the session is actually valid.

Current workaround: The live WebView connection test is skipped for FetLife entirely; session validity is checked by reading the cookie database directly. This is functional but means we can never detect a truly expired FetLife session via the connection test.

OnlyFans — Cloudflare latency and Vue.js interaction issues

OnlyFans is protected by Cloudflare and renders its composer using Vue.js. In the Qt embedded WebView context, several workarounds are required:

  • A 1,500 ms pre-fill delay to allow Cloudflare's JS challenge and Vue to complete hydration before GaleFling can inject text.
  • An 8-second DOM check delay before running the session expiry check.
  • A 2-second startup navigation delay to allow the cookie store to initialize.
  • A JavaScript injection that bypasses Vue's controlled-component override for the 2FA "remember me" checkbox.

These workarounds are fragile — any change in Cloudflare's challenge timing or OnlyFans' Vue component structure can break them.

Proposed Solution

Migrate all WebView platforms to Microsoft WebView2 (Edge-based), as designed in docs/plans/SNAPCHAT.md.

WebView2 uses the system Edge installation, which is updated automatically by Windows Update. Benefits:

  • Snapchat crash fixed: The system Edge Chromium version is significantly newer than 134 and does not crash on the Snapchat WASM/Web Worker bundle.
  • FetLife Cloudflare bypass: WebView2's fingerprint is indistinguishable from system Edge, so Cloudflare does not reject the connection test.
  • OnlyFans reliability: With a legitimate browser fingerprint and a continuously-updated Chromium, Cloudflare challenge delays are expected to be minimal or absent.
  • No bundling required: WebView2 Runtime is pre-installed on all Windows 10 1903+ and Windows 11 machines via Windows Update.

Implementation Plan (from docs/plans/SNAPCHAT.md)

  1. Dependency: Add comtypes>=1.4.0; sys_platform == "win32" to requirements.txt. Import is deferred to method bodies so Linux CI is unaffected.

  2. src/platforms/base_webview2.py: Implement WebView2Widget(QWidget) and BaseWebView2Platform(BasePlatform) with the same public interface as BaseWebViewPlatform. Key considerations:

    • HWND embedding: WebView2Widget hosts a CoreWebView2Controller as a Win32 child window inside its own HWND.
    • Thread marshalling: all WebView2 COM callbacks must be routed back to the Qt main thread via QTimer.singleShot(0, fn).
    • Cookie path: webprofiles/{id}/EBWebView/Default/Cookies (same SQLite schema as Qt Chromium — existing _has_valid_session_in_db() logic is reused).
    • UserDataFolder = same webprofiles/{account_id} root as current profiles.
  3. Snapchat → switch to BaseWebView2Platform, validate full login + post flow.

  4. OnlyFans, FetLife, Fansly → migrate one at a time.

  5. Cleanup: Remove base_webview.py, remove PyQt6-WebEngine from requirements.txt, remove remote debug port UI, remove compatibility mode (--disable-gpu) flag support.

Open Question

The spike (step 1 of implementation) must confirm that comtypes-generated WebView2 COM bindings handle the async CreateCoreWebView2EnvironmentWithOptions callback correctly within Qt's Windows message loop. If the COM message pump conflicts with Qt's event dispatcher, a dedicated COM thread with cross-thread queuing will be needed.

Affected Files

  • src/platforms/snapchat.py, onlyfans.py, fetlife.py, fansly.py
  • src/platforms/base_webview.py (to be replaced)
  • src/gui/webview_panel.py, setup_wizard.py, settings_dialog.py
  • src/main.py (remove _apply_remote_debugging, _apply_webview_compatibility_flags)
  • requirements.txt
  • tests/test_webview_platform.py, tests/test_webview_platforms.py (monkeypatching targets updated)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions