diff --git a/src/FwdState.cc b/src/FwdState.cc index b69e60c7ccb..a9131af0dae 100644 --- a/src/FwdState.cc +++ b/src/FwdState.cc @@ -150,8 +150,7 @@ FwdState::FwdState(const Comm::ConnectionPointer &client, StoreEntry * e, HttpRe start_t(squid_curtime), n_tries(0), destinations(new ResolvedPeers()), - pconnRace(raceImpossible), - storedWholeReply_(nullptr) + pconnRace(raceImpossible) { debugs(17, 2, "Forwarding client request " << client << ", url=" << e->url()); HTTPMSGLOCK(request); @@ -256,23 +255,6 @@ FwdState::selectPeerForIntercepted() } #endif -/// updates ALE when we finalize the transaction error (if any) -void -FwdState::updateAleWithFinalError() -{ - if (!err || !al) - return; - - LogTagsErrors lte; - lte.timedout = (err->xerrno == ETIMEDOUT || err->type == ERR_READ_TIMEOUT); - al->cache.code.err.update(lte); - if (!err->detail) { - static const auto d = MakeNamedErrorDetail("WITH_SERVER"); - err->detailError(d); - } - al->updateError(Error(err->type, err->detail)); -} - void FwdState::completed() { @@ -297,26 +279,20 @@ FwdState::completed() if (entry->store_status == STORE_PENDING) { if (entry->isEmpty()) { - assert(!storedWholeReply_); if (!err) // we quit (e.g., fd closed) before an error or content fail(new ErrorState(ERR_READ_ERROR, Http::scBadGateway, request, al)); assert(err); - updateAleWithFinalError(); errorAppendEntry(entry, err); err = NULL; #if USE_OPENSSL if (request->flags.sslPeek && request->clientConnectionManager.valid()) { CallJobHere1(17, 4, request->clientConnectionManager, ConnStateData, ConnStateData::httpsPeeked, ConnStateData::PinnedIdleContext(Comm::ConnectionPointer(nullptr), request)); - // no flags.dont_retry: completed() is a post-reforward() act } #endif } else { - updateAleWithFinalError(); // if any - if (storedWholeReply_) - entry->completeSuccessfully(storedWholeReply_); - else - entry->completeTruncated("FwdState default"); + entry->complete(); + entry->releaseRequest(); } } @@ -573,7 +549,6 @@ FwdState::complete() serverConn = nullptr; destinationReceipt = nullptr; - storedWholeReply_ = nullptr; entry->reset(); useDestinations(); @@ -583,8 +558,10 @@ FwdState::complete() debugs(17, 3, "server FD " << serverConnection()->fd << " not re-forwarding status " << replyStatus); else debugs(17, 3, "server (FD closed) not re-forwarding status " << replyStatus); + entry->complete(); - completed(); + if (!Comm::IsConnOpen(serverConn)) + completed(); stopAndDestroy("forwarding completed"); } @@ -596,18 +573,6 @@ FwdState::usingDestination() const return encryptionWait || peerWait || Comm::IsConnOpen(serverConn); } -void -FwdState::markStoredReplyAsWhole(const char * const whyWeAreSure) -{ - debugs(17, 5, whyWeAreSure << " for " << *entry); - - // the caller wrote everything to Store, but Store may silently abort writes - if (EBIT_TEST(entry->flags, ENTRY_ABORTED)) - return; - - storedWholeReply_ = whyWeAreSure; -} - void FwdState::noteDestination(Comm::ConnectionPointer path) { @@ -1045,8 +1010,6 @@ FwdState::connectedToPeer(Security::EncryptorAnswer &answer) // [in ways that may affect logging?]. Consider informing // ConnStateData about our tunnel or otherwise unifying tunnel // establishment [side effects]. - flags.dont_retry = true; // TunnelStateData took forwarding control - entry->abort(); complete(); // destroys us return; } else if (!Comm::IsConnOpen(answer.conn) || fd_table[answer.conn->fd].closing()) { @@ -1240,12 +1203,9 @@ FwdState::dispatch() #if USE_OPENSSL if (request->flags.sslPeek) { - // we were just asked to peek at the server, and we did that CallJobHere1(17, 4, request->clientConnectionManager, ConnStateData, ConnStateData::httpsPeeked, ConnStateData::PinnedIdleContext(serverConnection(), request)); unregister(serverConn); // async call owns it now - flags.dont_retry = true; // we gave up forwarding control - entry->abort(); complete(); // destroys us return; } diff --git a/src/FwdState.h b/src/FwdState.h index ebf5f82b15e..429763b84b4 100644 --- a/src/FwdState.h +++ b/src/FwdState.h @@ -77,11 +77,6 @@ class FwdState: public RefCountable, public PeerSelectionInitiator void unregister(Comm::ConnectionPointer &conn); void unregister(int fd); void complete(); - - /// Mark reply as written to Store in its entirety, including the header and - /// any body. If the reply has a body, the entire body has to be stored. - void markStoredReplyAsWhole(const char *whyWeAreSure); - void handleUnregisteredServerEnd(); int reforward(); bool reforwardableStatus(const Http::StatusCode s) const; @@ -163,8 +158,6 @@ class FwdState: public RefCountable, public PeerSelectionInitiator void notifyConnOpener(); void reactToZeroSizeObject(); - void updateAleWithFinalError(); - public: StoreEntry *entry; HttpRequest *request; @@ -206,10 +199,6 @@ class FwdState: public RefCountable, public PeerSelectionInitiator /// possible pconn race states typedef enum { raceImpossible, racePossible, raceHappened } PconnRace; PconnRace pconnRace; ///< current pconn race state - - /// Whether the entire reply (including any body) was written to Store. - /// The string literal value is only used for debugging. - const char *storedWholeReply_; }; void getOutgoingAddress(HttpRequest * request, const Comm::ConnectionPointer &conn); diff --git a/src/Store.h b/src/Store.h index 379cac2c4ac..7635e66fbca 100644 --- a/src/Store.h +++ b/src/Store.h @@ -67,18 +67,9 @@ class StoreEntry : public hash_link, public Packable bool isEmpty() const { return mem().endOffset() == 0; } bool isAccepting() const; size_t bytesWanted(Range const aRange, bool ignoreDelayPool = false) const; - - /// Signals that the entire response has been stored and no more append() - /// calls should be expected; cf. completeTruncated(). - void completeSuccessfully(const char *whyWeAreSureWeStoredTheWholeReply); - - /// Signals that a partial response (if any) has been stored but no more - /// append() calls should be expected; cf. completeSuccessfully(). - void completeTruncated(const char *whyWeConsiderTheReplyTruncated); - - /// \deprecated use either completeSuccessfully() or completeTruncated() instead + /// flags [truncated or too big] entry with ENTRY_BAD_LENGTH and releases it + void lengthWentBad(const char *reason); void complete(); - store_client_t storeClientType() const; /// \returns a malloc()ed buffer containing a length-long packed swap header const char *getSerialisedMetaData(size_t &length) const; @@ -320,9 +311,6 @@ class StoreEntry : public hash_link, public Packable StoreEntry *adjustVary(); const cache_key *calcPublicKey(const KeyScope keyScope); - /// flags [truncated or too big] entry with ENTRY_BAD_LENGTH and releases it - void lengthWentBad(const char *reason); - static MemAllocator *pool; unsigned short lock_count; /* Assume < 65536! */ diff --git a/src/client_side.cc b/src/client_side.cc index 4eb69769669..1a01426c317 100644 --- a/src/client_side.cc +++ b/src/client_side.cc @@ -4005,16 +4005,8 @@ ConnStateData::unpinConnection(const bool andClose) } void -ConnStateData::terminateAll(const Error &rawError, const LogTagsErrors <e) +ConnStateData::terminateAll(const Error &error, const LogTagsErrors <e) { - auto error = rawError; // (cheap) copy so that we can detail - // We detail even ERR_NONE: There should be no transactions left, and - // detailed ERR_NONE will be unused. Otherwise, this detail helps in triage. - if (!error.detail) { - static const auto d = MakeNamedErrorDetail("WITH_CLIENT"); - error.detail = d; - } - debugs(33, 3, pipeline.count() << '/' << pipeline.nrequests << " after " << error); if (pipeline.empty()) { diff --git a/src/client_side_request.cc b/src/client_side_request.cc index 0a4e2c26c25..72e819caedb 100644 --- a/src/client_side_request.cc +++ b/src/client_side_request.cc @@ -162,7 +162,6 @@ ClientHttpRequest::ClientHttpRequest(ConnStateData * aConn) : , sslBumpNeed_(Ssl::bumpEnd) #endif #if USE_ADAPTATION - , receivedWholeAdaptedReply(false) , request_satisfaction_mode(false) , request_satisfaction_offset(0) #endif @@ -2125,11 +2124,6 @@ void ClientHttpRequest::noteBodyProductionEnded(BodyPipe::Pointer) { assert(!virginHeadSource); - - // distinguish this code path from future noteBodyProducerAborted() that - // would continue storing/delivering (truncated) reply if necessary (TODO) - receivedWholeAdaptedReply = true; - // should we end request satisfaction now? if (adaptedBodySource != NULL && adaptedBodySource->exhausted()) endRequestSatisfaction(); @@ -2143,14 +2137,7 @@ ClientHttpRequest::endRequestSatisfaction() stopConsumingFrom(adaptedBodySource); // TODO: anything else needed to end store entry formation correctly? - if (receivedWholeAdaptedReply) { - // We received the entire reply per receivedWholeAdaptedReply. - // We are called when we consumed everything received (per our callers). - // We consume only what we store per noteMoreBodyDataAvailable(). - storeEntry()->completeSuccessfully("received, consumed, and, hence, stored the entire REQMOD reply"); - } else { - storeEntry()->completeTruncated("REQMOD request satisfaction default"); - } + storeEntry()->complete(); } void diff --git a/src/client_side_request.h b/src/client_side_request.h index 40e0a2e48cc..78ba83e9713 100644 --- a/src/client_side_request.h +++ b/src/client_side_request.h @@ -239,9 +239,6 @@ class ClientHttpRequest CbcPointer virginHeadSource; BodyPipe::Pointer adaptedBodySource; - /// noteBodyProductionEnded() was called - bool receivedWholeAdaptedReply; - bool request_satisfaction_mode; int64_t request_satisfaction_offset; #endif diff --git a/src/clients/Client.cc b/src/clients/Client.cc index 168a67f74d1..994b246a501 100644 --- a/src/clients/Client.cc +++ b/src/clients/Client.cc @@ -155,27 +155,6 @@ Client::setFinalReply(HttpReply *rep) return theFinalReply; } -void -Client::markParsedVirginReplyAsWhole(const char *reasonWeAreSure) -{ - assert(reasonWeAreSure); - debugs(11, 3, reasonWeAreSure); - - // The code storing adapted reply takes care of markStoredReplyAsWhole(). - // We need to take care of the remaining regular network-to-store case. -#if USE_ADAPTATION - if (startedAdaptation) { - debugs(11, 5, "adaptation handles markStoredReplyAsWhole()"); - return; - } -#endif - - // Convert the "parsed whole virgin reply" event into the "stored..." event - // because, without adaptation, we store everything we parse: There is no - // buffer for parsed content; addVirginReplyBody() stores every parsed byte. - fwd->markStoredReplyAsWhole(reasonWeAreSure); -} - // called when no more server communication is expected; may quit void Client::serverComplete() @@ -743,7 +722,6 @@ Client::handleAdaptedHeader(Http::Message *msg) assert(result); } else { // no body - fwd->markStoredReplyAsWhole("setFinalReply() stored header-only adapted reply"); if (doneWithAdaptation()) // we may still be sending virgin response handleAdaptationCompleted(); } @@ -818,9 +796,6 @@ Client::handleAdaptedBodyProductionEnded() if (abortOnBadEntry("entry went bad while waiting for adapted body eof")) return; - // distinguish this code path from handleAdaptedBodyProducerAborted() - receivedWholeAdaptedReply = true; - // end consumption if we consumed everything if (adaptedBodySource != NULL && adaptedBodySource->exhausted()) endAdaptedBodyConsumption(); @@ -831,14 +806,6 @@ void Client::endAdaptedBodyConsumption() { stopConsumingFrom(adaptedBodySource); - - if (receivedWholeAdaptedReply) { - // We received the entire adapted reply per receivedWholeAdaptedReply. - // We are called when we consumed everything received (per our callers). - // We consume only what we store per handleMoreAdaptedBodyAvailable(). - fwd->markStoredReplyAsWhole("received,consumed=>stored the entire RESPMOD reply"); - } - handleAdaptationCompleted(); } @@ -859,6 +826,7 @@ void Client::handleAdaptedBodyProducerAborted() if (handledEarlyAdaptationAbort()) return; + entry->lengthWentBad("body adaptation aborted"); handleAdaptationCompleted(); // the user should get a truncated response } diff --git a/src/clients/Client.h b/src/clients/Client.h index be79b395e4a..714f8478537 100644 --- a/src/clients/Client.h +++ b/src/clients/Client.h @@ -81,10 +81,6 @@ class Client: public: // should be protected void serverComplete(); /**< call when no server communication is expected */ - /// remember that the received virgin reply was parsed in its entirety, - /// including its body (if any) - void markParsedVirginReplyAsWhole(const char *reasonWeAreSure); - private: void serverComplete2(); /**< Continuation of serverComplete */ bool completed = false; /**< serverComplete() has been called */ @@ -180,9 +176,6 @@ class Client: bool adaptationAccessCheckPending = false; bool startedAdaptation = false; - - /// handleAdaptedBodyProductionEnded() was called - bool receivedWholeAdaptedReply = false; #endif bool receivedWholeRequestBody = false; ///< handleRequestBodyProductionEnded called diff --git a/src/clients/FtpGateway.cc b/src/clients/FtpGateway.cc index aeeaedb4834..736c777729e 100644 --- a/src/clients/FtpGateway.cc +++ b/src/clients/FtpGateway.cc @@ -2279,7 +2279,6 @@ ftpReadTransferDone(Ftp::Gateway * ftpState) ftpState->completedListing(); /* QUIT operation handles sending the reply to client */ } - ftpState->markParsedVirginReplyAsWhole("ftpReadTransferDone code 226 or 250"); ftpSendQuit(ftpState); } else { /* != 226 */ debugs(9, DBG_IMPORTANT, HERE << "Got code " << code << " after reading data"); diff --git a/src/clients/FtpRelay.cc b/src/clients/FtpRelay.cc index ce6ba3ba610..fbea2c2cc38 100644 --- a/src/clients/FtpRelay.cc +++ b/src/clients/FtpRelay.cc @@ -386,7 +386,6 @@ Ftp::Relay::forwardReply() reply->sources |= Http::Message::srcFtp; setVirginReply(reply); - markParsedVirginReplyAsWhole("Ftp::Relay::handleControlReply() does not forward partial replies"); adaptOrFinalizeReply(); serverComplete(); @@ -720,12 +719,7 @@ Ftp::Relay::readTransferDoneReply() { debugs(9, 3, status()); - // RFC 959 says that code 226 may indicate a successful response to a file - // transfer and file abort commands, but since we do not send abort - // commands, let's assume it was a successful file transfer. - if (ctrl.replycode == 226 || ctrl.replycode == 250) { - markParsedVirginReplyAsWhole("Ftp::Relay::readTransferDoneReply() code 226 or 250"); - } else { + if (ctrl.replycode != 226 && ctrl.replycode != 250) { debugs(9, DBG_IMPORTANT, "got FTP code " << ctrl.replycode << " after reading response data"); } diff --git a/src/gopher.cc b/src/gopher.cc index 576a3f7b146..0a596cc1d64 100644 --- a/src/gopher.cc +++ b/src/gopher.cc @@ -87,7 +87,6 @@ class GopherStateData HTML_header_added(0), HTML_pre(0), type_id(GOPHER_FILE /* '0' */), - overflowed(false), cso_recno(0), len(0), buf(NULL), @@ -115,15 +114,8 @@ class GopherStateData int HTML_pre; char type_id; char request[MAX_URL]; - - /// some received bytes ignored due to internal buffer capacity limits - bool overflowed; - int cso_recno; - - /// the number of not-yet-parsed Gopher line bytes in this->buf int len; - char *buf; /* pts to a 4k page */ Comm::ConnectionPointer serverConn; FwdState::Pointer fwd; @@ -437,7 +429,6 @@ gopherToHTML(GopherStateData * gopherState, char *inbuf, int len) if (gopherState->len + llen >= TEMP_BUF_SIZE) { debugs(10, DBG_IMPORTANT, "GopherHTML: Buffer overflow. Lost some data on URL: " << entry->url() ); llen = TEMP_BUF_SIZE - gopherState->len - 1; - gopherState->overflowed = true; // may already be true } if (!lpos) { /* there is no complete line in inbuf */ @@ -804,10 +795,6 @@ gopherReadReply(const Comm::ConnectionPointer &conn, char *buf, size_t len, Comm entry->timestampsSet(); entry->flush(); - - if (!gopherState->len && !gopherState->overflowed) - gopherState->fwd->markStoredReplyAsWhole("gopher EOF after receiving/storing some bytes"); - gopherState->fwd->complete(); gopherState->serverConn->close(); } else { @@ -966,7 +953,6 @@ gopherStart(FwdState * fwd) } gopherToHTML(gopherState, (char *) NULL, 0); - fwd->markStoredReplyAsWhole("gopher instant internal request satisfaction"); fwd->complete(); return; } diff --git a/src/http.cc b/src/http.cc index 7c9ae70185a..c0bdd8a86d9 100644 --- a/src/http.cc +++ b/src/http.cc @@ -1445,19 +1445,6 @@ HttpStateData::writeReplyBody() int len = inBuf.length(); addVirginReplyBody(data, len); inBuf.consume(len); - - // after addVirginReplyBody() wrote (when not adapting) everything we have - // received to Store, check whether we have received/parsed the entire reply - int64_t clen = -1; - const char *parsedWhole = nullptr; - if (!virginReply()->expectingBody(request->method, clen)) - parsedWhole = "http parsed header-only reply"; - else if (clen >= 0 && clen == payloadSeen - payloadTruncated) - parsedWhole = "http parsed Content-Length body bytes"; - else if (clen < 0 && eof) - parsedWhole = "http parsed body ending with expected/required EOF"; - if (parsedWhole) - markParsedVirginReplyAsWhole(parsedWhole); } bool @@ -1475,7 +1462,6 @@ HttpStateData::decodeAndWriteReplyBody() if (doneParsing) { lastChunk = 1; flags.do_next_read = false; - markParsedVirginReplyAsWhole("http parsed last-chunk"); } return true; } @@ -1593,6 +1579,8 @@ HttpStateData::processReplyBody() case COMPLETE_NONPERSISTENT_MSG: debugs(11, 5, "processReplyBody: COMPLETE_NONPERSISTENT_MSG from " << serverConnection); + if (flags.chunked && !lastChunk) + entry->lengthWentBad("missing last-chunk"); serverComplete(); return; diff --git a/src/store.cc b/src/store.cc index edc9d41c3fa..50b041f165f 100644 --- a/src/store.cc +++ b/src/store.cc @@ -755,7 +755,7 @@ StoreEntry::adjustVary() pe->startWriting(); // after timestampsSet() - pe->completeSuccessfully("wrote the entire Vary marker object"); + pe->complete(); return pe; } @@ -1055,20 +1055,6 @@ StoreEntry::lengthWentBad(const char *reason) releaseRequest(); } -void -StoreEntry::completeSuccessfully(const char * const whyWeAreSure) -{ - debugs(20, 3, whyWeAreSure << "; " << *this); - complete(); -} - -void -StoreEntry::completeTruncated(const char * const truncationReason) -{ - lengthWentBad(truncationReason); - complete(); -} - void StoreEntry::complete() { @@ -1762,7 +1748,7 @@ StoreEntry::storeErrorResponse(HttpReply *reply) buffer(); replaceHttpReply(HttpReplyPointer(reply)); flush(); - completeSuccessfully("replaceHttpReply() stored the entire error"); + complete(); negativeCache(); releaseRequest(false); // if it is safe to negatively cache, sharing is OK unlock("StoreEntry::storeErrorResponse"); diff --git a/src/whois.cc b/src/whois.cc index 306ea5c622f..9cf13717d87 100644 --- a/src/whois.cc +++ b/src/whois.cc @@ -169,9 +169,6 @@ WhoisState::readReply(const Comm::ConnectionPointer &conn, char *aBuffer, size_t if (!entry->makePublic()) entry->makePrivate(true); - if (dataWritten) // treat zero-length responses as incomplete - fwd->markStoredReplyAsWhole("whois received/stored the entire response"); - fwd->complete(); debugs(75, 3, "whoisReadReply: Done: " << entry->url()); conn->close();