From 92de6df113ddce8b85758541f2a23c38a45dc365 Mon Sep 17 00:00:00 2001 From: Fabio Alessandrelli Date: Fri, 14 Sep 2018 14:13:11 +0200 Subject: Add checks for clean disconnect in HTTP/TCP/SSL. Half-open TCP connection can, of course, only be detected by writing the socket, or waiting for TCP timeout. --- core/io/http_client.cpp | 12 ++++++++++++ core/io/stream_peer_ssl.cpp | 1 + core/io/stream_peer_tcp.cpp | 17 +++++++++++++++++ 3 files changed, 30 insertions(+) (limited to 'core') diff --git a/core/io/http_client.cpp b/core/io/http_client.cpp index 80a281a21d..ac563df0c3 100644 --- a/core/io/http_client.cpp +++ b/core/io/http_client.cpp @@ -375,6 +375,18 @@ Error HTTPClient::poll() { } } break; case STATUS_CONNECTED: { + // Check if we are still connected + if (ssl) { + Ref tmp = connection; + tmp->poll(); + if (tmp->get_status() != StreamPeerSSL::STATUS_CONNECTED) { + status = STATUS_CONNECTION_ERROR; + return ERR_CONNECTION_ERROR; + } + } else if (tcp_connection->get_status() != StreamPeerTCP::STATUS_CONNECTED) { + status = STATUS_CONNECTION_ERROR; + return ERR_CONNECTION_ERROR; + } // Connection established, requests can now be made return OK; } break; diff --git a/core/io/stream_peer_ssl.cpp b/core/io/stream_peer_ssl.cpp index 8d8682686a..138f91301e 100644 --- a/core/io/stream_peer_ssl.cpp +++ b/core/io/stream_peer_ssl.cpp @@ -128,6 +128,7 @@ void StreamPeerSSL::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "blocking_handshake"), "set_blocking_handshake_enabled", "is_blocking_handshake_enabled"); BIND_ENUM_CONSTANT(STATUS_DISCONNECTED); + BIND_ENUM_CONSTANT(STATUS_HANDSHAKING); BIND_ENUM_CONSTANT(STATUS_CONNECTED); BIND_ENUM_CONSTANT(STATUS_ERROR); BIND_ENUM_CONSTANT(STATUS_ERROR_HOSTNAME_MISMATCH); diff --git a/core/io/stream_peer_tcp.cpp b/core/io/stream_peer_tcp.cpp index f4bf8a13ae..28561e8cbc 100644 --- a/core/io/stream_peer_tcp.cpp +++ b/core/io/stream_peer_tcp.cpp @@ -249,6 +249,23 @@ StreamPeerTCP::Status StreamPeerTCP::get_status() { if (status == STATUS_CONNECTING) { _poll_connection(); + } else if (status == STATUS_CONNECTED) { + Error err; + err = _sock->poll(NetSocket::POLL_TYPE_IN, 0); + if (err == OK) { + // FIN received + if (_sock->get_available_bytes() == 0) { + disconnect_from_host(); + return status; + } + } + // Also poll write + err = _sock->poll(NetSocket::POLL_TYPE_IN_OUT, 0); + if (err != OK && err != ERR_BUSY) { + // Got an error + disconnect_from_host(); + status = STATUS_ERROR; + } } return status; -- cgit v1.2.3