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 )