#include "acl/FilledChecklist.h"
#include "acl/Gadgets.h"
#include "base/TextException.h"
+#include "clients/Client.h"
#include "comm/Connection.h"
#include "comm/forward.h"
#include "comm/Write.h"
#include "HttpHdrContRange.h"
#include "HttpReply.h"
#include "HttpRequest.h"
-#include "Server.h"
#include "SquidConfig.h"
#include "SquidTime.h"
#include "StatCounters.h"
// implemented in client_side_reply.cc until sides have a common parent
void purgeEntriesByUrl(HttpRequest * req, const char *url);
-ServerStateData::ServerStateData(FwdState *theFwdState): AsyncJob("ServerStateData"),
+Client::Client(FwdState *theFwdState): AsyncJob("Client"),
requestSender(NULL),
#if USE_ADAPTATION
adaptedHeadSource(NULL),
fwd = theFwdState;
entry = fwd->entry;
- entry->lock("ServerStateData");
+ entry->lock("Client");
request = fwd->request;
HTTPMSGLOCK(request);
}
-ServerStateData::~ServerStateData()
+Client::~Client()
{
// paranoid: check that swanSong has been called
assert(!requestBodySource);
assert(!adaptedBodySource);
#endif
- entry->unlock("ServerStateData");
+ entry->unlock("Client");
HTTPMSGUNLOCK(request);
HTTPMSGUNLOCK(theVirginReply);
}
void
-ServerStateData::swanSong()
+Client::swanSong()
{
// get rid of our piping obligations
if (requestBodySource != NULL)
}
HttpReply *
-ServerStateData::virginReply()
+Client::virginReply()
{
assert(theVirginReply);
return theVirginReply;
}
const HttpReply *
-ServerStateData::virginReply() const
+Client::virginReply() const
{
assert(theVirginReply);
return theVirginReply;
}
HttpReply *
-ServerStateData::setVirginReply(HttpReply *rep)
+Client::setVirginReply(HttpReply *rep)
{
debugs(11,5, HERE << this << " setting virgin reply to " << rep);
assert(!theVirginReply);
}
HttpReply *
-ServerStateData::finalReply()
+Client::finalReply()
{
assert(theFinalReply);
return theFinalReply;
}
HttpReply *
-ServerStateData::setFinalReply(HttpReply *rep)
+Client::setFinalReply(HttpReply *rep)
{
debugs(11,5, HERE << this << " setting final reply to " << rep);
// called when no more server communication is expected; may quit
void
-ServerStateData::serverComplete()
+Client::serverComplete()
{
debugs(11,5,HERE << "serverComplete " << this);
}
void
-ServerStateData::serverComplete2()
+Client::serverComplete2()
{
debugs(11,5,HERE << "serverComplete2 " << this);
completeForwarding();
}
-bool ServerStateData::doneAll() const
+bool Client::doneAll() const
{
return doneWithServer() &&
#if USE_ADAPTATION
// FTP side overloads this to work around multiple calls to fwd->complete
void
-ServerStateData::completeForwarding()
+Client::completeForwarding()
{
debugs(11,5, HERE << "completing forwarding for " << fwd);
assert(fwd != NULL);
}
// Register to receive request body
-bool ServerStateData::startRequestBodyFlow()
+bool Client::startRequestBodyFlow()
{
HttpRequest *r = originalRequest();
assert(r->body_pipe != NULL);
// Entry-dependent callbacks use this check to quit if the entry went bad
bool
-ServerStateData::abortOnBadEntry(const char *abortReason)
+Client::abortOnBadEntry(const char *abortReason)
{
if (entry->isAccepting())
return false;
// more request or adapted response body is available
void
-ServerStateData::noteMoreBodyDataAvailable(BodyPipe::Pointer bp)
+Client::noteMoreBodyDataAvailable(BodyPipe::Pointer bp)
{
#if USE_ADAPTATION
if (adaptedBodySource == bp) {
// the entire request or adapted response body was provided, successfully
void
-ServerStateData::noteBodyProductionEnded(BodyPipe::Pointer bp)
+Client::noteBodyProductionEnded(BodyPipe::Pointer bp)
{
#if USE_ADAPTATION
if (adaptedBodySource == bp) {
// premature end of the request or adapted response body production
void
-ServerStateData::noteBodyProducerAborted(BodyPipe::Pointer bp)
+Client::noteBodyProducerAborted(BodyPipe::Pointer bp)
{
#if USE_ADAPTATION
if (adaptedBodySource == bp) {
// more origin request body data is available
void
-ServerStateData::handleMoreRequestBodyAvailable()
+Client::handleMoreRequestBodyAvailable()
{
if (!requestSender)
sendMoreRequestBody();
// there will be no more handleMoreRequestBodyAvailable calls
void
-ServerStateData::handleRequestBodyProductionEnded()
+Client::handleRequestBodyProductionEnded()
{
receivedWholeRequestBody = true;
if (!requestSender)
// called when we are done sending request body; kids extend this
void
-ServerStateData::doneSendingRequestBody()
+Client::doneSendingRequestBody()
{
debugs(9,3, HERE << "done sending request body");
assert(requestBodySource != NULL);
// called when body producers aborts; kids extend this
void
-ServerStateData::handleRequestBodyProducerAborted()
+Client::handleRequestBodyProducerAborted()
{
if (requestSender != NULL)
debugs(9,3, HERE << "fyi: request body aborted while we were sending");
// called when we wrote request headers(!) or a part of the body
void
-ServerStateData::sentRequestBody(const CommIoCbParams &io)
+Client::sentRequestBody(const CommIoCbParams &io)
{
debugs(11, 5, "sentRequestBody: FD " << io.fd << ": size " << io.size << ": errflag " << io.flag << ".");
debugs(32,3,HERE << "sentRequestBody called");
}
void
-ServerStateData::sendMoreRequestBody()
+Client::sendMoreRequestBody()
{
assert(requestBodySource != NULL);
assert(!requestSender);
MemBuf buf;
if (getMoreRequestBody(buf) && buf.contentSize() > 0) {
debugs(9,3, HERE << "will write " << buf.contentSize() << " request body bytes");
- typedef CommCbMemFunT<ServerStateData, CommIoCbParams> Dialer;
- requestSender = JobCallback(93,3, Dialer, this, ServerStateData::sentRequestBody);
+ typedef CommCbMemFunT<Client, CommIoCbParams> Dialer;
+ requestSender = JobCallback(93,3, Dialer, this, Client::sentRequestBody);
Comm::Write(conn, &buf, requestSender);
} else {
debugs(9,3, HERE << "will wait for more request body bytes or eof");
/// either fill buf with available [encoded] request body bytes or return false
bool
-ServerStateData::getMoreRequestBody(MemBuf &buf)
+Client::getMoreRequestBody(MemBuf &buf)
{
// default implementation does not encode request body content
Must(requestBodySource != NULL);
// some HTTP methods should purge matching cache entries
void
-ServerStateData::maybePurgeOthers()
+Client::maybePurgeOthers()
{
// only some HTTP methods should purge matching cache entries
if (!request->method.purgesOthers())
/// called when we have final (possibly adapted) reply headers; kids extend
void
-ServerStateData::haveParsedReplyHeaders()
+Client::haveParsedReplyHeaders()
{
Must(theFinalReply);
maybePurgeOthers();
/// whether to prevent caching of an otherwise cachable response
bool
-ServerStateData::blockCaching()
+Client::blockCaching()
{
if (const Acl::Tree *acl = Config.accessList.storeMiss) {
// This relatively expensive check is not in StoreEntry::checkCachable:
}
HttpRequest *
-ServerStateData::originalRequest()
+Client::originalRequest()
{
return request;
}
#if USE_ADAPTATION
/// Initiate an asynchronous adaptation transaction which will call us back.
void
-ServerStateData::startAdaptation(const Adaptation::ServiceGroupPointer &group, HttpRequest *cause)
+Client::startAdaptation(const Adaptation::ServiceGroupPointer &group, HttpRequest *cause)
{
- debugs(11, 5, "ServerStateData::startAdaptation() called");
+ debugs(11, 5, "Client::startAdaptation() called");
// check whether we should be sending a body as well
// start body pipe to feed ICAP transaction if needed
assert(!virginBodyDestination);
// properly cleans up ICAP-related state
// may be called multiple times
-void ServerStateData::cleanAdaptation()
+void Client::cleanAdaptation()
{
debugs(11,5, HERE << "cleaning ICAP; ACL: " << adaptationAccessCheckPending);
}
bool
-ServerStateData::doneWithAdaptation() const
+Client::doneWithAdaptation() const
{
return !adaptationAccessCheckPending &&
!virginBodyDestination && !adaptedHeadSource && !adaptedBodySource;
// sends virgin reply body to ICAP, buffering excesses if needed
void
-ServerStateData::adaptVirginReplyBody(const char *data, ssize_t len)
+Client::adaptVirginReplyBody(const char *data, ssize_t len)
{
assert(startedAdaptation);
// can supply more virgin response body data
void
-ServerStateData::noteMoreBodySpaceAvailable(BodyPipe::Pointer)
+Client::noteMoreBodySpaceAvailable(BodyPipe::Pointer)
{
if (responseBodyBuffer) {
addVirginReplyBody(NULL, 0); // kick the buffered fragment alive again
// the consumer of our virgin response body aborted
void
-ServerStateData::noteBodyConsumerAborted(BodyPipe::Pointer)
+Client::noteBodyConsumerAborted(BodyPipe::Pointer)
{
stopProducingFor(virginBodyDestination, false);
// received adapted response headers (body may follow)
void
-ServerStateData::noteAdaptationAnswer(const Adaptation::Answer &answer)
+Client::noteAdaptationAnswer(const Adaptation::Answer &answer)
{
clearAdaptation(adaptedHeadSource); // we do not expect more messages
}
void
-ServerStateData::handleAdaptedHeader(HttpMsg *msg)
+Client::handleAdaptedHeader(HttpMsg *msg)
{
if (abortOnBadEntry("entry went bad while waiting for adapted headers")) {
// If the adapted response has a body, the ICAP side needs to know
}
void
-ServerStateData::resumeBodyStorage()
+Client::resumeBodyStorage()
{
if (abortOnBadEntry("store entry aborted while kick producer callback"))
return;
// more adapted response body is available
void
-ServerStateData::handleMoreAdaptedBodyAvailable()
+Client::handleMoreAdaptedBodyAvailable()
{
if (abortOnBadEntry("entry refuses adapted body"))
return;
if (spaceAvailable < contentSize ) {
// No or partial body data consuming
- typedef NullaryMemFunT<ServerStateData> Dialer;
- AsyncCall::Pointer call = asyncCall(93, 5, "ServerStateData::resumeBodyStorage",
- Dialer(this, &ServerStateData::resumeBodyStorage));
+ typedef NullaryMemFunT<Client> Dialer;
+ AsyncCall::Pointer call = asyncCall(93, 5, "Client::resumeBodyStorage",
+ Dialer(this, &Client::resumeBodyStorage));
entry->deferProducer(call);
}
// the entire adapted response body was produced, successfully
void
-ServerStateData::handleAdaptedBodyProductionEnded()
+Client::handleAdaptedBodyProductionEnded()
{
if (abortOnBadEntry("entry went bad while waiting for adapted body eof"))
return;
}
void
-ServerStateData::endAdaptedBodyConsumption()
+Client::endAdaptedBodyConsumption()
{
stopConsumingFrom(adaptedBodySource);
handleAdaptationCompleted();
}
// premature end of the adapted response body
-void ServerStateData::handleAdaptedBodyProducerAborted()
+void Client::handleAdaptedBodyProducerAborted()
{
stopConsumingFrom(adaptedBodySource);
handleAdaptationAborted();
// common part of noteAdaptationAnswer and handleAdaptedBodyProductionEnded
void
-ServerStateData::handleAdaptationCompleted()
+Client::handleAdaptationCompleted()
{
debugs(11,5, HERE << "handleAdaptationCompleted");
cleanAdaptation();
// common part of noteAdaptation*Aborted and noteBodyConsumerAborted methods
void
-ServerStateData::handleAdaptationAborted(bool bypassable)
+Client::handleAdaptationAborted(bool bypassable)
{
debugs(11,5, HERE << "handleAdaptationAborted; bypassable: " << bypassable <<
", entry empty: " << entry->isEmpty());
// adaptation service wants us to deny HTTP client access to this response
void
-ServerStateData::handleAdaptationBlocked(const Adaptation::Answer &answer)
+Client::handleAdaptationBlocked(const Adaptation::Answer &answer)
{
debugs(11,5, HERE << answer.ruleId);
}
void
-ServerStateData::noteAdaptationAclCheckDone(Adaptation::ServiceGroupPointer group)
+Client::noteAdaptationAclCheckDone(Adaptation::ServiceGroupPointer group)
{
adaptationAccessCheckPending = false;
#endif
void
-ServerStateData::sendBodyIsTooLargeError()
+Client::sendBodyIsTooLargeError()
{
ErrorState *err = new ErrorState(ERR_TOO_BIG, Http::scForbidden, request);
fwd->fail(err);
// TODO: when HttpStateData sends all errors to ICAP,
// we should be able to move this at the end of setVirginReply().
void
-ServerStateData::adaptOrFinalizeReply()
+Client::adaptOrFinalizeReply()
{
#if USE_ADAPTATION
// TODO: merge with client side and return void to hide the on/off logic?
/// initializes bodyBytesRead stats if needed and applies delta
void
-ServerStateData::adjustBodyBytesRead(const int64_t delta)
+Client::adjustBodyBytesRead(const int64_t delta)
{
int64_t &bodyBytesRead = originalRequest()->hier.bodyBytesRead;
}
void
-ServerStateData::addVirginReplyBody(const char *data, ssize_t len)
+Client::addVirginReplyBody(const char *data, ssize_t len)
{
adjustBodyBytesRead(len);
// writes virgin or adapted reply body to store
void
-ServerStateData::storeReplyBody(const char *data, ssize_t len)
+Client::storeReplyBody(const char *data, ssize_t len)
{
// write even if len is zero to push headers towards the client side
entry->write (StoreIOBuffer(len, currentOffset, (char*)data));
currentOffset += len;
}
-size_t ServerStateData::replyBodySpace(const MemBuf &readBuf,
+size_t Client::replyBodySpace(const MemBuf &readBuf,
const size_t minSpace) const
{
size_t space = readBuf.spaceSize(); // available space w/o heroic measures
size_t adaptation_space =
virginBodyDestination->buf().potentialSpaceSize();
- debugs(11,9, "ServerStateData may read up to min(" <<
+ debugs(11,9, "Client may read up to min(" <<
adaptation_space << ", " << space << ") bytes");
if (adaptation_space < space)