/*
- * $Id: client_side.cc,v 1.656 2003/08/13 00:17:26 robertc Exp $
+ * $Id: client_side.cc,v 1.657 2003/08/14 12:15:04 robertc Exp $
*
* DEBUG: section 33 Client-side Routines
* AUTHOR: Duane Wessels
static bool okToAccept();
static int clientIsRequestBodyValid(int bodyLength);
static int clientIsRequestBodyTooLargeForPolicy(size_t bodyLength);
-/* convenience class while splitting up body handling */
-/* temporary existence only - on stack use expected */
-
-class ClientBody
-{
-
-public:
- ClientBody (ConnStateData::Pointer &);
- void process();
- void preProcessing();
- void processBuffer();
-
-private:
- ConnStateData::Pointer conn;
- char *buf;
- CBCB *callback;
- HttpRequest *request;
-};
static void clientUpdateStatHistCounters(log_type logType, int svc_time);
static void clientUpdateStatCounters(log_type logType);
context->writeComplete (fd, bufnotused, size, errflag);
}
+void
+ClientSocketContext::doClose()
+{
+ comm_close(fd());
+}
+
+void
+ClientSocketContext::initiateClose()
+{
+ if (!http || !http->getConn().getRaw()) {
+ doClose();
+ return;
+ }
+
+ if (http->getConn()->body.size_left > 0) {
+ debug(33, 5) ("ClientSocketContext::initiateClose: closing, but first we need to read the rest of the request\n");
+ /* XXX We assumes the reply does fit in the TCP transmit window.
+ * If not the connection may stall while sending the reply
+ * (before reaching here) if the client does not try to read the
+ * response while sending the request body. As of yet we have
+ * not received any complaints indicating this may be an issue.
+ */
+ http->getConn()->closing(true);
+ clientAbortBody(http->request);
+ return;
+ }
+
+ doClose();
+}
+
void
ClientSocketContext::writeComplete(int fd, char *bufnotused, size_t size, comm_err_t errflag)
{
debug(33, 5) ("clientWriteComplete: FD %d, sz %ld, err %d, off %ld, len %d\n",
fd, (long int) size, errflag, (long int) http->out.size, entry ? objectLen(entry) : 0);
clientUpdateSocketStats(http->logType, size);
+ assert (this->fd() == fd);
if (errflag || clientHttpRequestStatus(fd, http)) {
debug (33,5)("clientWriteComplete: FD %d, closing connection due to failure, or true requeststatus\n", fd);
- comm_close(fd);
+ initiateClose();
/* Do we leak here ? */
return;
}
/* fallthrough */
case STREAM_FAILED:
- comm_close(fd);
+ initiateClose();
return;
default:
conn->body.bufsize = sizeof(bodyAbortBuf);
conn->body.cbdata = cbdataReference(data);
}
+
+ if (conn->closing())
+ comm_close(conn->fd);
}
/* Abort a body request */
cbdataFree(t);
}
-ConnStateData::ConnStateData() : transparent_ (false), reading_ (false)
+ConnStateData::ConnStateData() : transparent_ (false), reading_ (false), closing_ (false)
{
openReference = this;
}
reading_ = newBool;
}
+bool
+ConnStateData::closing() const
+{
+ return closing_;
+}
+
+void
+ConnStateData::closing(bool const newBool)
+{
+ assert (closing() != newBool);
+ closing_ = newBool;
+}
+
char *
ConnStateData::In::addressToReadInto() const
{
/*
- * $Id: client_side.h,v 1.8 2003/08/10 11:00:42 robertc Exp $
+ * $Id: client_side.h,v 1.9 2003/08/14 12:15:04 robertc Exp $
*
*
* SQUID Web Proxy Cache http://www.squid-cache.org/
void prepareReply(HttpReply * rep);
void packRange(StoreIOBuffer const &, MemBuf * mb);
void deRegisterWithConn();
+ void doClose();
+ void initiateClose();
bool mayUseConnection_; /* This request may use the connection. Don't read anymore requests for now */
bool connRegistered_;
};
void transparent(bool const);
bool reading() const;
void reading(bool const);
+ bool closing() const;
+ void closing(bool const);
private:
CBDATA_CLASS(ConnStateData);
bool transparent_;
bool reading_;
+ bool closing_;
Pointer openReference;
};
+/* convenience class while splitting up body handling */
+/* temporary existence only - on stack use expected */
+
+class ClientBody
+{
+
+public:
+ ClientBody (ConnStateData::Pointer &);
+ void process();
+ void preProcessing();
+ void processBuffer();
+
+private:
+ ConnStateData::Pointer conn;
+ char *buf;
+ CBCB *callback;
+ HttpRequest *request;
+};
+
#endif /* SQUID_CLIENTSIDE_H */