From 65425bdcea93278e861238beab0787ebdd53e78d Mon Sep 17 00:00:00 2001 From: Mike Lang Date: Sat, 27 May 2023 06:55:52 +1000 Subject: [PATCH] multipart uploads: Hack to support gsutil cp `gsutil` sends an invalid multipart boundary param, which golang's `mime.ParseMediaType` correctly rejects. However, the real GCS evidently does not reject this, so in order to make `gsutil` work we need to support it. In particular, `gsutil` sends a boundary param that is quoted using single-quotes when it should be using double-quotes. In cases where the param is definitely invalid (so we're guarenteed not to break any valid values), we replace all single-quotes with double-quotes to produce the intended meaning. Upstream bug: https://github.com/GoogleCloudPlatform/gsutil/issues/1466 --- fakestorage/upload.go | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/fakestorage/upload.go b/fakestorage/upload.go index 4b3d8593f9f..40bb53e6d88 100644 --- a/fakestorage/upload.go +++ b/fakestorage/upload.go @@ -306,7 +306,18 @@ func getObjectACL(predefinedACL string) []storage.ACLRule { func (s *Server) multipartUpload(bucketName string, r *http.Request) jsonResponse { defer r.Body.Close() - _, params, err := mime.ParseMediaType(r.Header.Get(contentTypeHeader)) + requestContentType := r.Header.Get(contentTypeHeader) + // gsutil is observed to submit incorrectly-quoted bounary strings + // like: boundary='===============5900997287163282353==' + // See https://github.com/GoogleCloudPlatform/gsutil/issues/1466 + // Having an "=" character in the boundary param requires the value be quoted, + // but ' is not a quote char, " is. + // If we see a string like "boundary='=", which is always invalid anyway, + // attempt to rescue the situation by converting all ' to ". + if strings.Contains(requestContentType, "boundary='=") { + requestContentType = strings.Replace(requestContentType, "'", "\"", -1) + } + _, params, err := mime.ParseMediaType(requestContentType) if err != nil { return jsonResponse{ status: http.StatusBadRequest,