class HttpControlMsg
{
public:
- typedef HttpMsgPointerT<HttpReply> MsgPtr;
typedef AsyncCall::Pointer Callback;
- HttpControlMsg(const MsgPtr &aReply, const Callback &aCallback):
+ HttpControlMsg(const HttpReply::Pointer &aReply, const Callback &aCallback):
reply(aReply), cbSuccess(aCallback) {}
public:
- MsgPtr reply; ///< the 1xx message being forwarded
+ HttpReply::Pointer reply; ///< the 1xx message being forwarded
Callback cbSuccess; ///< called after successfully writing the 1xx message
// We could add an API to notify of send failures as well, but the
packFirstLineInto(&p, true);
packerClean(&p);
}
-
-// use HTTPMSGLOCK() instead of calling this directly
-HttpMsg *
-HttpMsg::_lock()
-{
- lock();
- return this;
-}
-
-// use HTTPMSGUNLOCK() instead of calling this directly
-void
-HttpMsg::_unlock()
-{
- if (unlock() == 0)
- delete this;
-}
#include "HttpVersion.h"
#include "typedefs.h"
-// common parts of HttpRequest and HttpReply
-
-template <class Msg>
-class HttpMsgPointerT;
-
+/// common parts of HttpRequest and HttpReply
class HttpMsg : public RefCountable
{
public:
- typedef HttpMsgPointerT<HttpMsg> Pointer;
+ typedef RefCount<HttpMsg> Pointer;
HttpMsg(http_hdr_owner_type owner);
virtual ~HttpMsg();
void packInto(Packer * p, bool full_uri) const;
- virtual HttpMsg *_lock(); // please use HTTPMSGLOCK()
- virtual void _unlock(); // please use HTTPMSGUNLOCK()
-
///< produce a message copy, except for a few connection-specific settings
virtual HttpMsg *clone() const = 0; ///< \todo rename: not a true copy?
int httpMsgIsolateHeaders(const char **parse_start, int len, const char **blk_start, const char **blk_end);
-#define HTTPMSGUNLOCK(a) if(a){(a)->_unlock();(a)=NULL;}
-#define HTTPMSGLOCK(a) (a)->_lock()
-
-// TODO: replace HTTPMSGLOCK with general RefCounting and delete this class
-/// safe HttpMsg pointer wrapper that locks and unlocks the message
-template <class Msg>
-class HttpMsgPointerT
-{
-public:
- HttpMsgPointerT(): msg(NULL) {}
- explicit HttpMsgPointerT(Msg *m): msg(m) { lock(); }
- virtual ~HttpMsgPointerT() { unlock(); }
-
- HttpMsgPointerT(const HttpMsgPointerT &p): msg(p.msg) { lock(); }
- HttpMsgPointerT &operator =(const HttpMsgPointerT &p)
- { if (msg != p.msg) { unlock(); msg = p.msg; lock(); } return *this; }
- HttpMsgPointerT &operator =(Msg *newM)
- { if (msg != newM) { unlock(); msg = newM; lock(); } return *this; }
-
- /// support converting a child msg pointer into a parent msg pointer
- template <typename Other>
- HttpMsgPointerT(const HttpMsgPointerT<Other> &o): msg(o.raw()) { lock(); }
-
- /// support assigning a child msg pointer to a parent msg pointer
- template <typename Other>
- HttpMsgPointerT &operator =(const HttpMsgPointerT<Other> &o)
- { if (msg != o.raw()) { unlock(); msg = o.raw(); lock(); } return *this; }
-
- Msg &operator *() { return *msg; }
- const Msg &operator *() const { return *msg; }
- Msg *operator ->() { return msg; }
- const Msg *operator ->() const { return msg; }
- operator Msg *() const { return msg; }
- // add more as needed
-
- /// public access for HttpMsgPointerT copying and assignment; avoid
- Msg *raw() const { return msg; }
-
-protected:
- void lock() { if (msg) HTTPMSGLOCK(msg); } ///< prevent msg destruction
- void unlock() { HTTPMSGUNLOCK(msg); } ///< allows/causes msg destruction
-
-private:
- Msg *msg;
-};
-
-/// convenience wrapper to create HttpMsgPointerT<> object based on msg type
-template <class Msg>
-inline
-HttpMsgPointerT<Msg> HttpMsgPointer(Msg *msg)
-{
- return HttpMsgPointerT<Msg>(msg);
-}
+#define HTTPMSGUNLOCK(a) if (a) { if ((a)->unlock() == 0) delete (a); (a)=NULL; }
+#define HTTPMSGLOCK(a) (a)->lock()
#endif /* SQUID_HTTPMSG_H */
}
void
-HttpReply::calcMaxBodySize(HttpRequest& request)
+HttpReply::calcMaxBodySize(HttpRequest& request) const
{
// hack: -2 is used as "we have not calculated max body size yet" state
if (bodySizeMax != -2) // already tried
return;
ACLFilledChecklist ch(NULL, &request, NULL);
- ch.reply = HTTPMSGLOCK(this); // XXX: this lock makes method non-const
+ // XXX: cont-cast becomes irrelevant when checklist is HttpReply::Pointer
+ ch.reply = const_cast<HttpReply *>(this);
+ HTTPMSGLOCK(ch.reply);
for (AclSizeLimit *l = Config.ReplyBodySize; l; l = l -> next) {
/* if there is no ACL list or if the ACLs listed match use this size value */
if (!l->aclList || ch.fastCheck(l->aclList) == ACCESS_ALLOWED) {
{
public:
- typedef HttpMsgPointerT<HttpReply> Pointer;
+ typedef RefCount<HttpReply> Pointer;
MEMPROXY_CLASS(HttpReply);
HttpReply();
virtual void reset();
- /// \par use HTTPMSGLOCK() instead of calling this directly
- virtual HttpReply *_lock() {
- return static_cast<HttpReply*>(HttpMsg::_lock());
- };
-
- //virtual void unlock(); // only needed for debugging
-
/**
\retval true on success
\retval false and sets *error to zero when needs more data
/** Calculates and stores maximum body size if needed.
* Used by receivedBodyTooLarge() and expectedBodyTooLarge().
*/
- void calcMaxBodySize(HttpRequest& request);
+ void calcMaxBodySize(HttpRequest& request) const;
String removeStaleWarningValues(const String &value);
{
public:
- typedef HttpMsgPointerT<HttpRequest> Pointer;
+ typedef RefCount<HttpRequest> Pointer;
MEMPROXY_CLASS(HttpRequest);
HttpRequest();
~HttpRequest();
virtual void reset();
- // use HTTPMSGLOCK() instead of calling this directly
- virtual HttpRequest *_lock() {
- return static_cast<HttpRequest*>(HttpMsg::_lock());
- };
-
void initHTTP(const HttpRequestMethod& aMethod, AnyP::ProtocolType aProtocol, const char *aUrlpath);
virtual HttpRequest *clone() const;
MemObject::MemObject(char const *aUrl, char const *aLog_url)
{
debugs(20, 3, HERE << "new MemObject " << this);
- HttpReply *rep = new HttpReply;
+ _reply = new HttpReply;
+ HTTPMSGLOCK(_reply);
- _reply = HTTPMSGLOCK(rep);
url = xstrdup(aUrl);
#if URL_CHECKSUM_DEBUG
MemObject::replaceHttpReply(HttpReply *newrep)
{
HTTPMSGUNLOCK(_reply);
- _reply = HTTPMSGLOCK(newrep);
+ _reply = newrep;
+ HTTPMSGLOCK(_reply);
}
struct LowestMemReader : public unary_function<store_client, void> {
typedef Values::iterator VLI;
ACLFilledChecklist ch(NULL, request, NULL);
+ ch.reply = reply;
if (reply)
- ch.reply = HTTPMSGLOCK(reply);
+ HTTPMSGLOCK(ch.reply);
for (VLI i = values.begin(); i != values.end(); ++i ) {
const int ret= ch.fastCheck((*i)->aclList);
entry->lock();
- request = HTTPMSGLOCK(fwd->request);
+ request = fwd->request;
+ HTTPMSGLOCK(request);
}
ServerStateData::~ServerStateData()
debugs(11,5, HERE << this << " setting virgin reply to " << rep);
assert(!theVirginReply);
assert(rep);
- theVirginReply = HTTPMSGLOCK(rep);
+ theVirginReply = rep;
+ HTTPMSGLOCK(theVirginReply);
return theVirginReply;
}
assert(!theFinalReply);
assert(rep);
- theFinalReply = HTTPMSGLOCK(rep);
+ theFinalReply = rep;
+ HTTPMSGLOCK(theFinalReply);
// give entry the reply because haveParsedReplyHeaders() expects it there
entry->replaceHttpReply(theFinalReply, false); // but do not write yet
switch (answer.kind) {
case Adaptation::Answer::akForward:
- handleAdaptedHeader(answer.message);
+ handleAdaptedHeader(const_cast<HttpMsg*>(answer.message.getRaw()));
break;
case Adaptation::Answer::akBlock:
{
LOCAL_ARRAY(char, asres, 4096);
StoreEntry *e;
- HttpRequest *req;
ASState *asState;
asState = cbdataAlloc(ASState);
asState->dataRead = 0;
debugs(53, 3, "asnCacheStart: AS " << as);
snprintf(asres, 4096, "whois://%s/!gAS%d", Config.as_whois_server, as);
asState->as_number = as;
- req = HttpRequest::CreateFromUrl(asres);
- assert(NULL != req);
- asState->request = HTTPMSGLOCK(req);
+ asState->request = HttpRequest::CreateFromUrl(asres);
+ assert(NULL != asState->request);
+ HTTPMSGLOCK(asState->request);
if ((e = storeGetPublic(asres, Http::METHOD_GET)) == NULL) {
e = storeCreateEntry(asres, asres, RequestFlags(), Http::METHOD_GET);
accessList = cbdataReference(A);
if (http_request != NULL) {
- request = HTTPMSGLOCK(http_request);
+ request = http_request;
+ HTTPMSGLOCK(request);
#if FOLLOW_X_FORWARDED_FOR
if (Config.onoff.acl_uses_indirect_client)
src_addr = request->indirect_client_addr;
/* BUG 2526: what to do when r->acl is empty?? */
// XXX: we do not have access to conn->rfc931 here.
acl_checklist = new ACLFilledChecklist(r->acl, filter.request, dash_str);
- acl_checklist->reply = filter.reply ? HTTPMSGLOCK(filter.reply) : NULL;
+ acl_checklist->reply = filter.reply;
+ HTTPMSGLOCK(acl_checklist->reply);
acl_checklist->nonBlockingCheck(AccessCheckCallbackWrapper, this);
return;
}
std::ostream &print(std::ostream &os) const;
public:
- HttpMsgPointerT<HttpMsg> message; ///< HTTP request or response to forward
+ HttpMsg::Pointer message; ///< HTTP request or response to forward
String ruleId; ///< ACL (or similar rule) name that blocked forwarding
bool final; ///< whether the error, if any, cannot be bypassed
Kind kind; ///< the type of the answer
AsyncJob("Iterator"),
Adaptation::Initiate("Iterator"),
theGroup(aGroup),
- theMsg(HTTPMSGLOCK(aMsg)),
- theCause(aCause ? HTTPMSGLOCK(aCause) : NULL),
+ theMsg(aMsg),
+ theCause(aCause),
theLauncher(0),
iterations(0),
adapted(false)
{
+ if (theCause != NULL)
+ HTTPMSGLOCK(theCause);
+
+ if (theMsg != NULL)
+ HTTPMSGLOCK(theMsg);
}
Adaptation::Iterator::~Iterator()
{
switch (answer.kind) {
case Answer::akForward:
- handleAdaptedHeader(answer.message);
+ handleAdaptedHeader(const_cast<HttpMsg*>(answer.message.getRaw()));
break;
case Answer::akBlock:
Must(aMsg);
HTTPMSGUNLOCK(theMsg);
- theMsg = HTTPMSGLOCK(aMsg);
+ theMsg = aMsg;
+ HTTPMSGLOCK(theMsg);
adapted = true;
clearAdaptation(theLauncher);
{
clear();
if (aHeader) {
- header = HTTPMSGLOCK(aHeader);
+ header = aHeader;
+ HTTPMSGLOCK(header);
body_pipe = header->body_pipe;
}
}
#include "HttpReply.h"
#include "adaptation/ServiceFilter.h"
-Adaptation::ServiceFilter::ServiceFilter(Method aMethod, VectPoint aPoint,
- HttpRequest *aReq, HttpReply *aRep): method(aMethod), point(aPoint),
- request(HTTPMSGLOCK(aReq)),
- reply(aRep ? HTTPMSGLOCK(aRep) : NULL)
+Adaptation::ServiceFilter::ServiceFilter(Method aMethod, VectPoint aPoint, HttpRequest *aReq, HttpReply *aRep):
+ method(aMethod),
+ point(aPoint),
+ request(aReq),
+ reply(aRep)
{
+ if (reply)
+ HTTPMSGLOCK(reply);
+
// a lot of code assumes that there is always a virgin request or cause
assert(request);
+ HTTPMSGLOCK(request);
}
Adaptation::ServiceFilter::ServiceFilter(const ServiceFilter &f):
- method(f.method), point(f.point),
- request(HTTPMSGLOCK(f.request)),
- reply(f.reply ? HTTPMSGLOCK(f.reply) : NULL)
+ method(f.method),
+ point(f.point),
+ request(f.request),
+ reply(f.reply)
{
+ if (request)
+ HTTPMSGLOCK(request);
+
+ if (reply)
+ HTTPMSGLOCK(reply);
}
Adaptation::ServiceFilter::~ServiceFilter()
point = f.point;
HTTPMSGUNLOCK(request);
HTTPMSGUNLOCK(reply);
- request = HTTPMSGLOCK(f.request);
- reply = f.reply ? HTTPMSGLOCK(f.reply) : NULL;
+ request = f.request;
+ HTTPMSGLOCK(request);
+ reply = f.reply;
+ if (reply)
+ HTTPMSGLOCK(reply);
}
return *this;
}
void setCause(HttpRequest *r) {
if (r) {
HTTPMSGUNLOCK(cause);
- cause = HTTPMSGLOCK(r);
+ cause = r;
+ HTTPMSGLOCK(cause);
} else {
assert(!cause);
}
void setHeader(Header *h) {
HTTPMSGUNLOCK(header);
- header = HTTPMSGLOCK(h);
+ header = h;
+ HTTPMSGLOCK(header);
body_pipe = header->body_pipe;
}
ACLFilledChecklist *cl =
new ACLFilledChecklist(TheConfig.repeat, info.icapRequest, dash_str);
- cl->reply = HTTPMSGLOCK(info.icapReply);
+ cl->reply = info.icapReply;
+ HTTPMSGLOCK(cl->reply);
bool result = cl->fastCheck() == ACCESS_ALLOWED;
delete cl;
Adaptation::Icap::XactAbortInfo::XactAbortInfo(HttpRequest *anIcapRequest,
HttpReply *anIcapReply, bool beRetriable, bool beRepeatable):
- icapRequest(anIcapRequest ? HTTPMSGLOCK(anIcapRequest) : NULL),
- icapReply(anIcapReply ? HTTPMSGLOCK(anIcapReply) : NULL),
- isRetriable(beRetriable), isRepeatable(beRepeatable)
+ icapRequest(anIcapRequest),
+ icapReply(anIcapReply),
+ isRetriable(beRetriable),
+ isRepeatable(beRepeatable)
{
+ if (icapRequest)
+ HTTPMSGLOCK(icapRequest);
+ if (icapReply)
+ HTTPMSGLOCK(icapReply);
}
Adaptation::Icap::XactAbortInfo::XactAbortInfo(const Adaptation::Icap::XactAbortInfo &i):
- icapRequest(i.icapRequest ? HTTPMSGLOCK(i.icapRequest) : NULL),
- icapReply(i.icapReply ? HTTPMSGLOCK(i.icapReply) : NULL),
- isRetriable(i.isRetriable), isRepeatable(i.isRepeatable)
+ icapRequest(i.icapRequest),
+ icapReply(i.icapReply),
+ isRetriable(i.isRetriable),
+ isRepeatable(i.isRepeatable)
{
+ if (icapRequest)
+ HTTPMSGLOCK(icapRequest);
+ if (icapReply)
+ HTTPMSGLOCK(icapReply);
}
Adaptation::Icap::XactAbortInfo::~XactAbortInfo()
{
Must(state.sending == State::sendingUndecided);
- if (!parseHead(icapReply))
+ if (!parseHead(icapReply.getRaw()))
return;
if (httpHeaderHasConnDir(&icapReply->header, "close")) {
{
HttpMsg::Pointer newHead;
if (dynamic_cast<const HttpRequest*>(oldHead)) {
- HttpRequest::Pointer newR(new HttpRequest);
- newHead = newR;
+ newHead = new HttpRequest;
} else if (dynamic_cast<const HttpReply*>(oldHead)) {
newHead = new HttpReply;
}
newHead->inheritProperties(oldHead);
- adapted.setHeader(newHead);
+ adapted.setHeader(newHead.getRaw());
}
// parse the buffer back
al.cache.caddr = request_->client_addr;
- al.request = HTTPMSGLOCK(request_);
- if (reply_)
- al.reply = HTTPMSGLOCK(reply_);
- else
+ al.request = request_;
+ HTTPMSGLOCK(al.request);
+ if (reply_) {
+ al.reply = reply_;
+ HTTPMSGLOCK(al.reply);
+ } else
al.reply = NULL;
if (h->rfc931.size())
if (const HttpRequest* old_request = dynamic_cast<const HttpRequest*>(head)) {
HttpRequest::Pointer new_request(new HttpRequest);
Must(old_request->canonical);
- urlParse(old_request->method, old_request->canonical, new_request);
+ urlParse(old_request->method, old_request->canonical, new_request.getRaw());
new_request->http_ver = old_request->http_ver;
- headClone = new_request;
+ headClone = new_request.getRaw();
} else if (const HttpReply *old_reply = dynamic_cast<const HttpReply*>(head)) {
HttpReply::Pointer new_reply(new HttpReply);
new_reply->sline = old_reply->sline;
- headClone = new_reply;
+ headClone = new_reply.getRaw();
}
Must(headClone != NULL);
headClone->inheritProperties(head);
headClone->header.removeHopByHopEntries();
// pack polished HTTP header
- packHead(httpBuf, headClone);
+ packHead(httpBuf, headClone.getRaw());
// headClone unlocks and, hence, deletes the message we packed
}
debugs(93, 7, HERE << "readAll=" << readAll);
icap_tio_finish = current_time;
setOutcome(xoOpt);
- sendAnswer(Answer::Forward(icapReply));
+ sendAnswer(Answer::Forward(icapReply.getRaw()));
Must(done()); // there should be nothing else to do
return;
}
HttpReply::Pointer r(new HttpReply);
r->protoPrefix = "ICAP/"; // TODO: make an IcapReply class?
- if (!parseHttpMsg(r)) // throws on errors
+ if (!parseHttpMsg(r.getRaw())) // throws on errors
return false;
if (httpHeaderHasConnDir(&r->header, "close"))
// al.cache.caddr = 0;
al.icap.reqMethod = Adaptation::methodOptions;
- if (icapReply && al.icap.bytesRead > icapReply->hdr_sz)
+ if (icapReply != NULL && al.icap.bytesRead > icapReply->hdr_sz)
al.icap.bodyBytesRead = al.icap.bytesRead - icapReply->hdr_sz;
Adaptation::Icap::Xaction::finalizeLogInfo();
}
Must(answer.kind == Answer::akForward); // no akBlock for OPTIONS requests
- HttpMsg *msg = answer.message;
+ const HttpMsg *msg = answer.message.getRaw();
Must(msg);
debugs(93,5, HERE << "is interpreting new options " << status());
Adaptation::Icap::Options *newOptions = NULL;
- if (HttpReply *r = dynamic_cast<HttpReply*>(msg)) {
+ if (const HttpReply *r = dynamic_cast<const HttpReply*>(msg)) {
newOptions = new Adaptation::Icap::Options;
newOptions->configure(r);
} else {
{
debugs(93,3, typeName << " constructed, this=" << this <<
" [icapx" << id << ']'); // we should not call virtual status() here
- icapRequest = HTTPMSGLOCK(new HttpRequest);
+ icapRequest = new HttpRequest;
+ HTTPMSGLOCK(icapRequest);
icap_tr_start = current_time;
}
void Adaptation::Icap::Xaction::tellQueryAborted()
{
if (theInitiator.set()) {
- Adaptation::Icap::XactAbortInfo abortInfo(icapRequest, icapReply,
+ Adaptation::Icap::XactAbortInfo abortInfo(icapRequest, icapReply.getRaw(),
retriable(), repeatable());
Launcher *launcher = dynamic_cast<Launcher*>(theInitiator.get());
// launcher may be nil if initiator is invalid
al.icap.ioTime = tvSubMsec(icap_tio_start, icap_tio_finish);
al.icap.trTime = tvSubMsec(icap_tr_start, current_time);
- al.icap.request = HTTPMSGLOCK(icapRequest);
- if (icapReply) {
- al.icap.reply = HTTPMSGLOCK(icapReply);
+ al.icap.request = icapRequest;
+ HTTPMSGLOCK(al.icap.request);
+ if (icapReply != NULL) {
+ al.icap.reply = icapReply.getRaw();
+ HTTPMSGLOCK(al.icap.reply);
al.icap.resStatus = icapReply->sline.status;
}
}
void
ClientSocketContext::writeControlMsg(HttpControlMsg &msg)
{
- HttpReply *rep = msg.reply;
- Must(rep);
+ const HttpReply::Pointer rep(msg.reply);
+ Must(rep != NULL);
// apply selected clientReplyContext::buildReplyHeader() mods
// it is not clear what headers are required for control messages
ACLFilledChecklist *checklist = clientAclChecklistCreate(Config.accessList.log, this);
- if (al->reply)
- checklist->reply = HTTPMSGLOCK(al->reply);
+ if (al->reply) {
+ checklist->reply = al->reply;
+ HTTPMSGLOCK(checklist->reply);
+ }
if (!Config.accessList.log || checklist->fastCheck() == ACCESS_ALLOWED) {
- if (request)
- al->adapted_request = HTTPMSGLOCK(request);
+ if (request) {
+ al->adapted_request = request;
+ HTTPMSGLOCK(al->adapted_request);
+ }
accessLogLog(al, checklist);
if (request)
updateCounters();
context->sendBody(rep, receivedData);
else {
assert(rep);
- http->al->reply = HTTPMSGLOCK(rep);
+ http->al->reply = rep;
+ HTTPMSGLOCK(http->al->reply);
context->sendStartOfMessage(rep, receivedData);
}
repContext->setReplyToStoreEntry(sslServerBump->entry);
// save the original request for logging purposes
- if (!context->http->al->request)
- context->http->al->request = HTTPMSGLOCK(http->request);
+ if (!context->http->al->request) {
+ context->http->al->request = http->request;
+ HTTPMSGLOCK(context->http->al->request);
+ }
// Get error details from the fake certificate-peeking request.
http->request->detailError(sslServerBump->request->errType, sslServerBump->request->errDetail);
sslServerBump->serverCert.get(), NULL);
err->detail = errDetail;
// Save the original request for logging purposes.
- if (!context->http->al->request)
- context->http->al->request = HTTPMSGLOCK(request);
+ if (!context->http->al->request) {
+ context->http->al->request = request;
+ HTTPMSGLOCK(context->http->al->request);
+ }
repContext->setReplyToError(request->method, err);
assert(context->http->out.offset == 0);
context->pullData();
if ((request = HttpRequest::CreateFromUrlAndMethod(http->uri, method)) == NULL) {
clientStreamNode *node = context->getClientReplyContext();
debugs(33, 5, "Invalid URL: " << http->uri);
- conn->quitAfterError(request);
+ conn->quitAfterError(request.getRaw());
// setLogUri should called before repContext->setReplyToError
setLogUri(http, http->uri, true);
clientReplyContext *repContext = dynamic_cast<clientReplyContext *>(node->data.getRaw());
clientStreamNode *node = context->getClientReplyContext();
debugs(33, 5, "Unsupported HTTP version discovered. :\n" << HttpParserHdrBuf(hp));
- conn->quitAfterError(request);
+ conn->quitAfterError(request.getRaw());
// setLogUri should called before repContext->setReplyToError
setLogUri(http, http->uri, true);
clientReplyContext *repContext = dynamic_cast<clientReplyContext *>(node->data.getRaw());
if (http_ver.major >= 1 && !request->parseHeader(HttpParserHdrBuf(hp), HttpParserHdrSz(hp))) {
clientStreamNode *node = context->getClientReplyContext();
debugs(33, 5, "Failed to parse request headers:\n" << HttpParserHdrBuf(hp));
- conn->quitAfterError(request);
+ conn->quitAfterError(request.getRaw());
// setLogUri should called before repContext->setReplyToError
setLogUri(http, http->uri, true);
clientReplyContext *repContext = dynamic_cast<clientReplyContext *>(node->data.getRaw());
}
request->flags.internal = http->flags.internal;
- setLogUri (http, urlCanonicalClean(request));
+ setLogUri (http, urlCanonicalClean(request.getRaw()));
request->client_addr = conn->clientConnection->remote; // XXX: remove reuest->client_addr member.
#if FOLLOW_X_FORWARDED_FOR
// indirect client gets stored here because it is an HTTP header result (from X-Forwarded-For:)
mustReplyToOptions = (method == Http::METHOD_OPTIONS) &&
(request->header.getInt64(HDR_MAX_FORWARDS) == 0);
- if (!urlCheckRequest(request) || mustReplyToOptions || unsupportedTe) {
+ if (!urlCheckRequest(request.getRaw()) || mustReplyToOptions || unsupportedTe) {
clientStreamNode *node = context->getClientReplyContext();
- conn->quitAfterError(request);
+ conn->quitAfterError(request.getRaw());
clientReplyContext *repContext = dynamic_cast<clientReplyContext *>(node->data.getRaw());
assert (repContext);
repContext->setReplyToError(ERR_UNSUP_REQ, HTTP_NOT_IMPLEMENTED, request->method, NULL,
- conn->clientConnection->remote, request, NULL, NULL);
+ conn->clientConnection->remote, request.getRaw(), NULL, NULL);
assert(context->http->out.offset == 0);
context->pullData();
goto finish;
}
- if (!chunked && !clientIsContentLengthValid(request)) {
+ if (!chunked && !clientIsContentLengthValid(request.getRaw())) {
clientStreamNode *node = context->getClientReplyContext();
clientReplyContext *repContext = dynamic_cast<clientReplyContext *>(node->data.getRaw());
assert (repContext);
- conn->quitAfterError(request);
+ conn->quitAfterError(request.getRaw());
repContext->setReplyToError(ERR_INVALID_REQ,
HTTP_LENGTH_REQUIRED, request->method, NULL,
- conn->clientConnection->remote, request, NULL, NULL);
+ conn->clientConnection->remote, request.getRaw(), NULL, NULL);
assert(context->http->out.offset == 0);
context->pullData();
goto finish;
clientStreamNode *node = context->getClientReplyContext();
clientReplyContext *repContext = dynamic_cast<clientReplyContext *>(node->data.getRaw());
assert (repContext);
- conn->quitAfterError(request);
+ conn->quitAfterError(request.getRaw());
repContext->setReplyToError(ERR_INVALID_REQ, HTTP_EXPECTATION_FAILED, request->method, http->uri,
- conn->clientConnection->remote, request, NULL, NULL);
+ conn->clientConnection->remote, request.getRaw(), NULL, NULL);
assert(context->http->out.offset == 0);
context->pullData();
goto finish;
}
}
- http->request = HTTPMSGLOCK(request);
+ http->request = request.getRaw();
+ HTTPMSGLOCK(http->request);
clientSetKeepaliveFlag(http);
// Let tunneling code be fully responsible for CONNECT requests
clientStreamNode *node = context->getClientReplyContext();
clientReplyContext *repContext = dynamic_cast<clientReplyContext *>(node->data.getRaw());
assert (repContext);
- conn->quitAfterError(request);
+ conn->quitAfterError(request.getRaw());
repContext->setReplyToError(ERR_TOO_BIG,
HTTP_REQUEST_ENTITY_TOO_LARGE, Http::METHOD_NONE, NULL,
conn->clientConnection->remote, http->request, NULL, NULL);
* be freed and the above connNoteUseOfBuffer() would hit an
* assertion, not to mention that we were accessing freed memory.
*/
- if (request && request->flags.resetTcp && Comm::IsConnOpen(conn->clientConnection)) {
+ if (request != NULL && request->flags.resetTcp && Comm::IsConnOpen(conn->clientConnection)) {
debugs(33, 3, HERE << "Sending TCP RST on " << conn->clientConnection);
conn->flags.readMore = false;
comm_reset_close(conn->clientConnection);
if (X509 *mimicCert = sslServerBump->serverCert.get())
certProperties.mimicCert.resetAndLock(mimicCert);
- ACLFilledChecklist checklist(NULL, sslServerBump->request,
+ ACLFilledChecklist checklist(NULL, sslServerBump->request.getRaw(),
clientConnection != NULL ? clientConnection->rfc931 : dash_str);
checklist.sslErrors = cbdataReference(sslServerBump->sslErrors);
sslServerBump = new Ssl::ServerBump(request);
// will call httpsPeeked() with certificate and connection, eventually
- FwdState::fwdStart(clientConnection, sslServerBump->entry, sslServerBump->request);
+ FwdState::fwdStart(clientConnection, sslServerBump->entry, sslServerBump->request.getRaw());
return;
}
{
assert(reply == NULL);
- HttpReply *rep = http->storeEntry()->getReply()->clone();
-
- reply = HTTPMSGLOCK(rep);
+ reply = http->storeEntry()->getReply()->clone();
+ HTTPMSGLOCK(reply);
if (reply->sline.protocol == AnyP::PROTO_HTTP) {
/* RFC 2616 requires us to advertise our 1.1 version (but only on real HTTP traffic) */
/** Process http_reply_access lists */
ACLFilledChecklist *replyChecklist =
clientAclChecklistCreate(Config.accessList.reply, http);
- replyChecklist->reply = HTTPMSGLOCK(reply);
+ replyChecklist->reply = reply;
+ HTTPMSGLOCK(replyChecklist->reply);
replyChecklist->nonBlockingCheck(ProcessReplyAccessResult, this);
}
* so make a fake one.
*/
- if (http->request == NULL)
- http->request = HTTPMSGLOCK(new HttpRequest(m, AnyP::PROTO_NONE, null_string));
+ if (http->request == NULL) {
+ http->request = new HttpRequest(m, AnyP::PROTO_NONE, null_string);
+ HTTPMSGLOCK(http->request);
+ }
StoreEntry *e = storeCreateEntry(storeId(), http->log_uri, reqFlags, m);
HttpVersion http_ver(1,1);
request->http_ver = http_ver;
- http->request = HTTPMSGLOCK(request);
+ http->request = request;
+ HTTPMSGLOCK(http->request);
/* optional - skip the access check ? */
http->calloutContext = new ClientRequestContext(http);
safe_free(http->uri);
http->uri = xstrdup(urlCanonical(new_request));
HTTPMSGUNLOCK(old_request);
- http->request = HTTPMSGLOCK(new_request);
+ http->request = new_request;
+ HTTPMSGLOCK(http->request);
} else {
debugs(85, DBG_CRITICAL, "ERROR: URL-rewrite produces invalid request: " <<
old_request->method << " " << urlNote->firstValue() << " " << old_request->http_ver);
assert(calloutContext);
/*Save the original request for logging purposes*/
- if (!calloutContext->http->al->request)
- calloutContext->http->al->request = HTTPMSGLOCK(request);
+ if (!calloutContext->http->al->request) {
+ calloutContext->http->al->request = request;
+ HTTPMSGLOCK(calloutContext->http->al->request);
+ }
if (!calloutContext->error) {
// CVE-2009-0801: verify the Host: header is consistent with other known details.
switch (answer.kind) {
case Adaptation::Answer::akForward:
- handleAdaptedHeader(answer.message);
+ handleAdaptedHeader(const_cast<HttpMsg*>(answer.message.getRaw()));
break;
case Adaptation::Answer::akBlock:
* Replace the old request with the new request.
*/
HTTPMSGUNLOCK(request);
- request = HTTPMSGLOCK(new_req);
+ request = new_req;
+ HTTPMSGLOCK(request);
/*
* Store the new URI for logging
*/
}
bool
-TemplateFile::loadFor(HttpRequest *request)
+TemplateFile::loadFor(const HttpRequest *request)
{
String hdr;
httpStatus = ErrorDynamicPages.items[page_id - ERR_MAX]->page_redirect;
if (req != NULL) {
- request = HTTPMSGLOCK(req);
+ request = req;
+ HTTPMSGLOCK(request);
src_addr = req->client_addr;
}
}
* template selected (eg because of a "Accept-Language: *"), or not available
* template found this function return false.
*/
- bool loadFor(HttpRequest *request);
+ bool loadFor(const HttpRequest *request);
/**
* Load the file given by "path". It uses the "parse()" method.
debugs(17, 2, HERE << "Forwarding client request " << client << ", url=" << e->url() );
entry = e;
clientConn = client;
- request = HTTPMSGLOCK(r);
+ request = r;
+ HTTPMSGLOCK(request);
pconnRace = raceImpossible;
start_t = squid_curtime;
serverDestinations.reserve(Config.forward_max_tries);
* This seems like an odd place to bind mem_obj and request.
* Might want to assert that request is NULL at this point
*/
- entry->mem_obj->request = HTTPMSGLOCK(request);
+ entry->mem_obj->request = request;
+ HTTPMSGLOCK(entry->mem_obj->request);
#if URL_CHECKSUM_DEBUG
entry->mem_obj->checkUrlChecksum();
delete err;
err = errorState;
- if (!errorState->request)
- errorState->request = HTTPMSGLOCK(request);
+ if (!errorState->request) {
+ errorState->request = request;
+ HTTPMSGLOCK(errorState->request);
+ }
if (err->type != ERR_ZERO_SIZE_OBJECT)
return;
void
HttpStateData::handle1xx(HttpReply *reply)
{
- HttpMsgPointerT<HttpReply> msg(reply); // will destroy reply if unused
+ HttpReply::Pointer msg(reply); // will destroy reply if unused
// one 1xx at a time: we must not be called while waiting for previous 1xx
Must(!flags.handling1xx);
// check whether the 1xx response forwarding is allowed by squid.conf
if (Config.accessList.reply) {
ACLFilledChecklist ch(Config.accessList.reply, originalRequest(), NULL);
- ch.reply = HTTPMSGLOCK(reply);
+ ch.reply = reply;
+ HTTPMSGLOCK(ch.reply);
if (ch.fastCheck() != ACCESS_ALLOWED) { // TODO: support slow lookups?
debugs(11, 3, HERE << "ignoring denied 1xx");
proceedAfter1xx();
ICPState::ICPState(icp_common_t &aHeader, HttpRequest *aRequest):
header(aHeader),
- request(HTTPMSGLOCK(aRequest)),
+ request(aRequest),
fd(-1),
url(NULL)
-{}
+{
+ HTTPMSGLOCK(request);
+}
ICPState::~ICPState()
{
if (NULL == r)
fatal("mimeLoadIcon: cannot parse internal URL");
- e->mem_obj->request = HTTPMSGLOCK(r);
+ e->mem_obj->request = r;
+ HTTPMSGLOCK(e->mem_obj->request);
HttpReply *reply = new HttpReply;
fake = storeCreateEntry(url, url, RequestFlags(), Http::METHOD_GET);
HttpRequest *req = HttpRequest::CreateFromUrl(url);
psstate = new ps_state;
- psstate->request = HTTPMSGLOCK(req);
+ psstate->request = req;
+ HTTPMSGLOCK(psstate->request);
psstate->entry = fake;
psstate->callback = NULL;
psstate->callback_data = cbdataReference(p);
psstate->ping.start = current_time;
mem = fake->mem_obj;
- mem->request = HTTPMSGLOCK(psstate->request);
+ mem->request = psstate->request;
+ HTTPMSGLOCK(mem->request);
mem->start_ping = current_time;
mem->ping_reply_callback = peerCountHandleIcpReply;
mem->ircb_data = psstate;
fetch = cbdataAlloc(DigestFetchState);
- fetch->request = HTTPMSGLOCK(req);
+ fetch->request = req;
+ HTTPMSGLOCK(fetch->request);
fetch->pd = cbdataReference(pd);
/* our old entry is fine */
assert(fetch->old_entry);
- if (!fetch->old_entry->mem_obj->request)
- fetch->old_entry->mem_obj->request = HTTPMSGLOCK(fetch->entry->mem_obj->request);
+ if (!fetch->old_entry->mem_obj->request) {
+ fetch->old_entry->mem_obj->request = fetch->entry->mem_obj->request;
+ HTTPMSGLOCK(fetch->old_entry->mem_obj->request);
+ }
assert(fetch->old_entry->mem_obj->request);
psstate = new ps_state;
- psstate->request = HTTPMSGLOCK(request);
+ psstate->request = request;
+ HTTPMSGLOCK(psstate->request);
psstate->entry = entry;
psstate->paths = paths;
char const *t;
int code_len = 0;
- if (ErrorDetailsManager::GetInstance().getErrorDetail(error_no, request.raw(), detailEntry))
+ if (ErrorDetailsManager::GetInstance().getErrorDetail(error_no, request, detailEntry))
s = detailEntry.detail.termedBuf();
if (!s)
}
bool
-Ssl::ErrorDetailsManager::getErrorDetail(Ssl::ssl_error_t value, HttpRequest *request, ErrorDetailEntry &entry)
+Ssl::ErrorDetailsManager::getErrorDetail(Ssl::ssl_error_t value, const HttpRequest::Pointer &request, ErrorDetailEntry &entry)
{
#if USE_ERR_LOCALES
String hdr;
- if (request && request->header.getList(HDR_ACCEPT_LANGUAGE, &hdr)) {
+ if (request != NULL && request->header.getList(HDR_ACCEPT_LANGUAGE, &hdr)) {
ErrorDetailsList::Pointer errDetails = NULL;
//Try to retrieve from cache
size_t pos = 0;
debugs(83, 8, HERE << "Creating new ErrDetailList to read from disk");
errDetails = new ErrorDetailsList();
ErrorDetailFile detailTmpl(errDetails);
- if (detailTmpl.loadFor(request)) {
+ if (detailTmpl.loadFor(request.getRaw())) {
if (detailTmpl.language()) {
debugs(83, 8, HERE << "Found details on disk for language " << detailTmpl.language());
errDetails->errLanguage = detailTmpl.language();
* \param entry where to store error details
* \return true on success, false otherwise
*/
- bool getErrorDetail(Ssl::ssl_error_t value, HttpRequest *request, ErrorDetailEntry &entry);
+ bool getErrorDetail(Ssl::ssl_error_t value, const HttpRequest::Pointer &request, ErrorDetailEntry &entry);
const char *getDefaultErrorDescr(Ssl::ssl_error_t value); ///< the default error description for a given error
const char *getDefaultErrorDetail(Ssl::ssl_error_t value); ///< the default error details for a given error
sslErrors(NULL)
{
debugs(33, 4, HERE << "will peek at " << request->GetHost() << ':' << request->port);
- const char *uri = urlCanonical(request);
+ const char *uri = urlCanonical(request.getRaw());
if (e) {
entry = e;
entry->lock();
sd_state.rewrite_lock = e;
debugs(71, 3, "storeDigestRewrite: url: " << url << " key: " << e->getMD5Text());
HttpRequest *req = HttpRequest::CreateFromUrl(url);
- e->mem_obj->request = HTTPMSGLOCK(req);
+ e->mem_obj->request = req;
+ HTTPMSGLOCK(e->mem_obj->request);
/* wait for rebuild (if any) to finish */
if (sd_state.rebuild_lock) {
bool strHdrAcptLangGetItem(const String &hdr, char *lang, int langLen, size_t &pos) STUB_RETVAL(false)
bool TemplateFile::loadDefault() STUB_RETVAL(false)
TemplateFile::TemplateFile(char const*, err_type) STUB
-bool TemplateFile::loadFor(HttpRequest*) STUB_RETVAL(false)
+bool TemplateFile::loadFor(const HttpRequest *) STUB_RETVAL(false)
tunnelState->server.setDelayId(DelayId::DelayClient(http));
#endif
tunnelState->url = xstrdup(url);
- tunnelState->request = HTTPMSGLOCK(request);
+ tunnelState->request = request;
+ HTTPMSGLOCK(tunnelState->request);
tunnelState->server.size_ptr = size_ptr;
tunnelState->status_ptr = status_ptr;
tunnelState->client.conn = http->getConn()->clientConnection;
{
debugs(52, 3, "urnStart: '" << e->url() << "'" );
entry = e;
- request = HTTPMSGLOCK(r);
+ request = r;
+ HTTPMSGLOCK(request);
entry->lock();
setUriResFromRequest(r);