#include "base/TextException.h"
#include "Server.h"
#include "Store.h"
+#include "fde.h" /* for fd_table[fd].closing */
#include "HttpRequest.h"
#include "HttpReply.h"
#include "errorpage.h"
sendMoreRequestBody();
}
+bool
+ServerStateData::canSend(int fd) const
+{
+ return fd >= 0 && !fd_table[fd].closing();
+}
+
void
ServerStateData::sendMoreRequestBody()
{
assert(requestBodySource != NULL);
assert(!requestSender);
+
+ const int fd = dataDescriptor();
+
+ if (!canSend(fd)) {
+ debugs(9,3, HERE << "cannot send request body to closing FD " << fd);
+ return; // wait for the kid's close handler; TODO: assert(closer);
+ }
+
MemBuf buf;
if (requestBodySource->getMoreData(buf)) {
debugs(9,3, HERE << "will write " << buf.contentSize() << " request body bytes");
typedef CommCbMemFunT<ServerStateData, CommIoCbParams> Dialer;
requestSender = asyncCall(93,3, "ServerStateData::sentRequestBody",
Dialer(this, &ServerStateData::sentRequestBody));
- comm_write_mbuf(dataDescriptor(), &buf, requestSender);
+ comm_write_mbuf(fd, &buf, requestSender);
} else {
debugs(9,3, HERE << "will wait for more request body bytes or eof");
requestSender = NULL;
void handleRequestBodyProductionEnded();
virtual void handleRequestBodyProducerAborted() = 0;
+ /// whether it is not too late to write to the server
+ bool canSend(int fd) const;
// sending of the request body to the server
void sendMoreRequestBody();
// has body; kids overwrite to increment I/O stats counters
ctrl.last_command = ebuf;
+ if (!canSend(ctrl.fd)) {
+ debugs(9, 2, HERE << "cannot send to closing ctrl FD " << ctrl.fd);
+ // TODO: assert(ctrl.closer != NULL);
+ return;
+ }
+
typedef CommCbMemFunT<FtpStateData, CommIoCbParams> Dialer;
AsyncCall::Pointer call = asyncCall(9, 5, "FtpStateData::ftpWriteCommandCallback",
Dialer(this, &FtpStateData::ftpWriteCommandCallback));
MemBuf mb;
debugs(11, 5, "httpSendRequest: FD " << fd << ", request " << request << ", this " << this << ".");
+
+ if (!canSend(fd)) {
+ debugs(11,3, HERE << "cannot send request to closing FD " << fd);
+ assert(closeHandler != NULL);
+ return false;
+ }
+
typedef CommCbMemFunT<HttpStateData, CommTimeoutCbParams> TimeoutDialer;
AsyncCall::Pointer timeoutCall = asyncCall(11, 5, "HttpStateData::httpTimeout",
TimeoutDialer(this,&HttpStateData::httpTimeout));
sendComplete(io);
} else {
debugs(11, 2, "doneSendingRequestBody: matched brokenPosts");
+
+ if (!canSend(fd)) {
+ debugs(11,2, HERE << "cannot send CRLF to closing FD " << fd);
+ assert(closeHandler != NULL);
+ return;
+ }
+
typedef CommCbMemFunT<HttpStateData, CommIoCbParams> Dialer;
Dialer dialer(this, &HttpStateData::sendComplete);
AsyncCall::Pointer call= asyncCall(11,5, "HttpStateData::SendComplete", dialer);