Browse Source

Repeat OpenSSL Read/Write calls if the result is error 2/3 (possible fix for #320)

bel 9 years ago
parent
commit
0c054e78ed
1 changed files with 15 additions and 8 deletions
  1. 15 8
      src/civetweb.c

+ 15 - 8
src/civetweb.c

@@ -3905,6 +3905,9 @@ push(struct mg_context *ctx,
 				err = SSL_get_error(ssl, n);
 				if ((err == 5 /* SSL_ERROR_SYSCALL */) && (n == -1)) {
 					err = ERRNO;
+				} else if ((err == 2 /* SSL_ERROR_WANT_READ */)
+				           || (err == 3 /* SSL_ERROR_WANT_READ */)) {
+					n = 0;
 				} else {
 					DEBUG_TRACE("SSL_write() failed, error %d", err);
 					return -1;
@@ -3925,6 +3928,10 @@ push(struct mg_context *ctx,
 		} else {
 			n = (int)send(sock, buf, (len_t)len, MSG_NOSIGNAL);
 			err = (n < 0) ? ERRNO : 0;
+			if (n == 0) {
+				/* shutdown of the socket at client side */
+				return -1;
+			}
 		}
 
 		if (ctx->stop_flag) {
@@ -3935,10 +3942,6 @@ push(struct mg_context *ctx,
 			/* some data has been read, or no data was requested */
 			return n;
 		}
-		if (n == 0) {
-			/* shutdown of the socket at client side */
-			return -1;
-		}
 		if (n < 0) {
 			/* socket error - check errno */
 			DEBUG_TRACE("send() failed, error %d", err);
@@ -4044,6 +4047,9 @@ pull(FILE *fp, struct mg_connection *conn, char *buf, int len, double timeout)
 				err = SSL_get_error(conn->ssl, nread);
 				if ((err == 5 /* SSL_ERROR_SYSCALL */) && (nread == -1)) {
 					err = ERRNO;
+				} else if ((err == 2 /* SSL_ERROR_WANT_READ */)
+				           || (err == 3 /* SSL_ERROR_WANT_READ */)) {
+					nread = 0;
 				} else {
 					DEBUG_TRACE("SSL_read() failed, error %d", err);
 					return -1;
@@ -4056,6 +4062,10 @@ pull(FILE *fp, struct mg_connection *conn, char *buf, int len, double timeout)
 		} else {
 			nread = (int)recv(conn->client.sock, buf, (len_t)len, 0);
 			err = (nread < 0) ? ERRNO : 0;
+			if (nread == 0) {
+				/* shutdown of the socket at client side */
+				return -1;
+			}
 		}
 
 		if (conn->ctx->stop_flag) {
@@ -4066,10 +4076,7 @@ pull(FILE *fp, struct mg_connection *conn, char *buf, int len, double timeout)
 			/* some data has been read, or no data was requested */
 			return nread;
 		}
-		if (nread == 0) {
-			/* shutdown of the socket at client side */
-			return -1;
-		}
+
 		if (nread < 0) {
 /* socket error - check errno */
 #ifdef _WIN32