-
Notifications
You must be signed in to change notification settings - Fork 10.4k
SignalR Negotiate protocol versioning #13389
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
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.
Quick first pass
src/SignalR/common/Http.Connections/src/HttpConnectionDispatcherOptions.cs
Outdated
Show resolved
Hide resolved
src/SignalR/common/Http.Connections/src/HttpConnectionDispatcherOptions.cs
Outdated
Show resolved
Hide resolved
src/SignalR/common/Http.Connections/src/Internal/HttpConnectionDispatcher.cs
Outdated
Show resolved
Hide resolved
@@ -428,8 +429,10 @@ private async Task<NegotiationResponse> NegotiateAsync(Uri url, HttpClient httpC | |||
urlBuilder.Path += "/"; | |||
} | |||
urlBuilder.Path += "negotiate"; | |||
//urlBuilder.Query = $"version={_protocolVersionNumber}"; |
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.
nit:
//urlBuilder.Query = $"version={_protocolVersionNumber}"; |
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.
//urlBuilder.Query = $"version={_protocolVersionNumber}"; |
It looks like a follow up commit overwrote 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.
Yeah, idk what happened here
Version = options.MinimumProtocolVersion | ||
}; | ||
|
||
if (context.Request.Query.TryGetValue("version", out var queryStringVersion)) |
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.
If the client doesn't pass a version and a minimum protocol version is specified via options, shouldn't that connection also be rejected?
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.
options, shouldn't that connection also be rejected?
No version from the client implies V1 so if the minimum specified through options on the server is greater than that (it should be greater than V1 it it's explicitly set) we should reject the connection.
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 doesn't look like there is a check for that though
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
/// Gets or sets the minimum protocol verison supported by the server. | ||
/// The default value is 0, the lowest possible protocol version. | ||
/// </summary> | ||
public int MinimumProtocolVersion { get; set; } = 0; |
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.
What if this is set to a non-default value and a client tries to connection without negotiating?
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.
Yeah, this was an open question in the design doc. I think your suggestion there of having an option to reject clients that skip negotiation seems reasonable. Otherwise you're left in a weird position where the client and server are unaware of each other's capabilities.
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.
👍 We can always revisit if the default MinimumProtocolVersion ever goes above 0.
src/SignalR/clients/csharp/Client/test/FunctionalTests/HubConnectionTests.cs
Outdated
Show resolved
Hide resolved
src/SignalR/clients/csharp/Client/test/FunctionalTests/HubConnectionTests.cs
Outdated
Show resolved
Hide resolved
src/SignalR/common/Http.Connections.Common/src/NegotiateProtocol.cs
Outdated
Show resolved
Hide resolved
src/SignalR/clients/csharp/Client/test/FunctionalTests/Startup.cs
Outdated
Show resolved
Hide resolved
Version = options.MinimumProtocolVersion | ||
}; | ||
|
||
if (context.Request.Query.TryGetValue("version", out var queryStringVersion)) |
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 doesn't look like there is a check for that though
src/SignalR/common/Http.Connections/test/NegotiateProtocolTests.cs
Outdated
Show resolved
Hide resolved
src/SignalR/common/Http.Connections/test/NegotiateProtocolTests.cs
Outdated
Show resolved
Hide resolved
1716fae
to
24417fa
Compare
{ | ||
response.Version = clientProtocolVersion; | ||
} | ||
} else if (options.MinimumProtocolVersion > 0) |
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.
} else if (options.MinimumProtocolVersion > 0) | |
} | |
else if (options.MinimumProtocolVersion > 0) |
src/SignalR/common/Http.Connections/src/Internal/HttpConnectionDispatcher.cs
Outdated
Show resolved
Hide resolved
var clientProtocolVersion = int.Parse(queryStringVersion.ToString()); | ||
if (clientProtocolVersion < options.MinimumProtocolVersion) | ||
{ | ||
response.Error = $"The client requested version '{clientProtocolVersion}', but the server does not support this version."; |
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 message should include what the server-configure min protocol version is.
It might be nice to rename the "version" query string parameter and negotiate property to "protocolVersion" or similar so customers don't think this is supposed to match the SiganlR package version. |
ProtocolVersion is taken We can use |
src/SignalR/clients/csharp/Client/test/FunctionalTests/HubConnectionTests.cs
Outdated
Show resolved
Hide resolved
src/SignalR/common/Http.Connections/src/Internal/HttpConnectionDispatcher.cs
Outdated
Show resolved
Hide resolved
var clientProtocolVersion = int.Parse(queryStringVersion.ToString()); | ||
if (clientProtocolVersion < options.MinimumProtocolVersion) | ||
{ | ||
response.Error = $"The client requested version '{clientProtocolVersion}', but the server does not support this version."; |
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.
Might want to log on the server here and the one below?
response.AvailableTransports = new List<AvailableTransport>(); | ||
var response = new NegotiationResponse | ||
{ | ||
ConnectionId = connectionId, |
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.
We should delay setting this until we know the client is compatible, and perhaps we should invalidate the ID too if there is an error. Or maybe we can delay even creating the connectionId and do the version checking earlier?
Note to self to add a test for client sending an invalid version in the query string |
I think |
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.
We need to update the transport spec document too!
return; | ||
} | ||
|
||
if (response.Version > 0) |
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.
Per the spec, the server should send back the version even for clients that don't support versions yet.
This could be useful for bug reports where we see people with "version" in the negotiate but are using <=3.0 clients.
src/SignalR/common/Http.Connections/src/Internal/HttpConnectionDispatcher.Log.cs
Outdated
Show resolved
Hide resolved
src/SignalR/common/Http.Connections/src/Internal/HttpConnectionDispatcher.cs
Show resolved
Hide resolved
src/SignalR/common/Http.Connections/src/Internal/HttpConnectionDispatcher.cs
Show resolved
Hide resolved
This comment was made automatically. If there is a problem contact [email protected]. I've triaged the above build. I've created/commented on the following issue(s) |
This includes the changes for the server and the .NET client. Still polishing but ready for some review
Spec: https://github.com/aspnet/specs/pull/325