0

I have a server returning the following for a CURL request curl --insecure -i -F files=@test.png https://xxx.xx.xx.xxx/powerai-vision/api/dlapis/b06564c9-7c1e-4642-a5a6-490310563d49.

HTTP/1.1 200 OK
Server: nginx/1.15.5
Date: Mon, 04 Nov 2019 06:23:14 GMT
Content-Type: application/json
Content-Length: 3556
Connection: keep-alive
Vary: Accept-Encoding
X-Powered-By: Servlet/3.1
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: X-Auth-Token, origin, content-type,accept, authorization
Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS, HEAD
Content-Language: en
X-Frame-Options: SAMEORIGIN
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Strict-Transport-Security: max-age=15724800; includeSubDomains
{"webAPIId":"b06564c9-7c1e-4642-a5a6-490310563d49","imageUrl":"http://powerai-vision-service:9080/powerai-vision-api/uploads/temp/b06564c9-7c1e-4642-a5a6-490310563d49/58c6eb6a-aaa4-4d6b-8c20-aadec4558107.png","imageMd5":"bd123739171d95d30d570b2cd0ed1aed","classified":[{"confidence":0.997600257396698,"ymax":997,"label":"white_box","xmax":1407,"xmin":1166,"ymin":760,"attr":[{}]},],"result":"success"}

I want to build a web app using node.js to process this and get the json string at the end. I am using the following code for this purpose.

'use strict';
/* eslint-env node */

const express = require('express');
const request = require('request');
const MISSING_ENV =
  'Missing required runtime environment variable POWERAI_VISION_WEB_API_URL';

require('dotenv').config({
  silent: true,
});

const app = express();
const port = process.env.PORT || process.env.VCAP_APP_PORT || 8081;
const poweraiVisionWebApiUrl = process.env.POWERAI_VISION_WEB_API_URL;

console.log('Web API URL: ' + poweraiVisionWebApiUrl);

if (!poweraiVisionWebApiUrl) {
  console.log(MISSING_ENV);
}

app.use(express.static(__dirname));
app.use(express.json());

app.post('/uploadpic', function (req, result) {
  if (!poweraiVisionWebApiUrl) {
    console.log(MISSING_ENV);
    result.send({ data: JSON.stringify({ error: MISSING_ENV }) });
  } else {
    req.pipe(request.post({
      url: poweraiVisionWebApiUrl,
      agentOptions: {
        rejectUnauthorized: false,
      }
    }, function (err, resp, body) {
      if (err) {
        console.log(err);
      }
      console.log('Check 22');
      console.log(body);
      // console.log(JSON.parse(body).webAPIId);
      result.send({ data: body });
    }));
  }
});

app.listen(port, () => {
  console.log(`Server starting on ${port}`);
});

The issue I have is I don't know how to access the elements in the body (the json strong). Right now console.log(body) prints garbage (https://github.com/IBM/powerai-vision-object-detection/issues/61). What is the correct way to process this string in node.js.

I am new to node.js programming.

When I print the header of the response I get the following output.

{
server: 'nginx/1.15.5',
date: 'Tue, 05 Nov 2019 02:47:37 GMT',
'content-type': 'application/json',
'transfer-encoding': 'chunked',
connection: 'keep-alive',
vary: 'Accept-Encoding',
'x-powered-by': 'Servlet/3.1',
'access-control-allow-origin': '*',
'access-control-allow-headers': 'X-Auth-Token, origin, content-type, accept, authorization',
'access-control-allow-credentials': 'true',
'access-control-allow-methods': 'GET, POST, PUT, DELETE, OPTIONS, HEAD',
'content-language': 'en',
'x-frame-options': 'SAMEORIGIN',
'x-content-type-options': 'nosniff',
'x-xss-protection': '1; mode=block',
'strict-transport-security': 'max-age=15724800; includeSubDomains',
'content-encoding': 'gzip'
}

It looks like the content encoding is gzip. Why is the curl out and the node.js response different? How should I process the gzip content? Any links?

user77005
  • 1,769
  • 4
  • 18
  • 26
  • Try printing the headers of the response. Is the body gzipped or something? Using a weird encoding maybe? How did you arrive at the result in your first snippet? – Bergi Nov 05 '19 at 01:27
  • @Bergi updated the problem description with more details. You are right the response header says the content is gzip encoded? Why is it different to the curl output? How should I process it? – user77005 Nov 05 '19 at 02:56
  • `curl` decodes the response automatically. According to [this question](https://stackoverflow.com/q/8880741/1048572), you can either do it yourself by piping through `gzip`, or you can upgrade the `requests` package to a more recent version and it will handle it for you. – Bergi Nov 05 '19 at 09:46

1 Answers1

1

It looks like you are parsing the JSON the right way.

But after looking at the screenshot you posted on github it seems you have a binary in the body instead of a JSON (an image maybe?). If I was you I would check if you are calling the API sending the correct parameters.

UPDATE:

After seeing the headers it looks that the response is still gzip-compressed, following this should solve your problem: https://gist.github.com/miguelmota/9946206

curl probably does it automatically for you, that's why you see the plain json, or maybe it's because the curl request has an header set that tells the server to not use gzip

UPDATE 2:

try making the request by adding gzip: true, it should do everything for you

 req.pipe(request.post({
   url: poweraiVisionWebApiUrl,
     gzip: true,
     agentOptions: {
       rejectUnauthorized: false,
     }
   }, function (err ...)
brein
  • 1,409
  • 9
  • 11
  • That's the strange thing. When I use the curl command `curl --insecure -i -F files=@test.png https://XXX.xx.xx.xxx/powerai-vision/api/dlapis/b06564c9-7c1e-4642-a5a6-490310563d49` the output is what I gave in my first code snippet. So it confirms that the API is returning the JSON string. Isn't it so? Hence the reason why I thought I might be processing it wrong. Any feedback? – user77005 Nov 05 '19 at 01:17
  • surely the curls works, but here you are 'proxying' the post request with the node application and maybe it's adding something the destination api doesn't like. Can you log the headers of the response? – brein Nov 05 '19 at 01:27
  • Question description updated with additional information. – user77005 Nov 05 '19 at 02:56
  • the answer is in: `content encoding: gzip` you need to uncompress the response – brein Nov 05 '19 at 03:21