diff options
Diffstat (limited to 'src/zenhttp/servers/asio_socket_traits.h')
| -rw-r--r-- | src/zenhttp/servers/asio_socket_traits.h | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/src/zenhttp/servers/asio_socket_traits.h b/src/zenhttp/servers/asio_socket_traits.h new file mode 100644 index 000000000..25aeaa24e --- /dev/null +++ b/src/zenhttp/servers/asio_socket_traits.h @@ -0,0 +1,54 @@ +// Copyright Epic Games, Inc. All Rights Reserved. + +#pragma once + +ZEN_THIRD_PARTY_INCLUDES_START +#include <asio.hpp> +#if ZEN_USE_OPENSSL +# include <asio/ssl.hpp> +#endif +ZEN_THIRD_PARTY_INCLUDES_END + +namespace zen::asio_http { + +/** + * Traits for abstracting socket shutdown/close across plain TCP, Unix domain, and SSL sockets. + * SSL sockets need lowest_layer() access and have different shutdown semantics. + */ +template<typename SocketType> +struct SocketTraits +{ + /// SSL sockets cannot use zero-copy file send (TransmitFile/sendfile) because + /// those bypass the encryption layer. This flag lets templated code fall back + /// to reading-into-memory for SSL connections. + static constexpr bool IsSslSocket = false; + + static void ShutdownReceive(SocketType& S, std::error_code& Ec) { S.shutdown(asio::socket_base::shutdown_receive, Ec); } + + static void ShutdownBoth(SocketType& S, std::error_code& Ec) { S.shutdown(asio::socket_base::shutdown_both, Ec); } + + static void Close(SocketType& S, std::error_code& Ec) { S.close(Ec); } +}; + +#if ZEN_USE_OPENSSL +using SslSocket = asio::ssl::stream<asio::ip::tcp::socket>; + +template<> +struct SocketTraits<SslSocket> +{ + static constexpr bool IsSslSocket = true; + + static void ShutdownReceive(SslSocket& S, std::error_code& Ec) { S.lowest_layer().shutdown(asio::socket_base::shutdown_receive, Ec); } + + static void ShutdownBoth(SslSocket& S, std::error_code& Ec) + { + // Best-effort SSL close_notify, then TCP shutdown + S.shutdown(Ec); + S.lowest_layer().shutdown(asio::socket_base::shutdown_both, Ec); + } + + static void Close(SslSocket& S, std::error_code& Ec) { S.lowest_layer().close(Ec); } +}; +#endif + +} // namespace zen::asio_http |