From: Alex Rousskov Date: Sun, 12 Sep 2010 21:58:38 +0000 (-0600) Subject: Keep ICAP connection persistent after an OPTIONS response if possible. X-Git-Tag: take1~269 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=0a1ac29e64a775db783a8ec18e18625ad6585b0b;p=thirdparty%2Fsquid.git Keep ICAP connection persistent after an OPTIONS response if possible. Old OptXact code used Xaction::doneReading() which was only true at EOF. Thus, closeConnection() was thinking we are still reading (i.e., not doneWithIo) at the end of the transaction and force-closed the connection. New OptXact implements its own doneReading() which returns true at EOF and when we read the entire response. Since we cannot parse OPTIONS body and do not know where it ends, OPTIONS responses with bodies still result in connection closure. We should not be getting any, but there are broken ICAP servers that do send them. Hopefully, they all use Encapsulated: opt-body. --- diff --git a/src/adaptation/icap/OptXact.cc b/src/adaptation/icap/OptXact.cc index be06693e01..b6f0af6f97 100644 --- a/src/adaptation/icap/OptXact.cc +++ b/src/adaptation/icap/OptXact.cc @@ -19,7 +19,8 @@ CBDATA_NAMESPACED_CLASS_INIT(Adaptation::Icap, OptXactLauncher); Adaptation::Icap::OptXact::OptXact(Adaptation::Icap::ServiceRep::Pointer &aService): AsyncJob("Adaptation::Icap::OptXact"), - Adaptation::Icap::Xaction("Adaptation::Icap::OptXact", aService) + Adaptation::Icap::Xaction("Adaptation::Icap::OptXact", aService), + readAll(false) { } @@ -69,6 +70,13 @@ void Adaptation::Icap::OptXact::handleCommWrote(size_t size) void Adaptation::Icap::OptXact::handleCommRead(size_t) { if (parseResponse()) { + Must(icapReply != NULL); + // We read everything if there is no response body. If there is a body, + // we cannot parse it because we do not support any opt-body-types, so + // we leave readAll false which forces connection closure. + readAll = !icapReply->header.getByNameListMember("Encapsulated", + "opt-body", ',').size(); + debugs(93, 7, HERE << "readAll=" << readAll); icap_tio_finish = current_time; setOutcome(xoOpt); sendAnswer(icapReply); diff --git a/src/adaptation/icap/OptXact.h b/src/adaptation/icap/OptXact.h index 0fee9a78cc..d59fd28a5d 100644 --- a/src/adaptation/icap/OptXact.h +++ b/src/adaptation/icap/OptXact.h @@ -63,11 +63,15 @@ protected: bool parseResponse(); void startReading(); + virtual bool doneReading() const { return commEof || readAll; } virtual void swanSong(); private: virtual void finalizeLogInfo(); + + bool readAll; ///< read the entire OPTIONS response + CBDATA_CLASS2(OptXact); };