From: rousskov <> Date: Thu, 28 Jun 2007 20:20:05 +0000 (+0000) Subject: Bug #1986 fix: Do not abandon ICAP when doing FTP HEAD. X-Git-Tag: SQUID_3_0_PRE7~180 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=063a47b558e3666eb34e0456bc56e5c370a09b59;p=thirdparty%2Fsquid.git Bug #1986 fix: Do not abandon ICAP when doing FTP HEAD. Also, do not forget to adjust cachability of FTP responses when doing ICAP. FTP HEAD processing code was calling appendSuccessHeader() but was not checking whether the latter set icapAccessCheckPending. This resulted in aborted FTP HEAD transactions. Also, appendSuccessHeader was adjusting entry cachability based on authentication flags but _not_ when ICAP was enabled. I moved that code to newly added haveParsedReplyHeaders() which is called with or without ICAP, just like in HttpState. TODO: rename appendSuccessHeader because it is doing a lot more than that. --- diff --git a/src/ftp.cc b/src/ftp.cc index 47fc452e20..3d2a306533 100644 --- a/src/ftp.cc +++ b/src/ftp.cc @@ -1,6 +1,6 @@ /* - * $Id: ftp.cc,v 1.426 2007/06/25 22:34:24 rousskov Exp $ + * $Id: ftp.cc,v 1.427 2007/06/28 14:20:05 rousskov Exp $ * * DEBUG: section 9 File Transfer Protocol (FTP) * AUTHOR: Harvest Derived @@ -206,6 +206,7 @@ public: virtual void closeServer(); virtual void completeForwarding(); virtual void abortTransaction(const char *reason); + void processHeadResponse(); void processReplyBody(); void writeCommand(const char *buf); @@ -223,6 +224,8 @@ public: virtual void sentRequestBody(int fd, size_t size, comm_err_t errflag); virtual void doneSendingRequestBody(); + virtual void haveParsedReplyHeaders(); + virtual bool doneWithServer() const; private: @@ -1331,6 +1334,12 @@ void FtpStateData::processReplyBody() { debugs(9, 5, HERE << "FtpStateData::processReplyBody starting."); + + if (request->method == METHOD_HEAD && (flags.isdir || size != -1)) { + serverComplete(); + return; + } + if (!flags.http_header_sent && data.readBuf->contentSize() >= 0) appendSuccessHeader(); @@ -2215,20 +2224,7 @@ ftpSendPasv(FtpStateData * ftpState) debugs(9, 3, HERE << "ftpSendPasv started"); if (ftpState->request->method == METHOD_HEAD && (ftpState->flags.isdir || ftpState->size != -1)) { - /* Terminate here for HEAD requests */ - ftpState->appendSuccessHeader(); - ftpState->entry->timestampsSet(); - /* - * On rare occasions I'm seeing the entry get aborted after - * ftpReadControlReply() and before here, probably when - * trying to write to the client. - */ - - if (!EBIT_TEST(ftpState->entry->flags, ENTRY_ABORTED)) - ftpState->completeForwarding(); - - ftpSendQuit(ftpState); - + ftpState->processHeadResponse(); // may call serverComplete return; } @@ -2291,6 +2287,34 @@ ftpSendPasv(FtpStateData * ftpState) commSetTimeout(ftpState->data.fd, 15, FtpStateData::ftpTimeout, ftpState); } +void +FtpStateData::processHeadResponse() +{ + debugs(9, 5, HERE << "handling HEAD response"); + ftpSendQuit(this); + appendSuccessHeader(); + + /* + * On rare occasions I'm seeing the entry get aborted after + * ftpReadControlReply() and before here, probably when + * trying to write to the client. + */ + if (EBIT_TEST(entry->flags, ENTRY_ABORTED)) { + abortTransaction("entry aborted while processing HEAD"); + return; + } + +#if ICAP_CLIENT + if (icapAccessCheckPending) { + debugs(9,3,HERE << "returning from ftpSendPasv due to icapAccessCheckPending"); + return; + } +#endif + + // processReplyBody calls serverComplete() since there is no body + processReplyBody(); +} + static void ftpReadPasv(FtpStateData * ftpState) { @@ -3206,6 +3230,13 @@ FtpStateData::appendSuccessHeader() #endif e->replaceHttpReply(reply); + haveParsedReplyHeaders(); +} + +void +FtpStateData::haveParsedReplyHeaders() +{ + StoreEntry *e = entry; e->timestampsSet();