---------------------
PatchSet 6066 
Date: 2003/12/01 14:23:44
Author: rhorstmann
Branch: icap-2_5
Tag: (none) 
Log:
Added new error template for ICAP. Implemented bypass for
RESPMOD_PRECACHE.

Members: 
	errors/list:1.1.1.1->1.1.1.1.182.1 
	errors/English/ERR_ICAP_FAILURE:1.1->1.1.2.1 
	src/client_side.c:1.47.2.28.2.17->1.47.2.28.2.18 
	src/enums.h:1.29.2.8.2.3->1.29.2.8.2.4 
	src/http.c:1.17.6.3.6.19->1.17.6.3.6.20 
	src/icap_common.c:1.1.2.24->1.1.2.25 
	src/icap_reqmod.c:1.1.2.25->1.1.2.26 
	src/icap_respmod.c:1.1.2.28->1.1.2.29 

Index: squid/errors/list
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/list,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.1.182.1
diff -u -r1.1.1.1 -r1.1.1.1.182.1
--- squid/errors/list	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/errors/list	1 Dec 2003 14:23:44 -0000	1.1.1.1.182.1
@@ -23,3 +23,4 @@
 ERR_URN_RESOLVE
 ERR_WRITE_ERROR
 ERR_ZERO_SIZE_OBJECT
+ERR_ICAP_FAILURE
--- /dev/null	Wed Feb 14 01:07:22 2007
+++ squid/errors/English/ERR_ICAP_FAILURE	Wed Feb 14 01:09:30 2007
@@ -0,0 +1,31 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<HTML><HEAD>
+<TITLE>ERROR: The requested URL could not be retrieved</TITLE>
+<STYLE type="text/css"><!--BODY{background-color:#ffffff; font-family:verdana,sans-serif}--></STYLE>
+</HEAD><BODY>
+<H1>ERROR</H1>
+<H2>The requested URL could not be retrieved</H2>
+<HR noshade size="1px">
+<P>
+While trying to retrieve the URL:
+<A HREF="%U">%U</A>
+<P>
+The following error was encountered:
+<UL>
+<LI>
+<STRONG>
+ICAP protocol error.
+</STRONG>
+</UL>
+
+<P>
+<P>
+Some aspect of the ICAP communication failed. Possible problems:
+<UL>
+<LI>ICAP server is not reachable
+<LI>Illegal response from ICAP server
+</UL>
+</P>
+
+<P>Your cache administrator is <A HREF="mailto:%w">%w</A>. 
+
Index: squid/src/client_side.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/client_side.c,v
retrieving revision 1.47.2.28.2.17
retrieving revision 1.47.2.28.2.18
diff -u -r1.47.2.28.2.17 -r1.47.2.28.2.18
--- squid/src/client_side.c	28 Nov 2003 13:47:16 -0000	1.47.2.28.2.17
+++ squid/src/client_side.c	1 Dec 2003 14:23:44 -0000	1.47.2.28.2.18
@@ -1,6 +1,6 @@
 
 /*
- * $Id: client_side.c,v 1.47.2.28.2.17 2003/11/28 13:47:16 rhorstmann Exp $
+ * $Id: client_side.c,v 1.47.2.28.2.18 2003/12/01 14:23:44 rhorstmann Exp $
  *
  * DEBUG: section 33    Client-side Routines
  * AUTHOR: Duane Wessels
@@ -3861,7 +3861,7 @@
 	http->icap_reqmod = NULL;
 	debug(33, 2) ("clientIcapReqMod: icap told us to send an error\n");
 	http->log_type = LOG_TCP_DENIED;
-	err = errorCon(ERR_READ_ERROR, HTTP_INTERNAL_SERVER_ERROR);
+	err = errorCon(ERR_ICAP_FAILURE, HTTP_INTERNAL_SERVER_ERROR);
 	err->xerrno = ETIMEDOUT;
 	err->request = requestLink(http->request);
 	err->src_addr = http->conn->peer.sin_addr;
Index: squid/src/enums.h
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/enums.h,v
retrieving revision 1.29.2.8.2.3
retrieving revision 1.29.2.8.2.4
diff -u -r1.29.2.8.2.3 -r1.29.2.8.2.4
--- squid/src/enums.h	22 Sep 2003 19:17:16 -0000	1.29.2.8.2.3
+++ squid/src/enums.h	1 Dec 2003 14:23:44 -0000	1.29.2.8.2.4
@@ -1,6 +1,6 @@
 
 /*
- * $Id: enums.h,v 1.29.2.8.2.3 2003/09/22 19:17:16 dwsquid Exp $
+ * $Id: enums.h,v 1.29.2.8.2.4 2003/12/01 14:23:44 rhorstmann Exp $
  *
  *
  * SQUID Web Proxy Cache          http://www.squid-cache.org/
@@ -93,6 +93,7 @@
     ERR_ONLY_IF_CACHED_MISS,	/* failure to satisfy only-if-cached request */
     ERR_TOO_BIG,
     TCP_RESET,
+    ERR_ICAP_FAILURE,
     ERR_MAX
 } err_type;
 
Index: squid/src/http.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/http.c,v
retrieving revision 1.17.6.3.6.19
retrieving revision 1.17.6.3.6.20
diff -u -r1.17.6.3.6.19 -r1.17.6.3.6.20
--- squid/src/http.c	24 Nov 2003 15:51:10 -0000	1.17.6.3.6.19
+++ squid/src/http.c	1 Dec 2003 14:23:44 -0000	1.17.6.3.6.20
@@ -1,6 +1,6 @@
 
 /*
- * $Id: http.c,v 1.17.6.3.6.19 2003/11/24 15:51:10 rhorstmann Exp $
+ * $Id: http.c,v 1.17.6.3.6.20 2003/12/01 14:23:44 rhorstmann Exp $
  *
  * DEBUG: section 11    Hypertext Transfer Protocol (HTTP)
  * AUTHOR: Harvest Derived
@@ -797,7 +797,16 @@
 	    httpState->icap_writer = icapRespModStart(
 		ICAP_SERVICE_RESPMOD_PRECACHE,
 		httpState->orig_request, httpState->entry, httpState->flags);
-	    if (httpState->icap_writer) {
+	    if (-1 == (int) httpState->icap_writer) {
+		/* TODO: send error here and exit */
+		httpState->icap_writer = 0;
+		err = errorCon(ERR_ICAP_FAILURE, HTTP_INTERNAL_SERVER_ERROR);
+		err->xerrno = errno;
+		err->request = requestLink(httpState->orig_request);
+		errorAppendEntry(entry, err);
+		comm_close(fd);
+		return;
+	    } else if (httpState->icap_writer) {
 		request_flags fake_flags = httpState->orig_request->flags;
 		method_t fake_method = entry->mem_obj->method;
 		const char *fake_msg = "this is a fake entry for "
@@ -832,11 +841,9 @@
 		 */
 	    } else {
 		/*
-		 * failed to open connection to ICAP server.  Close
-		 * the HTTP socket and bail.
+		 * failed to open connection to ICAP server. 
+		 * But bypass request, so just continue here.
 		 */
-		comm_close(fd);
-		return;
 	    }
 	}
 #endif
@@ -1160,6 +1167,7 @@
     int fd = fwd->server_fd;
     HttpStateData *httpState;
     request_t *proxy_req;
+    ErrorState *err;
     request_t *orig_req = fwd->request;
     debug(11, 3) ("httpStart: \"%s %s\"\n",
 	RequestMethodStr[orig_req->method],
@@ -1201,8 +1209,9 @@
     if (icapService(ICAP_SERVICE_REQMOD_POSTCACHE, httpState->orig_request)) {
 	httpState->icap_writer = icapRespModStart(ICAP_SERVICE_REQMOD_POSTCACHE,
 	    httpState->orig_request, httpState->entry, httpState->flags);
-	if (httpState->icap_writer)
+	if (httpState->icap_writer) {
 	    return;
+	}
     }
 #endif
     /*
Index: squid/src/icap_common.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/Attic/icap_common.c,v
retrieving revision 1.1.2.24
retrieving revision 1.1.2.25
diff -u -r1.1.2.24 -r1.1.2.25
--- squid/src/icap_common.c	28 Nov 2003 14:34:39 -0000	1.1.2.24
+++ squid/src/icap_common.c	1 Dec 2003 14:23:45 -0000	1.1.2.25
@@ -1,5 +1,5 @@
 /*
- * $Id: icap_common.c,v 1.1.2.24 2003/11/28 14:34:39 rhorstmann Exp $
+ * $Id: icap_common.c,v 1.1.2.25 2003/12/01 14:23:45 rhorstmann Exp $
  *
  * DEBUG: section 81    Internet Content Adaptation Protocol (ICAP) Client
  * AUTHOR: Geetha Manjunath, Hewlett Packard Company
@@ -135,15 +135,23 @@
 icap_service *
 icapService(icap_service_t type, request_t * r)
 {
+    debug(81, 8) ("icapService: type=%s\n", icapServiceToStr(type));
     icap_service_list *isl_iter;
-    if (NULL == r)
+    if (NULL == r) {
+	debug(81, 8) ("icapService: no request_t\n");
 	return NULL;
-    if (NULL == r->class)
+    }
+    if (NULL == r->class) {
+	debug(81, 8) ("icapService: no class\n");
 	return NULL;
+    }
     for (isl_iter = r->class->isl; isl_iter; isl_iter = isl_iter->next) {
-	if (type == isl_iter->service->type)
+	if (type == isl_iter->service->type) {
+	    debug(81, 8) ("icapService: found service %s\n", isl_iter->service->name);
 	    return isl_iter->service;
+	}
     }
+    debug(81, 8) ("icapService: no service found\n");
     return NULL;
 }
 
@@ -262,6 +270,7 @@
     IcapStateData *icap = data;
     debug(17, 2) ("icapConnectTimeout: FD %d\n", fd);
     assert(fd == icap->icap_fd);
+    icapOptSetUnreachable(icap->current_service);
     comm_close(fd);
 }
 
@@ -269,8 +278,9 @@
 icapReadTimeout(int fd, void *data)
 {
     IcapStateData *icap = data;
-    debug(17, 2) ("icapConnectTimeout: FD %d\n", fd);
+    debug(17, 2) ("icapReadTimeout: FD %d\n", fd);
     assert(fd == icap->icap_fd);
+    icapOptSetUnreachable(icap->current_service);
     comm_close(fd);
 }
 
@@ -638,7 +648,7 @@
  *  Builds and adds the X-Authenticated-User header to an ICAP request headers.
  */
 void
-icapAddAuthUserHeader(MemBuf * mb, auth_user_request_t *auth_user_request)
+icapAddAuthUserHeader(MemBuf * mb, auth_user_request_t * auth_user_request)
 {
     char *user = authenticateUserRequestUsername(auth_user_request);
     char *authuser;
@@ -649,21 +659,20 @@
 	debug(81, 5) ("icapAddAuthUserHeader: NULL username\n");
 	return;
     }
-
     userlen = strlen(user);
     schemelen = strlen(Config.icapcfg.auth_scheme);
     len = userlen + schemelen + 1;
     authuser = xcalloc(len, 1);
 
     if ((userofs = strstr(Config.icapcfg.auth_scheme, "%u")) == NULL) {
-        /* simply add user at end of string */
+	/* simply add user at end of string */
 	snprintf(authuser, len, "%s%s", Config.icapcfg.auth_scheme, user);
     } else {
 	userofslen = userofs - Config.icapcfg.auth_scheme;
 	xmemcpy(authuser, Config.icapcfg.auth_scheme, userofslen);
 	xmemcpy(authuser + userofslen, user, userlen);
-	xmemcpy(authuser + userofslen + userlen, 
-		userofs + 2, schemelen - (userofslen + 2) + 1);
+	xmemcpy(authuser + userofslen + userlen,
+	    userofs + 2, schemelen - (userofslen + 2) + 1);
     }
 
     memBufPrintf(mb, "X-Authenticated-User: %s\r\n", base64_encode(authuser));
Index: squid/src/icap_reqmod.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/Attic/icap_reqmod.c,v
retrieving revision 1.1.2.25
retrieving revision 1.1.2.26
diff -u -r1.1.2.25 -r1.1.2.26
--- squid/src/icap_reqmod.c	28 Nov 2003 14:34:39 -0000	1.1.2.25
+++ squid/src/icap_reqmod.c	1 Dec 2003 14:23:45 -0000	1.1.2.26
@@ -1,6 +1,6 @@
 
 /*
- * $Id: icap_reqmod.c,v 1.1.2.25 2003/11/28 14:34:39 rhorstmann Exp $
+ * $Id: icap_reqmod.c,v 1.1.2.26 2003/12/01 14:23:45 rhorstmann Exp $
  *
  * DEBUG: section 81    Internet Content Adaptation Protocol (ICAP) Client
  * AUTHOR: Geetha Manjunath, Hewlett Packard Company
@@ -509,7 +509,7 @@
     if (x < 0) {
 	/* Did not find a proper ICAP response */
 	debug(81, 3) ("ICAP : Error path!\n");
-	icapEntryError(icap, ERR_READ_ERROR, HTTP_INTERNAL_SERVER_ERROR, errno);
+	icapEntryError(icap, ERR_ICAP_FAILURE, HTTP_INTERNAL_SERVER_ERROR, errno);
 	comm_close(fd);
 	return;
     }
@@ -534,7 +534,7 @@
 	|| ver <= 0.0) {
 	debug(81, 1) ("BAD ICAP status line <%s>\n", icap->icap_hdr.buf);
 	/* is this correct in case of ICAP protocol error? */
-	icapEntryError(icap, ERR_READ_ERROR, HTTP_INTERNAL_SERVER_ERROR, errno);
+	icapEntryError(icap, ERR_ICAP_FAILURE, HTTP_INTERNAL_SERVER_ERROR, errno);
 	comm_close(fd);
 	return;
     };
@@ -590,7 +590,7 @@
     if (errflag) {
 	debug(81, 3) ("icapSendReqModDone: unreachable=1, service=%s\n", icap->current_service->uri);
 	icapOptSetUnreachable(icap->current_service);
-	icapEntryError(icap, ERR_WRITE_ERROR, HTTP_INTERNAL_SERVER_ERROR, errno);
+	icapEntryError(icap, ERR_ICAP_FAILURE, HTTP_INTERNAL_SERVER_ERROR, errno);
 	comm_close(fd);
 	return;
     }
@@ -636,7 +636,7 @@
 	    xstrerror());
 	debug(81, 3) ("icapSendReqMod: unreachable=1, service=%s\n", icap->current_service->uri);
 	icapOptSetUnreachable(icap->current_service);
-	icapEntryError(icap, ERR_CONNECT_FAIL, HTTP_SERVICE_UNAVAILABLE, errno);
+	icapEntryError(icap, ERR_ICAP_FAILURE, HTTP_SERVICE_UNAVAILABLE, errno);
 	comm_close(fd);
 	return;
     }
@@ -671,7 +671,7 @@
     if (Config.icapcfg.send_client_ip)
 	memBufPrintf(&mb, "X-Client-IP: %s\r\n", client_addr);
     if (Config.icapcfg.send_auth_user && icap->request->auth_user_request != NULL)
-        icapAddAuthUserHeader(&mb, icap->request->auth_user_request);
+	icapAddAuthUserHeader(&mb, icap->request->auth_user_request);
     icap->flags.keep_alive = 1;
     if (!icap->flags.keep_alive)
 	memBufAppend(&mb, "Connection: close\r\n", 19);
@@ -719,7 +719,7 @@
 	    return NULL;
 	} else {
 	    debug(81, 5) ("icapReqModStart: ERROR  because service unreachable: %s\n", service->uri);
-	    return -1;
+	    return (IcapStateData *) - 1;
 	}
     }
     icap = icapAllocate();
@@ -761,7 +761,7 @@
     if (errflag == COMM_ERR_CLOSING)
 	return;
     if (errflag) {
-	icapEntryError(icap, ERR_WRITE_ERROR, HTTP_INTERNAL_SERVER_ERROR, errno);
+	icapEntryError(icap, ERR_ICAP_FAILURE, HTTP_INTERNAL_SERVER_ERROR, errno);
 	comm_close(fd);
 	return;
     }
Index: squid/src/icap_respmod.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/Attic/icap_respmod.c,v
retrieving revision 1.1.2.28
retrieving revision 1.1.2.29
diff -u -r1.1.2.28 -r1.1.2.29
--- squid/src/icap_respmod.c	28 Nov 2003 14:34:39 -0000	1.1.2.28
+++ squid/src/icap_respmod.c	1 Dec 2003 14:23:45 -0000	1.1.2.29
@@ -1,6 +1,6 @@
 
 /*
- * $Id: icap_respmod.c,v 1.1.2.28 2003/11/28 14:34:39 rhorstmann Exp $
+ * $Id: icap_respmod.c,v 1.1.2.29 2003/12/01 14:23:45 rhorstmann Exp $
  *
  * DEBUG: section 81    Internet Content Adaptation Protocol (ICAP) Client
  * AUTHOR: Geetha Manjunath, Hewlett Packard Company
@@ -47,7 +47,7 @@
 
 void
 getICAPRespModString(MemBuf * mb, int o1, int o2, int o3, char *service, char *client_addr,
-		     IcapStateData * icap)
+    IcapStateData * icap)
 {
     memBufPrintf(mb, "RESPMOD %s ICAP/1.0\r\nEncapsulated:", service);
     if (o1 >= 0)
@@ -353,7 +353,7 @@
     if (x < 0) {
 	/* Did not find a proper ICAP response */
 	debug(81, 3) ("ICAP : Error path!\n");
-	err = errorCon(ERR_READ_ERROR, HTTP_INTERNAL_SERVER_ERROR);
+	err = errorCon(ERR_ICAP_FAILURE, HTTP_INTERNAL_SERVER_ERROR);
 	err->request = requestLink(icap->request);
 	err->xerrno = errno;
 	errorAppendEntry(icap->respmod.entry, err);
@@ -380,7 +380,7 @@
     if (sscanf(icap->icap_hdr.buf, "ICAP/%f %d %s\r", &ver, &status, tmpbuf) < 3 || ver <= 0.0) {
 	debug(81, 1) ("BAD ICAP status line <%s>\n", icap->icap_hdr.buf);
 	/* is this correct in case of ICAP protocol error? */
-	err = errorCon(ERR_READ_ERROR, HTTP_INTERNAL_SERVER_ERROR);
+	err = errorCon(ERR_ICAP_FAILURE, HTTP_INTERNAL_SERVER_ERROR);
 	err->request = requestLink(icap->request);
 	err->xerrno = errno;
 	errorAppendEntry(icap->respmod.entry, err);
@@ -445,7 +445,7 @@
     if (200 != status) {
 	debug(81, 1) ("Unsupported status '%d' from ICAP server\n", status);
 	/* Did not find a proper ICAP response */
-	err = errorCon(ERR_READ_ERROR, HTTP_INTERNAL_SERVER_ERROR);
+	err = errorCon(ERR_ICAP_FAILURE, HTTP_INTERNAL_SERVER_ERROR);
 	err->request = requestLink(icap->request);
 	err->xerrno = errno;
 	errorAppendEntry(icap->respmod.entry, err);
@@ -471,7 +471,7 @@
     if (!directResponse) {
 	/* Did not find a proper ICAP response */
 	debug(81, 3) ("ICAP : Error path!\n");
-	err = errorCon(ERR_READ_ERROR, HTTP_INTERNAL_SERVER_ERROR);
+	err = errorCon(ERR_ICAP_FAILURE, HTTP_INTERNAL_SERVER_ERROR);
 	err->request = requestLink(icap->request);
 	err->xerrno = errno;
 	errorAppendEntry(icap->respmod.entry, err);
@@ -530,7 +530,7 @@
     if (errflag == COMM_ERR_CLOSING)
 	return;
     if (errflag) {
-	err = errorCon(ERR_WRITE_ERROR, HTTP_INTERNAL_SERVER_ERROR);
+	err = errorCon(ERR_ICAP_FAILURE, HTTP_INTERNAL_SERVER_ERROR);
 	err->xerrno = errno;
 	if (cbdataValid(icap))
 	    err->request = requestLink(icap->request);
@@ -578,11 +578,12 @@
     debug(81, 3) ("icapConnectOver: FD %d, status=%d\n", fd, status);
     icap->flags.connect_pending = 0;
     if (status < 0) {
-	err = errorCon(ERR_WRITE_ERROR, HTTP_INTERNAL_SERVER_ERROR);
+	err = errorCon(ERR_ICAP_FAILURE, HTTP_INTERNAL_SERVER_ERROR);
 	err->xerrno = errno;
 	err->request = requestLink(icap->request);
 	errorAppendEntry(icap->respmod.entry, err);
 	comm_close(fd);
+	icapOptSetUnreachable(icap->current_service);
 	return;
     }
     commSetSelect(fd, COMM_SELECT_READ, icapRespModReadReply, icap, 0);
@@ -605,6 +606,15 @@
 	debug(81, 3) ("icapRespModStart: no service found\n");
 	return NULL;		/* no service found */
     }
+    if (service->unreachable) {
+	if (service->bypass) {
+	    debug(81, 5) ("icapRespModStart: BYPASS because service unreachable: %s\n", service->uri);
+	    return NULL;
+	} else {
+	    debug(81, 5) ("icapRespModStart: ERROR  because service unreachable: %s\n", service->uri);
+	    return (IcapStateData *) - 1;
+	}
+    }
     switch (type) {
     case ICAP_SERVICE_RESPMOD_PRECACHE:
 	theCallback = icapConnectOver;
@@ -762,7 +772,7 @@
 	} else if (entry->mem_obj->inmem_hi == 0) {
 	    ErrorState *err;
 	    debug(81, 2) ("icapReadReply: FD %d: generating error page\n", fd);
-	    err = errorCon(ERR_READ_ERROR, HTTP_INTERNAL_SERVER_ERROR);
+	    err = errorCon(ERR_ICAP_FAILURE, HTTP_INTERNAL_SERVER_ERROR);
 	    err->request = requestLink((request_t *) request);
 	    err->xerrno = errno;
 	    errorAppendEntry(entry, err);
