Skip to content

fix: support http(s) connection strings and sqld namespace URLs - #7

Merged
jonaspm merged 4 commits into
mainfrom
fix/http-connection-string-schemes
Sep 15, 2026
Merged

jonaspm merged 4 commits into
mainfrom
fix/http-connection-string-schemes

Conversation

@jonaspm

@jonaspm jonaspm commented Sep 15, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Three gaps made a sqld namespace URL (http://192.0.2.10:8080/dev/example/) unusable from Tabularis (all found during manual testing against a real self-hosted sqld):

  1. Scheme not declared. .tabularium declared connection_uri: true but its connection_uri_schemes only listed turso, wss, ws and file. The host resolves a pasted connection string's protocol against that registry, so http:///https:// URIs were rejected as an unsupported driver before the plugin ever saw them — even though resolve_backend/normalize_remote_url already handled those schemes.
  2. Decomposed params dropped the path. When the host sends host/port/database instead of the verbatim URI, the database value was ignored on the remote branch, so the plugin built http://host:8080 and posted to /v2/pipeline instead of the namespaced URL.
  3. Path-based namespaces never selected the namespace. sqld resolves the namespace from the x-namespace header, not the URL path — 0.24.x serves /dev/<ns>/v2/pipeline but still takes the namespace from the Host header (the first octet of an IP literal), producing a 404 Namespace ... doesn't exist. The plugin now derives the namespace from the URL path (dev/example → example) and sends it as x-namespace.
  • .tabularium: declare http and https; mention the sqld namespace form in connection_string_example
  • src/client.rs: keep a multi-segment database value as a path prefix on the bare-host branch; Turso names contain no /, so plain names stay pathless
  • src/hrana.rs: namespace_from_url_path + x-namespace header; plain hosts (Turso) send no header
  • Regression tests: scheme/path preservation, connection_uri resolution, decomposed host/port/database (with/without trailing slash), plain-name no-path guard, namespace derivation/absence
  • README + CHANGELOG (release 1.0.1), version bump in Cargo.toml and .tabularium

Closes #6

Test plan

  • just test — 98 tests pass
  • just lint — clippy -D warnings clean
  • End-to-end against a local listener on port 8080:
    • {"connection_uri":"http://localhost:8080/dev/example/"} → captured POST /dev/example/v2/pipeline
    • {"host":"127.0.0.1","port":8080,"database":"dev/example/","ssl_mode":"disable"} → captured POST /dev/example/v2/pipeline
  • Against a real self-hosted sqld 0.24.33 with the params the host sent: test_connection succeeds and metadata queries return real data; raw HTTP probes confirmed /dev/<ns>/v2/pipeline + x-namespace: <ns> → 200, while the same request without the header → 404.

Release

Merging this unblocks git tag v1.0.1, which triggers the release workflow. Run just dev-install + restart Tabularis to reload the manifest locally.

@jonaspm jonaspm changed the title fix: accept http:// and https:// connection strings fix: support http(s) connection strings and sqld namespace URLs Sep 15, 2026
The host only forwards the raw URI to a plugin for schemes declared in .tabularium's connection_uri_schemes, so http://localhost:8080/dev/example/ was rejected as an unsupported driver before the plugin saw it. Declare http/https, after which resolve_backend keeps the verbatim URL and its path, posting to /dev/example/v2/pipeline.

Release 1.0.1.
When the host sends params decomposed (host/port/database) instead of the verbatim URI, the database value was ignored on the remote branch: http://192.0.2.10:8080/dev/example/ became a POST to /v2/pipeline, so sqld picked the namespace from the Host header and returned 404. Treat a multi-segment database value as a path prefix; Turso database names cannot contain a separator.
sqld resolves the namespace from the x-namespace header, not the URL path: 0.24.x ignores a /dev/<ns>/ prefix and falls back to the Host header (the first octet of an IP literal, and a 404). Derive the namespace from the URL path (dev/example -> example) and send it as x-namespace; plain Turso hosts get no header. Verified against sqld 0.24.33: test_connection and get_tables return real data.
@jonaspm
jonaspm force-pushed the fix/http-connection-string-schemes branch from 35375ca to 186426e Compare September 15, 2026 19:03
@jonaspm
jonaspm merged commit 6879414 into main Sep 15, 2026
@jonaspm
jonaspm deleted the fix/http-connection-string-schemes branch September 15, 2026 19:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant