Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

THRIFT-5710: Stop sharing headers across all instances of transports in nodejs #2805

Merged
merged 1 commit into from Jun 4, 2023

Conversation

ngavalas
Copy link
Contributor

@ngavalas ngavalas commented May 11, 2023

THRIFT-5710

There is an issue with the header transport implementation in nodejs. All TBufferedTransport and TFramedTransport instances across all connections and clients share a single object for their read and write headers. There is a different copy for the two transport types, but within one type, they are shared.

This means that there are both data races and incorrect results possible:

  • You can write headers to a request that has written headers but hasn't flushed yet. This is especially troubling if the headers are used for auth, because you're able to mix up requests and auth as the wrong entity.
  • You can read headers from other requests. They only clobber each other if they have the same name, but the union of all seen headers is returned in getReadHeaders .

The issue is that we aren't calling the header transport constructor with the new this from the concrete implementations, so the TBufferedTransport.prototype = new THeaderTransport(); line is not properly binding this and causes the object sharing.

You can see this in the two test cases that fail before this PR and succeed now. Two completely unrelated TFramedTransport objects shared read and write results.

I did not create a JIRA ticket yet because I am still waiting on approval, but I wanted to get the PR up ASAP; we are currently experiencing this bug in production.

Note: my editor reformatted those two or three random lines because they had trailing whitespace and/or tabs, which is against the coding style. I can revert them if you want this PR to be clean, but figured I'd leave the changes in since the existing files were incorrectly formatted.

  • Did you create an Apache Jira ticket? (Request account here, not required for trivial changes)
  • If a ticket exists: Does your pull request title follow the pattern "THRIFT-NNNN: describe my issue"?
  • Did you squash your changes to a single commit? (not required, but preferred)
  • Did you do your best to avoid breaking changes? If one was needed, did you label the Jira ticket with "Breaking-Change"?
  • If your change does not involve any code, include [skip ci] anywhere in the commit message to free up build resources.

@ngavalas ngavalas changed the title Stop sharing write headers across all instances of transports Stop sharing headers across all instances of transports May 11, 2023
transport.inBuf = buf;

const headers = transport.readHeaders();
assert.equals(headers.Parent, undefined);
Copy link
Contributor Author

@ngavalas ngavalas May 11, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to be 100% clear, before this fix, headers would have contained { Parent: "shoobar", Parens: "shoobaz", Trace: "abcde" } because it was reusing the same object as the first test. This is not test-only though and happens in real life.

Similar story for the write test.

@ngavalas ngavalas changed the title Stop sharing headers across all instances of transports THRIFT-5710: Stop sharing headers across all instances of transports May 12, 2023
@ngavalas ngavalas changed the title THRIFT-5710: Stop sharing headers across all instances of transports THRIFT-5710: Stop sharing headers across all instances of transports in nodejs May 12, 2023
@Jens-G Jens-G added the javascript Pull requests that update Javascript code label May 15, 2023
@ngavalas
Copy link
Contributor Author

@Jens-G I'm going to assume that the cross-test failures are not from me since none of them involve nodejs. Safe to assume?

@Jens-G
Copy link
Member

Jens-G commented May 16, 2023

Yes, seems so.

@ngavalas
Copy link
Contributor Author

Sounds good. Thoughts on the bug and the PR? We're blocked on using nodejs Thrift on this, so I'm eager to get this one in.

@ngavalas
Copy link
Contributor Author

@Jens-G Anything you need from me to review this? Happy to do whatever it takes!

@Jens-G Jens-G merged commit dd53b94 into apache:master Jun 4, 2023
17 of 27 checks passed
@ngavalas
Copy link
Contributor Author

ngavalas commented Jun 6, 2023

Thanks @Jens-G! Can we cut a new npm package as well?

@Jens-G
Copy link
Member

Jens-G commented Jun 7, 2023

Sure, after release (somewhere this summer) as usual there will be a new npm package.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
javascript Pull requests that update Javascript code
Projects
None yet
2 participants