zaphoyd / websocketpp

C++ websocket client/server library
http://www.zaphoyd.com/websocketpp
Other
7.02k stars 1.97k forks source link

How to dynamically switch between secure and non-secure connections #597

Open freitass opened 8 years ago

freitass commented 8 years ago

What is the recommended way to determine client connection security based on the uri? I'm interested in the actual implementation. It appears that websocketpp::client<websocketpp::config::asio_client> and websocketpp::client<websocketpp::config::asio_tls_client> are two completely unrelated types and, therefore, cannot be held by the same (smart) pointer.

I'm currently going for the approach of creating an abstract class ConnectionBase that is specialized for standard and secure connections. I then use the location object to choose between both specializations. It works, but results in far too much boilerplate code. I went over the examples and the only one that I found, echo_server_both, actually created two endpoints. Is there a better alternative?

MacGritsch commented 8 years ago

Do you try to hanlde http and https on the same port? Its common to have different ports for that (80/443).

freitass commented 8 years ago

That is server-side, what about on the client side?

MacGritsch commented 8 years ago

You directly see if the server responds encrypted or unecncryptet.

freitass commented 8 years ago

I mean, if the user wants to connect to "wss://..." you are supposed to use websocketpp::client<websocketpp::config::asio_tls_client> while for a "ws://..." address you use websocketpp::client<websocketpp::config::asio_client>. The question is how to do it dynamically? Those types do not have a common ancestor (so that they could be handled by the same pointer).

I improved my solution a little bit. Now I still have the base class, but the derived class has a template that takes one of those two types. Then I specialize SetTlsInitHandler() to call set_tls_init_handler() on the secure client and to do nothing on the non-secure one (the non-secure client doesn't even define that function).

--edit--

Ultimately what I'm trying to do is something like:

std::unique_ptr<base_client> client;
if (address.starts_with("wss://")) {
  client = std::make_unique<asio_tls_client>();
} else {
  client = std::make_unique<asio_client>();
}

base_client is the piece of the puzzle that is missing.

zaphoyd commented 7 years ago

The way to do this right now is to have two endpoints, one for secure and one for unsecure, and switch on which one you use by inspecting the address.

I agree that it would be useful to have the secure endpoint be able to make non-secure connections and this is something that I've been looking into. It is a bit tricky right now as WebSocket++ uses static/compile time dispatch and dynamically choosing which code to run via a shared base or runtime "is secure" flag class would introduce dynamic dispatch into everything.

goodxianping commented 7 years ago

@freitass , your thought is very useful. I want to known how to support both ws and wss client in one app? thanks.

jbwdevries commented 7 years ago

@zaphoyd We have a situation where an application does both, it has multiple websocket client connections which up to now we could support with a single websocketpp::client instance. Just choosing at construction time may not be enough.

Possibly it's easier to make sure tls_client can also handle non-tls connections, via location->get_secure()check maybe?

troppoli commented 7 years ago

I find myself in a similar place... websocketpp::server gets you pretty far. If websocketpp::config::asio_tls and websocketpp::config::asio shared a common base that had noopps for tls routines I'd be using it.

barsnick commented 5 years ago

If websocketpp::config::asio_tls and websocketpp::config::asio shared a common base that had noopps for tls routines I'd be using it.

They do, except that you can't use the one directly in place of the other. (One should have been a child class of the other, perhaps?) I tried to wrap around that with templates, as demonstrated in my modification of the debug_client example in #776.

nico-abram commented 5 years ago

Has there been any progress on this?

goya commented 1 year ago

of course not.