Keep the empty host for a state_dir starting with //

With OmitHost set, a state_dir starting with // gave a db_url starting
file://, and SQLite read the first directory name as a host, so pixa
failed to start. OmitHost is now left off for such a directory: the URL
starts file://// and SQLite reads an empty host followed by the path.
Every other state_dir gives the same URL as before.

Model: opus-5-5
This commit is contained in:
2026-10-16 01:42:43 +00:00
parent 1911489815
commit 51528c92b4
3 changed files with 14 additions and 9 deletions
+7 -6
View File
@@ -716,12 +716,13 @@ Key settings in more detail:
- `db_url` — the SQLite database to open; omitted, it is - `db_url` — the SQLite database to open; omitted, it is
`file:<state_dir>/state.sqlite3?_pragma=journal_mode(WAL)`, which keeps the `file:<state_dir>/state.sqlite3?_pragma=journal_mode(WAL)`, which keeps the
database in WAL mode. `state_dir` is percent-encoded in it, so a `%`, `?` or database in WAL mode. `state_dir` is percent-encoded in it, so a `%`, `?` or
`#` in the name is written as `%25`, `%3F` or `%23`. pixa opens one connection `#` in the name is written as `%25`, `%3F` or `%23`. For a `state_dir`
to it, so its own reads and writes run one at a time. pixa adds starting with `//` it starts `file:////`, so SQLite does not read the first
`_pragma=busy_timeout(5000)` to any `db_url`, so a write that finds another directory name as a host. pixa opens one connection to it, so its own reads
program writing to the file waits up to five seconds for it instead of and writes run one at a time. pixa adds `_pragma=busy_timeout(5000)` to any
failing. WAL mode comes only from the URL: keep `_pragma=journal_mode(WAL)` in `db_url`, so a write that finds another program writing to the file waits up
one you set to five seconds for it instead of failing. WAL mode comes only from the URL:
keep `_pragma=journal_mode(WAL)` in one you set
- `cache_max_bytes` — disk cache size limit in bytes; `0` disables the disk - `cache_max_bytes` — disk cache size limit in bytes; `0` disables the disk
cache entirely; omitted defaults to 75% of the sum of the free space on the cache entirely; omitted defaults to 75% of the sum of the free space on the
filesystem containing `<state_dir>/cache/` and the bytes of source and filesystem containing `<state_dir>/cache/` and the bytes of source and
+3 -1
View File
@@ -48,7 +48,9 @@ P2: security: per-origin rate limiting
it put the name into a `file:` URL as it was, so SQLite read `%41` as `A`, a it put the name into a `file:` URL as it was, so SQLite read `%41` as `A`, a
`?` or `#` ended the path early, and the journal mode parameter was lost. The `?` or `#` ended the path early, and the journal mode parameter was lost. The
derived `db_url` is now built with Go's `net/url`, which writes those derived `db_url` is now built with Go's `net/url`, which writes those
characters as `%25`, `%3F` and `%23`. characters as `%25`, `%3F` and `%23`. For a `state_dir` starting with `//` it
starts `file:////`, so SQLite no longer reads the first directory name as a
host.
- 2026-10-15 a thin source requested with `fit=cover` no longer makes libvips - 2026-10-15 a thin source requested with `fit=cover` no longer makes libvips
build a huge image (closes #282): libvips' thumbnail scaled the whole source build a huge image (closes #282): libvips' thumbnail scaled the whole source
to cover the requested size and copied that into memory before it cut out the to cover the requested size and copied that into memory before it cut out the
+4 -2
View File
@@ -359,11 +359,13 @@ func newFromSmartConfig(sc *smartconfig.Config) (*Config, error) {
// the directory name, which SQLite decodes back, so the URL names exactly // the directory name, which SQLite decodes back, so the URL names exactly
// this file. OmitHost writes file:/var/lib/pixa/... instead of // this file. OmitHost writes file:/var/lib/pixa/... instead of
// file:///var/lib/pixa/..., and keeps a relative stateDir from being read // file:///var/lib/pixa/..., and keeps a relative stateDir from being read
// as a host name. // as a host name. A stateDir starting with // keeps the empty host, so the
// URL starts file://// and SQLite does not read the first directory name
// as a host.
func defaultDBURL(stateDir string) string { func defaultDBURL(stateDir string) string {
dbURL := url.URL{ dbURL := url.URL{
Scheme: "file", Scheme: "file",
OmitHost: true, OmitHost: !strings.HasPrefix(stateDir, "//"),
Path: stateDir + "/state.sqlite3", Path: stateDir + "/state.sqlite3",
RawQuery: "_pragma=journal_mode(WAL)", RawQuery: "_pragma=journal_mode(WAL)",
} }