2
votes

Using this for to generate GCS Upload signed url v4 https://github.com/GoogleCloudPlatform/python-docs-samples/blob/master/storage/cloud-client/storage_generate_upload_signed_url_v4.py#L27

I have generated upload signed url using this function "generate_upload_signed_url_v4" as mentioned above and also I tried using GSUTIL as well using gsutil signurl -m PUT service_account.json gs://<bucket>/file.png I am working on a demo where I need to upload PDF, PNG to GCS bucket. File uploading is file. But when I preview file in GCS Storage Console and download/preview file form Link URL
PDF is fine. But PNG somehow got damaged and not opening/previewing. I am using Chrome '81.0.4044.138'

When I further preview PNG file using text editor it contains some header content at the top of file. i.e ------WebKitFormBoundarysZ3BDVaNOhqwENsp Content-Disposition: form-data; name="file"; filename="test.png" Content-Type: image/png So if we remove this from top of file the file will open fine..

I have created a sample React project which can be accessed here

Demo: https://github.com/qaisershehzad/upload-gcs

I am using this code for file upload

` const url = "https://storage.googleapis.com//file.png.png?X-Goog-Algorithm=GOOG4-RSA-SHA256&X-Goog-Credential=gitlab-ci%.iam.gserviceaccount.com%2F20200521%2Fauto%2Fstorage%2Fgoog4_request&X-Goog-Date=20200521T175304Z&X-Goog-Expires=36000&X-Goog-SignedHeaders=content-type%3Bhost&X-Goog-Signature="

const data = new FormData()
data.append('file', this.state.selectedFile)

var xhr = new XMLHttpRequest();

xhr.open('PUT', url, true);
xhr.setRequestHeader("Content-type", "application/octet-stream");


xhr.onload = function (response) {
  console.log('on-load', response);
};

xhr.onreadystatechange = function () {
  if (xhr.readyState === 4) {

    if (xhr.status === 200) {
      console.log("Status OK")

    } else {
      console.log("Status not 200")
    }
  }
};

xhr.onerror = function (response) {
  console.log("Response error", response)
};

xhr.upload.onprogress = function (evt) {
  // For uploads
  if (evt.lengthComputable) {
    var percentComplete = parseInt((evt.loaded / evt.total) * 100);
    console.log("progress", percentComplete)

  }
}
xhr.send(data);`

I also tried same thing on Android as well and facing same issue. In Png at top these header string got added which not allowing to open Png file.

Png uploading is working fine using this CURL request. curl -X PUT -H 'Content-Type: application/octet-stream' --upload-filen file.png 'https://storage.googleapis.com//file.png?X-Goog-Algorithm=GOOG4-RSA-SHA256&X-Goog-Credential=gitlab-ci%.iam.gserviceaccount.com%2F20200521%2Fauto%2Fstorage%2Fgoog4_request&X-Goog-Date=20200521T175304Z&X-Goog-Expires=36000&X-Goog-SignedHeaders=content-type%3Bhost&X-Goog-Signature='

It will be helpful if someone can help to resolve this issue.

1
If you believe this issue is in the GCS side and not related to your specific React JS application, you can try to reproduce it in an environment supported by App Engine, and if you are able to, please create an Issue Tracker about this so it can be investigated further.David
yes same happening in android as well. It appends some headers to the image file. But using CURL (curl -X PUT) it is working fine. So can't understand what is going onMalik

1 Answers

1
votes

Actually you are sending FormData which causes a problem, you will see file get uploaded but when you retrieve file its content will be different in case of image possibly image will not get rendered.

The reason why cURL is working, because you are directly sending file not FormData.

To fix this scenario directly pass the file to ajax like mentioned below:

const file = this.state.selectedFile;

ajax.setRequestHeader('Content-Type', file.type);    
ajax.send(file); // direct file not FormData