-
Notifications
You must be signed in to change notification settings - Fork 4.4k
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
client: fix "unix" scheme handling for some corner cases #4021
client: fix "unix" scheme handling for some corner cases #4021
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This appears to be missing one case: passthrough:///unix:///a/b/c
needs to be handled by the transport's default dialer (i.e. it sees unix:
at the start and behaves as it used to before #3890)
internal/grpcutil/target.go
Outdated
@@ -60,9 +60,17 @@ func ParseTarget(target string, skipUnixColonParsing bool) (ret resolver.Target) | |||
return resolver.Target{Endpoint: target} | |||
} | |||
if ret.Scheme == "unix" { | |||
// Prevents behavior change in "unix:///[...]" case. | |||
if skipUnixColonParsing && ret.Authority == "" { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why does this check skipUnixColonParsing
? That only impacts unix:<path>
, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The check is still there just moved (and'd with the =="unix" check). This is so I don't append a "/" to the address when it isn't going to the resolver, since that is only so the resolver gets the right address.
internal/grpcutil/target_test.go
Outdated
{targetStr: "unix:/a/b/c", want: resolver.Target{Scheme: "unix", Authority: "", Endpoint: "/a/b/c"}, wantWithDialer: resolver.Target{Scheme: "", Authority: "", Endpoint: "unix:/a/b/c"}}, | ||
{targetStr: "unix:///a/b/c", want: resolver.Target{Scheme: "unix", Authority: "", Endpoint: "/a/b/c"}, wantWithDialer: resolver.Target{Scheme: "", Authority: "", Endpoint: "unix:///a/b/c"}}, | ||
|
||
{targetStr: "passthrough:///unix:///a/b/c", want: resolver.Target{Scheme: "unix", Authority: "", Endpoint: "/a/b/c"}, wantWithDialer: resolver.Target{Scheme: "passthrough", Authority: "", Endpoint: "unix:///a/b/c"}}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this should always be Scheme: "passthrough", Endpoint: "unix:///a/b/c"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed this, that is what it is in both cases now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like you have omitted wantWithDialer
now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With wantWithDialer
omitted, the test sets it to want
and just expects the same thing in both cases.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh.. that makes sense. Thanks.
internal/grpcutil/target.go
Outdated
return ret | ||
} | ||
|
||
// ParseDialTarget returns the network and address to pass to dialer | ||
func ParseDialTarget(target string) (string, string) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you move this into the transport?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Moved that to transport.
internal/grpcutil/target_test.go
Outdated
{targetStr: "unix:/a/b/c", want: resolver.Target{Scheme: "unix", Authority: "", Endpoint: "/a/b/c"}, wantWithDialer: resolver.Target{Scheme: "", Authority: "", Endpoint: "unix:/a/b/c"}}, | ||
{targetStr: "unix:///a/b/c", want: resolver.Target{Scheme: "unix", Authority: "", Endpoint: "/a/b/c"}, wantWithDialer: resolver.Target{Scheme: "", Authority: "", Endpoint: "unix:///a/b/c"}}, | ||
|
||
{targetStr: "passthrough:///unix:///a/b/c", want: resolver.Target{Scheme: "unix", Authority: "", Endpoint: "/a/b/c"}, wantWithDialer: resolver.Target{Scheme: "passthrough", Authority: "", Endpoint: "unix:///a/b/c"}}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh.. that makes sense. Thanks.
internal/grpcutil/target.go
Outdated
ret.Endpoint = "/" + ret.Endpoint | ||
} else { | ||
// Custom dialer should receive "unix:///[...]". | ||
return resolver.Target{Endpoint: target} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should not be here; instead make the transport invoke the user's dialer after prepending "unix://" to the address string.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed that part and am now appending to the address in transport.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add an end-to-end test that uses a custom dialer with "unix:///" and "passthrough:///unix:///" to confirm everything is working correctly ("unix:///" appears in the address passed to the dialer for both).
internal/grpcutil/target_test.go
Outdated
@@ -70,7 +70,7 @@ func TestParseTargetString(t *testing.T) { | |||
// If we can only parse part of the target. | |||
{targetStr: "://", want: resolver.Target{Scheme: "", Authority: "", Endpoint: "://"}}, | |||
{targetStr: "unix://domain", want: resolver.Target{Scheme: "", Authority: "", Endpoint: "unix://domain"}}, | |||
{targetStr: "unix://a/b/c", want: resolver.Target{Scheme: "unix", Authority: "a", Endpoint: "/b/c"}, wantWithDialer: resolver.Target{Scheme: "unix", Authority: "a", Endpoint: "b/c"}}, | |||
{targetStr: "unix://a/b/c", want: resolver.Target{Scheme: "unix", Authority: "a", Endpoint: "b/c"}}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be Endpoint: "/b/c"
since we have the 3-slashes form. It doesn't matter in practice since the authority is non-empty, so it will be an error either way, but that's how it should be.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's "/b/c" now due to the revert of the +"/" change.
internal/transport/http2_client.go
Outdated
n, ok := networktype.Get(addr) | ||
if fn != nil { | ||
if ok && n == "unix" { | ||
return fn(ctx, "unix:///"+address) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This deserves a comment. Something like: For backward compatibility, if the user dialed "unix:///path", the passthrough resolver would be used and the user's custom dialer would see "unix:///path". Re-add "unix://" here since we now support the "unix" scheme by default, which strips this prefix.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added this comment.
internal/transport/http2_client.go
Outdated
if n, ok := networktype.Get(addr); ok { | ||
n, ok := networktype.Get(addr) | ||
if fn != nil { | ||
if ok && n == "unix" { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok
is redundant - if !ok
, n
will be ""
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Got rid of redundant ok
internal/transport/http2_client.go
Outdated
networkType := "tcp" | ||
address := addr.Addr | ||
if n, ok := networktype.Get(addr); ok { | ||
n, ok := networktype.Get(addr) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
networkType, ok := ...
- the "tcp"
default is no longer used (see below if !ok
).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Made this change.
internal/grpcutil/target.go
Outdated
if ret.Scheme == "unix" { | ||
// Add the "/" back in the unix case, so the unix resolver receives the | ||
// actual endpoint. | ||
if ret.Scheme == "unix" && !skipUnixColonParsing && ret.Authority == "" { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did this need to change? I think this can be reverted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reverted this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add an end-to-end test that uses a custom dialer with "unix:///" and "passthrough:///unix:///" to confirm everything is working correctly ("unix:///" appears in the address passed to the dialer for both).
End-to-end test added. Only oddity is authority in "passthrough:///unix:///path" case is "unix:///path" which I confirmed is the case before the change. This is because the result of the target parsing is |
internal/grpcutil/target_test.go
Outdated
// behaviors with a custom dialer, to prevent behavior changes with custom dialers. | ||
{targetStr: "unix:a/b/c", want: resolver.Target{Scheme: "unix", Authority: "", Endpoint: "a/b/c"}, wantWithDialer: resolver.Target{Scheme: "", Authority: "", Endpoint: "unix:a/b/c"}}, | ||
{targetStr: "unix:/a/b/c", want: resolver.Target{Scheme: "unix", Authority: "", Endpoint: "/a/b/c"}, wantWithDialer: resolver.Target{Scheme: "", Authority: "", Endpoint: "unix:/a/b/c"}}, | ||
{targetStr: "unix:///a/b/c", want: resolver.Target{Scheme: "unix", Authority: "", Endpoint: "/a/b/c"}, wantWithDialer: resolver.Target{Scheme: "unix", Authority: "", Endpoint: "/a/b/c"}}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Delete wantWithDialer
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Made this change.
test/authority_test.go
Outdated
expectedTarget string | ||
} | ||
|
||
func tests() []authorityTest { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use a variable not a function. Also, need a better name than tests
since this is package-global.
OR, make this non-global and put it in TestUnix
, with a runUnixCustomDialerTest
or something for the other tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Made it a variable named authorityTests
test/authority_test.go
Outdated
address string | ||
target string | ||
authority string | ||
expectedTarget string |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Go uses "want". How about dialTargetWant
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed it to dialTargetWant
Fixes #3990 .