FwdState::closeServerConnection(const char *reason)
{
debugs(17, 3, "because " << reason << "; " << serverConn);
- comm_remove_close_handler(serverConn->fd, fwdServerClosedWrapper, this);
+ comm_remove_close_handler(serverConn->fd, closeHandler);
+ closeHandler = NULL;
fwdPconnPool->noteUses(fd_table[serverConn->fd].pconn.uses);
serverConn->close();
}
debugs(17, 3, HERE << entry->url() );
assert(serverConnection() == conn);
assert(Comm::IsConnOpen(conn));
- comm_remove_close_handler(conn->fd, fwdServerClosedWrapper, this);
+ comm_remove_close_handler(conn->fd, closeHandler);
+ closeHandler = NULL;
serverConn = NULL;
}
serverConn = conn;
debugs(17, 3, HERE << serverConnection() << ": '" << entry->url() << "'" );
- comm_add_close_handler(serverConnection()->fd, fwdServerClosedWrapper, this);
+ closeHandler = comm_add_close_handler(serverConnection()->fd, fwdServerClosedWrapper, this);
#if USE_OPENSSL
if (!request->flags.pinned) {
request->flags.pinned = true;
if (pinned_connection->pinnedAuth())
request->flags.auth = true;
- comm_add_close_handler(serverConn->fd, fwdServerClosedWrapper, this);
+
+ closeHandler = comm_add_close_handler(serverConn->fd, fwdServerClosedWrapper, this);
syncWithServerConn(pinned_connection->pinning.host);
debugs(17, 3, HERE << "reusing pconn " << serverConnection());
++n_tries;
- comm_add_close_handler(serverConnection()->fd, fwdServerClosedWrapper, this);
+ closeHandler = comm_add_close_handler(serverConnection()->fd, fwdServerClosedWrapper, this);
syncWithServerConn(request->url.host());
Comm::ConnectionPointer serverConn; ///< a successfully opened connection to a server.
+ AsyncCall::Pointer closeHandler; ///< The serverConn close handler
+
/// possible pconn race states
typedef enum { raceImpossible, racePossible, raceHappened } PconnRace;
PconnRace pconnRace; ///< current pconn race state
virtual void sentRequestBody(const CommIoCbParams &io) = 0;
virtual void doneSendingRequestBody() = 0;
- virtual void closeServer() = 0; /**< end communication with the server */
+ /// Use this to end communication with the server. The call cancels our
+ /// closure handler and tells FwdState to forget about the connection.
+ virtual void closeServer() = 0;
virtual bool doneWithServer() const = 0; /**< did we end communication? */
/// whether we may receive more virgin response body bytes
virtual bool mayReadVirginReplyBody() const = 0;
return Comm::COMM_ERROR;
}
-void
+AsyncCall::Pointer
comm_add_close_handler(int fd, CLCB * handler, void *data)
{
debugs(5, 5, "comm_add_close_handler: FD " << fd << ", handler=" <<
AsyncCall::Pointer call=commCbCall(5,4, "SomeCloseHandler",
CommCloseCbPtrFun(handler, data));
comm_add_close_handler(fd, call);
+ return call;
}
void
void commCloseAllSockets(void);
void checkTimeouts(void);
-void comm_add_close_handler(int fd, CLCB *, void *);
+AsyncCall::Pointer comm_add_close_handler(int fd, CLCB *, void *);
void comm_add_close_handler(int fd, AsyncCall::Pointer &);
void comm_remove_close_handler(int fd, CLCB *, void *);
void comm_remove_close_handler(int fd, AsyncCall::Pointer &);
fwd->fail(new ErrorState(ERR_READ_TIMEOUT, Http::scGatewayTimeout, fwd->request));
}
- serverConnection->close();
+ closeServer();
+ mustStop("HttpStateData::httpTimeout");
}
/// Remove an existing public store entry if the incoming response (to be
err->xerrno = rd.xerrno;
fwd->fail(err);
flags.do_next_read = false;
- io.conn->close();
-
+ closeServer();
+ mustStop("HttpStateData::readReply");
return;
}
entry->reset();
fwd->fail(new ErrorState(error, Http::scBadGateway, fwd->request));
flags.do_next_read = false;
- serverConnection->close();
+ closeServer();
+ mustStop("HttpStateData::continueAfterParsingHeader");
return false; // quit on error
}
ErrorState *err = new ErrorState(ERR_WRITE_ERROR, Http::scBadGateway, fwd->request);
err->xerrno = io.xerrno;
fwd->fail(err);
- serverConnection->close();
+ closeServer();
+ mustStop("HttpStateData::wroteLast");
return;
}
request->hier.peer_http_request_sent = current_time;
}
-// Close the HTTP server connection. Used by serverComplete().
void
HttpStateData::closeServer()
{
debugs(11, DBG_IMPORTANT, "http handleMoreRequestBodyAvailable: Likely proxy abuse detected '" << request->client_addr << "' -> '" << entry->url() << "'" );
if (virginReply()->sline.status() == Http::scInvalidHeader) {
- serverConnection->close();
+ closeServer();
+ mustStop("HttpStateData::handleMoreRequestBodyAvailable");
return;
}
}