1

I have followed this article as well as this SO answer on uploading a file to Google Drive which includes metadata, resulting in following code:

readonly BOUNDARY = '--4561564891651634213217'; //Randomly mashed in numbers

uploadToDrive(file: File /*<input type="file">.files[0]*/, fileName: string) {
    this.readFile(file)
        .then(base64File => {
          gapi.client.request({
            path: 'upload/drive/v3/files', method: 'POST', params: {
              uploadType: 'multipart'
            }, headers: {
              'Content-type': `multipart/related; boundary=${this.BOUNDARY}`,
              'Content-length': file.size
            }, body: this.formatMultipartBody(file, fileName, base64File)
          })
              .then(response => console.log('Upload success! ', response), error => console.error('Upload error! ', error));
        });
  }

private readFile(file: File): Promise<string> {
    const fileReader: FileReader = new FileReader();
    return new Promise(resolve => {
      fileReader.readAsBinaryString(file);
      fileReader.onload = (event: any) => resolve(btoa(fileReader.result));
    });
  }

private formatMultipartBody(file: File, fileName: string, base64File: string) {
    const delimiter = `\r\n--${this.BOUNDARY}\r\n`;
    const closeDelimiter = `\r\n--${this.BOUNDARY}--`;
    const metadata = {
      name: fileName, mimeType: file.type || 'application/octet-stream'
    };
    const body = `
    ${delimiter}
    Content-Type: application/json; charset=UTF-8\r\n\r\n
    Content-Transfer-Encoding: base64
    ${JSON.stringify(metadata)}
    ${delimiter}
    Content-Type: ${file.type || 'application/octet-stream'}\r\n
    ${base64File}
    ${closeDelimiter}
    `;
    return body;
  }

No matter which type of file I upload, I keep getting the following error:

{
 "error": {
  "errors": [
   {
    "domain": "global",
    "reason": "badContent",
    "message": "Unsupported content with type: application/octet-stream"
   }
  ],
  "code": 400,
  "message": "Unsupported content with type: application/octet-stream"
 }
}

This error appears even if the file has an extension (e.g. a hello.txt file containing the text "Hello, world!") and nowhere in the request is anything mentioning "application/octet-stream".

tehhowch
  • 9,645
  • 4
  • 24
  • 42
Robin-Hoodie
  • 4,886
  • 4
  • 30
  • 63
  • @DaImTo Not a duplicate, as I'm linking to the same SO question, the provided answers do not work for me, as mentioned in my post – Robin-Hoodie Jul 28 '18 at 09:38
  • then you should ask for additional information on the original question – Linda Lawton - DaImTo Jul 28 '18 at 10:56
  • @DaImTo I explained what result I'm expecting, what I've tried, what my code looks like right now, and what error I'm receiving. I'm not sure what additional information you want me to provide – Robin-Hoodie Jul 28 '18 at 11:24

1 Answers1

1

It seems that the Google Drive API is very picky about formatting the request body, this formatMultiPartBody method worked for me in the end:

private formatMultipartBody(file: File, fileName: string, base64Data: string): string {
    const delimiter = `--${this.BOUNDARY}`;
    const closeDelimiter = `--${this.BOUNDARY}--`;
    const metadata = {
      name: fileName, mimeType: file.type || 'application/octet-stream'
    };
    const body = `
    \n${delimiter}\
    \nContent-Type: application/json; charset=UTF-8\
    \n\n${JSON.stringify(metadata)}\
    \n${delimiter}\
    \nContent-Type: ${file.type || 'application/octet-stream'}\
    \nContent-Transfer-Encoding: base64\      
    \n\n${base64Data}\
    \n${closeDelimiter}`;
    return body;
  }
Robin-Hoodie
  • 4,886
  • 4
  • 30
  • 63