| 
					
				 | 
			
			
				@@ -2296,12 +2296,12 @@ open_file_in_memory(const struct mg_connection *conn, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	return (buf != NULL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    (void)conn; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    (void)path; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    (void)filep; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    (void)mode; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	(void)conn; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	(void)path; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	(void)filep; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	(void)mode; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -4829,9 +4829,17 @@ push_all(struct mg_context *ctx, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 /* Read from IO channel - opened file descriptor, socket, or SSL descriptor. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- * Return negative value on error, or number of bytes read on success. */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * Return value: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ *  >=0 .. number of bytes successfully read 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ *   -1 .. timeout 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ *   -2 .. error 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 static int 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-pull(FILE *fp, struct mg_connection *conn, char *buf, int len, double timeout) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+pull_inner(FILE *fp, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+           struct mg_connection *conn, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+           char *buf, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+           int len, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+           double timeout) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	int nread, err = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -4841,6 +4849,11 @@ pull(FILE *fp, struct mg_connection *conn, char *buf, int len, double timeout) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	typedef size_t len_t; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	/* We need an additional wait loop around this, because in some cases 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	 * with TLSwe may get data from the socket but not from SSL_read. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	 * In this case we need to repeat at least once. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	if (fp != NULL) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #if !defined(_WIN32_WCE) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		/* Use read() instead of fread(), because if we're reading from the 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -4865,7 +4878,7 @@ pull(FILE *fp, struct mg_connection *conn, char *buf, int len, double timeout) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		pollres = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		    mg_poll(pfd, 1, (int)(timeout * 1000.0), &(conn->ctx->stop_flag)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		if (conn->ctx->stop_flag) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			return -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			return -2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		if (pollres > 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			nread = SSL_read(conn->ssl, buf, len); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -4878,7 +4891,7 @@ pull(FILE *fp, struct mg_connection *conn, char *buf, int len, double timeout) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 					nread = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				} else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 					DEBUG_TRACE("SSL_read() failed, error %d", err); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					return -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					return -2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			} else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				err = 0; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -4886,7 +4899,7 @@ pull(FILE *fp, struct mg_connection *conn, char *buf, int len, double timeout) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		} else if (pollres < 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			/* Error */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			return -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			return -2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		} else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			/* pollres = 0 means timeout */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			nread = 0; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -4903,18 +4916,18 @@ pull(FILE *fp, struct mg_connection *conn, char *buf, int len, double timeout) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		pollres = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		    mg_poll(pfd, 1, (int)(timeout * 1000.0), &(conn->ctx->stop_flag)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		if (conn->ctx->stop_flag) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			return -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			return -2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		if (pollres > 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			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; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				return -2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		} else if (pollres < 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			/* error callint poll */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			return -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			return -2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		} else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			/* pollres = 0 means timeout */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			nread = 0; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -4922,7 +4935,7 @@ pull(FILE *fp, struct mg_connection *conn, char *buf, int len, double timeout) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	if (conn->ctx->stop_flag) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		return -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		return -2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	if ((nread > 0) || (nread == 0 && len == 0)) { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -4936,17 +4949,17 @@ pull(FILE *fp, struct mg_connection *conn, char *buf, int len, double timeout) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		if (err == WSAEWOULDBLOCK) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			/* TODO (low): check if this is still required */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			/* standard case if called from close_socket_gracefully */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			return -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			return -2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		} else if (err == WSAETIMEDOUT) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			/* TODO (low): check if this is still required */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			/* timeout is handled by the while loop  */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		} else if (err == WSAECONNABORTED) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			/* See https://www.chilkatsoft.com/p/p_299.asp */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			return -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			return -2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		} else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			DEBUG_TRACE("recv() failed, error %d", err); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			return -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			return -2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		/* TODO: POSIX returns either EAGAIN or EWOULDBLOCK in both cases, 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -4968,7 +4981,7 @@ pull(FILE *fp, struct mg_connection *conn, char *buf, int len, double timeout) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			 * => stay in the while loop */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		} else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			DEBUG_TRACE("recv() failed, error %d", err); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			return -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			return -2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -4983,16 +4996,30 @@ pull_all(FILE *fp, struct mg_connection *conn, char *buf, int len) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	int n, nread = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	double timeout = -1.0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	double dt; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	struct timespec start_time, now; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	if (conn->ctx->config[REQUEST_TIMEOUT]) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		timeout = atoi(conn->ctx->config[REQUEST_TIMEOUT]) / 1000.0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		clock_gettime(CLOCK_MONOTONIC, &start_time); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	while (len > 0 && conn->ctx->stop_flag == 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		n = pull(fp, conn, buf + nread, len, timeout); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		if (n < 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		n = pull_inner(fp, conn, buf + nread, len, timeout); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if (n == -2) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			if (nread == 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				nread = n; /* Propagate the error */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				nread = -1; /* Propagate the error */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} else if (n == -1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			/* timeout */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			if (timeout > 0.0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				clock_gettime(CLOCK_MONOTONIC, &now); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				dt = (now.tv_sec - start_time.tv_sec) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				     + 1.0E-9 * (now.tv_nsec - start_time.tv_nsec); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				if (dt < timeout) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					continue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		} else if (n == 0) { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -8135,13 +8162,18 @@ read_request(FILE *fp, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			return -2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		n = pull(fp, conn, buf + *nread, bufsiz - *nread, request_timeout); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		if (n < 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		n = pull_inner( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		    fp, conn, buf + *nread, bufsiz - *nread, request_timeout); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if (n == -2) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			/* Receive error */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			return -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		*nread += n; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		request_len = get_request_len(buf, *nread); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if (n > 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			*nread += n; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			request_len = get_request_len(buf, *nread); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			request_len = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		if ((request_len == 0) && (request_timeout >= 0)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			if (mg_difftimespec(&last_action_time, &(conn->req_time)) 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -8302,11 +8334,16 @@ forward_body_data(struct mg_connection *conn, FILE *fp, SOCKET sock, SSL *ssl) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			if ((int64_t)to_read > conn->content_len - conn->consumed_content) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				to_read = (int)(conn->content_len - conn->consumed_content); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			nread = pull(NULL, conn, buf, to_read, timeout); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			if (nread <= 0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			    || push_all(conn->ctx, fp, sock, ssl, buf, nread) != nread) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			nread = pull_inner(NULL, conn, buf, to_read, timeout); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			if (nread == -2) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				/* error */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			if (nread > 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				if (push_all(conn->ctx, fp, sock, ssl, buf, nread) != nread) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			conn->consumed_content += nread; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -9752,16 +9789,20 @@ read_websocket(struct mg_connection *conn, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				memcpy(data, buf + header_len, len); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				error = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				while (len < data_len) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					n = pull(NULL, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					         conn, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					         (char *)(data + len), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					         (int)(data_len - len), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					         timeout); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					if (n <= 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					n = pull_inner(NULL, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					               conn, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					               (char *)(data + len), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					               (int)(data_len - len), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					               timeout); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					if (n <= -2) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 						error = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 						break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					} else if (n > 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						len += (size_t)n; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					} else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						/* Timeout: should retry */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						/* TODO: retry condition */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 					} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					len += (size_t)n; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				if (error) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 					mg_cry(conn, "Websocket pull failed; closing connection"); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -9816,15 +9857,21 @@ read_websocket(struct mg_connection *conn, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		} else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			/* Read from the socket into the next available location in the 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			 * message queue. */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			if ((n = pull(NULL, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			              conn, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			              conn->buf + conn->data_len, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			              conn->buf_size - conn->data_len, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			              timeout)) <= 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			n = pull_inner(NULL, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			               conn, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			               conn->buf + conn->data_len, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			               conn->buf_size - conn->data_len, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			               timeout); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			if (n <= -2) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				/* Error, no bytes read */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			conn->data_len += n; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			if (n > 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				conn->data_len += n; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			} else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				/* Timeout: should retry */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				/* TODO: get timeout def */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -12742,7 +12789,7 @@ close_socket_gracefully(struct mg_connection *conn) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	 * when server decides to close the connection; then when client 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	 * does recv() it gets no data back. */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	do { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		n = pull(NULL, conn, buf, sizeof(buf), /* Timeout in s: */ 1.0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		n = pull_inner(NULL, conn, buf, sizeof(buf), /* Timeout in s: */ 1.0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} while (n > 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 |