First of all I'm sorry for pasting so much code here, but as there's a lot of things that could go wrong in each step of this process, I'm trying to make sure that every error that I faced and was able to fix is recorded here so there's no back and forth in comunication.
Im trying to create a signed upload url to send some files from the browser to a gcp bucket.
I have a backend in go creating the signed upload url like this
func generateV4PutObjectSignedURL(bucket, object string) (string, error) {
ctx := context.Background()
client, err := storage.NewClient(ctx)
if err != nil {
return "", fmt.Errorf("storage.NewClient: %v", err)
}
defer client.Close()
pkey, err := ioutil.ReadFile("key.pem")
check(err)
opts := &storage.SignedURLOptions{
PrivateKey: pkey,
Scheme: storage.SigningSchemeV4,
Method: "PUT",
ContentType: "video/wav",
Expires: time.Now().Add(20 * time.Hour),
}
u, err := client.Bucket(bucket).SignedURL(object, opts)
if err != nil {
return "", fmt.Errorf("Bucket(%q).SignedURL: %v", bucket, err)
}
return u, nil
}
key.pem has every permission possible.
I'm sending the file like this
const reader = new FileReader();
console.log(file);
reader.onabort = () => console.log("file reading was aborted");
reader.onerror = () => console.log("file reading has failed");
reader.onload = () => {
const binaryFile = reader.result;
const blob = new Blob([binaryFile], { type: file.type });
var request = new XMLHttpRequest();
request.open("PUT", uploadUrl, true);
request.setRequestHeader("Content-Type", file.type);
request.onload = (e) => {
if (request.status === 200) {
poll();
}
};
request.send(blob);
};
reader.readAsArrayBuffer(file);
And I'm receiving this error
Access to XMLHttpRequest at {THE_SIGNED_URL} from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
CORS configuration in the bucket is like this
[{"maxAgeSeconds": 86400, "method": ["*"], "origin": ["*"], "responseHeader": ["*"]}]
And the XML error I'm getting is this
<Error>
<Code>MalformedSecurityHeader</Code>
<Message>Your request has a malformed header.</Message>
<ParameterName>content-type</ParameterName>
<Details>Header was included in signedheaders, but not in the request.</Details>
</Error>
But chrome developers network tab says that the Content-Type header is present in the request and is exactly what I said it would be in the backend.
What am I doing wrong?