UniEvent-WebSocket

 view release on metacpan or  search on metacpan

clib/tests/lib/test.cc  view on Meta::CPAN

#include "test.h"
#include "panda/cast.h"
#include "panda/protocol/websocket/ConnectRequest.h"
#include "panda/protocol/websocket/inc.h"
// #include <openssl/dh.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
// #include <openssl/conf.h>
// #include <openssl/engine.h>
// #include <chrono>
// #include <iostream>
// #include <catch2/reporters/catch_reporter_registrars.hpp>
// #include <catch2/reporters/catch_reporter_event_listener.hpp>

using panda::unievent::Timer;
using panda::unievent::TimerSP;
using unievent::Pipe;
using unievent::Tcp;

bool secure = false;
int TServer::dcnt;
// int TClient::dcnt;

// static int64_t _time_mark;

TServerSP make_server (const LoopSP& loop, Server::Config cfg) {
    TServerSP server = new TServer(loop);

    if (!cfg.locations.size()) {
        Location loc;
        loc.host = "127.0.0.1";
        if (secure) { loc.ssl_ctx = TServer::get_context("ca"); }
        cfg.locations.push_back(loc);
    } else if (secure) {
        cfg.locations.front().ssl_ctx = TServer::get_context("ca");
    }

    cfg.tcp_nodelay = true;
    server->configure(cfg);

    server->run();
    return server;
}

SslContext TServer::get_context (string cert_name) {
    auto ctx = SSL_CTX_new(SSLv23_server_method());
    auto r = SslContext::attach(ctx);
    string path("tests/cert");
    string cert = path + "/" + cert_name + ".pem";
    string key = path + "/" + cert_name + ".key";
    int err;

    err = SSL_CTX_use_certificate_file(ctx, cert.c_str(), SSL_FILETYPE_PEM);
    assert(err);

    err = SSL_CTX_use_PrivateKey_file(ctx, key.c_str(), SSL_FILETYPE_PEM);
    assert(err);

    err = SSL_CTX_check_private_key(ctx);
    assert(err);
    return r;
}

SslContext TClient::get_context(string cert_name, const string& ca_name) {
    auto ctx = SSL_CTX_new(SSLv23_client_method());
    auto r = SslContext::attach(ctx);
    string path("tests/cert");
    string ca = path + "/" + ca_name + ".pem";
    string cert = path + "/" + cert_name + ".pem";
    string key = path + "/" + cert_name + ".key";
    int err;

    err = SSL_CTX_load_verify_locations(ctx, ca.c_str(), nullptr);
    assert(err);

    err = SSL_CTX_use_certificate_file(ctx, cert.c_str(), SSL_FILETYPE_PEM);
    if (err != 1) printf("SSL CERT ERROR: %s (load cert %s)\n", ERR_error_string(ERR_get_error(), NULL), cert.c_str());
    assert(err);

    err = SSL_CTX_use_PrivateKey_file(ctx, key.c_str(), SSL_FILETYPE_PEM);
    assert(err);

    SSL_CTX_check_private_key(ctx);
    assert(err);

    SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, nullptr);
    SSL_CTX_set_verify_depth(ctx, 4);

    return r;
}

ServerPair::ServerPair (const LoopSP& loop, Server::Config cfg, bool unixsock) {
    server = make_server(loop, cfg);

    server->connection_event.add([this](auto, auto& cli, auto){
        this->sconn = cli;
    });

    TcpSP tcp;
    PipeSP pipe;
    if (unixsock) { pipe = new Pipe(loop); conn = pipe; }
    else          { tcp  = new Tcp(loop); conn = tcp; }

    if (secure) {  conn->use_ssl( TClient::get_context("ca")); }
    conn->connect_event.add([this](auto& conn, auto& err, auto){
        if (err) {
            printf("server pair connect error: %s\n", err.what().c_str());
            throw err;
        }

        ConnectRequestSP req = new protocol::websocket::ConnectRequest();
        req->uri = new URI("ws://example.com");
        conn->write(parser.connect_request(req));
    });
    conn->read_event.add([this](auto& self, auto, auto& str, auto& err){
        if (parser.established()) return;
        if (err) {
            printf("server pair client read error: %s\n", err.what().c_str());
            throw err;
        }
        auto res = parser.connect(str);
        if (!res) return;
        conn->read_event.remove(self);

        conn->loop()->stop();
    });
    if (unixsock) pipe->connect(panda::dyn_cast<Pipe*>(server->listeners()[0].get())->sockname().value());
    else          tcp->connect(server->sockaddr().value());
    loop->run();
}

void ServerPair::enable_echo () {
    sconn->message_event.remove_all();
    sconn->message_event.add([](auto& sconn, auto& msg){
        sconn->message().opcode(msg->opcode()).send(msg->payload.begin(), msg->payload.end());
    });
}

void ServerPair::autorespond (const string& str) {
    if (!autores) {
        autores = true;
        sconn->message_event.add([this](auto, auto&){
            if (!autoresponse_queue.size()) return;



( run in 1.841 second using v1.01-cache-2.11-cpan-39bf76dae61 )