Fix Host header in websocket examples

closes #1633
This commit is contained in:
Richard Hodges
2020-04-08 14:09:24 +02:00
parent 483b00d20f
commit c397227eb5
8 changed files with 56 additions and 15 deletions

View File

@ -1,3 +1,9 @@
Version XXX:
* Fix Host header in websocket examples
--------------------------------------------------------------------------------
Version 288: Version 288:
* Fix Content-Length parsing * Fix Content-Length parsing

View File

@ -109,11 +109,16 @@ public:
} }
void void
on_connect(beast::error_code ec, tcp::resolver::results_type::endpoint_type) on_connect(beast::error_code ec, tcp::resolver::results_type::endpoint_type ep)
{ {
if(ec) if(ec)
return fail(ec, "connect"); return fail(ec, "connect");
// Update the host_ string. This will provide the value of the
// Host HTTP header during the WebSocket handshake.
// See https://tools.ietf.org/html/rfc7230#section-5.4
host_ += ':' + std::to_string(ep.port());
// Set a timeout on the operation // Set a timeout on the operation
beast::get_lowest_layer(ws_).expires_after(std::chrono::seconds(30)); beast::get_lowest_layer(ws_).expires_after(std::chrono::seconds(30));

View File

@ -101,11 +101,16 @@ public:
} }
void void
on_connect(beast::error_code ec, tcp::resolver::results_type::endpoint_type) on_connect(beast::error_code ec, tcp::resolver::results_type::endpoint_type ep)
{ {
if(ec) if(ec)
return fail(ec, "connect"); return fail(ec, "connect");
// Update the host_ string. This will provide the value of the
// Host HTTP header during the WebSocket handshake.
// See https://tools.ietf.org/html/rfc7230#section-5.4
host_ += ':' + std::to_string(ep.port());
// Set a timeout on the operation // Set a timeout on the operation
beast::get_lowest_layer(ws_).expires_after(std::chrono::seconds(30)); beast::get_lowest_layer(ws_).expires_after(std::chrono::seconds(30));

View File

@ -95,7 +95,7 @@ public:
} }
void void
on_connect(beast::error_code ec, tcp::resolver::results_type::endpoint_type) on_connect(beast::error_code ec, tcp::resolver::results_type::endpoint_type ep)
{ {
if(ec) if(ec)
return fail(ec, "connect"); return fail(ec, "connect");
@ -118,6 +118,11 @@ public:
" websocket-client-async"); " websocket-client-async");
})); }));
// Update the host_ string. This will provide the value of the
// Host HTTP header during the WebSocket handshake.
// See https://tools.ietf.org/html/rfc7230#section-5.4
host_ += ':' + std::to_string(ep.port());
// Perform the websocket handshake // Perform the websocket handshake
ws_.async_handshake(host_, "/", ws_.async_handshake(host_, "/",
beast::bind_front_handler( beast::bind_front_handler(

View File

@ -44,7 +44,7 @@ fail(beast::error_code ec, char const* what)
// Sends a WebSocket message and prints the response // Sends a WebSocket message and prints the response
void void
do_session( do_session(
std::string const& host, std::string host,
std::string const& port, std::string const& port,
std::string const& text, std::string const& text,
net::io_context& ioc, net::io_context& ioc,
@ -67,10 +67,15 @@ do_session(
beast::get_lowest_layer(ws).expires_after(std::chrono::seconds(30)); beast::get_lowest_layer(ws).expires_after(std::chrono::seconds(30));
// Make the connection on the IP address we get from a lookup // Make the connection on the IP address we get from a lookup
beast::get_lowest_layer(ws).async_connect(results, yield[ec]); auto ep = beast::get_lowest_layer(ws).async_connect(results, yield[ec]);
if(ec) if(ec)
return fail(ec, "connect"); return fail(ec, "connect");
// Update the host_ string. This will provide the value of the
// Host HTTP header during the WebSocket handshake.
// See https://tools.ietf.org/html/rfc7230#section-5.4
host += ':' + std::to_string(ep.port());
// Set a timeout on the operation // Set a timeout on the operation
beast::get_lowest_layer(ws).expires_after(std::chrono::seconds(30)); beast::get_lowest_layer(ws).expires_after(std::chrono::seconds(30));

View File

@ -39,7 +39,7 @@ fail(beast::error_code ec, char const* what)
// Sends a WebSocket message and prints the response // Sends a WebSocket message and prints the response
void void
do_session( do_session(
std::string const& host, std::string host,
std::string const& port, std::string const& port,
std::string const& text, std::string const& text,
net::io_context& ioc, net::io_context& ioc,
@ -60,10 +60,15 @@ do_session(
beast::get_lowest_layer(ws).expires_after(std::chrono::seconds(30)); beast::get_lowest_layer(ws).expires_after(std::chrono::seconds(30));
// Make the connection on the IP address we get from a lookup // Make the connection on the IP address we get from a lookup
beast::get_lowest_layer(ws).async_connect(results, yield[ec]); auto ep = beast::get_lowest_layer(ws).async_connect(results, yield[ec]);
if(ec) if(ec)
return fail(ec, "connect"); return fail(ec, "connect");
// Update the host_ string. This will provide the value of the
// Host HTTP header during the WebSocket handshake.
// See https://tools.ietf.org/html/rfc7230#section-5.4
host += ':' + std::to_string(ep.port());
// Turn off the timeout on the tcp_stream, because // Turn off the timeout on the tcp_stream, because
// the websocket stream has its own timeout system. // the websocket stream has its own timeout system.
beast::get_lowest_layer(ws).expires_never(); beast::get_lowest_layer(ws).expires_never();

View File

@ -47,9 +47,9 @@ int main(int argc, char** argv)
" websocket-client-sync-ssl echo.websocket.org 443 \"Hello, world!\"\n"; " websocket-client-sync-ssl echo.websocket.org 443 \"Hello, world!\"\n";
return EXIT_FAILURE; return EXIT_FAILURE;
} }
auto const host = argv[1]; std::string host = argv[1];
auto const port = argv[2]; auto const port = argv[2];
auto const text = argv[3]; auto const text = argv[3];
// The io_context is required for all I/O // The io_context is required for all I/O
net::io_context ioc; net::io_context ioc;
@ -68,7 +68,12 @@ int main(int argc, char** argv)
auto const results = resolver.resolve(host, port); auto const results = resolver.resolve(host, port);
// Make the connection on the IP address we get from a lookup // Make the connection on the IP address we get from a lookup
net::connect(ws.next_layer().next_layer(), results.begin(), results.end()); auto ep = net::connect(get_lowest_layer(ws), results);
// Update the host_ string. This will provide the value of the
// Host HTTP header during the WebSocket handshake.
// See https://tools.ietf.org/html/rfc7230#section-5.4
host += ':' + std::to_string(ep.port());
// Perform the SSL handshake // Perform the SSL handshake
ws.next_layer().handshake(ssl::stream_base::client); ws.next_layer().handshake(ssl::stream_base::client);

View File

@ -43,9 +43,9 @@ int main(int argc, char** argv)
" websocket-client-sync echo.websocket.org 80 \"Hello, world!\"\n"; " websocket-client-sync echo.websocket.org 80 \"Hello, world!\"\n";
return EXIT_FAILURE; return EXIT_FAILURE;
} }
auto const host = argv[1]; std::string host = argv[1];
auto const port = argv[2]; auto const port = argv[2];
auto const text = argv[3]; auto const text = argv[3];
// The io_context is required for all I/O // The io_context is required for all I/O
net::io_context ioc; net::io_context ioc;
@ -58,7 +58,12 @@ int main(int argc, char** argv)
auto const results = resolver.resolve(host, port); auto const results = resolver.resolve(host, port);
// Make the connection on the IP address we get from a lookup // Make the connection on the IP address we get from a lookup
net::connect(ws.next_layer(), results.begin(), results.end()); auto ep = net::connect(ws.next_layer(), results);
// Update the host_ string. This will provide the value of the
// Host HTTP header during the WebSocket handshake.
// See https://tools.ietf.org/html/rfc7230#section-5.4
host += ':' + std::to_string(ep.port());
// Set a decorator to change the User-Agent of the handshake // Set a decorator to change the User-Agent of the handshake
ws.set_option(websocket::stream_base::decorator( ws.set_option(websocket::stream_base::decorator(