<feed xmlns='http://www.w3.org/2005/Atom'>
<title>neko/web, branch claude/improve-image-proxy-5iY78</title>
<subtitle>self-hosted, single user rss reader</subtitle>
<link rel='alternate' type='text/html' href='https://git.adammathes.com/neko/'/>
<entry>
<title>Improve image proxy: streaming, size limits, Content-Type validation</title>
<updated>2026-02-18T21:33:02+00:00</updated>
<author>
<name>Claude</name>
<email>noreply@anthropic.com</email>
</author>
<published>2026-02-18T21:33:02+00:00</published>
<link rel='alternate' type='text/html' href='https://git.adammathes.com/neko/commit/?id=c585d7873e9b4bfd9f6efd30f9ce08aed8a0d92b'/>
<id>c585d7873e9b4bfd9f6efd30f9ce08aed8a0d92b</id>
<content type='text'>
Rewrites the image proxy handler to address several issues:

- Stream responses with io.Copy instead of buffering entire image in memory
- Add 25MB size limit via io.LimitReader to prevent memory exhaustion
- Close resp.Body (was previously leaked on every request)
- Validate Content-Type is an image, rejecting HTML/JS/etc
- Forward Content-Type and Content-Length from upstream
- Use http.NewRequestWithContext to propagate client cancellation
- Check upstream status codes, returning 502 for non-2xx
- Fix ETag: use proper quoted format, remove bogus Etag request header check
- Increase timeout from 5s to 30s for slow image servers
- Use proper HTTP status codes (400 for bad input, 502 for upstream errors)
- Add Cache-Control max-age directive alongside Expires header

Tests: comprehensive coverage for Content-Type filtering, upstream errors,
streaming, ETag validation, User-Agent forwarding, and Content-Length.
Benchmarks: cache hit path and streaming at 1KB/64KB/1MB/5MB sizes.

https://claude.ai/code/session_01CZcDDVmF6wNs2YjdhvCppy
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Rewrites the image proxy handler to address several issues:

- Stream responses with io.Copy instead of buffering entire image in memory
- Add 25MB size limit via io.LimitReader to prevent memory exhaustion
- Close resp.Body (was previously leaked on every request)
- Validate Content-Type is an image, rejecting HTML/JS/etc
- Forward Content-Type and Content-Length from upstream
- Use http.NewRequestWithContext to propagate client cancellation
- Check upstream status codes, returning 502 for non-2xx
- Fix ETag: use proper quoted format, remove bogus Etag request header check
- Increase timeout from 5s to 30s for slow image servers
- Use proper HTTP status codes (400 for bad input, 502 for upstream errors)
- Add Cache-Control max-age directive alongside Expires header

Tests: comprehensive coverage for Content-Type filtering, upstream errors,
streaming, ETag validation, User-Agent forwarding, and Content-Length.
Benchmarks: cache hit path and streaming at 1KB/64KB/1MB/5MB sizes.

https://claude.ai/code/session_01CZcDDVmF6wNs2YjdhvCppy
</pre>
</div>
</content>
</entry>
<entry>
<title>Merge pull request #18 from adammathes/claude/improve-test-coverage-iBkwc</title>
<updated>2026-02-18T15:52:29+00:00</updated>
<author>
<name>Adam Mathes</name>
<email>adam@adammathes.com</email>
</author>
<published>2026-02-18T15:52:29+00:00</published>
<link rel='alternate' type='text/html' href='https://git.adammathes.com/neko/commit/?id=f66114a6159e3830f5c6ea772f76c988ae65623a'/>
<id>f66114a6159e3830f5c6ea772f76c988ae65623a</id>
<content type='text'>
Add comprehensive test coverage for security and import features</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Add comprehensive test coverage for security and import features</pre>
</div>
</content>
</entry>
<entry>
<title>Increase test coverage across lowest-coverage packages</title>
<updated>2026-02-18T06:18:28+00:00</updated>
<author>
<name>Claude</name>
<email>noreply@anthropic.com</email>
</author>
<published>2026-02-18T06:18:28+00:00</published>
<link rel='alternate' type='text/html' href='https://git.adammathes.com/neko/commit/?id=269e44da41f9feed32214bbab6fc16ec88fffd85'/>
<id>269e44da41f9feed32214bbab6fc16ec88fffd85</id>
<content type='text'>
Major coverage improvements:
- safehttp: 46.7% -&gt; 93.3% (SafeDialer, redirect checking, SSRF protection)
- api: 81.8% -&gt; 96.4% (HandleImport 0% -&gt; 100%, stream errors, content types)
- importer: 85.3% -&gt; 94.7% (ImportFeeds dispatcher, OPML nesting, edge cases)
- cmd/neko: 77.1% -&gt; 85.4% (purge, secure-cookies, minutes, allow-local flags)

New tests added:
- Security regression tests (CSRF token uniqueness, mismatch rejection,
  auth cookie HttpOnly, security headers, API auth requirements)
- Stress tests for concurrent mixed operations and rapid state toggling
- SSRF protection tests for SafeDialer hostname resolution and redirect paths

https://claude.ai/code/session_01XUBh32rHpbYue1JYXSH64Q
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Major coverage improvements:
- safehttp: 46.7% -&gt; 93.3% (SafeDialer, redirect checking, SSRF protection)
- api: 81.8% -&gt; 96.4% (HandleImport 0% -&gt; 100%, stream errors, content types)
- importer: 85.3% -&gt; 94.7% (ImportFeeds dispatcher, OPML nesting, edge cases)
- cmd/neko: 77.1% -&gt; 85.4% (purge, secure-cookies, minutes, allow-local flags)

New tests added:
- Security regression tests (CSRF token uniqueness, mismatch rejection,
  auth cookie HttpOnly, security headers, API auth requirements)
- Stress tests for concurrent mixed operations and rapid state toggling
- SSRF protection tests for SafeDialer hostname resolution and redirect paths

https://claude.ai/code/session_01XUBh32rHpbYue1JYXSH64Q
</pre>
</div>
</content>
</entry>
<entry>
<title>Redesign sidebar theme controls layout and fix dark mode visibility</title>
<updated>2026-02-18T06:04:55+00:00</updated>
<author>
<name>Claude</name>
<email>noreply@anthropic.com</email>
</author>
<published>2026-02-18T06:04:55+00:00</published>
<link rel='alternate' type='text/html' href='https://git.adammathes.com/neko/commit/?id=9f4e80dfa2d829ae33b3e5dc830034ef659befeb'/>
<id>9f4e80dfa2d829ae33b3e5dc830034ef659befeb</id>
<content type='text'>
Split light/dark into ☀ ☽ buttons above a horizontal rule, with
the 5 style emoji below. Increases icon size from 0.8rem to 1rem.

Replaces opacity-only approach with explicit rgba(0,0,0) color in dark
mode (sidebar remains grey in dark theme, so icons need dark ink).
Switches hover/active backgrounds to neutral rgba(128,128,128) so
they work correctly across all themes and modes.

https://claude.ai/code/session_01Jv3c8GdaDQMm5WYwHUJMVe
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Split light/dark into ☀ ☽ buttons above a horizontal rule, with
the 5 style emoji below. Increases icon size from 0.8rem to 1rem.

Replaces opacity-only approach with explicit rgba(0,0,0) color in dark
mode (sidebar remains grey in dark theme, so icons need dark ink).
Switches hover/active backgrounds to neutral rgba(128,128,128) so
they work correctly across all themes and modes.

https://claude.ai/code/session_01Jv3c8GdaDQMm5WYwHUJMVe
</pre>
</div>
</content>
</entry>
<entry>
<title>Remove visual 'selected' state highlight from feed items</title>
<updated>2026-02-18T03:47:48+00:00</updated>
<author>
<name>Adam Mathes</name>
<email>adam@adammathes.com</email>
</author>
<published>2026-02-18T03:47:48+00:00</published>
<link rel='alternate' type='text/html' href='https://git.adammathes.com/neko/commit/?id=d7c1cc00abe7c8097625ee905a1285aa0794a598'/>
<id>d7c1cc00abe7c8097625ee905a1285aa0794a598</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>Fix scrolling behavior, CI linting, and update Dockerfile</title>
<updated>2026-02-18T03:35:55+00:00</updated>
<author>
<name>Adam Mathes</name>
<email>adam@adammathes.com</email>
</author>
<published>2026-02-18T03:34:08+00:00</published>
<link rel='alternate' type='text/html' href='https://git.adammathes.com/neko/commit/?id=5c5f440085255bf7f11af589faa4fa14d74f9294'/>
<id>5c5f440085255bf7f11af589faa4fa14d74f9294</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>Replace sidebar style cycle button with 5 emoji icons</title>
<updated>2026-02-18T01:25:04+00:00</updated>
<author>
<name>Claude</name>
<email>noreply@anthropic.com</email>
</author>
<published>2026-02-18T01:25:04+00:00</published>
<link rel='alternate' type='text/html' href='https://git.adammathes.com/neko/commit/?id=81c78496e1fa0701618254986e9ff17081a74f11'/>
<id>81c78496e1fa0701618254986e9ff17081a74f11</id>
<content type='text'>
Swap the single cycle button for individual emoji per theme:
○ Default, ◆ Refined, ▮ Terminal, ❧ Codex, ❀ Sakura.
Active theme gets a highlighted state. Separated from the
light/dark toggle with a thin divider.

https://claude.ai/code/session_01Jv3c8GdaDQMm5WYwHUJMVe
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Swap the single cycle button for individual emoji per theme:
○ Default, ◆ Refined, ▮ Terminal, ❧ Codex, ❀ Sakura.
Active theme gets a highlighted state. Separated from the
light/dark toggle with a thin divider.

https://claude.ai/code/session_01Jv3c8GdaDQMm5WYwHUJMVe
</pre>
</div>
</content>
</entry>
<entry>
<title>Refine themes, add sidebar controls, and theme docs</title>
<updated>2026-02-18T01:07:17+00:00</updated>
<author>
<name>Claude</name>
<email>noreply@anthropic.com</email>
</author>
<published>2026-02-18T01:07:17+00:00</published>
<link rel='alternate' type='text/html' href='https://git.adammathes.com/neko/commit/?id=042c8ba30a6cbc1915fce8910de31af86253a044'/>
<id>042c8ba30a6cbc1915fce8910de31af86253a044</id>
<content type='text'>
Refined: softer dark-mode link color (#a0c4e8), fix export button
vertical alignment with inline-flex, tighten settings page spacing
(reduce gaps from 3rem to 1.5rem).

Terminal: switch accent from cyan to green (#4ae54a dark / #1a7a2e
light), add proper light mode with pale steel background, scanlines
only in dark mode.

Sidebar: add quick-access controls in footer — moon/sun icon toggles
light/dark, circle icon cycles through style themes showing current
name. Both update reactively on state change.

Add THEMES.md with full documentation on creating new themes:
variable reference, selector guide, light/dark mode tips, and the
registration process.

https://claude.ai/code/session_01Jv3c8GdaDQMm5WYwHUJMVe
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Refined: softer dark-mode link color (#a0c4e8), fix export button
vertical alignment with inline-flex, tighten settings page spacing
(reduce gaps from 3rem to 1.5rem).

Terminal: switch accent from cyan to green (#4ae54a dark / #1a7a2e
light), add proper light mode with pale steel background, scanlines
only in dark mode.

Sidebar: add quick-access controls in footer — moon/sun icon toggles
light/dark, circle icon cycles through style themes showing current
name. Both update reactively on state change.

Add THEMES.md with full documentation on creating new themes:
variable reference, selector guide, light/dark mode tips, and the
registration process.

https://claude.ai/code/session_01Jv3c8GdaDQMm5WYwHUJMVe
</pre>
</div>
</content>
</entry>
<entry>
<title>Add 4 CSS style themes with runtime switcher</title>
<updated>2026-02-17T23:58:59+00:00</updated>
<author>
<name>Claude</name>
<email>noreply@anthropic.com</email>
</author>
<published>2026-02-17T23:48:10+00:00</published>
<link rel='alternate' type='text/html' href='https://git.adammathes.com/neko/commit/?id=18a85a30f4282b5d07528eb8e1dd8ff7617190d2'/>
<id>18a85a30f4282b5d07528eb8e1dd8ff7617190d2</id>
<content type='text'>
Adds a style theme system that layers additional CSS files on top of the
base stylesheet. Themes are loaded/unloaded dynamically via &lt;link&gt; tags.

- Default: existing look, unchanged
- Refined: typographic rhythm fixes, consistent spacing on settings page
- Terminal: monospace, dark phosphor CRT aesthetic (scanlines, cyan glow)
- Codex: book/Tufte-inspired with warm paper tones, serif type, fleurons
- Sakura: Japanese-inspired calm aesthetic (named for neko = cat)

Each theme supports both light and dark mode. Style selection persists
in localStorage and is independent of the light/dark toggle.

https://claude.ai/code/session_01Jv3c8GdaDQMm5WYwHUJMVe
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Adds a style theme system that layers additional CSS files on top of the
base stylesheet. Themes are loaded/unloaded dynamically via &lt;link&gt; tags.

- Default: existing look, unchanged
- Refined: typographic rhythm fixes, consistent spacing on settings page
- Terminal: monospace, dark phosphor CRT aesthetic (scanlines, cyan glow)
- Codex: book/Tufte-inspired with warm paper tones, serif type, fleurons
- Sakura: Japanese-inspired calm aesthetic (named for neko = cat)

Each theme supports both light and dark mode. Style selection persists
in localStorage and is independent of the light/dark toggle.

https://claude.ai/code/session_01Jv3c8GdaDQMm5WYwHUJMVe
</pre>
</div>
</content>
</entry>
<entry>
<title>Refine Settings labels and apply heading font to sidebar</title>
<updated>2026-02-17T23:51:14+00:00</updated>
<author>
<name>Adam Mathes</name>
<email>adam@adammathes.com</email>
</author>
<published>2026-02-17T23:51:14+00:00</published>
<link rel='alternate' type='text/html' href='https://git.adammathes.com/neko/commit/?id=fd5f67d2a45dbefbc1045bf8270cc3bc5d711592'/>
<id>fd5f67d2a45dbefbc1045bf8270cc3bc5d711592</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
</feed>
