UniEvent-HTTP
view release on metacpan or search on metacpan
clib/tests/lib/test.cc view on Meta::CPAN
server_cfg.locations.push_back(loc);
server_cfg.tcp_nodelay = true;
TServerSP server = new TServer(loop);
server->configure(server_cfg);
server->run();
return server;
}
void TServer::enable_echo () {
request_event.remove_all();
request_event.add([](auto& req){
auto h = std::move(req->headers);
h.remove("Host");
h.remove("User-Agent");
h.remove("Accept-Encoding");
h.remove("Content-Length"); /* causes problems if req is not compressed, and res is */
auto res = new ServerResponse(200, std::move(h), Body(req->body.to_string()));
res->compression.type = Compression::GZIP;
req->respond(res);
});
}
void TServer::autorespond (const ServerResponseSP& res) {
if (!autores) {
autores = true;
request_event.add([this](auto& req){
if (!autoresponse_queue.size()) return;
auto res = autoresponse_queue.front();
autoresponse_queue.pop_front();
req->respond(res);
});
}
autoresponse_queue.push_back(res);
}
string TServer::location () const {
auto sa = sockaddr().value();
return sa.ip() + ':' + panda::to_string(sa.port());
}
NetLoc TServer::netloc () const {
return { sockaddr()->ip(), sockaddr()->port(), nullptr, {} };
}
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;
}
string TServer::uri () const {
string uri = secure ? string("https://") : string("http://");
uri += sockaddr()->ip();
uri += ":";
uri += to_string(sockaddr()->port());
uri += "/";
return uri;
}
void TClient::request (const RequestSP& req) {
req->tcp_nodelay = true;
if (sa) {
req->uri->host(sa.ip());
req->uri->port(sa.port());
}
if (secure) req->uri->scheme("https");
Client::request(req);
}
ResponseSP TClient::get_response (const RequestSP& req) {
ResponseSP response;
req->response_event.add([this, &response](auto, auto& res, auto& err){
if (err) throw err;
response = res;
this->loop()->stop();
});
request(req);
loop()->run();
return response;
}
ResponseSP TClient::get_response (const string& uri, Headers&& headers, Body&& body, bool chunked) {
auto b = Request::Builder().uri(uri).headers(std::move(headers)).body(std::move(body));
if (chunked) b.chunked();
return get_response(b.build());
}
ErrorCode TClient::get_error (const RequestSP& req) {
ErrorCode error;
req->response_event.add([this, &error](auto, auto, auto& err){
error = err;
this->loop()->stop();
});
request(req);
loop()->run();
return error;
}
ErrorCode TClient::get_error (const string& uri, Headers&& headers, Body&& body, bool chunked) {
auto b = Request::Builder().uri(uri).headers(std::move(headers)).body(std::move(body));
if (chunked) b.chunked();
return get_error(b.build());
}
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);
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;
}
TClientSP TPool::request (const RequestSP& req) {
TClientSP client = dynamic_pointer_cast<TClient>(Pool::request(req));
return client;
}
static TcpSP make_socks_server (const LoopSP& loop, const net::SockAddr& sa) {
TcpSP server = new Tcp(loop);
server->bind(sa);
server->listen(128);
server->connection_event.add([](auto server, auto stream, auto& err) {
if (err) throw err;
std::shared_ptr<int> state = std::make_shared<int>(0);
TcpSP client = new Tcp(server->loop());
client->read_event.add([stream](auto, auto& buf, auto& err) {
if (err) throw err;
// read from remote server
stream->write(buf);
});
client->eof_event.add([stream](auto) mutable {
stream->shutdown();
});
client->write_event.add([](auto, auto& err, auto) { if (err) throw err; });
stream->read_event.add([client, state](auto stream, auto& buf, auto&err) {
if (err) throw err;
switch (*state) {
case 0: {
stream->write("\x05\x00");
*state = 1;
break;
}
case 1: {
string request_type = buf.substr(0, 4);
if (request_type == string("\x05\x01\x00\x03")) {
int host_length = buf[4];
string host = buf.substr(5, host_length);
uint16_t port = ntohs(*(uint16_t*)buf.substr(5 + host_length).data());
client->connect("127.0.0.1", port);
client->connect_event.add([](auto, auto& err, auto){ if (err) throw err; });
} else {
throw std::runtime_error("bad request");
}
stream->write("\x05\x00\x00\x01\xFF\xFF\xFF\xFF\xFF\xFF");
*state = 2;
break;
}
case 2: {
// write to remote server
( run in 2.808 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )