소스 검색

Webserver drops websocket connections too early

Fix for #148
bel 10 년 전
부모
커밋
9e7cb0f686
1개의 변경된 파일29개의 추가작업 그리고 3개의 파일을 삭제
  1. 29 3
      src/civetweb.c

+ 29 - 3
src/civetweb.c

@@ -2973,7 +2973,8 @@ static int push(struct mg_context *ctx,
 		}
 		if (n < 0) {
 			/* socket error - check errno */
-			DEBUG_TRACE("send() failed, error %d", ERRNO);
+			int err = ERRNO;
+			DEBUG_TRACE("send() failed, error %d", err);
 			return -1;
 		}
 		if (timeout > 0) {
@@ -3066,8 +3067,33 @@ pull(FILE *fp, struct mg_connection *conn, char *buf, int len, double timeout)
 		}
 		if (nread < 0) {
 			/* socket error - check errno */
-			DEBUG_TRACE("recv() failed, error %d", ERRNO);
-			return -1;
+			int err = ERRNO;
+#ifdef _WIN32
+			if (err == WSAEWOULDBLOCK) {
+				/* standard case if called from close_socket_gracefully */
+				return -1;
+			} else if (err == WSAETIMEDOUT) {
+				/* timeout is handled by the while loop  */
+			} else {
+				DEBUG_TRACE("recv() failed, error %d", err);
+				return -1;
+			}
+#else
+			/* TODO: POSIX returns either EAGAIN or EWOULDBLOCK in both cases,
+			 * if the timeout is reached and if the socket was set to non-
+			 * blocking in close_socket_gracefully, so we can not distinguish
+			 * here. We have to wait for the timeout in both cases for now.
+			 */
+			if (err == EAGAIN || err == EWOULDBLOCK) {
+				/* standard case if called from close_socket_gracefully
+				 * => should return -1 */
+				/* or timeout occured
+				 * => the code must stay in the while loop */
+			} else {
+				DEBUG_TRACE("recv() failed, error %d", err);
+				return -1;
+			}
+#endif
 		}
 		if (timeout > 0) {
 			clock_gettime(CLOCK_MONOTONIC, &now);