--- /dev/null
+/*
+ * Copyright (C) 1996-2015 The Squid Software Foundation and contributors
+ *
+ * Squid software is distributed under GPLv2+ license and includes
+ * contributions from numerous individuals and organizations.
+ * Please see the COPYING and CONTRIBUTORS files for details.
+ */
+
+#include "squid.h"
+#include "comm/Flag.h"
+#include "CommCalls.h"
+#include "HttpControlMsg.h"
+
+/// called when we wrote the 1xx response
+void
+HttpControlMsgSink::wroteControlMsg(const CommIoCbParams ¶ms)
+{
+ if (params.flag == Comm::ERR_CLOSING)
+ return;
+
+ if (params.flag == Comm::OK) {
+ if (cbControlMsgSent)
+ ScheduleCallHere(cbControlMsgSent);
+ return;
+ }
+
+ debugs(33, 3, "1xx writing failed: " << xstrerr(params.xerrno));
+ // no error notification: see HttpControlMsg.h for rationale and
+ // note that some errors are detected elsewhere (e.g., close handler)
+
+ // close on 1xx errors to be conservative and to simplify the code
+ // (if we do not close, we must notify the source of a failure!)
+ params.conn->close();
+
+ // XXX: writeControlMsgAndCall() should handle writer-specific writing
+ // results, including errors and then call us with success/failure outcome.
+}
+
#include "base/AsyncCall.h"
#include "HttpReply.h"
+class CommIoCbParams;
class HttpControlMsg;
/*
/// called to send the 1xx message and notify the Source
virtual void sendControlMsg(HttpControlMsg msg) = 0;
+
+ /// callback to handle Comm::Write completion
+ void wroteControlMsg(const CommIoCbParams &);
+
+ /// Call to schedule when the control msg has been sent
+ AsyncCall::Pointer cbControlMsgSent;
};
/// bundles HTTP 1xx reply and the "successfully forwarded" callback
HttpHeaderTools.cc \
HttpBody.h \
HttpBody.cc \
+ HttpControlMsg.cc \
HttpControlMsg.h \
HttpMsg.cc \
HttpMsg.h \
HttpHeaderFieldInfo.h \
HttpHeaderTools.h \
HttpHeaderTools.cc \
+ HttpControlMsg.cc \
HttpControlMsg.h \
HttpMsg.cc \
HttpMsg.h \
tests/testCacheManager.cc \
tests/testCacheManager.h \
tests/stub_main_cc.cc \
+ tests/stub_HttpControlMsg.cc \
tests/stub_ipc_Forwarder.cc \
tests/stub_store_stats.cc \
tests/stub_EventLoop.cc \
http.cc \
HttpBody.h \
HttpBody.cc \
+ tests/stub_HttpControlMsg.cc \
HttpHeader.h \
HttpHeader.cc \
HttpHeaderFieldInfo.h \
http.cc \
HttpBody.h \
HttpBody.cc \
+ tests/stub_HttpControlMsg.cc \
HttpHeader.h \
HttpHeader.cc \
HttpHeaderFieldInfo.h \
http.cc \
HttpBody.h \
HttpBody.cc \
+ tests/stub_HttpControlMsg.cc \
HttpHeaderFieldStat.h \
HttpHdrCc.h \
HttpHdrCc.cc \
http.cc \
HttpBody.h \
HttpBody.cc \
+ tests/stub_HttpControlMsg.cc \
HttpHeader.h \
HttpHeader.cc \
HttpHeaderFieldInfo.h \
http.cc \
HttpBody.h \
HttpBody.cc \
+ tests/stub_HttpControlMsg.cc \
HttpHeaderFieldStat.h \
HttpHdrCc.h \
HttpHdrCc.cc \
deferredparams.rep = NULL;
}
-void
-ClientSocketContext::writeControlMsg(HttpControlMsg &msg)
-{
- HttpReply::Pointer rep(msg.reply);
- Must(rep != NULL);
-
- // remember the callback
- cbControlMsgSent = msg.cbSuccess;
-
- AsyncCall::Pointer call = commCbCall(33, 5, "ClientSocketContext::wroteControlMsg",
- CommIoCbPtrFun(&WroteControlMsg, this));
-
- getConn()->writeControlMsgAndCall(this, rep.getRaw(), call);
-}
-
-/// called when we wrote the 1xx response
-void
-ClientSocketContext::wroteControlMsg(const Comm::ConnectionPointer &conn, char *, size_t, Comm::Flag errflag, int xerrno)
-{
- if (errflag == Comm::ERR_CLOSING)
- return;
-
- if (errflag == Comm::OK) {
- ScheduleCallHere(cbControlMsgSent);
- return;
- }
-
- debugs(33, 3, HERE << "1xx writing failed: " << xstrerr(xerrno));
- // no error notification: see HttpControlMsg.h for rationale and
- // note that some errors are detected elsewhere (e.g., close handler)
-
- // close on 1xx errors to be conservative and to simplify the code
- // (if we do not close, we must notify the source of a failure!)
- conn->close();
-
- // XXX: writeControlMsgAndCall() should handle writer-specific writing
- // results, including errors and then call us with success/failure outcome.
-}
-
-/// wroteControlMsg() wrapper: ClientSocketContext is not an AsyncJob
-void
-ClientSocketContext::WroteControlMsg(const Comm::ConnectionPointer &conn, char *bufnotused, size_t size, Comm::Flag errflag, int xerrno, void *data)
-{
- ClientSocketContext *context = static_cast<ClientSocketContext*>(data);
- context->wroteControlMsg(conn, bufnotused, size, errflag, xerrno);
-}
-
#if USE_IDENT
static void
clientIdentDone(const char *ident, void *data)
return;
}
+ // HTTP/1 1xx status messages are only valid when there is a transaction to trigger them
if (!pipeline.empty()) {
- pipeline.front()->writeControlMsg(msg); // will call msg.cbSuccess
+ HttpReply::Pointer rep(msg.reply);
+ Must(rep);
+ // remember the callback
+ cbControlMsgSent = msg.cbSuccess;
+
+ typedef CommCbMemFunT<HttpControlMsgSink, CommIoCbParams> Dialer;
+ AsyncCall::Pointer call = JobCallback(33, 5, Dialer, this, HttpControlMsgSink::wroteControlMsg);
+
+ writeControlMsgAndCall(rep.getRaw(), call);
return;
}
void registerWithConn();
void noteIoError(const int xerrno); ///< update state to reflect I/O error
- /// starts writing 1xx control message to the client
- void writeControlMsg(HttpControlMsg &msg);
-
-protected:
- static IOCB WroteControlMsg;
- void wroteControlMsg(const Comm::ConnectionPointer &conn, char *bufnotused, size_t size, Comm::Flag errflag, int xerrno);
-
private:
void prepareReply(HttpReply * rep);
void packChunk(const StoreIOBuffer &bodyData, MemBuf &mb);
void doClose();
void initiateClose(const char *reason);
- AsyncCall::Pointer cbControlMsgSent; ///< notifies HttpControlMsg Source
-
bool mayUseConnection_; /* This request may use the connection. Don't read anymore requests for now */
bool connRegistered_;
};
virtual bool handleReadData();
virtual void afterClientRead();
+ /* HttpControlMsgSink API */
+ virtual void sendControlMsg(HttpControlMsg);
+
/// Traffic parsing
bool clientParseRequests();
void readNextRequest();
bool isOpen() const;
- // HttpControlMsgSink API
- virtual void sendControlMsg(HttpControlMsg msg);
-
Http1::TeChunkedParser *bodyParser; ///< parses HTTP/1.1 chunked request body
/** number of body bytes we need to comm_read for the "current" request
void connectionTag(const char *aTag) { connectionTag_ = aTag; }
/// handle a control message received by context from a peer and call back
- virtual void writeControlMsgAndCall(ClientSocketContext *context, HttpReply *rep, AsyncCall::Pointer &call) = 0;
+ virtual void writeControlMsgAndCall(HttpReply *rep, AsyncCall::Pointer &call) = 0;
/// ClientStream calls this to supply response header (once) and data
/// for the current ClientSocketContext.
}
void
-Ftp::Server::writeControlMsgAndCall(ClientSocketContext *, HttpReply *reply, AsyncCall::Pointer &call)
+Ftp::Server::writeControlMsgAndCall(HttpReply *reply, AsyncCall::Pointer &call)
{
// the caller guarantees that we are dealing with the current context only
// the caller should also make sure reply->header.has(Http::HdrType::FTP_STATUS)
virtual void clientPinnedConnectionClosed(const CommCloseCbParams &io);
virtual void handleReply(HttpReply *header, StoreIOBuffer receivedData);
virtual int pipelinePrefetchMax() const;
- virtual void writeControlMsgAndCall(ClientSocketContext *context, HttpReply *rep, AsyncCall::Pointer &call);
+ virtual void writeControlMsgAndCall(HttpReply *rep, AsyncCall::Pointer &call);
virtual time_t idleTimeout() const;
/* BodyPipe API */
}
void
-Http::One::Server::writeControlMsgAndCall(ClientSocketContext *context, HttpReply *rep, AsyncCall::Pointer &call)
+Http::One::Server::writeControlMsgAndCall(HttpReply *rep, AsyncCall::Pointer &call)
{
// apply selected clientReplyContext::buildReplyHeader() mods
// it is not clear what headers are required for control messages
debugs(11, 2, "HTTP Client " << clientConnection);
debugs(11, 2, "HTTP Client CONTROL MSG:\n---------\n" << mb->buf << "\n----------");
- Comm::Write(context->clientConnection, mb, call);
+ Comm::Write(clientConnection, mb, call);
delete mb;
}
virtual ClientSocketContext *parseOneRequest();
virtual void processParsedRequest(ClientSocketContext *context);
virtual void handleReply(HttpReply *rep, StoreIOBuffer receivedData);
- virtual void writeControlMsgAndCall(ClientSocketContext *context, HttpReply *rep, AsyncCall::Pointer &call);
+ virtual void writeControlMsgAndCall(HttpReply *rep, AsyncCall::Pointer &call);
virtual time_t idleTimeout() const;
/* BodyPipe API */
tests/stub_helper.cc \
tests/stub_HelperChildConfig.cc \
tests/stub_http.cc \
+ tests/stub_HttpControlMsg.cc \
tests/stub_HttpReply.cc \
tests/stub_HttpRequest.cc \
tests/stub_icp.cc \
--- /dev/null
+/*
+ * Copyright (C) 1996-2015 The Squid Software Foundation and contributors
+ *
+ * Squid software is distributed under GPLv2+ license and includes
+ * contributions from numerous individuals and organizations.
+ * Please see the COPYING and CONTRIBUTORS files for details.
+ */
+
+#include "squid.h"
+
+#define STUB_API "HttpControlMsg.cc"
+#include "STUB.h"
+
+#include "HttpControlMsg.h"
+void HttpControlMsgSink::wroteControlMsg(CommIoCbParams const&) STUB
bool ClientSocketContext::multipartRangeRequest() const STUB_RETVAL(false)
void ClientSocketContext::registerWithConn() STUB
void ClientSocketContext::noteIoError(const int xerrno) STUB
-void ClientSocketContext::writeControlMsg(HttpControlMsg &msg) STUB
bool ConnStateData::clientParseRequests() STUB_RETVAL(false)
void ConnStateData::readNextRequest() STUB