/*
- * Copyright (C) 1996-2016 The Squid Software Foundation and contributors
+ * Copyright (C) 1996-2017 The Squid Software Foundation and contributors
*
* Squid software is distributed under GPLv2+ license and includes
* contributions from numerous individuals and organizations.
#include "adaptation/icap/icap_log.h"
#endif
-HttpRequest::HttpRequest() :
- HttpMsg(hoRequest)
+HttpRequest::HttpRequest(const MasterXaction::Pointer &mx) :
+ Http::Message(hoRequest),
+ masterXaction(mx)
{
+ assert(mx);
init();
}
-HttpRequest::HttpRequest(const HttpRequestMethod& aMethod, AnyP::ProtocolType aProtocol, const char *aUrlpath) :
- HttpMsg(hoRequest)
+HttpRequest::HttpRequest(const HttpRequestMethod& aMethod, AnyP::ProtocolType aProtocol, const char *aSchemeImg, const char *aUrlpath, const MasterXaction::Pointer &mx) :
+ Http::Message(hoRequest),
+ masterXaction(mx)
{
+ assert(mx);
static unsigned int id = 1;
debugs(93,7, HERE << "constructed, this=" << this << " id=" << ++id);
init();
- initHTTP(aMethod, aProtocol, aUrlpath);
+ initHTTP(aMethod, aProtocol, aSchemeImg, aUrlpath);
}
HttpRequest::~HttpRequest()
}
void
-HttpRequest::initHTTP(const HttpRequestMethod& aMethod, AnyP::ProtocolType aProtocol, const char *aUrlpath)
+HttpRequest::initHTTP(const HttpRequestMethod& aMethod, AnyP::ProtocolType aProtocol, const char *aSchemeImg, const char *aUrlpath)
{
method = aMethod;
- url.setScheme(aProtocol);
+ url.setScheme(aProtocol, aSchemeImg);
url.path(aUrlpath);
}
#endif
extacl_log = null_string;
extacl_message = null_string;
- pstate = psReadyToParseStartLine;
+ pstate = Http::Message::psReadyToParseStartLine;
#if FOLLOW_X_FORWARDED_FOR
indirect_client_addr.setEmpty();
#endif /* FOLLOW_X_FORWARDED_FOR */
myportname.clean();
- notes = NULL;
+ theNotes = nullptr;
tag.clean();
#if USE_AUTH
HttpRequest *
HttpRequest::clone() const
{
- HttpRequest *copy = new HttpRequest();
+ HttpRequest *copy = new HttpRequest(masterXaction);
copy->method = method;
// TODO: move common cloning clone to Msg::copyTo() or copy ctor
copy->header.append(&header);
copy->pstate = pstate; // TODO: should we assert a specific state here?
copy->body_pipe = body_pipe;
- copy->url.setScheme(url.getScheme());
- copy->url.userInfo(url.userInfo());
- copy->url.host(url.host());
- copy->url.port(url.port());
- copy->url.path(url.path());
+ copy->url = url;
// range handled in hdrCacheInit()
copy->ims = ims;
}
bool
-HttpRequest::inheritProperties(const HttpMsg *aMsg)
+HttpRequest::inheritProperties(const Http::Message *aMsg)
{
const HttpRequest* aReq = dynamic_cast<const HttpRequest*>(aMsg);
if (!aReq)
downloader = aReq->downloader;
- notes = aReq->notes;
+ theNotes = aReq->theNotes;
sources = aReq->sources;
return true;
* (char *) end = '\0'; // temp terminate URI, XXX dangerous?
- HttpRequest *tmp = urlParse(method, (char *) start, this);
+ const bool ret = urlParse(method, (char *) start, *this);
* (char *) end = save;
- if (NULL == tmp)
- return false;
-
- return true;
+ return ret;
}
/* swaps out request using httpRequestPack */
void
HttpRequest::hdrCacheInit()
{
- HttpMsg::hdrCacheInit();
+ Http::Message::hdrCacheInit();
assert(!range);
range = header.getRange();
* If the request cannot be created cleanly, NULL is returned
*/
HttpRequest *
-HttpRequest::CreateFromUrl(char * url, const HttpRequestMethod& method)
+HttpRequest::FromUrl(char * url, const MasterXaction::Pointer &mx, const HttpRequestMethod& method)
{
- return urlParse(method, url, NULL);
+ std::unique_ptr<HttpRequest> req(new HttpRequest(mx));
+ if (urlParse(method, url, *req))
+ return req.release();
+ return nullptr;
}
/**
if (!method.respMaybeCacheable())
return false;
- // XXX: this would seem the correct place to detect request cache-controls
- // no-store, private and related which block cacheability
+ // RFC 7234 section 5.2.1.5:
+ // "cache MUST NOT store any part of either this request or any response to it"
+ //
+ // NP: refresh_pattern ignore-no-store only applies to response messages
+ // this test is handling request message CC header.
+ if (!flags.ignoreCc && cache_control && cache_control->hasNoStore())
+ return false;
break;
case AnyP::PROTO_GOPHER:
const SBuf &
HttpRequest::effectiveRequestUri() const
{
- if (method.id() == Http::METHOD_CONNECT)
+ if (method.id() == Http::METHOD_CONNECT || url.getScheme() == AnyP::PROTO_AUTHORITY_FORM)
return url.authority(true); // host:port
return url.absolute();
}
+NotePairs::Pointer
+HttpRequest::notes()
+{
+ if (!theNotes)
+ theNotes = new NotePairs;
+ return theNotes;
+}
+
+void
+UpdateRequestNotes(ConnStateData *csd, HttpRequest &request, NotePairs const &helperNotes)
+{
+ // Tag client connection if the helper responded with clt_conn_tag=tag.
+ const char *cltTag = "clt_conn_tag";
+ if (const char *connTag = helperNotes.findFirst(cltTag)) {
+ if (csd) {
+ csd->notes()->remove(cltTag);
+ csd->notes()->add(cltTag, connTag);
+ }
+ }
+ request.notes()->replaceOrAdd(&helperNotes);
+}
+