Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/marian-nmt/Simple-WebSocket-Server.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoman Grundkiewicz <rgrundkiewicz@gmail.com>2021-02-10 17:19:16 +0300
committerGitHub <noreply@github.com>2021-02-10 17:19:16 +0300
commit1d7e84aeb3f1ebdc78f6965d79ad3ca3003789fe (patch)
tree632919470254d78cb9a0c20e39f75a75d40c8407
parent257439f5bd0a15f315c1c2733ea8a4fb0e32c1db (diff)
parent92cbb95fe06378a0f0cac0f7cf90a829aa85ea4a (diff)
Merge pull request #1 from rihardsk/upstream-master
Merge upstream master
-rw-r--r--.clang-format1
-rw-r--r--.gitignore6
-rw-r--r--CMakeLists.txt12
-rw-r--r--asio_compatibility.hpp12
-rw-r--r--client_ws.hpp14
-rw-r--r--server_ws.hpp74
-rw-r--r--tests/CMakeLists.txt18
-rw-r--r--utility.hpp6
-rw-r--r--ws_examples.cpp3
-rw-r--r--wss_examples.cpp3
10 files changed, 83 insertions, 66 deletions
diff --git a/.clang-format b/.clang-format
index 50f9423..740ccf7 100644
--- a/.clang-format
+++ b/.clang-format
@@ -7,3 +7,4 @@ SpaceBeforeParens: Never
BreakBeforeBraces: Custom
BraceWrapping: {BeforeElse: true, BeforeCatch: true}
NamespaceIndentation: All
+AllowShortCaseLabelsOnASingleLine: true
diff --git a/.gitignore b/.gitignore
index 75fe027..4e12767 100644
--- a/.gitignore
+++ b/.gitignore
@@ -17,6 +17,6 @@ compile_commands.json
# executables
ws_examples
wss_examples
-crypto_test
-io_test
-parse_test
+swss_crypto_test
+swss_io_test
+swss_parse_test
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 9d2d4f7..11e11f1 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,9 +1,13 @@
-cmake_minimum_required (VERSION 3.0)
+cmake_minimum_required(VERSION 3.0)
-project (Simple-WebSocket-Server)
+project(Simple-WebSocket-Server)
option(USE_STANDALONE_ASIO "set ON to use standalone Asio instead of Boost.Asio" OFF)
-option(BUILD_TESTING "set ON to build library tests" OFF)
+if(CMAKE_SOURCE_DIR STREQUAL "${CMAKE_CURRENT_SOURCE_DIR}")
+ option(BUILD_TESTING "set ON to build library tests" ON)
+else()
+ option(BUILD_TESTING "set ON to build library tests" OFF)
+endif()
add_library(simple-websocket-server INTERFACE)
@@ -60,8 +64,6 @@ if(CMAKE_SOURCE_DIR STREQUAL "${CMAKE_CURRENT_SOURCE_DIR}")
add_executable(wss_examples wss_examples.cpp)
target_link_libraries(wss_examples simple-websocket-server)
- set(BUILD_TESTING ON)
-
install(FILES asio_compatibility.hpp server_ws.hpp client_ws.hpp server_wss.hpp client_wss.hpp crypto.hpp utility.hpp status_code.hpp mutex.hpp DESTINATION include/simple-websocket-server)
endif()
diff --git a/asio_compatibility.hpp b/asio_compatibility.hpp
index a9abd7c..c2e0b66 100644
--- a/asio_compatibility.hpp
+++ b/asio_compatibility.hpp
@@ -42,9 +42,9 @@ namespace SimpleWeb {
inline asio::ip::address make_address(const std::string &str) noexcept {
return asio::ip::make_address(str);
}
- template <typename socket_type>
- asio::executor get_socket_executor(socket_type &socket) {
- return socket.get_executor();
+ template <typename socket_type, typename duration_type>
+ std::unique_ptr<asio::steady_timer> make_steady_timer(socket_type &socket, std::chrono::duration<duration_type> duration) {
+ return std::unique_ptr<asio::steady_timer>(new asio::steady_timer(socket.get_executor(), duration));
}
template <typename handler_type>
void async_resolve(asio::ip::tcp::resolver &resolver, const std::pair<std::string, std::string> &host_port, handler_type &&handler) {
@@ -68,9 +68,9 @@ namespace SimpleWeb {
inline asio::ip::address make_address(const std::string &str) noexcept {
return asio::ip::address::from_string(str);
}
- template <typename socket_type>
- io_context &get_socket_executor(socket_type &socket) {
- return socket.get_io_service();
+ template <typename socket_type, typename duration_type>
+ std::unique_ptr<asio::steady_timer> make_steady_timer(socket_type &socket, std::chrono::duration<duration_type> duration) {
+ return std::unique_ptr<asio::steady_timer>(new asio::steady_timer(socket.get_io_service(), duration));
}
template <typename handler_type>
void async_resolve(asio::ip::tcp::resolver &resolver, const std::pair<std::string, std::string> &host_port, handler_type &&handler) {
diff --git a/client_ws.hpp b/client_ws.hpp
index b5ce2d7..e4a26f6 100644
--- a/client_ws.hpp
+++ b/client_ws.hpp
@@ -86,6 +86,8 @@ namespace SimpleWeb {
std::atomic<bool> closed;
+ asio::ip::tcp::endpoint endpoint; // The endpoint is read in SocketClient::upgrade and must be stored so that it can be read reliably in all handlers, including on_error
+
void close() noexcept {
error_code ec;
socket->lowest_layer().shutdown(asio::ip::tcp::socket::shutdown_both, ec);
@@ -106,7 +108,7 @@ namespace SimpleWeb {
return;
}
- timer = std::unique_ptr<asio::steady_timer>(new asio::steady_timer(get_socket_executor(*socket), std::chrono::seconds(seconds)));
+ timer = make_steady_timer(*socket, std::chrono::seconds(seconds));
std::weak_ptr<Connection> connection_weak(this->shared_from_this()); // To avoid keeping Connection instance alive longer than needed
timer->async_wait([connection_weak, use_timeout_idle](const error_code &ec) {
if(!ec) {
@@ -252,6 +254,10 @@ namespace SimpleWeb {
// fin_rsv_opcode=136: message close
send(out_message, std::move(callback), 136);
}
+
+ const asio::ip::tcp::endpoint &remote_endpoint() const noexcept {
+ return endpoint;
+ }
};
class Config {
@@ -409,6 +415,12 @@ namespace SimpleWeb {
ostream << header_field.first << ": " << header_field.second << "\r\n";
ostream << "\r\n";
+ try {
+ connection->endpoint = connection->socket->lowest_layer().remote_endpoint();
+ }
+ catch(...) {
+ }
+
connection->in_message = std::shared_ptr<InMessage>(new InMessage());
connection->set_timeout(config.timeout_request);
diff --git a/server_ws.hpp b/server_ws.hpp
index 158813d..2256d55 100644
--- a/server_ws.hpp
+++ b/server_ws.hpp
@@ -87,42 +87,8 @@ namespace SimpleWeb {
regex::smatch path_match;
- const asio::ip::tcp::endpoint &remote_endpoint() const noexcept {
- return endpoint;
- }
-
- asio::ip::tcp::endpoint local_endpoint() const noexcept {
- try {
- if(auto connection = this->connection.lock())
- return connection->socket->lowest_layer().local_endpoint();
- }
- catch(...) {
- }
- return asio::ip::tcp::endpoint();
- }
-
- /// Deprecated, please use remote_endpoint().address().to_string() instead.
- DEPRECATED std::string remote_endpoint_address() const noexcept {
- try {
- return endpoint.address().to_string();
- }
- catch(...) {
- }
- return std::string();
- }
-
- /// Deprecated, please use remote_endpoint().port() instead.
- DEPRECATED unsigned short remote_endpoint_port() const noexcept {
- try {
- return endpoint.port();
- }
- catch(...) {
- }
- return 0;
- }
-
private:
- /// Used to call Server::upgrade.
+ /// Used to call SocketServer::upgrade.
template <typename... Args>
Connection(std::shared_ptr<ScopeRunner> handler_runner_, long timeout_idle, Args &&... args) noexcept
: handler_runner(std::move(handler_runner_)), socket(new socket_type(std::forward<Args>(args)...)), timeout_idle(timeout_idle), closed(false) {}
@@ -141,7 +107,7 @@ namespace SimpleWeb {
std::atomic<bool> closed;
- asio::ip::tcp::endpoint endpoint; // The endpoint is read in Server::write_handshake and must be stored so that it can be read reliably in all handlers, including on_error
+ asio::ip::tcp::endpoint endpoint; // The endpoint is read in SocketServer::write_handshake and must be stored so that it can be read reliably in all handlers, including on_error
void close() noexcept {
error_code ec;
@@ -160,7 +126,7 @@ namespace SimpleWeb {
return;
}
- timer = std::unique_ptr<asio::steady_timer>(new asio::steady_timer(get_socket_executor(*socket), std::chrono::seconds(seconds)));
+ timer = make_steady_timer(*socket, std::chrono::seconds(seconds));
std::weak_ptr<Connection> connection_weak(this->shared_from_this()); // To avoid keeping Connection instance alive longer than needed
timer->async_wait([connection_weak](const error_code &ec) {
if(!ec) {
@@ -292,6 +258,40 @@ namespace SimpleWeb {
// fin_rsv_opcode=136: message close
send(std::move(send_stream), std::move(callback), 136);
}
+
+ const asio::ip::tcp::endpoint &remote_endpoint() const noexcept {
+ return endpoint;
+ }
+
+ asio::ip::tcp::endpoint local_endpoint() const noexcept {
+ try {
+ if(auto connection = this->connection.lock())
+ return connection->socket->lowest_layer().local_endpoint();
+ }
+ catch(...) {
+ }
+ return asio::ip::tcp::endpoint();
+ }
+
+ /// Deprecated, please use remote_endpoint().address().to_string() instead.
+ DEPRECATED std::string remote_endpoint_address() const noexcept {
+ try {
+ return endpoint.address().to_string();
+ }
+ catch(...) {
+ }
+ return std::string();
+ }
+
+ /// Deprecated, please use remote_endpoint().port() instead.
+ DEPRECATED unsigned short remote_endpoint_port() const noexcept {
+ try {
+ return endpoint.port();
+ }
+ catch(...) {
+ }
+ return 0;
+ }
};
class Endpoint {
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index f5b1526..9d50bdd 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -4,15 +4,15 @@ if(NOT MSVC)
add_compile_options(-Wno-thread-safety)
endif()
- add_executable(parse_test parse_test.cpp)
- target_link_libraries(parse_test simple-websocket-server)
- add_test(parse_test parse_test)
+ add_executable(swss_parse_test parse_test.cpp)
+ target_link_libraries(swss_parse_test simple-websocket-server)
+ add_test(swss_parse_test swss_parse_test)
endif()
-add_executable(crypto_test crypto_test.cpp)
-target_link_libraries(crypto_test simple-websocket-server)
-add_test(crypto_test crypto_test)
+add_executable(swss_crypto_test crypto_test.cpp)
+target_link_libraries(swss_crypto_test simple-websocket-server)
+add_test(swss_crypto_test swss_crypto_test)
-add_executable(io_test io_test.cpp)
-target_link_libraries(io_test simple-websocket-server)
-add_test(io_test io_test)
+add_executable(swss_io_test io_test.cpp)
+target_link_libraries(swss_io_test simple-websocket-server)
+add_test(swss_io_test swss_io_test)
diff --git a/utility.hpp b/utility.hpp
index 2c0e7cf..3b41ff3 100644
--- a/utility.hpp
+++ b/utility.hpp
@@ -145,13 +145,13 @@ namespace SimpleWeb {
name_end_pos = std::string::npos;
value_pos = std::string::npos;
}
- else if(query_string[c] == '=') {
+ else if(query_string[c] == '=' && name_end_pos == std::string::npos) {
name_end_pos = c;
value_pos = c + 1;
}
}
if(name_pos < query_string.size()) {
- auto name = query_string.substr(name_pos, name_end_pos - name_pos);
+ auto name = query_string.substr(name_pos, (name_end_pos == std::string::npos ? std::string::npos : name_end_pos - name_pos));
if(!name.empty()) {
auto value = value_pos >= query_string.size() ? std::string() : query_string.substr(value_pos);
result.emplace(std::move(name), Percent::decode(value));
@@ -260,7 +260,7 @@ namespace SimpleWeb {
std::size_t query_start = std::string::npos;
std::size_t path_and_query_string_end = std::string::npos;
for(std::size_t i = method_end + 1; i < line.size(); ++i) {
- if(line[i] == '?' && (i + 1) < line.size())
+ if(line[i] == '?' && (i + 1) < line.size() && query_start == std::string::npos)
query_start = i + 1;
else if(line[i] == ' ') {
path_and_query_string_end = i;
diff --git a/ws_examples.cpp b/ws_examples.cpp
index 36798cd..ce516ff 100644
--- a/ws_examples.cpp
+++ b/ws_examples.cpp
@@ -103,7 +103,8 @@ int main() {
server_port.set_value(port);
});
});
- cout << "Server listening on port " << server_port.get_future().get() << endl << endl;
+ cout << "Server listening on port " << server_port.get_future().get() << endl
+ << endl;
// Example 4: Client communication with server
// Possible output:
diff --git a/wss_examples.cpp b/wss_examples.cpp
index d5a2527..74e4a84 100644
--- a/wss_examples.cpp
+++ b/wss_examples.cpp
@@ -103,7 +103,8 @@ int main() {
server_port.set_value(port);
});
});
- cout << "Server listening on port " << server_port.get_future().get() << endl << endl;
+ cout << "Server listening on port " << server_port.get_future().get() << endl
+ << endl;
// Example 4: Client communication with server
// Possible output: