fix(pdf): use assets:// protocol for local PDFs/images on Electron - #12970
Open
e-zz wants to merge 3 commits into
Open
fix(pdf): use assets:// protocol for local PDFs/images on Electron#12970e-zz wants to merge 3 commits into
e-zz wants to merge 3 commits into
Conversation
On Electron, Chromium blocks file:// URLs from the renderer process. The assets:// custom protocol is already registered to handle local file access. This change ensures all code paths that generate PDF or image URLs use assets:// instead of file:// on Electron. Fixes logseq#12746
get-zotero-local-pdf-path concatenated assets:// directly with the joined path, so 'assets://C:/Users/...' was parsed with C: as the URL host (lowercased to c), losing the path. Route through normalize-asset-resource-url which applies protect-windows-drive-in-assets-path (C: -> C/logseq__colon/), producing assets:///C/logseq__colon/Users/...
…drives The previous fix replaced file:// with assets:// but left the drive letter as the URL host (assets://C:/Users -> host 'c', losing the path). Now strip file:// and route through normalize-asset-resource-url, which applies protect-windows-drive-in-assets-path (C: -> C/logseq__colon/). Also fix zotero-linked-file/zotero-imported-file macros to build local paths and let normalize handle them on Electron.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes #12746 — local PDFs and inline images fail to open in the Electron app because Chromium's security policy blocks
file://URLs in the renderer ("Not allowed to load local resource" /Unexpected server response (0)).Note: this PR was generated with the assistance of AI agents. The key findings from our debugging trials are documented below so reviewers can verify the reasoning rather than just the diff.
Root cause
Three code paths assembled PDF/image URLs by raw string concatenation, bypassing Logseq's registered
assets://protocol on Electron:frontend.extensions.zotero/zotero-linked-fileandzotero-full-path—(str "file://" (node-path/join ...))frontend.extensions.pdf.assets/get-zotero-local-pdf-path—(str "assets://" (node-path/join ...))frontend.handler.assets/normalize-asset-resource-urland<make-asset-url— returnedfile://URLs unchangedKey findings from our trials
Finding 1: naive
file://→assets://replacement is NOT enough on WindowsThe first fix attempt simply replaced the
file://prefix withassets://. This broke on Windows:assets://C:/Users/...is parsed by the URL parser as host=c, port=/Users/...— the drive letter is consumed as the authority, the path is lost, and the request fails. The error shown in the app was:Note the lowercase
c— that's the host component, not the path.Finding 2: the drive letter must be protected before URL assembly
Logseq already has
protect-windows-drive-in-assets-path(C:→C/logseq__colon/), used by the normal asset path. The Electron main process reverses it indecode-protected-assets-schema-path(src/electron/electron/utils.cljs). The fix routes everyfile://URL and zotero path throughnormalize-asset-resource-url, which applies this protection:The correct form has three slashes and the encoded drive — the host is empty, the path is preserved.
Finding 3: verify the transformation, not just the prefix
Verified end-to-end with the real file paths from a user graph: the produced URL decodes through the Electron handler to the exact filesystem path (
C:/Users/zhang/biblio/library/qn/Cao et al....pdf) and the file exists. All three code paths produce the canonicalassets:///C/logseq__colon/...form that Electron already serves correctly for Windows images.Changes
src/main/frontend/handler/assets.cljsnormalize-asset-resource-url: on Electron, stripfile://then re-normalize (applies drive protection)<make-asset-url: same conversion when the URL protocol isfile:src/main/frontend/extensions/pdf/assets.cljsget-zotero-local-pdf-path: build the local path, then normalize on Electroninflate-asset: stripfile://then normalize on Electronsrc/main/frontend/extensions/zotero.cljszotero-linked-file/zotero-full-path: build the local path, normalize on Electron instead of rawfile://concatNon-Electron (web browser) behavior is unchanged —
file://is still emitted there since it's the only way a browser can reference local files.Test plan
bb dev:test -v frontend.handler.assets-test— 14 tests, 23 assertions, 0 failures{{zotero-linked-file ...}}PDF and an asset-block PDF on Windows Electron — both load viaassets://