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
Fully implement ClientWebSocketOptions for .NET Core #15994
Comments
@karelz, @davidsh this is tracking ClientWebSocketOptions work using WinHTTP on Windows. This type enables scenarios such as HTTP client cert, headers, cookies, credentials, proxy and WS sub-protocol specification. @stephentoub I remember there is similar work required for the ManagedWebSocket implementation (proxy, etc). We may need to create an issue and review it for netstandard2.0. |
The pieces not currently handled by ManagedWebSocket are listed here: |
I've opened dotnet/corefx#14480 to track the item. I'll submit a PR to change the code to point to the issue. (The TODO is missing the issue number.) |
We should consider it for 2.0 -- we should also find out if it is reasonable for us to reuse the ManagedWebSocket also on Windows. |
We discussed this last week and decided to push it to Future. We plan to replace WebSockets with ManagedWebSockets (which lack some other implementation that is currently supported). |
Just raising another request for this feature. @SidharthNabar, If I get it right, there is currently no way to get websocket client running behind a proxy server in net core? |
@SidharthNabar is no longer working on the .NET Core project. In terms of client websocket ability to navigate thru a proxy, I believe that it can thru the default system proxy. However, it will not be able to go thru a custom IWebProxy since it is not honoring the .Proxy property. |
@davidsh I tried running a basic console app with this functionality and changed my system proxy to point to fiddler ( My code roughly looks like this ClientWebSocket cws = new ClientWebSocket();
cws.Options.AddSubProtocol("amqp");
Task task = cws.ConnectAsync(this.settings.Uri, CancellationToken.None).WithTimeout(timeout, () => "timeout"); While debugging, I can see that in |
For a repro, try this: public static async Task WsProxyTest()
{
try
{
var uri = new Uri("wss://echo.websocket.org");
ClientWebSocket cws = new ClientWebSocket();
cws.Options.AddSubProtocol("amqp");
await cws.ConnectAsync(uri, CancellationToken.None);
await cws.SendAsync(new ArraySegment<byte>(new[] { (byte)65, (byte)66, (byte)67 }), WebSocketMessageType.Binary, true, CancellationToken.None);
var buffer = new ArraySegment<byte>(new byte[1000]);
await cws.ReceiveAsync(buffer, CancellationToken.None);
await cws.CloseAsync(WebSocketCloseStatus.NormalClosure, "close", CancellationToken.None);
}
catch (Exception e)
{
Console.WriteLine(e);
}
} These are the two target frameworks: When I run this code under |
The managed ClientWebSocket implementation as of dotnet/corefx#24288 now provides support for all of ClientWebSocketOptions, in that it passes all of the relevant options along to the ManagedHandler implementation. |
@stephentoub is the app-compat table still correct given this new commit? |
The table only goes up through 2.0, so yes. It'll need to be updated once we have a 2.1. |
Is this supposed to work in the latest nightly builds? I tried using the ClientWebSocket with the latest nightly build (the debugger tells me I'm on veresion Specifying client certificates and proxy servers via Options doesn't seem to work on my side. My code is something along these lines (trying to connect to Kubernetes): ClientWebSocket webSocket = new ClientWebSocket();
webSocket.Options.Proxy = new WebProxy("127.0.0.1:8888");
await webSocket.ConnectAsync(wssUrl, CancellationToken.None).ConfigureAwait(false); I'm fairly sure the client certificates don't work as I get an exception telling me I need to specify one; the WebProxy also doesn't seem to work as my proxy servers (Fiddler/Burp) don't see any incoming request. The URL represents an external server, so loopback exceptions don't apply, either. |
ClientWebSocketOptions is not fully implemented yet. So, it is expected that the code above doesn't work. |
(If you want to give it a try on Linux, though, I'd expect/hope with the nightly it should work there.) |
Sure, I can give Linux a try. Is there any way to force the client to use the managed implementation on Windows? |
If you overwrite the System.Net.WebSockets.Client.dll you have with the Unix one from the package, that should "just work", though you'll want to make a backup of the original just in case :) |
@stephentoub I gave it a try on Linux; right now I'm getting SSL certification errors: "The remote certificate is invalid according to the validation procedure". I have a PS: Copying the dll from Linux to Windows doesn't "just work" as the file is marked as targetting Linux so the runtime rejects it on Windows. I was able to patch the architecture in the PE header of the assembly but apparently that wasn't enough, so I decided to abandon that experiment for now ;-) |
I'm not aware of that. @weshaggard, do you know what @qmfrederik is referring to here? We should not be doing anything special to say that the assembly is somehow Linux-specific... it's not.
ClientWebSocket here is just using SslStream, which on Windows should be using standard validation mechanisms. @bartonjs, can you help? |
@stephentoub @weshaggard For example, the WinPE header of contains |
@stephentoub @bartonjs Regarding the SSL validation (I'm trying on Linux ATM), it looks like dotnet/corefx#12038 is related. |
For IL only assemblies we shouldn't be marking them as OS or architecture specific (I think the default is prefer32bit) so I would expect them to work just fine between linux and windows. In fact we build all our IL assemblies on windows. However if you are taking the binaries out of the runtime zips then those are native ngen'ed binaries and will not work on the other platform as you point out. @qmfrederik you should be able to download the nuget package for this library and take the unix asset which is IL only and try and run it. |
@weshaggard OK - that makes sense. Where should I find the NuGet package? I tried https://dotnet.myget.org/feed/dotnet-core/package/nuget/System.Net.WebSockets.Client but it looks that hasn't been updated since January. |
@stephentoub Adding my CA to the list of trusted CA's on Linux got me this gem:
|
Go to NuGet.org: |
Hmm, that error is coming from here: |
@davidsh Hmm, looks like that package is built off https://github.com/dotnet/corefx/commits/1503bfaac164addc2821b41193d2c54512d49e37 which doesn't seem to include dotnet/corefx#24288 though |
The NuGet.org package is from the official release, 1.1 which was the last release that had a separate System.Net.WebSockets.Client NuGet package. If you want daily feeds from MYGET.ORG, then your previous link would have been correct. However, we no longer build a separate System.Net.WebSockets.Client NuGet package. The new model starting with .NET Core 2.0 actually is for mega-packages. That is why the last date for that package is last January. Instead of looking for the System.Net.WebSockets.Client.dll binary in a System.Net.WebSockets.Client NuGet package, you should look for that binary is one of the larger packages, i.e. NetCoreApp packages, etc. @weshaggard can explain this further. |
As of 2.0 we ship this library in the Microsoft.NETCore.App packages which also contain ngen'ed binaries. However we do have our private corefx package https://dotnet.myget.org/F/dotnet-core/api/v2/package/runtime.linux-x64.Microsoft.Private.CoreFx.NETCoreApp/4.5.0-preview1-26001-02 which should contain the IL file for this. Give that a try. As an aside @davidsh this fact is going to make fixing https://github.com/dotnet/corefx/issues/9503 more complicated |
@stephentoub Yes, I think that validation condition needs tweaking. At least in my case, Changing the condition to:
worked for me. In other news, I got the managed implementation to work on Windows - thanks all who helped me, greatly appreciated! I'll keep you posted. |
Excellent. |
@stephentoub I wanted to come back on this:
Is there a way for me to override the server certificate validation or pass a list of valid root certificates to |
Not currently. Feel free to open an API proposal issue. |
We will be switching Windows WebSockets to managed WebSockets implementation in dotnet/corefx#9503, which already implements all Closing as duplicate of dotnet/corefx#9503. |
Currently, .NET Core has a placeholder implementation for ClientWebSocketOptions. Filing this issue to track the complete implementation.
The text was updated successfully, but these errors were encountered: