<feed xmlns='http://www.w3.org/2005/Atom'>
<title>skunky-art.git/app/api.go, branch main</title>
<subtitle>alternative deviantart frontend, no javascript. go.
</subtitle>
<id>http://git.krz.sh/krz/skunky-art.git/atom?h=main</id>
<link rel='self' href='http://git.krz.sh/krz/skunky-art.git/atom?h=main'/>
<link rel='alternate' type='text/html' href='http://git.krz.sh/krz/skunky-art.git/'/>
<updated>2026-08-02T13:30:01+00:00</updated>
<entry>
<title>update org name</title>
<updated>2026-08-02T13:30:01+00:00</updated>
<author>
<name>Christian Cleberg</name>
<email>hello@cleberg.net</email>
</author>
<published>2026-08-02T06:51:22+00:00</published>
<link rel='alternate' type='text/html' href='http://git.krz.sh/krz/skunky-art.git/commit/?id=4178e3893f310425e76f6d4515af9e7d0ea36a0a'/>
<id>urn:sha1:4178e3893f310425e76f6d4515af9e7d0ea36a0a</id>
<content type='text'>
</content>
</entry>
<entry>
<title>fix: harden HTTP transport, server timeouts and panic paths</title>
<updated>2026-07-15T07:24:58+00:00</updated>
<author>
<name>Christian Cleberg</name>
<email>hello@cleberg.net</email>
</author>
<published>2026-07-15T07:24:58+00:00</published>
<link rel='alternate' type='text/html' href='http://git.krz.sh/krz/skunky-art.git/commit/?id=7eb5e5e2230b6fb5b1bed6f0eaa03279aa61555b'/>
<id>urn:sha1:7eb5e5e2230b6fb5b1bed6f0eaa03279aa61555b</id>
<content type='text'>
Correctness and security findings surfaced by golangci-lint, plus two
latent panics found alongside them.

- router: http.ListenAndServe has no timeouts at all (gosec G114), so a
  slow client could hold a connection and its handler open indefinitely.
  Replace it with an explicit http.Server carrying read/write/idle
  timeouts.
- httpclient: InstallDAThrottle asserted http.DefaultTransport was a
  *http.Transport and would panic outright if anything had already
  wrapped it -- which is precisely what that function does. Check the
  assertion and fall back to a fresh transport. Expose ProxiedTransport
  so a configured download-proxy can inherit the same throttle and
  timeouts instead of silently bypassing them.
- cache: the Sys() assertion to *syscall.Stat_t is only valid on unix and
  would panic elsewhere; skip rotation instead. Indexing
  Headers["Content-Type"][0] panics when the header is absent; use
  Headers.Get. Cache files are written 0600 rather than 0700, as they are
  never executed.
- cli, api: check error returns, and exit rather than nil-dereference a
  file handle that failed to open.

SHA-1 and math/rand keep //nolint:gosec with reasons: they are cache-key
hashes and random-artwork picks, not security primitives.
</content>
</entry>
<entry>
<title>fix: remove russian language throughout</title>
<updated>2026-07-15T06:58:41+00:00</updated>
<author>
<name>Christian Cleberg</name>
<email>hello@cleberg.net</email>
</author>
<published>2026-07-15T06:54:26+00:00</published>
<link rel='alternate' type='text/html' href='http://git.krz.sh/krz/skunky-art.git/commit/?id=b1ad14553277d9d72a5e4b4462a52a2e2d0fdbb1'/>
<id>urn:sha1:b1ad14553277d9d72a5e4b4462a52a2e2d0fdbb1</id>
<content type='text'>
</content>
</entry>
<entry>
<title>fix(api): harden random-art retry loop</title>
<updated>2026-07-15T01:22:14+00:00</updated>
<author>
<name>Christian Cleberg</name>
<email>hello@cleberg.net</email>
</author>
<published>2026-07-15T01:22:14+00:00</published>
<link rel='alternate' type='text/html' href='http://git.krz.sh/krz/skunky-art.git/commit/?id=8a00f7c55cdbcddcd878c01a79f2db7dc3f080ef'/>
<id>urn:sha1:8a00f7c55cdbcddcd878c01a79f2db7dc3f080ef</id>
<content type='text'>
Three bugs in Random():

- The retry loop was unbounded. Only the NSFW path incremented attempt,
  so a run of DeviantArt errors span forever, hammering the API and
  risking an egress-IP ban.
- string(rand.Intn(999)) converts a rune, not a number: string(65) is
  "A", not "65". Searches were querying garbage. Use strconv.Itoa.
- rand.Intn panics on 0, so an empty result set crashed the handler.
  Skip empty results.

The exhausted-retries error now fires when the loop ends rather than
falling through to index an empty slice.
</content>
</entry>
<entry>
<title>deps: migrate to github.com/zerolabsco/devianter v0.3.1</title>
<updated>2026-07-15T01:22:04+00:00</updated>
<author>
<name>Christian Cleberg</name>
<email>hello@cleberg.net</email>
</author>
<published>2026-07-15T01:22:04+00:00</published>
<link rel='alternate' type='text/html' href='http://git.krz.sh/krz/skunky-art.git/commit/?id=0fdc45a668d95d603a9013f90392f6bc966c72f9'/>
<id>urn:sha1:0fdc45a668d95d603a9013f90392f6bc966c72f9</id>
<content type='text'>
Repoint the import path from git.macaw.me/skunky/devianter, replacing a
placeholder v0.0.0 require that had no go.sum entry and did not resolve.

v0.3.1 reorders the last two return values of PerformSearch, Group.Get
and Group.Gallery from (..., error, Error) to (..., Error, error);
adapt the call sites. The two types differ, so the compiler enforces
this.
</content>
</entry>
<entry>
<title>Add da.opnxng.com + lost-skunk.cc is now in Finland</title>
<updated>2025-04-07T10:53:47+00:00</updated>
<author>
<name>lost+skunk</name>
<email>me@lost-skunk.cc</email>
</author>
<published>2025-04-07T10:53:47+00:00</published>
<link rel='alternate' type='text/html' href='http://git.krz.sh/krz/skunky-art.git/commit/?id=210c69e48c2af4d1fdb53c0654ed33a21688696c'/>
<id>urn:sha1:210c69e48c2af4d1fdb53c0654ed33a21688696c</id>
<content type='text'>
</content>
</entry>
<entry>
<title>Переключатель кеша в озу, небольшие улучшения ксс, фикс нсфв, фикс максимального размера кеша</title>
<updated>2025-02-22T12:30:29+00:00</updated>
<author>
<name>lost+skunk</name>
<email>skunky@macaw.me</email>
</author>
<published>2025-02-22T12:30:29+00:00</published>
<link rel='alternate' type='text/html' href='http://git.krz.sh/krz/skunky-art.git/commit/?id=048bb470ab8dc3adce83d2e615f3ab369efa2199'/>
<id>urn:sha1:048bb470ab8dc3adce83d2e615f3ab369efa2199</id>
<content type='text'>
</content>
</entry>
<entry>
<title>v1.3.2</title>
<updated>2024-09-23T06:38:32+00:00</updated>
<author>
<name>lost+skunk</name>
<email>skunky@ebloid.ru</email>
</author>
<published>2024-09-23T06:38:32+00:00</published>
<link rel='alternate' type='text/html' href='http://git.krz.sh/krz/skunky-art.git/commit/?id=191984b31ef228c4077904a2831a2af593352670'/>
<id>urn:sha1:191984b31ef228c4077904a2831a2af593352670</id>
<content type='text'>
</content>
</entry>
<entry>
<title>отображение ошибок</title>
<updated>2024-09-04T17:22:58+00:00</updated>
<author>
<name>lost+skunk</name>
<email>skunky@ebloid.ru</email>
</author>
<published>2024-09-04T17:22:58+00:00</published>
<link rel='alternate' type='text/html' href='http://git.krz.sh/krz/skunky-art.git/commit/?id=c39399403e031a8c1ad53969770e4261d2c9e7aa'/>
<id>urn:sha1:c39399403e031a8c1ad53969770e4261d2c9e7aa</id>
<content type='text'>
</content>
</entry>
<entry>
<title>Два API-эндпоинта</title>
<updated>2024-09-03T12:36:19+00:00</updated>
<author>
<name>lost+skunk</name>
<email>skunky@ebloid.ru</email>
</author>
<published>2024-09-03T12:36:19+00:00</published>
<link rel='alternate' type='text/html' href='http://git.krz.sh/krz/skunky-art.git/commit/?id=db53a8bd9004098e6a1507e5826a833fd9efa954'/>
<id>urn:sha1:db53a8bd9004098e6a1507e5826a833fd9efa954</id>
<content type='text'>
</content>
</entry>
</feed>
