32 {
34
35 {
37 using Request = LegacyClient::Request;
38 using Response = LegacyClient::Response;
39 using LegacySocketAddress = LegacyClient::SocketAddress;
40
41 const LegacyClient legacyClient(
42 "legacy",
43 [](const std::shared_ptr<Request>& req) {
44 VLOG(1) << "OnRequestBegin";
45
46 VLOG(1) << "Requesting upgrade to 'websocket' and any of the subprotocols 'subprotocol' and 'echo'";
47
48 req->set("Sec-WebSocket-Protocol", "subprotocol, echo");
49
50 if (!req->upgrade("/ws/",
51 "upgradeprotocol, websocket",
52 [](const std::shared_ptr<Request>& req, const std::shared_ptr<Response>& res) {
53 VLOG(1) << "OnResponse";
54 VLOG(2) << " Status:";
55 VLOG(2) << " " << res->httpVersion << " " << res->statusCode << " " << res->reason;
56 VLOG(2) << " Headers:";
57 for (const auto& [field, value] : res->headers) {
58 VLOG(2) << " " << field + " = " + value;
59 }
60
61 VLOG(2) << " Cookies:";
62 for (const auto& [name, cookie] : res->cookies) {
63 VLOG(2) << " " + name + " = " + cookie.getValue();
64 for (const auto& [option, value] : cookie.getOptions()) {
65 VLOG(2) << " " + option + " = " + value;
66 }
67 }
68
69 req->upgrade(res, [req](const std::string& name) {
70 if (!name.empty()) {
71 VLOG(1) << "Successful upgrade to '" << name << "' from options: " << req->header("Upgrade");
72 } else {
73 VLOG(1) << "Can not upgrade to any of '" << req->header("Upgrade") << "'";
74 }
75 });
76 })) {
77 VLOG(1) << "Initiating upgrade to any of 'upgradeprotocol, websocket' failed";
78 }
79 },
80 []([[maybe_unused]] const std::shared_ptr<Request>& req) {
81 VLOG(1) << "OnRequestEnd";
82 });
83
84 legacyClient.connect([instanceName = legacyClient.getConfig().getInstanceName()](const LegacySocketAddress& socketAddress,
86 switch (state) {
88 VLOG(1) << instanceName << " connected to '" << socketAddress.toString() << "'";
89 break;
91 VLOG(1) << instanceName << " disabled";
92 break;
94 VLOG(1) << instanceName << " " << socketAddress.toString() << ": " << state.what();
95 break;
97 VLOG(1) << instanceName << " " << socketAddress.toString() << ": " << state.what();
98 break;
99 }
100 });
101
103 using Request = TlsClient::Request;
104 using Response = TlsClient::Response;
105 using TLSSocketAddress = TlsClient::SocketAddress;
106
107 const TlsClient tlsClient(
108 "tls",
109 [](const std::shared_ptr<Request>& req) {
110 VLOG(1) << "OnRequestBegin";
111
112 VLOG(1) << "Requesting upgrade to 'websocket' and any of the subprotocols 'subprotocol' and 'echo'";
113
114 req->set("Sec-WebSocket-Protocol", "subprotocol, echo");
115
116 if (!req->upgrade("/ws/",
117 "upgradeprotocol, websocket",
118 [](const std::shared_ptr<Request>& req, const std::shared_ptr<Response>& res) {
119 VLOG(1) << "OnResponse";
120 VLOG(2) << " Status:";
121 VLOG(2) << " " << res->httpVersion << " " << res->statusCode << " " << res->reason;
122 VLOG(2) << " Headers:";
123 for (const auto& [field, value] : res->headers) {
124 VLOG(2) << " " << field + " = " + value;
125 }
126
127 VLOG(2) << " Cookies:";
128 for (const auto& [name, cookie] : res->cookies) {
129 VLOG(2) << " " + name + " = " + cookie.getValue();
130 for (const auto& [option, value] : cookie.getOptions()) {
131 VLOG(2) << " " + option + " = " + value;
132 }
133 }
134
135 req->upgrade(res, [req](const std::string& name) {
136 if (!name.empty()) {
137 VLOG(1) << "Successful upgrade to '" << name << "' from options: " << req->header("Upgrade");
138 } else {
139 VLOG(1) << "Can not upgrade to any of '" << req->header("Upgrade") << "'";
140 }
141 });
142 })) {
143 VLOG(1) << "Initiating upgrade to any of 'upgradeprotocol, websocket' failed";
144 }
145 },
146 []([[maybe_unused]] const std::shared_ptr<Request>& req) {
147 VLOG(1) << "OnRequestEnd";
148 });
149
150 tlsClient.connect([instanceName = tlsClient.getConfig().getInstanceName()](const TLSSocketAddress& socketAddress,
152 switch (state) {
154 VLOG(1) << instanceName << " connected to '" << socketAddress.toString() << "'";
155 break;
157 VLOG(1) << instanceName << " disabled";
158 break;
160 VLOG(1) << instanceName << " " << socketAddress.toString() << ": " << state.what();
161 break;
163 VLOG(1) << instanceName << " " << socketAddress.toString() << ": " << state.what();
164 break;
165 }
166 });
167 }
168
170}
static void init(int argc, char *argv[])
static int start(const utils::Timeval &timeOut={LONG_MAX, 0})
static constexpr int DISABLED
static constexpr int ERROR
static constexpr int FATAL
Client::Response Response
ClientBase< web::http::client::Request, web::http::client::Response > Client
ClientBase< web::http::client::Request, web::http::client::Response > Client