54 {
56
57 {
59 using Request = LegacyClient::Request;
60 using Response = LegacyClient::Response;
61 using LegacySocketAddress = LegacyClient::SocketAddress;
62
63 const LegacyClient legacyClient(
64 "legacy",
65 [](const std::shared_ptr<Request>& req) {
66 VLOG(1) << "OnRequestBegin";
67
68 VLOG(1) << "Requesting upgrade to 'websocket' and any of the subprotocols 'subprotocol' and 'echo'";
69
70 req->set("Sec-WebSocket-Protocol", "subprotocol, echo");
71
72 if (!req->upgrade("/ws/",
73 "upgradeprotocol, websocket",
74 [](const std::shared_ptr<Request>& req, const std::shared_ptr<Response>& res) {
75 VLOG(1) << "OnResponse";
76 VLOG(2) << " Status:";
77 VLOG(2) << " " << res->httpVersion << " " << res->statusCode << " " << res->reason;
78 VLOG(2) << " Headers:";
79 for (const auto& [field, value] : res->headers) {
80 VLOG(2) << " " << field + " = " + value;
81 }
82
83 VLOG(2) << " Cookies:";
84 for (const auto& [name, cookie] : res->cookies) {
85 VLOG(2) << " " + name + " = " + cookie.getValue();
86 for (const auto& [option, value] : cookie.getOptions()) {
87 VLOG(2) << " " + option + " = " + value;
88 }
89 }
90
91 req->upgrade(res, [req](const std::string& name) {
92 if (!name.empty()) {
93 VLOG(1) << "Successful upgrade to '" << name << "' from options: " << req->header("Upgrade");
94 } else {
95 VLOG(1) << "Can not upgrade to any of '" << req->header("Upgrade") << "'";
96 }
97 });
98 })) {
99 VLOG(1) << "Initiating upgrade to any of 'upgradeprotocol, websocket' failed";
100 }
101 },
102 []([[maybe_unused]] const std::shared_ptr<Request>& req) {
103 VLOG(1) << "OnRequestEnd";
104 });
105
106 legacyClient.connect([instanceName = legacyClient.getConfig().getInstanceName()](const LegacySocketAddress& socketAddress,
108 switch (state) {
110 VLOG(1) << instanceName << " connected to '" << socketAddress.toString() << "'";
111 break;
113 VLOG(1) << instanceName << " disabled";
114 break;
116 VLOG(1) << instanceName << " " << socketAddress.toString() << ": " << state.what();
117 break;
119 VLOG(1) << instanceName << " " << socketAddress.toString() << ": " << state.what();
120 break;
121 }
122 });
123
125 using Request = TlsClient::Request;
126 using Response = TlsClient::Response;
127 using TLSSocketAddress = TlsClient::SocketAddress;
128
129 const TlsClient tlsClient(
130 "tls",
131 [](const std::shared_ptr<Request>& req) {
132 VLOG(1) << "OnRequestBegin";
133
134 VLOG(1) << "Requesting upgrade to 'websocket' and any of the subprotocols 'subprotocol' and 'echo'";
135
136 req->set("Sec-WebSocket-Protocol", "subprotocol, echo");
137
138 if (!req->upgrade("/ws/",
139 "upgradeprotocol, websocket",
140 [](const std::shared_ptr<Request>& req, const std::shared_ptr<Response>& res) {
141 VLOG(1) << "OnResponse";
142 VLOG(2) << " Status:";
143 VLOG(2) << " " << res->httpVersion << " " << res->statusCode << " " << res->reason;
144 VLOG(2) << " Headers:";
145 for (const auto& [field, value] : res->headers) {
146 VLOG(2) << " " << field + " = " + value;
147 }
148
149 VLOG(2) << " Cookies:";
150 for (const auto& [name, cookie] : res->cookies) {
151 VLOG(2) << " " + name + " = " + cookie.getValue();
152 for (const auto& [option, value] : cookie.getOptions()) {
153 VLOG(2) << " " + option + " = " + value;
154 }
155 }
156
157 req->upgrade(res, [req](const std::string& name) {
158 if (!name.empty()) {
159 VLOG(1) << "Successful upgrade to '" << name << "' from options: " << req->header("Upgrade");
160 } else {
161 VLOG(1) << "Can not upgrade to any of '" << req->header("Upgrade") << "'";
162 }
163 });
164 })) {
165 VLOG(1) << "Initiating upgrade to any of 'upgradeprotocol, websocket' failed";
166 }
167 },
168 []([[maybe_unused]] const std::shared_ptr<Request>& req) {
169 VLOG(1) << "OnRequestEnd";
170 });
171
172 tlsClient.connect([instanceName = tlsClient.getConfig().getInstanceName()](const TLSSocketAddress& socketAddress,
174 switch (state) {
176 VLOG(1) << instanceName << " connected to '" << socketAddress.toString() << "'";
177 break;
179 VLOG(1) << instanceName << " disabled";
180 break;
182 VLOG(1) << instanceName << " " << socketAddress.toString() << ": " << state.what();
183 break;
185 VLOG(1) << instanceName << " " << socketAddress.toString() << ": " << state.what();
186 break;
187 }
188 });
189 }
190
192}
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
web::http::client::Client< net::in::stream::legacy::SocketClient > Client
web::http::client::Client< net::in::stream::tls::SocketClient > Client