NodeJS http: Wait for another response in a request listener before returning

Issue

Basically, it is a web proxy. In a request listener, I create another http request, read its response and pass it to the response. But I need to wait for the other request to end. Please see the function structure below.

I have searched for existing answers, but the existing answers were using await or Promise etc, which I think, do not fit my structure. I think I need something like the ManualResetEvent of C#. Right after sending the request (POS 1), I need to mark the thread to block so that before finishing the response (POS 3) it can be blocked. When the request’s response ends (POS 2), I need to mark the thread to continue. How do I do this in TypeScript/NodeJS?

function onRequest(req: http.IncomingMessage, res: http.ServerResponse)
{
  ....

  if(arguments are valid)
  {
    ... prepare options for request

    try
    {
        const remoteReq = https.request(options, (remoteRes) =>
        {
          remoteRes.on('data', (d) =>
          {
            ... pass it to the response.
          });

          remoteRes.on('end', (d) =>
          {
            //POS 2: resetevent.Set() allow thread to proceed
          });
        });
        remoteReq.end();
        //POS 1:resetevent.Reset() block thread
      }
    }
    catch
    {
    }
  }
  else
  {
  }

  //POS 3: resetevent.WaitOne() wait for the remote response to end.
  res.end("");
}

Solution

You don’t "wait" in nodejs. You register a listener for an event and you finish the request when that listener is called. You move the res.end() and and res.write() into the listener that tells you you’re done or you have data. Nodejs is a non-blocking, event driven, asynchronous I/O model. You have to program it that way.

You don’t show enough of your real code for us to write something that would actually work, but the general scheme would be like this where you listen for the data, end and error events on the http request you sent and you handle the original request in those event handlers. There is no crying in baseball. There is no "waiting" in nodejs:

function onRequest(req: http.IncomingMessage, res: http.ServerResponse) {
    ....

    if(arguments are valid) {
        ...prepare options
        try {
            const remoteReq = https.request(options, (remoteRes) => {
                remoteRes.on('data', (d) => {
                    ...pass it to the response.
                    res.write(...)
                });

                remoteRes.on('end', (d) => {
                    res.end(...);
                });

            });
            remoteReq.on('error', err => {
                console.log(err);
                if (res.headersSent) {
                    // not much to do other than just hangup
                    res.end();
                } else {
                    res.statusCode = 500;
                    res.end();
                }
            });
            remoteReq.end();
        } catch (e) {
            // highly unlikely anything gets here because this is all
            // asynchronous.  Instead, you need to listen for the 'error' event.
        }
    }
    else {
        // need to send some sort of response here, probably a 400 status
        // if arguments are invalid
    }
}

Answered By – jfriend00

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published