Skip to content

transport: Reject non-positive timeout values in server #8290

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

Merged
merged 2 commits into from
May 12, 2025

Conversation

evanj
Copy link
Contributor

@evanj evanj commented May 6, 2025

Negative timeouts should be forbidden. The previous implementation called ParseInt and allowed negative timeouts. Change it to call ParseUint to reject these values. This is also slightly faster, since ParseInt eventually calles ParseUint. Extend the test to cover more cases.

RELEASE NOTES:

  • transport: Non-positive grpc-timeout header values are now rejected by servers. This is consistent with the gRPC protocol spec.

Negative timeouts should be forbidden. The previous implementation
called ParseInt and allowed negative timeouts. Change it to call
ParseUint to reject these values. This is also slightly faster,
since ParseInt eventually calles ParseUint. Extend the test to
cover more cases.
Copy link

codecov bot commented May 6, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 82.27%. Comparing base (7fb5738) to head (98de62f).
Report is 13 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #8290      +/-   ##
==========================================
+ Coverage   82.15%   82.27%   +0.11%     
==========================================
  Files         419      419              
  Lines       41904    41949      +45     
==========================================
+ Hits        34426    34513      +87     
+ Misses       6013     5983      -30     
+ Partials     1465     1453      -12     
Files with missing lines Coverage Δ
internal/transport/http_util.go 94.50% <100.00%> (+2.44%) ⬆️

... and 36 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Contributor

@arjan-bal arjan-bal left a comment

Choose a reason for hiding this comment

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

Thanks for adding these test cases!

{"2562047H", time.Hour * 2562047, nil},
{"2562048H", time.Duration(math.MaxInt64), nil},
{"99999999H", time.Duration(math.MaxInt64), nil},
{"-1S", 0, fmt.Errorf("strconv.ParseUint: parsing %q: invalid syntax", "-1")},
Copy link
Contributor

Choose a reason for hiding this comment

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

This error string is not part of gRPC and can cause the test to break when run with a different version of golang. You can instead use cmp.Equal() with cmpopts.EquateErrors(). You can use cmpopts.AnyError as the expected value.

https://google.github.io/styleguide/go/decisions#test-error-semantics

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good suggestion! However, since this function is returning fmt.Errorf, none of the expected errors can be compared, since I changed the error check to just be for "has an error". We could change the function to return some other typed error instead, like maybe a status error? I think the test checking for existence of an error is probably okay.

@arjan-bal arjan-bal added this to the 1.73 Release milestone May 7, 2025
@arjan-bal arjan-bal added Type: Bug Area: Server Includes Server, Streams and Server Options. labels May 7, 2025
* forbid timeout == 0
* change test to check for err != nil and not compare messages
@evanj
Copy link
Contributor Author

evanj commented May 7, 2025

Thanks for the suggestion! This caused me to add a check for t != 0 to the function, and to revise the test to avoid comparing error strings, since fmt.Errorf does not compare with errors.Is, so this matches the style guide: "If a test uses cmpopts.EquateErrors but all of its wantErr values are either nil or cmpopts.AnyError, then [...] Simplify the code by making the want field a bool."

@arjan-bal arjan-bal changed the title internal/transport.decodeTimeout: ParseUint to reject negative transport: Reject non-positive timeout values in server May 9, 2025
Copy link
Contributor

@arjan-bal arjan-bal left a comment

Choose a reason for hiding this comment

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

LGTM, adding a second reviewer.

@arjan-bal arjan-bal assigned dfawley and unassigned evanj May 9, 2025
@arjan-bal arjan-bal requested a review from dfawley May 9, 2025 03:22
Copy link
Member

@dfawley dfawley left a comment

Choose a reason for hiding this comment

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

Looks fine and correct, but can you tell us why you wanted to make this change? Is this something you're seeing happen in practice?

@dfawley dfawley assigned evanj and unassigned dfawley May 9, 2025
@evanj
Copy link
Contributor Author

evanj commented May 9, 2025

I've been investigating grpc overhead in services at Datadog that do a lot of requests/second, which means they spend a lot of time in grpc-go. I noticed this function and wondered why decodeTimeout shows up (47ms out of 87s CPU time or 0.05% in other words: irrelevant), but then I noticed it allows negative values, and switching to ParseUint theoretically saves some of this time so it is theoretically correct and theoretically faster.

So ... Maybe not worth our time discussing and reviewing the change, but I thought it wasn't a total waste.

@dfawley dfawley assigned dfawley and unassigned evanj May 9, 2025
@dfawley
Copy link
Member

dfawley commented May 9, 2025

So ... Maybe not worth our time discussing and reviewing the change, but I thought it wasn't a total waste.

No, that's fine. I was just wondering if there was some other significant event at play here, like one of our grpc libraries was actually sending negative timeouts.

Thanks for the change!

@dfawley dfawley merged commit 96e31db into grpc:master May 12, 2025
30 of 33 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area: Server Includes Server, Streams and Server Options. Type: Bug
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants