From: Alex Rousskov Date: Tue, 7 Dec 2010 19:32:43 +0000 (-0700) Subject: Tolerate adapted body delivery failures in REQMOD request satisfaction mode. X-Git-Tag: take1~15 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=eae3a9a618a865cf4226a1d5da468e860ed3dffc;p=thirdparty%2Fsquid.git Tolerate adapted body delivery failures in REQMOD request satisfaction mode. Without these changes, Squid may assert if an ICAP or eCAP service fails while delivering response body in REQMOD: assertion failed: client_side.cc:1438: "rep" Other assertions may be possible as well, because we were trying to serve a freshly built, HttpReply-free error response while already writing the REQMOD "request satisfaction" response. The assertion probably depends on that writing stage (wrote nothing yet, wrote headers, wrote some body, etc). Polished ERR_DETAIL constants to distinguish the special "request satisfaction" case and to remove ICAP-specific labels from general adaptation code. --- diff --git a/src/client_side_request.cc b/src/client_side_request.cc index 161819cf1c..76e3d3aadc 100644 --- a/src/client_side_request.cc +++ b/src/client_side_request.cc @@ -1462,7 +1462,7 @@ ClientHttpRequest::noteAdaptationQueryAbort(bool final) { clearAdaptation(virginHeadSource); assert(!adaptedBodySource); - handleAdaptationFailure(ERR_DETAIL_ICAP_REQMOD_ABORT, !final); + handleAdaptationFailure(ERR_DETAIL_CLT_REQMOD_ABORT, !final); } void @@ -1515,7 +1515,16 @@ ClientHttpRequest::noteBodyProducerAborted(BodyPipe::Pointer) { assert(!virginHeadSource); stopConsumingFrom(adaptedBodySource); - handleAdaptationFailure(ERR_DETAIL_ICAP_RESPMOD_CLT_SIDE_BODY); + + debugs(85,3, HERE << "REQMOD body production failed"); + if (request_satisfaction_mode) { // too late to recover or serve an error + request->detailError(ERR_ICAP_FAILURE, ERR_DETAIL_CLT_REQMOD_RESP_BODY); + const int fd = getConn()->fd; + Must(fd >= 0); + comm_close(fd); // drastic, but we may be writing a response already + } else { + handleAdaptationFailure(ERR_DETAIL_CLT_REQMOD_REQ_BODY); + } } void diff --git a/src/err_detail_type.h b/src/err_detail_type.h index e683215c84..3246a2fb5d 100644 --- a/src/err_detail_type.h +++ b/src/err_detail_type.h @@ -4,8 +4,9 @@ typedef enum { ERR_DETAIL_NONE, ERR_DETAIL_START = 100000, // to avoid clashes with most OS error numbers - ERR_DETAIL_ICAP_REQMOD_ABORT = ERR_DETAIL_START, // transaction abort - ERR_DETAIL_ICAP_RESPMOD_CLT_SIDE_BODY, // client-side detected body abort + ERR_DETAIL_CLT_REQMOD_ABORT = ERR_DETAIL_START, // client-side detected transaction abort + ERR_DETAIL_CLT_REQMOD_REQ_BODY, // client-side detected REQMOD request body adaptation failure + ERR_DETAIL_CLT_REQMOD_RESP_BODY, // client-side detected REQMOD satisfaction reply body failure ERR_DETAIL_ICAP_RESPMOD_EARLY, // RESPMOD failed w/o store entry ERR_DETAIL_ICAP_RESPMOD_LATE, // RESPMOD failed with a store entry ERR_DETAIL_ICAP_XACT_START, // transaction start failure