zaphoyd / websocketpp

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

-> Working SSL Client example here <- #706

Open Maexel opened 6 years ago

Maexel commented 6 years ago

Hello,

i havent found an example for an working client with ssl, but i was able to create a working client by myself today. Basically it is just the echo client code where i activated tls and addet the tls init handler, but for people who aren't that familiar with c++ it will be really helpful and save time. Maybe someone wants to create a echo client tls in the examples dir from it :)


``/*
 * Copyright (c) 2016, Peter Thorson. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of the WebSocket++ Project nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

#include <websocketpp/config/asio_client.hpp>
#include <websocketpp/client.hpp>

#include <iostream>

typedef websocketpp::client<websocketpp::config::asio_tls_client> client;
typedef std::shared_ptr<boost::asio::ssl::context> context_ptr;
using websocketpp::lib::placeholders::_1;
using websocketpp::lib::placeholders::_2;
using websocketpp::lib::bind;

// pull out the type of messages sent by our config
typedef websocketpp::config::asio_client::message_type::ptr message_ptr;

// This message handler will be invoked once for each incoming message. It
// prints the message and then sends a copy of the message back to the server.
void on_message(client* c, websocketpp::connection_hdl hdl, message_ptr msg) {
    std::cout << "on_message called with hdl: " << hdl.lock().get()
              << " and message: " << msg->get_payload()
              << std::endl;

    websocketpp::lib::error_code ec;

    c->send(hdl, msg->get_payload(), msg->get_opcode(), ec);
    if (ec) {
        std::cout << "Echo failed because: " << ec.message() << std::endl;
    }
}

static context_ptr on_tls_init() {
    // establishes a SSL connection
    context_ptr ctx = std::make_shared<boost::asio::ssl::context>(boost::asio::ssl::context::sslv23);

    try {
        ctx->set_options(boost::asio::ssl::context::default_workarounds |
                         boost::asio::ssl::context::no_sslv2 |
                         boost::asio::ssl::context::no_sslv3 |
                         boost::asio::ssl::context::single_dh_use);
    } catch (std::exception &e) {
        std::cout << "Error in context pointer: " << e.what() << std::endl;
    }
    return ctx;
}

int main(int argc, char* argv[]) {
    // Create a client endpoint
    client c;

    std::string uri = "wss://localhost";

    if (argc == 2) {
        uri = argv[1];
    }

    try {
        // Set logging to be pretty verbose (everything except message payloads)
        c.set_access_channels(websocketpp::log::alevel::all);
        c.clear_access_channels(websocketpp::log::alevel::frame_payload);

        // Initialize ASIO
        c.init_asio();
        c.set_tls_init_handler(bind(&on_tls_init));

        // Register our message handler
        c.set_message_handler(bind(&on_message,&c,::_1,::_2));

        websocketpp::lib::error_code ec;
        client::connection_ptr con = c.get_connection(uri, ec);
        if (ec) {
            std::cout << "could not create connection because: " << ec.message() << std::endl;
            return 0;
        }

        // Note that connect here only requests a connection. No network messages are
        // exchanged until the event loop starts running in the next line.
        c.connect(con);

        // Start the ASIO io_service run loop
        // this will cause a single connection to be made to the server. c.run()
        // will exit when this connection is closed.
        c.run();
    } catch (websocketpp::exception const & e) {
        std::cout << e.what() << std::endl;
    }
}
aharonamir commented 6 years ago

:+1: good example, but can't connect with this config to non-secure servers Is there a good example for mixing secure/non-secure?

hejian1639 commented 6 years ago

same question

Sleepingbug commented 6 years ago

has no member "set_tls_init_handler"

zaphoyd commented 6 years ago

For mixed TLS/non TLS clients the procedure is similar to servers. I’ll see if I can prepare a client example that handles both secure and non-secure endpoints. In the meantime there is an echo_server_both example that demonstrates 95% of what is needed:

Sleepingbug commented 6 years ago

Thank you all. I've fixed my problem.

logieestrada commented 5 years ago

can you tell me what openssl version is required to get tls support going ? will v1.0.2 work?

br101 commented 5 years ago

Thanks a lot! This got me started with WebSocketPP

0d2f1x commented 5 years ago

Thanks, helpful

Scott-Taiwan commented 4 years ago

Dear Maexel, the sample code seems to be a client, but after it's running, how can I enter some message into the terminal for sending to the other end? do you have run example?

Thank you very much

Scott

zghong commented 4 years ago

Very wonderful example for tls-demo on websocketpp, thanks a lot!.

Non-Unruly commented 3 years ago

Awesome!

clxye commented 2 years ago

I also encountered the same problem and consulted a lot of information. Thank you very much!

cotomonaga commented 2 years ago

Thank you, Mr. Maexel!

I wrote a WebSocket client that supports TLS, based on Maexel's excellent code.

a WebSocket client that supports TLS https://github.com/cotomonaga/websocketpp_tutorial/blob/master/utility_client/step7.cpp

For those who have tried websocketpp's "Utility Client Example Application Tutorial", this code would be the answer to step7 "Using TLS / Secure WebSockets".

Utility Client Example Application Tutorial https://docs.websocketpp.org/md_tutorials_utility_client_utility_client.html

If you are looking for a config to non-secure servers, the above tutorial will be helpful.

Thanks.