mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-07-24 00:53:05 +00:00
* s3: accept raw semicolons in query strings Go's url.ParseQuery drops any key=value pair containing a raw ';'. A presigned PUT that signs content-type carries X-Amz-SignedHeaders=content-type%3Bhost; when a client or proxy decodes the %3B, the parameter vanished and the upload failed with MissingFields, while AWS accepts the raw ';' as query data. Re-encode it before routing so the pair survives parsing and signature verification. * iam, iceberg: recover raw-semicolon query pairs on the other listeners The standalone IAM API verifies SigV4 with a canonical query recomputed from the parsed query, and Iceberg REST warehouse/parent values may legally contain ';'. Move the normalization middleware to util/http and attach it to both routers.
26 lines
771 B
Go
26 lines
771 B
Go
package http
|
|
|
|
import (
|
|
"net/http"
|
|
"strings"
|
|
)
|
|
|
|
// EscapeSemicolonsInQuery re-encodes raw ';' in the query string. RFC 3986
|
|
// allows ';' in a query and AWS treats it as data, but Go's url.ParseQuery
|
|
// drops every key=value pair containing one. Presigned URLs carry
|
|
// X-Amz-SignedHeaders=content-type%3Bhost; clients that decode the %3B would
|
|
// otherwise lose the parameter entirely and fail signature verification.
|
|
func EscapeSemicolonsInQuery(next http.Handler) http.Handler {
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
if strings.Contains(r.URL.RawQuery, ";") {
|
|
u := *r.URL
|
|
u.RawQuery = strings.ReplaceAll(u.RawQuery, ";", "%3B")
|
|
r2 := new(http.Request)
|
|
*r2 = *r
|
|
r2.URL = &u
|
|
r = r2
|
|
}
|
|
next.ServeHTTP(w, r)
|
|
})
|
|
}
|