From: Dan Fuhry Date: Mon, 17 Nov 2025 23:55:02 +0000 (-0500) Subject: [http/route_action_s3] use etag over ChecksumSHA1; fix URL decoding; limit to GET... X-Git-Url: https://go.fuhry.dev/?a=commitdiff_plain;h=6593afdccb49da7a9a0089336df9182e53764779;p=runtime.git [http/route_action_s3] use etag over ChecksumSHA1; fix URL decoding; limit to GET and HEAD --- diff --git a/http/route_action_s3.go b/http/route_action_s3.go index 40dc3a1..8659c1a 100644 --- a/http/route_action_s3.go +++ b/http/route_action_s3.go @@ -4,6 +4,7 @@ import ( "fmt" "io" "net/http" + "net/url" "strings" "sync" "time" @@ -27,6 +28,11 @@ type S3Action struct { // Handle implements RouteAction func (a *S3Action) Handle(w http.ResponseWriter, r *http.Request, next http.HandlerFunc) { + if r.Method != "HEAD" && r.Method != "GET" { + http.Error(w, fmt.Sprintf("Method not allowed: %s", r.Method), http.StatusMethodNotAllowed) + return + } + mc, err := a.minioClient() if err != nil { w.WriteHeader(http.StatusInternalServerError) @@ -35,7 +41,13 @@ func (a *S3Action) Handle(w http.ResponseWriter, r *http.Request, next http.Hand } reqPath := strings.TrimPrefix(r.URL.Path, a.StripPrefix) - objPath := "/" + strings.Trim(strings.Join( + reqPath, err = url.PathUnescape(reqPath) + if err != nil { + w.WriteHeader(http.StatusBadRequest) + w.Write([]byte(fmt.Sprintf("failed decoding path: %+v", err))) + return + } + objPath := strings.Trim(strings.Join( []string{ strings.Trim(a.ObjectPrefix, "/"), strings.Trim(reqPath, "/"), @@ -85,15 +97,15 @@ func (a *S3Action) Handle(w http.ResponseWriter, r *http.Request, next http.Hand } w.Header().Set("last-modified", stat.LastModified.Format(http.TimeFormat)) - if stat.ChecksumSHA1 != "" { + if stat.ETag != "" { if inm := r.Header.Get("if-none-match"); inm != "" { - if inm == stat.ChecksumSHA1 { + if inm == stat.ETag { w.WriteHeader(http.StatusNotModified) return } } - w.Header().Set("ETag", stat.ChecksumSHA1) + w.Header().Set("ETag", stat.ETag) } var seek int64 @@ -156,6 +168,10 @@ func (a *S3Action) Handle(w http.ResponseWriter, r *http.Request, next http.Hand w.Header().Set("content-type", stat.ContentType) w.WriteHeader(rc) + if r.Method == "HEAD" { + return + } + io.CopyN(w, object, size) }