1af9dc58a448

encode S3 keys once so repos with spaces sign correctly (3.0.7)

time
2026-09-23 21:40 UTC · 2 weeks ago
machine
koh2
agent
claude-opus-5-5
session
koh 3 review fixes
parent
69c3ac67d7c8
4 files VERSION+1 −1src/remote/s3_test.v+8 −2src/remote/sigv4.v+4 −4v.mod+1 −1
VERSION+1 −1
@@ -1 +1 @@1-3.0.61+3.0.7

view file

src/remote/s3_test.v+8 −2
@@ -77,9 +77,15 @@7777 	assert parts.host == 's3.fr-par.scw.cloud'7878 	assert parts.path == '/bucket/repo/objects/abc'7979 80-	// Slashes in the key stay slashes; anything else is encoded.81-	spaces := split_url('https://example.com/bucket/a file.txt')80+	// The URL arrives as it will be sent, already encoded: splitting it must81+	// not encode it a second time.82+	spaces := split_url('https://example.com/bucket/a%20file.txt')8283 	assert spaces.path == '/bucket/a%20file.txt'84+85+	// A repo named after a folder with a space: the path that is signed is the86+	// path that is sent, encoded once.87+	s3 := new_s3('https://s3.fr-par.scw.cloud', 'bucket', 'fr-par', 'key', 'secret')!88+	assert split_url(s3.url_for('my repo/head', '')).path == '/bucket/my%20repo/head'8389 8490 	// An endpoint with a path prefix keeps it.8591 	prefixed := split_url('https://example.com/prefix/bucket/key?x=1')

view file

src/remote/sigv4.v+4 −4
@@ -91,9 +91,9 @@9191 	path string // canonical URI, already encoded9292 }9393 94-// split_url takes a URL apart for the canonical request. The path is encoded95-// here, and the caller builds its URL from these same parts, so the URL the96-// server sees and the URL that was signed cannot drift.94+// split_url takes a URL apart for the canonical request. The URL is the one95+// that will be sent, already encoded by its builder, so its path is signed as96+// it stands: encoding it again would sign `%2520` for a `%20` on the wire.9797 pub fn split_url(url string) UrlParts {9898 	mut rest := url9999 	if at := rest.index('://') {@@ -110,7 +110,7 @@110110 	}111111 	return UrlParts{112112 		host: host113-		path: encode(path, true)113+		path: path114114 	}115115 }116116 

view file

v.mod+1 −1
@@ -1,6 +1,6 @@11 Module {22 	name: 'koh3'3-	version: '3.0.6'3+	version: '3.0.7'44 	description: 'One SQLite file per repo, one line of history.'55 	license: 'MIT'66 }

view file