Closed NatMarchand closed 7 years ago
It should be in the method CreateWebSocketTransportSettings in AmqpConnectionHelper but how can we pass the proxy configuration ? Through the connection string ?
We don't have a precedent in how to pass the proxy connection details. And moreover, this seems to be more of client configuration and not server endpoint details. So I'm not completely inclined towards having this in connectionString. But at the same time, since we don't expose connection
object itself, the only place I can currently think of is ServiceBusConnectionStringBuilder
. And looking at WebProxy() class
, it potentially requires multiple setting values, including and not limiting to credentials. Passing all the details to us might be lot of work. Instead what are your opinions on exposing the IWebProxy as a property in ServiceBusconnectionStringBuilder
class itself?
Also, There are lot of different ways by which people use proxy
. FMU, could you describe the scenario which you are currently targeting?
The other thing is the IWebProxy implementation, the only one I know is only available in NET451. What can we do for others platforms ?
Looks like this has already been ported to dotnetcore - https://github.com/dotnet/corefx/pull/11996. It is part of 2.0.0 version though.
At last, how is it possible to test this ?
I don't know the perfect solution for this. For now, I think we could start with manual testing using any of the public / open source proxy solutions that we can configure on our machines.
I did a small test implementation locally, using the ConnectionStringProperties of ServiceBusConnectionStringBuilder. I'm not sure but we might not need all the properties of WebProxy : bypass properties shouldn't be used as we only target one url in the connection string, there's no point in by-passing. The only thing that might be useful is the credentials property. In this case I'm not sure because I can't test but I think using a uri such as http://login:password@proxyadress:proxyport/ should work.
Instead what are your opinions on exposing the IWebProxy as a property in ServiceBusconnectionStringBuilder class itself?
That could be one way but it has to be clear that it won't have any effect in the case the user uses TCP transport.
Also, There are lot of different ways by which people use proxy. FMU, could you describe the scenario which you are currently targeting?
At work, all the outbound traffic is either blocked or going through a Squid http proxy. We also have an express route but it's only private peering for now and as service bus is not "vnet-able", we can't use it. We're looking to also connect with public peering but in my previous client, even with express routes we had to use proxy (for security issues).
@NatMarchand, I see that the System.Net.WebSocket by default initializes the proxy to WebRequest.DefaultWebProxy
in ClientWebSocketOptions() constructor
.
And based on its summary,
The DefaultWebProxy property reads proxy settings from the app.config file. If there is no config file, the current user's Internet Explorer (IE) proxy settings are used.
Have you tried this yet? We might not need to add a custom proxy if it is set at a machine-wide level.
The main idea is to use underlying system's proxy instead of making users give explicit proxy details to our client.
Looks like there are couple of issues which are already filed: https://github.com/dotnet/corefx/issues/5120 https://github.com/dotnet/corefx/issues/7037
Amqp library uses ClientWebSocket
which internally uses WebSocket
which reads proxy from WebRequest.DefaultWebProxy
which is currently not implemented.
Looks like webSocket hasn't ported Proxy functionality to its dotnet core. :(
Ah! You had me follow an interesting lead with the app.config. I tested yesterday and it didn't work but I didn't wonder why. Then I debugged the Microsoft.Azure.Amqp, its WebSocketTransportInitiator and I've the following code :
public override bool ConnectAsync(TimeSpan timeout, TransportAsyncCallbackArgs callbackArgs)
{
ClientWebSocket cws = new ClientWebSocket();
cws.Options.AddSubProtocol(this.settings.SubProtocol);
cws.Options.Proxy = this.settings.Proxy;
The thing here is that when we create a ClientWebSocket it DOES have a default web proxy BUT when we assign the value from the settings we erase the default value with null. The code should be as following:
public override bool ConnectAsync(TimeSpan timeout, TransportAsyncCallbackArgs callbackArgs)
{
ClientWebSocket cws = new ClientWebSocket();
cws.Options.AddSubProtocol(this.settings.SubProtocol);
if(this.settings.Proxy != null)
cws.Options.Proxy = this.settings.Proxy;
Do you agree ? If so I can make directly the pull request on the other repo.
It's very weird, I can see the line cws.Options.Proxy = this.settings.Proxy;
when I decompile with DotPeek or Reflector but I can't find it in the repo. I'm totally lost 😕
@NatMarchand , Before you go ahead and raise a PR, do a quick check and let me know if you got it working on dotnet core.
I tried to stitch up the whole proxy thing across Azure.ServiceBus
and Azure.amqp
library and it hasnt worked on dotnet core (even after bumping up the version to netcore2.0
). The exact same setup for net451
works.
Based on the comments here, this is not yet implemented in dot net core. Let me know if you could get it working.
It's very weird, I can see the line cws.Options.Proxy = this.settings.Proxy; when I decompile with DotPeek or Reflector but I can't find it in the repo. I'm totally lost
I've observed this as well. I'll try to sync up with the owner of the amqp library and get back to you on that. But this might take a few days as he is OOF as of now.
@Natmarchand, I did couple of tests. It looks like for net451, the system default proxy is read and used for the proxy (even if we don't specify it in our code). And I couldnt' get it working for netcoreapp framework. Given that, I'm going to close this issue as now proxy can be configured by configuring the system default proxy. Let me know if you have any concerns
Regarding what's been done in PR #288 and issue #269 it should work for most of the configuration. Unfortunately, there are some case where the proxy needs to be set explicitely. I'd like to implement this but I have few questions first. It should be in the method CreateWebSocketTransportSettings in AmqpConnectionHelper but how can we pass the proxy configuration ? Through the connection string ? The other thing is the IWebProxy implementation, the only one I know is only available in NET451. What can we do for others platforms ? At last, how is it possible to test this ?