]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Tolerate adapted body delivery failures in REQMOD request satisfaction mode.
authorAlex Rousskov <rousskov@measurement-factory.com>
Tue, 7 Dec 2010 19:32:43 +0000 (12:32 -0700)
committerAlex Rousskov <rousskov@measurement-factory.com>
Tue, 7 Dec 2010 19:32:43 +0000 (12:32 -0700)
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.

src/client_side_request.cc
src/err_detail_type.h

index 161819cf1c1ef0f948fe96f06595a7d1ca585ce7..76e3d3aadc463a44d38395b3d08f5fe8cb626624 100644 (file)
@@ -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
index e683215c845468aab8e75d50c8822fb709fcae73..3246a2fb5d02d961a68432dc1bc097f5da1d6df9 100644 (file)
@@ -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