Skip to content

Add custom protocol for serving local image assets#22

Merged
ptheofan merged 3 commits into
mainfrom
claude/fix-kafka-readme-images-pjWcG
May 14, 2026
Merged

Add custom protocol for serving local image assets#22
ptheofan merged 3 commits into
mainfrom
claude/fix-kafka-readme-images-pjWcG

Conversation

@ptheofan

Copy link
Copy Markdown
Owner

Summary

Implement a custom om-asset: protocol to serve local image assets referenced in markdown documents. This allows markdown files to reference images using relative or absolute filesystem paths, which are resolved and served by the main process instead of failing to load due to CSP restrictions.

Key Changes

  • AssetProtocolService (src/main/services/AssetProtocolService.ts): New service that registers and handles the om-asset: protocol. The handler validates file extensions against a whitelist of image types, reads files from disk, and returns appropriate HTTP responses with correct content-type headers.

  • Asset Resolver (src/preload/assetResolver.ts): New preload utility that resolves image references from markdown documents to om-asset: URLs. Handles relative paths (resolved against the document directory), absolute paths, and leaves external URLs and data URIs untouched.

  • Asset Path Rewriting (src/renderer/utils/assetPaths.ts): New renderer utility that rewrites src and srcset attributes in rendered markdown to use resolved asset URLs. Supports both simple <img> elements and <picture> elements with <source> tags.

  • MarkdownViewer Integration (src/renderer/components/MarkdownViewer.ts): Updated to call asset path rewriting after rendering markdown content, using the preload resolver via the Electron API.

  • API Exposure (src/preload/preload.ts, src/shared/types/api.ts): Exposed assets.resolve() method through the Electron API bridge to allow the renderer to resolve asset paths.

  • Main Process Setup (src/main/index.ts): Register the asset protocol scheme before app ready and handler after app ready.

  • CSP Update (index.html): Updated Content-Security-Policy to allow om-asset: scheme for images.

  • Constants (src/shared/constants/index.ts): Added ASSET_PROTOCOL_SCHEME constant.

Implementation Details

  • The protocol handler restricts served files to image extensions (SVG, PNG, JPEG, GIF, WebP, BMP, ICO, AVIF, APNG) to prevent arbitrary file access.
  • Asset URLs are converted between file: and om-asset: schemes to maintain compatibility with Node's path utilities.
  • Query strings and fragments are stripped from references before resolution, as filesystem paths don't support them.
  • Percent-encoded references are decoded before resolution.
  • Comprehensive test coverage for all three layers: protocol handler, asset resolver, and path rewriting.

https://claude.ai/code/session_01T2U6dtaZLWCuztQVRFTj7U

claude added 3 commits May 14, 2026 13:36
Markdown files commonly reference images with relative or absolute
filesystem paths (e.g. the Kafka README's <picture> logo). Those never
loaded: the document origin is the app bundle/dev server and the CSP
forbids file: images.

Add an om-asset: custom protocol that serves local image files, rewrite
img/source src and srcset references against the document's directory
after render, and allow the scheme through the CSP.

https://claude.ai/code/session_01T2U6dtaZLWCuztQVRFTj7U
Markdown files routinely embed remote images (e.g. the CI status badges
in the Kafka README). The CSP only permitted local assets, so https
images were blocked. Add https: to img-src.

https://claude.ai/code/session_01T2U6dtaZLWCuztQVRFTj7U
A bare om-asset:///path URL had its first path segment consumed as the
URL host (and lowercased), so local image requests 404'd/400'd. Carry
the file path under a fixed `local` host instead.

https://claude.ai/code/session_01T2U6dtaZLWCuztQVRFTj7U
@ptheofan ptheofan merged commit c29535f into main May 14, 2026
4 checks passed
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.

2 participants