0

I'm uploading files from the browser via a multipart request to a GraphQL-API which is powered by graphql-yoga which is powered by express. Now I want to forward this exact same request body to another GraphQL-API.

const fetch = require('node-fetch');

async passThrough(args, opts) {
  const { body, getRawBody, headers, method } = opts.request;
  var rawBody;
  if (body.files && body.files.length) {
    rawBody = await getRawBody;
  } else {
    rawBody = typeof body == 'string' ? body : JSON.stringify(body)
  }
  let options = {
    body: rawBody,
    method, headers
  };
  var res = await fetch(otherApiUrl, options).then((res) => {
    return res.json();
  });
  return res;
}

In this function I get the body as an object. But it includes "files" as promises which I can't simply forward (Couldn't find anything to do it). So I tried to get the raw body through a express middleware and access it like above with await getRawBody.

function getRawBody(req, res, next) {
  req.getRawBody = new Promise(resolve => {
    var buf = '';
    req.on('data', x => buf += x);
    req.on('end', () => {
      resolve(buf);
    });
  });
  next();
}

server.express.use(getRawBody);

It passes the request to the other API but the files are no valid jpegs anymore. I found out, that the uploaded file is shifted some bits from the original file. What am I maybe doing wrong?

Martin Cup
  • 2,399
  • 1
  • 21
  • 32

1 Answers1

0

I found a solution here and adapted the function to get the raw body. Now the file contents are not shifted anymore on the target host.

const concatStream = require('concat-stream');
function getRawBody(req, res, next) {
  req.getRawBody = new Promise(resolve => {
    req.pipe(concatStream(function (data) {
      resolve(data);
    }));
  });
  next();
}
Martin Cup
  • 2,399
  • 1
  • 21
  • 32