node-http-proxy icon indicating copy to clipboard operation
node-http-proxy copied to clipboard

feat onProxyReqWs async handler

Open LiranBri opened this issue 5 years ago • 6 comments
trafficstars

Following issues https://github.com/http-party/node-http-proxy/issues/490 and https://github.com/http-party/node-http-proxy/issues/1403, currently the library does not support async handler for the proxyReqWs event for modifying the request before proxying it forward.

This suggested PR solved the problem, without breaking backward compatibility, by introducing a new argument asyncContext which is used as follows:


onProxyReqWs: (proxyReq, req, socket, options, head, asyncContext) =>
      asyncContext(async () => {
        // code ...
        const result = await anyAsyncOperation()
        // code ...
        proxyReq.setHeader('key', result)
      }),

LiranBri avatar Dec 16 '19 11:12 LiranBri

Codecov Report

Merging #1407 into master will increase coverage by 0.11%. The diff coverage is 100%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #1407      +/-   ##
==========================================
+ Coverage   92.35%   92.47%   +0.11%     
==========================================
  Files           6        6              
  Lines         314      319       +5     
==========================================
+ Hits          290      295       +5     
  Misses         24       24
Impacted Files Coverage Δ
lib/http-proxy/passes/ws-incoming.js 96.29% <100%> (+0.37%) :arrow_up:

Continue to review full report at Codecov.

Legend - Click here to learn more Δ = absolute <relative> (impact), ø = not affected, ? = missing data Powered by Codecov. Last update 9bbe486...79fa77c. Read the comment docs.

codecov-io avatar Jan 01 '20 05:01 codecov-io

All tests have passed, can we please merge the PR? thanks @indexzero @jcrugzz @yawnt

LiranBri avatar Apr 22 '21 12:04 LiranBri

any development on this PR?

asturur avatar Mar 22 '22 16:03 asturur

Would love to see this merged !

paulrostorp avatar May 31 '22 15:05 paulrostorp

I've created a patch for this PR as well as one for the typescript types package:

http-proxy+1.18.1.patch:

diff --git a/node_modules/http-proxy/lib/http-proxy/passes/ws-incoming.js b/node_modules/http-proxy/lib/http-proxy/passes/ws-incoming.js
index 270f23f..809ec20 100644
--- a/node_modules/http-proxy/lib/http-proxy/passes/ws-incoming.js
+++ b/node_modules/http-proxy/lib/http-proxy/passes/ws-incoming.js
@@ -76,7 +76,7 @@ module.exports = {
    *
    * @api private
    */
-  stream : function stream(req, socket, options, head, server, clb) {
+  stream : async function stream(req, socket, options, head, server, clb) {
 
     var createHttpHeader = function(line, headers) {
       return Object.keys(headers).reduce(function (head, key) {
@@ -104,9 +104,7 @@ module.exports = {
       common.setupOutgoing(options.ssl || {}, options, req)
     );
 
-    // Enable developers to modify the proxyReq before headers are sent
-    if (server) { server.emit('proxyReqWs', proxyReq, req, socket, options, head); }
-
+    // It is important to register the event listeners of proxyReq before the first await, so we don't have small period of time in which we lose emitted events
     // Error Handler
     proxyReq.on('error', onOutgoingError);
     proxyReq.on('response', function (res) {
@@ -148,7 +146,23 @@ module.exports = {
       server.emit('proxySocket', proxySocket);  //DEPRECATED.
     });
 
-    return proxyReq.end(); // XXX: CHECK IF THIS IS THIS CORRECT
+
+    // Enable developers to modify the proxyReq before headers are sent
+    if (server) {
+      // Provides a way for the event handler to communicate back to the emitter when it finishes its async handling
+      let asyncHandler
+      const asyncContext = (callback) => {
+        asyncHandler = callback
+      }
+
+      server.emit('proxyReqWs', proxyReq, req, socket, options, head, asyncContext);
+
+      if (asyncHandler) {
+        await asyncHandler()
+      }
+    }
+
+    proxyReq.end();
 
     function onOutgoingError(err) {
       if (clb) {

@types+http-proxy+1.17.9.patch:

diff --git a/node_modules/@types/http-proxy/index.d.ts b/node_modules/@types/http-proxy/index.d.ts
index ca805df..b674ff8 100755
--- a/node_modules/@types/http-proxy/index.d.ts
+++ b/node_modules/@types/http-proxy/index.d.ts
@@ -208,6 +208,7 @@ declare namespace Server {
         socket: net.Socket,
         options: ServerOptions,
         head: any,
+        asyncContext: (cb: Promise) => void
     ) => void;
     type EconnresetCallback<TError = Error, TIncomingMessage = http.IncomingMessage, TServerResponse = http.ServerResponse> = (
         err: TError,

paulrostorp avatar Jun 06 '22 09:06 paulrostorp