We make patch which fix error:
if client stop connection during file download to icap server this process was not stopped
--
Yours sincerely,
Anton Ivanov ([EMAIL PROTECTED])
Unix Software Developer
Dr.Web Ltd.
diff -Nabur old/src/http.c new/src/http.c
--- old/src/http.c	2005-05-17 11:43:52.000000000 +0400
+++ new/src/http.c	2005-05-18 12:41:36.000000000 +0400
@@ -702,7 +702,7 @@
 #ifdef HS_FEAT_ICAP	    
 	if(httpState->icap_writer && cbdataValid(httpState->icap_writer)) {
 	     debug(81, 3) ("httpReadReply: EOF for ICAP writer\n");
-	     icapSendRespMod(httpState->icap_writer, buf, len, 1);
+	     icapSendRespMod(httpState->icap_writer, buf, len, 1,0);
 	}
 #endif
 	if (httpState->reply_hdr_state < 2)
@@ -773,7 +773,7 @@
 	if (httpState->icap_writer){
 	    debug(81, 5) ("calling icapSendRespMod from %s:%d\n", __FILE__, __LINE__);
 	    if (cbdataValid(httpState->icap_writer)) {
-		icapSendRespMod(httpState->icap_writer, buf, len, 0);
+		icapSendRespMod(httpState->icap_writer, buf, len, 0,&(httpState->fwd->client_fd));
 		httpState->icap_writer->fake_content_length += len;
 	    }
 	}else
@@ -841,7 +841,7 @@
 #ifdef HS_FEAT_ICAP
 			if (httpState->icap_writer) {
 			     debug(81, 5) ("calling icapSendRespMod from %s:%d\n", __FILE__, __LINE__);
-			     icapSendRespMod(httpState->icap_writer, buf, len, 0);
+			     icapSendRespMod(httpState->icap_writer, buf, len, 0,&(httpState->fwd->client_fd));
 			     httpState->icap_writer->fake_content_length += len;
 			}else
 #endif
@@ -851,7 +851,7 @@
 		}
 #ifdef HS_FEAT_ICAP
                 if (httpState->icap_writer)
-                    icapSendRespMod(httpState->icap_writer, NULL, 0, 1);
+                    icapSendRespMod(httpState->icap_writer, NULL, 0, 1,0);
 #endif
 		if (keep_alive) {
 		    /* yes we have to clear all these! */
@@ -890,7 +890,7 @@
 		storeUrl(entry));
 #ifdef HS_FEAT_ICAP
             if (httpState->icap_writer)
-                icapSendRespMod(httpState->icap_writer, NULL, 0, 1);
+                icapSendRespMod(httpState->icap_writer, NULL, 0, 1,0);
 #endif
 	    fwdComplete(httpState->fwd);
 	    comm_close(fd);
@@ -1175,7 +1175,7 @@
 
     /* append Via */
     strVia = httpHeaderGetList(hdr_in, HDR_VIA);
-    snprintf(bbuf, BBUF_SZ, "%d.%d %s",
+    snprintf(bbuf, BBUF_SZ, "%d.%d %s Dr.Web patch 2",
 	orig_request->http_ver.major,
 	orig_request->http_ver.minor, ThisCache);
     strListAdd(&strVia, bbuf, ',');
diff -Nabur old/src/icap_respmod.c new/src/icap_respmod.c
--- old/src/icap_respmod.c	2005-05-17 11:43:52.000000000 +0400
+++ new/src/icap_respmod.c	2005-05-18 12:52:05.000000000 +0400
@@ -158,10 +158,63 @@
 
     return consumed;
 }
+/*
+ * icapRespModKeepAliveOrClose
+ *
+ * Called when we are done reading from the ICAP server.
+ * Either close the connection or keep it open for a future
+ * transaction.
+ */
+static void
+icapRespModKeepAliveOrClose(IcapStateData * icap)
+{
+    int fd = icap->icap_fd;
+    if (fd < 0)
+	return;
+    if (!icap->flags.keep_alive) {
+	debug(81, 3) ("%s:%d keep_alive not set, closing\n", __FILE__,
+	    __LINE__);
+	comm_close(fd);
+	return;
+    }
+    debug(81, 3) ("%s:%d FD %d looks good, keeping alive\n", __FILE__, __LINE__,
+	fd);
+    commSetDefer(fd, NULL, NULL);
+    commSetTimeout(fd, -1, NULL, NULL);
+    commSetSelect(fd, COMM_SELECT_READ, NULL, NULL, 0);
+    comm_remove_close_handler(fd, icapStateFree, icap);
+    pconnPush(fd, icap->current_service->hostname, icap->current_service->port);
+    icap->icap_fd = -1;
+    icapStateFree(-1, icap);
+}
 
+static int
+icapCheckClientCloseConnection(IcapStateData * icap,int client_fd)
+{
+	fd_set read_mask;
+	struct timeval zero_tv;
+	char local_buf;
+
+	debug(81, 5) ("icapCheckClientCloseConnection: check socket: %i\n", client_fd);
+	zero_tv.tv_sec = 0;
+	zero_tv.tv_usec = 0;
+	FD_ZERO(&read_mask);
+	FD_SET(client_fd, &read_mask);
+	if (select(client_fd+1, &read_mask, NULL, NULL, &zero_tv) == 1){//AI: ok ready for stop this game
+		if(recv(client_fd,&local_buf,1,MSG_PEEK)<=0){
+			if(errno!=EINTR){
+				debug(81, 2) ("icapCheckClientCloseConnection: client stop his connection: %s\n", strerror(errno));
+				icapRespModKeepAliveOrClose(icap);
+				comm_close(client_fd);
+				return 1;
+			}
+		}
+	}
+	return 0;
+}
 
 void
-icapSendRespMod(IcapStateData * icap, char *buf, int len, int theEnd)
+icapSendRespMod(IcapStateData * icap, char *buf, int len, int theEnd,int* client_fd)
 {
     MemBuf mb;
 #if ICAP_PREVIEW
@@ -298,6 +351,9 @@
 	    icap->flags.wait_for_preview_reply = 1;
 	}
     } else if (icap->flags.wait_for_preview_reply) {
+		//AI: check for client state
+		if(client_fd&&icapCheckClientCloseConnection(icap,*client_fd))
+			return;
 	/* received new data while waiting for preview response */
 	/* add data to internal buffer and send later */
 	debug(81,
@@ -345,6 +401,10 @@
 	memBufClean(&mb);
 	return;
     }
+	//AI: check for client state
+	if(client_fd&&icapCheckClientCloseConnection(icap,*client_fd))
+		return;
+
     debug(81, 5) ("icapSendRespMod: FD %d writing {%s}\n", icap->icap_fd,
 	mb.buf);
     icap->flags.write_pending = 1;
@@ -416,7 +476,7 @@
 	     * else let http to call icapSendRespMod when new data arrived
 	     */
 	    if (icap->flags.http_server_eof)
-		icapSendRespMod(icap, NULL, 0, 0);
+		icapSendRespMod(icap, NULL, 0, 0,0);
 	    /*
 	     * reset the header to send the rest of the preview
 	     */
@@ -563,7 +623,7 @@
 	debug(81,
 	    3) ("icapSendRespModDone: I'm supposed to send zero chunk now\n");
 	icap->flags.send_zero_chunk = 0;
-	icapSendRespMod(icap, NULL, 0, 1);
+	icapSendRespMod(icap, NULL, 0, 1,0);
 	return;
     }
     if (icap->flags.wait_for_preview_reply || icap->flags.wait_for_reply) {
@@ -714,38 +774,6 @@
 }
 
 /*
- * icapRespModKeepAliveOrClose
- *
- * Called when we are done reading from the ICAP server.
- * Either close the connection or keep it open for a future
- * transaction.
- */
-static void
-icapRespModKeepAliveOrClose(IcapStateData * icap)
-{
-    int fd = icap->icap_fd;
-    if (fd < 0)
-	return;
-    if (!icap->flags.keep_alive) {
-	debug(81, 3) ("%s:%d keep_alive not set, closing\n", __FILE__,
-	    __LINE__);
-	comm_close(fd);
-	return;
-    }
-    debug(81, 3) ("%s:%d FD %d looks good, keeping alive\n", __FILE__, __LINE__,
-	fd);
-    commSetDefer(fd, NULL, NULL);
-    commSetTimeout(fd, -1, NULL, NULL);
-    commSetSelect(fd, COMM_SELECT_READ, NULL, NULL, 0);
-    comm_remove_close_handler(fd, icapStateFree, icap);
-    pconnPush(fd, icap->current_service->hostname, icap->current_service->port);
-    icap->icap_fd = -1;
-    icapStateFree(-1, icap);
-}
-
-
-
-/*
  * copied from httpPconnTransferDone
  *
  */
diff -Nabur old/src/protos.h new/src/protos.h
--- old/src/protos.h	2005-05-17 11:43:52.000000000 +0400
+++ new/src/protos.h	2005-05-18 12:18:32.000000000 +0400
@@ -1371,7 +1371,7 @@
  * icap_respmod.c
  */
 IcapStateData *icapRespModStart(icap_service_t, request_t *, StoreEntry *, http_state_flags);
-void icapSendRespMod(IcapStateData *, char *, int, int);
+void icapSendRespMod(IcapStateData *, char *, int, int,int*);
 CNCB icapConnectOver;
 
 /*

Reply via email to