PostObject doesn't work #456

Closed
opened 2024-08-09 14:10:02 +00:00 by dkirillov · 0 comments
Member

Expected Behavior

Post object works as expected https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-UsingHTTPPOST.html

Current Behavior

We get panic:

 panic: runtime error: invalid memory address or nil pointer dereference
 
 -> git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api.NewRouter.Auth.func5.1
 ->   /home/denis/github/tcl/neofs-s3-gw/api/middleware/auth.go:75

    net/http.HandlerFunc.ServeHTTP
      /home/denis/go/go1.21.6/src/net/http/server.go:2136
    git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api.NewRouter.LogSuccessResponse.func4.1
      /home/denis/github/tcl/neofs-s3-gw/api/middleware/response.go:304
    net/http.HandlerFunc.ServeHTTP
      /home/denis/go/go1.21.6/src/net/http/server.go:2136
    git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/middleware.stats.func1
      /home/denis/github/tcl/neofs-s3-gw/api/middleware/metrics.go:75
    net/http.HandlerFunc.ServeHTTP
      /home/denis/go/go1.21.6/src/net/http/server.go:2136
    git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api.NewRouter.Tracing.func2.1
      /home/denis/github/tcl/neofs-s3-gw/api/middleware/tracing.go:23
    net/http.HandlerFunc.ServeHTTP
      /home/denis/go/go1.21.6/src/net/http/server.go:2136
    github.com/go-chi/chi/v5/middleware.Recoverer.func1
      /home/denis/go/pkg/mod/github.com/go-chi/chi/v5@v5.0.8/middleware/recoverer.go:43
    net/http.HandlerFunc.ServeHTTP
      /home/denis/go/go1.21.6/src/net/http/server.go:2136
    github.com/go-chi/chi/v5/middleware.ThrottleWithOpts.func1.1
      /home/denis/go/pkg/mod/github.com/go-chi/chi/v5@v5.0.8/middleware/throttle.go:100
    net/http.HandlerFunc.ServeHTTP
      /home/denis/go/go1.21.6/src/net/http/server.go:2136
    git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api.NewRouter.Request.func1.1
      /home/denis/github/tcl/neofs-s3-gw/api/middleware/reqinfo.go:195
    net/http.HandlerFunc.ServeHTTP
      /home/denis/go/go1.21.6/src/net/http/server.go:2136
    github.com/go-chi/chi/v5.(*Mux).ServeHTTP
      /home/denis/go/pkg/mod/github.com/go-chi/chi/v5@v5.0.8/mux.go:90
    net/http.serverHandler.ServeHTTP
      /home/denis/go/go1.21.6/src/net/http/server.go:2938
    net/http.(*conn).serve
      /home/denis/go/go1.21.6/src/net/http/server.go:2009
    created by net/http.(*Server).Serve in goroutine 154
      /home/denis/go/go1.21.6/src/net/http/server.go:3086
    

Possible Solution

diff --git a/api/auth/center.go b/api/auth/center.go
index 72fb7fea..d2c65f56 100644
--- a/api/auth/center.go
+++ b/api/auth/center.go
@@ -290,7 +290,15 @@ func (c *Center) checkFormData(r *http.Request) (*middleware.Box, error) {
 			reqSignature, signature)
 	}
 
-	return &middleware.Box{AccessBox: box, Attributes: attrs}, nil
+	return &middleware.Box{
+		AccessBox: box,
+		AuthHeaders: &middleware.AuthHeader{
+			AccessKeyID: submatches["access_key_id"],
+			Region:      region,
+			SignatureV4: signature,
+		},
+		Attributes: attrs,
+	}, nil
 }
 
 func cloneRequest(r *http.Request, authHeader *AuthHeader) *http.Request {
diff --git a/api/handler/put.go b/api/handler/put.go
index 94cc0f35..308f0a25 100644
--- a/api/handler/put.go
+++ b/api/handler/put.go
@@ -482,13 +482,22 @@ func (h *handler) PostObject(w http.ResponseWriter, r *http.Request) {
 		}
 		contentReader = file
 		size = uint64(head.Size)
-		reqInfo.ObjectName = strings.ReplaceAll(reqInfo.ObjectName, "${filename}", head.Filename)
+		if reqInfo.ObjectName == "" {
+			reqInfo.ObjectName = head.Filename
+		} else {
+			reqInfo.ObjectName = strings.ReplaceAll(reqInfo.ObjectName, "${filename}", head.Filename)
+		}
 	}
 	if !policy.CheckContentLength(size) {
 		h.logAndSendError(w, "invalid content-length", reqInfo, errors.GetAPIError(errors.ErrInvalidArgument))
 		return
 	}
 
+	if reqInfo.ObjectName == "" {
+		h.logAndSendError(w, "missing object name", reqInfo, errors.GetAPIError(errors.ErrInvalidArgument))
+		return
+	}
+
 	params := &layer.PutObjectParams{
 		BktInfo: bktInfo,
 		Object:  reqInfo.ObjectName,

Steps to Reproduce (for bugs)

Try to upload object from browser using steps from spec https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-post-example.html

Request example:

 curl -X POST http://localhost:8084/test3 \
-H 'Content-Type: multipart/form-data; boundary=ade4749fd805cf7903338195fac70a2f9a8998eae7f749b7823879dedb12' \
--data-binary ' \
--ade4749fd805cf7903338195fac70a2f9a8998eae7f749b7823879dedb12
Content-Disposition: form-data; name="Policy"

eyJleHBpcmF0aW9uIjogIjIwMjUtMTItMDFUMTI6MDA6MDAuMDAwWiIsImNvbmRpdGlvbnMiOiBbCiBbInN0YXJ0cy13aXRoIiwgIiR4LWFtei1jcmVkZW50aWFsIiwgIiJdLAogWyJzdGFydHMtd2l0aCIsICIkeC1hbXotZGF0ZSIsICIiXQpdfQ==
--ade4749fd805cf7903338195fac70a2f9a8998eae7f749b7823879dedb12
Content-Disposition: form-data; name="X-Amz-Credential"

5jizSbYu8hX345aqCKDgRWKCJYHxnzxRS8e6SUYHZ8Fw0HiRkf3KbJAWBn5mRzmiyHQ3UHADGyzVXLusn1BrmAfLn/20240809T164847Z/default/s3/aws4_request
--ade4749fd805cf7903338195fac70a2f9a8998eae7f749b7823879dedb12
Content-Disposition: form-data; name="X-Amz-Date"

20240809T164847Z
--ade4749fd805cf7903338195fac70a2f9a8998eae7f749b7823879dedb12
Content-Disposition: form-data; name="X-Amz-Signature"

d51a75f772782a708f649439105fde6466cd1f3bfb4a1e6e777d7d37d0894e69
--ade4749fd805cf7903338195fac70a2f9a8998eae7f749b7823879dedb12
Content-Disposition: form-data; name="file"; filename="test.txt"
Content-Type: application/octet-stream

--ade4749fd805cf7903338195fac70a2f9a8998eae7f749b7823879dedb12--
'

Context

No

Regression

Yes

Your Environment

  • Version used: v0.30.1
  • Server setup and configuration: devenv
<!--- Provide a general summary of the issue in the Title above --> ## Expected Behavior Post object works as expected https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-UsingHTTPPOST.html ## Current Behavior We get panic: ``` panic: runtime error: invalid memory address or nil pointer dereference -> git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api.NewRouter.Auth.func5.1 -> /home/denis/github/tcl/neofs-s3-gw/api/middleware/auth.go:75 net/http.HandlerFunc.ServeHTTP /home/denis/go/go1.21.6/src/net/http/server.go:2136 git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api.NewRouter.LogSuccessResponse.func4.1 /home/denis/github/tcl/neofs-s3-gw/api/middleware/response.go:304 net/http.HandlerFunc.ServeHTTP /home/denis/go/go1.21.6/src/net/http/server.go:2136 git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/middleware.stats.func1 /home/denis/github/tcl/neofs-s3-gw/api/middleware/metrics.go:75 net/http.HandlerFunc.ServeHTTP /home/denis/go/go1.21.6/src/net/http/server.go:2136 git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api.NewRouter.Tracing.func2.1 /home/denis/github/tcl/neofs-s3-gw/api/middleware/tracing.go:23 net/http.HandlerFunc.ServeHTTP /home/denis/go/go1.21.6/src/net/http/server.go:2136 github.com/go-chi/chi/v5/middleware.Recoverer.func1 /home/denis/go/pkg/mod/github.com/go-chi/chi/v5@v5.0.8/middleware/recoverer.go:43 net/http.HandlerFunc.ServeHTTP /home/denis/go/go1.21.6/src/net/http/server.go:2136 github.com/go-chi/chi/v5/middleware.ThrottleWithOpts.func1.1 /home/denis/go/pkg/mod/github.com/go-chi/chi/v5@v5.0.8/middleware/throttle.go:100 net/http.HandlerFunc.ServeHTTP /home/denis/go/go1.21.6/src/net/http/server.go:2136 git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api.NewRouter.Request.func1.1 /home/denis/github/tcl/neofs-s3-gw/api/middleware/reqinfo.go:195 net/http.HandlerFunc.ServeHTTP /home/denis/go/go1.21.6/src/net/http/server.go:2136 github.com/go-chi/chi/v5.(*Mux).ServeHTTP /home/denis/go/pkg/mod/github.com/go-chi/chi/v5@v5.0.8/mux.go:90 net/http.serverHandler.ServeHTTP /home/denis/go/go1.21.6/src/net/http/server.go:2938 net/http.(*conn).serve /home/denis/go/go1.21.6/src/net/http/server.go:2009 created by net/http.(*Server).Serve in goroutine 154 /home/denis/go/go1.21.6/src/net/http/server.go:3086 ``` ## Possible Solution ```diff diff --git a/api/auth/center.go b/api/auth/center.go index 72fb7fea..d2c65f56 100644 --- a/api/auth/center.go +++ b/api/auth/center.go @@ -290,7 +290,15 @@ func (c *Center) checkFormData(r *http.Request) (*middleware.Box, error) { reqSignature, signature) } - return &middleware.Box{AccessBox: box, Attributes: attrs}, nil + return &middleware.Box{ + AccessBox: box, + AuthHeaders: &middleware.AuthHeader{ + AccessKeyID: submatches["access_key_id"], + Region: region, + SignatureV4: signature, + }, + Attributes: attrs, + }, nil } func cloneRequest(r *http.Request, authHeader *AuthHeader) *http.Request { diff --git a/api/handler/put.go b/api/handler/put.go index 94cc0f35..308f0a25 100644 --- a/api/handler/put.go +++ b/api/handler/put.go @@ -482,13 +482,22 @@ func (h *handler) PostObject(w http.ResponseWriter, r *http.Request) { } contentReader = file size = uint64(head.Size) - reqInfo.ObjectName = strings.ReplaceAll(reqInfo.ObjectName, "${filename}", head.Filename) + if reqInfo.ObjectName == "" { + reqInfo.ObjectName = head.Filename + } else { + reqInfo.ObjectName = strings.ReplaceAll(reqInfo.ObjectName, "${filename}", head.Filename) + } } if !policy.CheckContentLength(size) { h.logAndSendError(w, "invalid content-length", reqInfo, errors.GetAPIError(errors.ErrInvalidArgument)) return } + if reqInfo.ObjectName == "" { + h.logAndSendError(w, "missing object name", reqInfo, errors.GetAPIError(errors.ErrInvalidArgument)) + return + } + params := &layer.PutObjectParams{ BktInfo: bktInfo, Object: reqInfo.ObjectName, ``` ## Steps to Reproduce (for bugs) Try to upload object from browser using steps from spec https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-post-example.html Request example: ``` curl -X POST http://localhost:8084/test3 \ -H 'Content-Type: multipart/form-data; boundary=ade4749fd805cf7903338195fac70a2f9a8998eae7f749b7823879dedb12' \ --data-binary ' \ --ade4749fd805cf7903338195fac70a2f9a8998eae7f749b7823879dedb12 Content-Disposition: form-data; name="Policy" eyJleHBpcmF0aW9uIjogIjIwMjUtMTItMDFUMTI6MDA6MDAuMDAwWiIsImNvbmRpdGlvbnMiOiBbCiBbInN0YXJ0cy13aXRoIiwgIiR4LWFtei1jcmVkZW50aWFsIiwgIiJdLAogWyJzdGFydHMtd2l0aCIsICIkeC1hbXotZGF0ZSIsICIiXQpdfQ== --ade4749fd805cf7903338195fac70a2f9a8998eae7f749b7823879dedb12 Content-Disposition: form-data; name="X-Amz-Credential" 5jizSbYu8hX345aqCKDgRWKCJYHxnzxRS8e6SUYHZ8Fw0HiRkf3KbJAWBn5mRzmiyHQ3UHADGyzVXLusn1BrmAfLn/20240809T164847Z/default/s3/aws4_request --ade4749fd805cf7903338195fac70a2f9a8998eae7f749b7823879dedb12 Content-Disposition: form-data; name="X-Amz-Date" 20240809T164847Z --ade4749fd805cf7903338195fac70a2f9a8998eae7f749b7823879dedb12 Content-Disposition: form-data; name="X-Amz-Signature" d51a75f772782a708f649439105fde6466cd1f3bfb4a1e6e777d7d37d0894e69 --ade4749fd805cf7903338195fac70a2f9a8998eae7f749b7823879dedb12 Content-Disposition: form-data; name="file"; filename="test.txt" Content-Type: application/octet-stream --ade4749fd805cf7903338195fac70a2f9a8998eae7f749b7823879dedb12-- ' ``` ## Context No ## Regression Yes ## Your Environment <!--- Include as many relevant details about the environment you experienced the bug in --> * Version used: `v0.30.1` * Server setup and configuration: devenv
dkirillov added the
bug
label 2024-08-09 14:10:02 +00:00
alexvanin added this to the v0.31.0 milestone 2024-11-20 11:48:13 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: TrueCloudLab/frostfs-s3-gw#456
No description provided.