Welcome to the Linux Foundation Forum!

fastify-reply-from with transform stream

arturo.miguel.next
edited November 2022 in LFW212 Class Forum

Hello

Could someone explain to me why this does not work?

'use strict'

const {Transform, Readable} = require('stream');
const createTransformStream = () => {
  new Transform({
    transform(chunk, enc, next) {
      const uppercase = chunk.toString().toUpperCase();
      next(null, uppercase);
    }
  })
}
const uppercaseStream = createTransformStream();


module.exports = async function (fastify, opts) {
  fastify.get('/', async function (request, reply) {
    const { url } = request.query;
    try {
      new URL(url)
    } catch (error) {
      throw fastify.httpErrors.badRequest() 
    }
    await reply.from(url, {
      onResponse(req, reply, response) {
        reply.send(response.pipe(uppercaseStream));
      }
    });
  })
}

Thanks

Comments

  • I forgot to return the Transform

    'use strict'
    
    const {Transform, Readable} = require('stream');
    const createTransformStream = () => {
      return new Transform({
        transform(chunk, enc, next) {
          const uppercase = chunk.toString().toUpperCase();
          next(null, uppercase);
        }
      })
    }
    const uppercaseStream = createTransformStream();
    
    
    module.exports = async function (fastify, opts) {
      fastify.get('/', async function (request, reply) {
        const { url } = request.query;
        try {
          new URL(url)
        } catch (error) {
          throw fastify.httpErrors.badRequest() 
        }
        await reply.from(url, {
          onResponse(req, reply, response) {
            reply.send(response.pipe(uppercaseStream));
          }
        });
      })
    }
    
  • d.m.c
    d.m.c Posts: 160

    nice catch @arturo.miguel.next

  • elamin
    elamin Posts: 7

    I wrote the code differently, but in all ways, the GET request from the client hangs forever.
    However, sending the reply without any transformation return reply.from(url) works as expected.

    the command curl http://localhost:3000/?url=http://localhost:5050 from inside the server does not return any response either.

    any1 have an idea, why it's not working with me?
    Thanks a lot

    here are two examples where the GET request is stuck forever:

    'use strict'
    
    const { Transform, pipeline } = require('stream')
    
    function upper() {
      return new Transform({
        transform(chunk, encoding, callback) {
          callback(null, chunk.toString().toUpperCase())
        }
      })
    }
    
    module.exports = async function (fastify, opts) {
      fastify.get('/', async function (request, reply) {
        const { url } = request.query
        try {
          new URL(url)
        } catch (err) {
          throw fastify.httpErrors.badRequest()
        }
        console.log('Fetching from URL:', url)
        return reply.from(url, {
          onResponse (request, reply, res) { 
            console.log('Received response from upstream URL')
            pipeline(res, upper(), reply.raw,
              (err) => {
                if (err) {
                  console.error('Pipeline failed:', err)
                  reply.code(500).send({ error: 'Internal Server Error' })
                } else {
                  console.log('Pipeline succeeded')
                }
              }
            )
          }
        })
      })
    }
    

    The original code as in the course also beating the same with me:

    'use strict'
    const { Readable } = require('stream')
    async function * upper (res) {
      for await (const chunk of res) {
        yield chunk.toString().toUpperCase()
      }
    }
    module.exports = async function (fastify, opts) {
      fastify.get('/', async function (request, reply) {
        const { url } = request.query
        try {
          new URL(url)
        } catch (err) {
          throw fastify.httpErrors.badRequest()
        }
        return reply.from(url, {
          onResponse (request, reply, res) {
            reply.send(Readable.from(upper(res)))
          }
        })
      })
    }
    

  • elamin
    elamin Posts: 7

    for the bellow code, I get an error message "res is not async iterable"

    'use strict'
    const { Readable } = require('stream')
    async function * upper (res) {
      for await (const chunk of res) {
        yield chunk.toString().toUpperCase()
      }
    }
    module.exports = async function (fastify, opts) {
      fastify.get('/', async function (request, reply) {
        const { url } = request.query
        try {
          new URL(url)
        } catch (err) {
          throw fastify.httpErrors.badRequest()
        }
        return reply.from(url, {
          onResponse (request, reply, res) {
            reply.send(Readable.from(upper(res)))
          }
        })
      })
    }
    

Categories

Upcoming Training