Google-api-nodejs-client: Accessing plain text file containing string-looking data using alt: 'media' produces incorrect data in response

Created on 31 Dec 2019  Â·  4Comments  Â·  Source: googleapis/google-api-nodejs-client

Environment details

  • OS: OSX 10.15.2
  • Node.js version: v11.10.1
  • npm version: 6.13.4
  • googleapis version: 46.0.0

Steps to reproduce

  1. Upload a plain text file that has only whitespace and some characters in double quotes, like this one:

https://drive.google.com/file/d/15RszQHSm4kmKwbAKXXrfq_IWYs2_QErx/view?usp=sharing

  1. Load it using alt: 'media' using files.get:

```var gapi = require('googleapis').google;

var client = new gapi.auth.OAuth2(
"",
"",
"ignore"
);
var access_token = ""

client.setCredentials({
access_token: access_token
});

var drive = gapi.drive({ version: 'v3', auth: client });
drive.files.get({fileId: '15RszQHSm4kmKwbAKXXrfq_IWYs2_QErx', alt: 'media'}).then(function(result) {
console.log(result);
}).catch(function(e) {
console.error("Failed: ", e);
});


Expected result – `result.data` is the string `"\n\n\n\"just a string\"\n\n\n\n\n"`
Actual result – `result.data` is the string `"just a string"` (note the lack of quotes in the string data itself)

Here's the full output of the log that I see:

```{ config:
   { url:
      'https://www.googleapis.com/drive/v3/files/15RszQHSm4kmKwbAKXXrfq_IWYs2_QErx?alt=media',
     method: 'GET',
     paramsSerializer: [Function],
     headers:
      { 'x-goog-api-client': 'gdcl/3.2.0 gl-node/11.10.1 auth/5.7.0',
        'Accept-Encoding': 'gzip',
        'User-Agent': 'google-api-nodejs-client/3.2.0 (gzip)',
        Authorization:
         'Bearer y...',
        Accept: 'application/json' },
     params: [Object: null prototype] { alt: 'media' },
     validateStatus: [Function],
     retry: true,
     responseType: 'json' },
  data: 'just a string',
  headers:
   { 'alt-svc':
      'quic=":443"; ma=2592000; v="46,43",h3-Q050=":443"; ma=2592000,h3-Q049=":443"; ma=2592000,h3-Q048=":443"; ma=2592000,h3-Q046=":443"; ma=2592000,h3-Q043=":443"; ma=2592000',
     'cache-control': 'private, max-age=0, must-revalidate',
     connection: 'close',
     'content-disposition': 'attachment',
     'content-length': '23',
     'content-type': 'text/plain',
     date: 'Tue, 31 Dec 2019 19:24:08 GMT',
     expires: 'Tue, 31 Dec 2019 19:24:08 GMT',
     server: 'UploadServer',
     vary: 'Origin, X-Origin',
     'x-goog-hash': '...',
     'x-guploader-uploadid':
      '...' },
  status: 200,
  statusText: 'OK',
  request:
   { responseURL:
      'https://www.googleapis.com/drive/v3/files/15RszQHSm4kmKwbAKXXrfq_IWYs2_QErx?alt=media' } }

If I add other characters on other lines, I get the expected result. For example, if I add an a or "a" at the end of the file, I get the result I expect.

Happy to hear if I'm mis-using the API. I ran into this when I was updating from a much older, pre-25 version of the gapi and had some uses with explicit alt: 'media' configuration parameters.

Thanks!

needs more info p2 bug

All 4 comments

@jpolitz this definitely sounds odd, have you managed to figure out a workaround for your own use-case?

I don't have a workaround on the server. Our app (code.pyret.org) makes similar requests using the client-side (browser) APIs and the same content will round-trip fine, so I don't think it's an issue in Drive's storage or serving of the content or anything.

I also noticed after I submitted that the content-length in the headers shown is the right length (including the quotes and \n characters).

My best guess is that it's happening after the response comes in, somewhere in processing the string in the response to stick in in the data field (maybe JSON-vs-plaintext logic in the sense that JSON.parse("\n\n\"abc\"\n\n\n") returns "abc" but "\"abc\"\n\na" doesn't parse).

But that's me speculating about code in the library I don't know, so I'm not sure.

I may have an idea what's happening here. We assume, unless told otherwise, all responses are going to come back as json, then try to do a JSON.parse on the result. Now we should fall back to assuming text if that fails, but nonetheless - could I trouble you to try:

const drive = google.drive({ version: 'v3', auth: client });
drive.files.get(
  {
    fileId: '15RszQHSm4kmKwbAKXXrfq_IWYs2_QErx', 
    alt: 'media'
  }, {
    responseType: 'text'
  }).then(function(result) {
    console.log(result);
  }).catch(function(e) {
    console.error("Failed: ", e);
  });

Sorry for the slow response. I tried the snippet and it gives the expected response, so I think this counts as a fine workaround. Maybe I didn't understand the second argument – I think I tried using responseType as part of the parameters to the request.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

skiod picture skiod  Â·  3Comments

raapperez picture raapperez  Â·  3Comments

joseparoli picture joseparoli  Â·  3Comments

rainabba picture rainabba  Â·  4Comments

ashishbajaj99 picture ashishbajaj99  Â·  3Comments