Skip to content

passing a promises resolve callback to an event callback in the oposite direction looses context #552

@tommyvn

Description

@tommyvn

I'm on the nginx dockerhub builds of 1.21.6 mainline and 1.22.0 stable, I tried on both and got the same result.

I have an upstream TCP service that wants a handshake. depending on this handshake, it wants the proxy to forward some or all of the protocol header. a good example is some upstreams want a proxy protocol header, others do not, and the handshake tells me this, but there are other things I strip from the protocol handshake so it's not only this.

If I hard code any given filter ahead of time I am indeed able to filter my protocol for my upstreams, so this part at least is not impossible, it is only the dynamic nature of the handshake that I am struggling with.

it is something like this:

sequenceDiagram
    client->>proxy: initial protocol data
    proxy->>upstream: handshake
    upstream->>proxy: filter
    proxy->>upstream: initial protocol data with filter applied
    upstream-->>client: passthru
    client-->>upstream: passthru
Loading

to achieve this I tried to pass a promise resolve callback from my upload event into a download event and then await it (and also tried a .then(...), same issue).
The problem I'm having is that my upload event handler switches it's s object to the download event handlers context after my await returns, after the download handler calls the passed resolve function from my promise. It seems that whoever calls resolve takes over the context for anyone awaiting. The most concise way I could find to illustrate this is by forcing an exception. immediately before awaiting this object my exception claims to be in the upstream direction, but immediately after it claims to be in the client direction.

Is it possible to fix my promise to achieve my handshake sequence diagram, or really are there any tricks to get that handshake over from the download to the upload handler?

Here is a stream filter function that illustrates my issue with forced exceptions:

function filter(s) {
  async function handleUpload (data, flags) {
    s.send('\x00\x00\x17yolo-test.dev.localhost\x00P', flags);
    const p = new Promise(( resolve, reject ) => {
      s.on("download", prepareHandleDownload(resolve));
    });
    s.off("upload");
    s.on("upload", handleUploadPhase2);
    // s.error(e);  // <=== if I uncomment this I get "e" is not defined while proxying and sending to upstream in my error log
    await p;
    // s.error(e);  // <=== if I uncomment this I get "e" is not defined while proxying and sending to client in my error log
  };
  function handleUploadPhase2 (data, flags) {
        s.error("handleUpload");
    };

  function prepareHandleDownload(resolve) {
    function handleDownload(data, flags) {
      s.off("download");
      resolve("yolo");
    };
    return handleDownload;
  };

  s.on("upload", handleUpload);
}

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions