From 7652cf4068f77905a56b9165455ec7e90917ec31 Mon Sep 17 00:00:00 2001
From: Azat Khuzhin <azat@libevent.org>
Date: Sun, 14 May 2023 16:53:13 +0200
Subject: [PATCH] ssl: do not triger EOF if some data had been successfully 
read

Reference:https://github.com/libevent/libevent/commit/ef51444f439b922c8fb00c7ef3f8482b6400b6ea
https://github.com/libevent/libevent/commit/49a7ae4c5668ebad7b6c4618664224c1a0bc5079
https://github.com/libevent/libevent/commit/7652cf4068f77905a56b9165455ec7e90917ec31

Previously in case when evbuffer_reserve_space() returns > 1, but
it was able to read only 1 IO vector, it will try to read the next one,
got 0 (EOF for mbedTLS or SSL_ERROR_ZERO_RETURN for OpenSSL) and will
trigger EOF, while instead, it should trigger EV_READ w/o EOF and only
after EOF.
---
 bufferevent_openssl.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/bufferevent_openssl.c b/bufferevent_openssl.c
index b51b834..8b4b655 100644
--- a/bufferevent_openssl.c
+++ b/bufferevent_openssl.c
@@ -616,6 +616,17 @@ do_read(struct bufferevent_openssl *bev_ssl, int n_to_read) {
 		} else {
 			int err = SSL_get_error(bev_ssl->ssl, r);
 			print_err(err);
+			/* NOTE: we ignore the error in case of some progress was done,
+			 * because currently we do not send close_notify, and this will
+			 * lead to error from SSL_read() (it will return 0, and
+			 * SSL_get_error() will return SSL_ERROR_SSL), and this is because
+			 * of lack of close_notify
+			 *
+			 * But AFAICS some code uses it the same way (i.e. nginx) */
+			if (result & OP_MADE_PROGRESS) {
+				/* Process existing data */
+				break;
+			}
 			switch (err) {
 			case SSL_ERROR_WANT_READ:
 				/* Can't read until underlying has more data. */
-- 
2.27.0

