#if USE_AUTH
auth_user_request = NULL;
#endif
- canonical = NULL;
memset(&flags, '\0', sizeof(flags));
range = NULL;
ims = -1;
#if USE_AUTH
auth_user_request = NULL;
#endif
- safe_free(canonical);
-
safe_free(vary_headers);
url.clear();
copy->url.port(url.port());
copy->url.path(url.path());
- // urlPath handled in ctor
- copy->canonical = canonical ? xstrdup(canonical) : NULL;
-
// range handled in hdrCacheInit()
copy->ims = ims;
copy->imslen = imslen;
void
HttpRequest::packFirstLineInto(Packable * p, bool full_uri) const
{
- SBuf tmp;
- if (full_uri)
- tmp = urlCanonical((HttpRequest*)this);
- else
- tmp = url.path();
+ const SBuf tmp(full_uri ? effectiveRequestUri() : url.path());
// form HTTP request-line
p->appendf(SQUIDSBUFPH " " SQUIDSBUFPH " HTTP/%d.%d\r\n",
return NULL;
}
-const char *
+const SBuf
HttpRequest::storeId()
{
if (store_id.size() != 0) {
- debugs(73, 3, "sent back store_id:" << store_id);
-
- return store_id.termedBuf();
+ debugs(73, 3, "sent back store_id: " << store_id);
+ return SBuf(store_id);
}
- debugs(73, 3, "sent back canonicalUrl:" << urlCanonical(this) );
+ debugs(73, 3, "sent back effectiveRequestUrl: " << effectiveRequestUri());
+ return effectiveRequestUri();
+}
- return urlCanonical(this);
+const SBuf &
+HttpRequest::effectiveRequestUri() const
+{
+ if (method.id() == Http::METHOD_CONNECT)
+ return url.authority(true); // host:port
+ return url.absolute();
}
/// whether the client is likely to be able to handle a 1xx reply
bool canHandle1xx() const;
- /* HACK: This method is only inline to get around Makefile dependancies */
- /* caused by HttpRequest being used in places it really shouldn't. */
- /* ideally URL would be used directly instead. */
- inline void SetHost(const char *src) {
- url.host(src);
- safe_free(canonical); // force its re-build
- };
-
#if USE_ADAPTATION
/// Returns possibly nil history, creating it if adapt. logging is enabled
Adaptation::History::Pointer adaptLogHistory() const;
Auth::UserRequest::Pointer auth_user_request;
#endif
- char *canonical;
+ /// RFC 7230 section 5.5 - Effective Request URI
+ const SBuf &effectiveRequestUri() const;
/**
* If defined, store_id_program mapped the request URL to this ID.
/**
* Returns the current StoreID for the request as a nul-terminated char*.
* Always returns the current id for the request
- * (either the request canonical url or modified ID by the helper).
- * Does not return NULL.
+ * (either the effective request URI or modified ID by the helper).
*/
- const char *storeId();
+ const SBuf storeId();
/**
* The client connection manager, if known;
// ErrorState, getOutgoingAddress(), and other APIs may require a request.
// We fake one. TODO: Optionally send this request to peers?
request = new HttpRequest(Http::METHOD_OPTIONS, AnyP::PROTO_HTTP, "*");
- request->SetHost(peer->host);
+ request->url.host(peer->host);
checkpoint("peer initialized");
}
// Produce a URL for display identifying the transaction we are
// trying to locate a peer for.
- const char * url() const;
+ const SBuf url() const;
HttpRequest *request;
AccessLogEntry::Pointer al; ///< info for the future access.log entry
AnyP::ProtocolType urlParseProtocol(const char *, const char *e = NULL);
void urlInitialize(void);
HttpRequest *urlParse(const HttpRequestMethod&, char *, HttpRequest *request = NULL);
-const char *urlCanonical(HttpRequest *);
char *urlCanonicalClean(const HttpRequest *);
const char *urlCanonicalFakeHttps(const HttpRequest * request);
bool urlIsRelative(const char *);
#include "acl/Checklist.h"
#include "acl/RegexData.h"
#include "acl/Url.h"
+#include "HttpRequest.h"
#include "rfc1738.h"
#include "src/URL.h"
int
ACLUrlStrategy::match (ACLData<char const *> * &data, ACLFilledChecklist *checklist, ACLFlags &)
{
- char *esc_buf = xstrdup(urlCanonical(checklist->request));
+ const SBuf &tmp = checklist->request->effectiveRequestUri();
+ char *esc_buf = xstrndup(tmp.rawContent(), tmp.length()+1);
rfc1738_unescape(esc_buf);
int result = data->match(esc_buf);
- safe_free(esc_buf);
+ xfree(esc_buf);
return result;
}
Adaptation::Ecap::RequestLineRep::Area
Adaptation::Ecap::RequestLineRep::uri() const
{
- const char *fullUrl = urlCanonical(&theMessage);
- Must(fullUrl);
+ const SBuf &fullUrl = theMessage.effectiveRequestUri();
+ // XXX: effectiveRequestUri() cannot return NULL or even empty string, some other problem?
+ Must(!fullUrl.isEmpty());
// optimize: avoid copying by having an Area::Detail that locks theMessage
- return Area::FromTempBuffer(fullUrl, strlen(fullUrl));
+ return Area::FromTempBuffer(fullUrl.rawContent(), fullUrl.length());
}
void
httpBuf.terminate(); // HttpMsg::parse requires nil-terminated buffer
Must(adapted.header->parse(httpBuf.content(), httpBuf.contentSize(), true, &error));
-
- if (HttpRequest *r = dynamic_cast<HttpRequest*>(adapted.header))
- urlCanonical(r); // parse does not set HttpRequest::canonical
-
Must(adapted.header->hdr_sz == httpBuf.contentSize()); // no leftovers
httpBuf.clean();
return false;
}
- if (HttpRequest *r = dynamic_cast<HttpRequest*>(head))
- urlCanonical(r); // parse does not set HttpRequest::canonical
-
debugs(93, 5, HERE << "parse success, consume " << head->hdr_sz << " bytes, return true");
readBuf.consume(head->hdr_sz);
return true;
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.getRaw());
+ // copy the requst-line details
+ new_request->method = old_request->method;
+ new_request->url = old_request->url;
new_request->http_ver = old_request->http_ver;
headClone = new_request.getRaw();
} else if (const HttpReply *old_reply = dynamic_cast<const HttpReply*>(head)) {
return NULL;
/* calculate hash key */
- debugs(39, 2, "carpSelectParent: Calculating hash for " << urlCanonical(request));
+ debugs(39, 2, "carpSelectParent: Calculating hash for " << request->effectiveRequestUri());
/* select CachePeer */
for (k = 0; k < n_carp_peers; ++k) {
SBuf key;
tp = carp_peers[k];
if (tp->options.carp_key.set) {
- //this code follows urlCanonical's pattern.
- // corner cases should use the canonical URL
+ // this code follows URI syntax pattern.
+ // corner cases should use the full effective request URI
if (tp->options.carp_key.scheme) {
key.append(request->url.getScheme().c_str());
if (key.length()) //if the scheme is not empty
}
// if the url-based key is empty, e.g. because the user is
// asking to balance on the path but the request doesn't supply any,
- // then fall back to canonical URL
+ // then fall back to the effective request URI
if (key.isEmpty())
- key=SBuf(urlCanonical(request));
+ key=request->effectiveRequestUri();
for (const char *c = key.rawContent(), *e=key.rawContent()+key.length(); c < e; ++c)
user_hash += ROTATE_LEFT(user_hash, 19) + *c;
} else if (Config.onoff.global_internal_static && internalStaticCheck(request->url.path())) {
debugs(33, 2, "internal URL found: " << request->url.getScheme() << "://" << request->url.authority(true) << " (global_internal_static on)");
request->url.setScheme(AnyP::PROTO_HTTP);
- request->SetHost(internalHostname());
+ request->url.host(internalHostname());
request->url.port(getMyPort());
http->flags.internal = true;
} else
HttpRequest *request = new HttpRequest();
static char ip[MAX_IPSTRLEN];
assert(clientConnection->flags & (COMM_TRANSPARENT | COMM_INTERCEPTION));
- request->SetHost(clientConnection->local.toStr(ip, sizeof(ip)));
+ request->url.host(clientConnection->local.toStr(ip, sizeof(ip)));
request->url.port(clientConnection->local.port());
request->myportname = port->name;
*/
assert(http->logType.oldType == LOG_TCP_HIT);
- if (strcmp(e->mem_obj->storeId(), http->request->storeId()) != 0) {
+ if (http->request->storeId().cmp(e->mem_obj->storeId()) != 0) {
debugs(33, DBG_IMPORTANT, "clientProcessHit: URL mismatch, '" << e->mem_obj->storeId() << "' != '" << http->request->storeId() << "'");
http->logType = LOG_TCP_MISS; // we lack a more precise LOG_*_MISS code
processMiss();
void
clientReplyContext::purgeAllCached()
{
- const char *url = urlCanonical(http->request);
- purgeEntriesByUrl(http->request, url);
+ // XXX: performance regression, c_str() reallocates
+ SBuf url(http->request->effectiveRequestUri());
+ purgeEntriesByUrl(http->request, url.c_str());
}
void
clientReplyContext::purgeDoPurgeHead(StoreEntry *newEntry)
{
if (newEntry && !newEntry->isNull()) {
- debugs(88, 4, "clientPurgeRequest: HEAD '" << newEntry->url() << "'" );
+ debugs(88, 4, "HEAD " << newEntry->url());
#if USE_HTCP
neighborsHtcpClear(newEntry, NULL, http->request, HttpRequestMethod(Http::METHOD_HEAD), HTCP_CLR_PURGE);
#endif
if (http->request->vary_headers
&& !strstr(http->request->vary_headers, "=")) {
- StoreEntry *entry = storeGetPublic(urlCanonical(http->request), Http::METHOD_GET);
+ // XXX: performance regression, c_str() reallocates
+ SBuf tmp(http->request->effectiveRequestUri());
+ StoreEntry *entry = storeGetPublic(tmp.c_str(), Http::METHOD_GET);
if (entry) {
- debugs(88, 4, "clientPurgeRequest: Vary GET '" << entry->url() << "'" );
+ debugs(88, 4, "Vary GET " << entry->url());
#if USE_HTCP
neighborsHtcpClear(entry, NULL, http->request, HttpRequestMethod(Http::METHOD_GET), HTCP_CLR_PURGE);
#endif
purgeStatus = Http::scOkay;
}
- entry = storeGetPublic(urlCanonical(http->request), Http::METHOD_HEAD);
+ entry = storeGetPublic(tmp.c_str(), Http::METHOD_HEAD);
if (entry) {
- debugs(88, 4, "clientPurgeRequest: Vary HEAD '" << entry->url() << "'" );
+ debugs(88, 4, "Vary HEAD " << entry->url());
#if USE_HTCP
neighborsHtcpClear(entry, NULL, http->request, HttpRequestMethod(Http::METHOD_HEAD), HTCP_CLR_PURGE);
#endif
// NP: we do not yet handle CONNECT tunnels well, so ignore for them
if (!Config.onoff.hostStrictVerify && http->request->method != Http::METHOD_CONNECT) {
debugs(85, 3, "SECURITY ALERT: Host header forgery detected on " << http->getConn()->clientConnection <<
- " (" << A << " does not match " << B << ") on URL: " << urlCanonical(http->request));
+ " (" << A << " does not match " << B << ") on URL: " << http->request->effectiveRequestUri());
// NP: it is tempting to use 'flags.noCache' but that is all about READing cache data.
// The problems here are about WRITE for new cache content, which means flags.cachable
debugs(85, DBG_IMPORTANT, "SECURITY ALERT: Host header forgery detected on " <<
http->getConn()->clientConnection << " (" << A << " does not match " << B << ")");
debugs(85, DBG_IMPORTANT, "SECURITY ALERT: By user agent: " << http->request->header.getStr(HDR_USER_AGENT));
- debugs(85, DBG_IMPORTANT, "SECURITY ALERT: on URL: " << urlCanonical(http->request));
+ debugs(85, DBG_IMPORTANT, "SECURITY ALERT: on URL: " << http->request->effectiveRequestUri());
// IP address validation for Host: failed. reject the connection.
clientStreamNode *node = (clientStreamNode *)http->client_stream.tail->prev->data;
/* ACCESS_ALLOWED continues here ... */
safe_free(http->uri);
-
- http->uri = xstrdup(urlCanonical(http->request));
-
+ const SBuf tmp(http->request->effectiveRequestUri());
+ http->uri = xstrndup(tmp.rawContent(), tmp.length()+1);
http->doCallouts();
}
// XXX: the clone() should be done only AFTER we know the new URL is valid.
HttpRequest *new_request = old_request->clone();
if (urlParse(old_request->method, const_cast<char*>(urlNote), new_request)) {
- debugs(61,2, HERE << "URL-rewriter diverts URL from " << urlCanonical(old_request) << " to " << urlCanonical(new_request));
+ debugs(61, 2, "URL-rewriter diverts URL from " << old_request->effectiveRequestUri() << " to " << new_request->effectiveRequestUri());
// update the new request to flag the re-writing was done on it
new_request->flags.redirected = true;
// update the current working ClientHttpRequest fields
safe_free(http->uri);
- http->uri = xstrdup(urlCanonical(new_request));
+ const SBuf tmp(new_request->effectiveRequestUri());
+ http->uri = xstrndup(tmp.rawContent(), tmp.length()+1);
HTTPMSGUNLOCK(old_request);
http->request = new_request;
HTTPMSGLOCK(http->request);
#endif
if (calloutContext->error) {
- const char *storeUri = request->storeId();
- StoreEntry *e= storeCreateEntry(storeUri, storeUri, request->flags, request->method);
+ // XXX: prformance regression. c_str() reallocates
+ SBuf storeUri(request->storeId());
+ StoreEntry *e = storeCreateEntry(storeUri.c_str(), storeUri.c_str(), request->flags, request->method);
#if USE_OPENSSL
if (sslBumpNeeded()) {
// We have to serve an error, so bump the client first.
HTTPMSGLOCK(request);
// update the new message to flag whether URL re-writing was done on it
- if (strcmp(urlCanonical(request),uri) != 0)
+ if (request->effectiveRequestUri().cmp(uri) != 0)
request->flags.redirected = 1;
/*
* Store the new URI for logging
*/
xfree(uri);
- uri = xstrdup(urlCanonical(request));
+ const SBuf tmp(request->effectiveRequestUri());
+ uri = xstrndup(tmp.rawContent(), tmp.length());
setLogUri(this, urlCanonicalClean(request));
assert(request->method.id());
} else if (HttpReply *new_rep = dynamic_cast<HttpReply*>(msg)) {
return;
// XXX: should we use originalRequest() here?
- const char *reqUrl = urlCanonical(request);
- debugs(88, 5, "maybe purging due to " << request->method << ' ' << reqUrl);
+ SBuf tmp(request->effectiveRequestUri());
+ const char *reqUrl = tmp.c_str();
+ debugs(88, 5, "maybe purging due to " << request->method << ' ' << tmp);
purgeEntriesByUrl(request, reqUrl);
purgeEntriesByHeader(request, reqUrl, theFinalReply, HDR_LOCATION);
purgeEntriesByHeader(request, reqUrl, theFinalReply, HDR_CONTENT_LOCATION);
return newrep;
}
-const char *
+const SBuf &
Ftp::UrlWith2f(HttpRequest * request)
{
SBuf newbuf("%2f");
- if (request->url.getScheme() != AnyP::PROTO_FTP)
- return NULL;
+ if (request->url.getScheme() != AnyP::PROTO_FTP) {
+ static const SBuf nil;
+ return nil;
+ }
if (request->url.path()[0] == '/') {
newbuf.append(request->url.path());
request->url.path(newbuf);
- safe_free(request->canonical);
} else if (!request->url.path().startsWith(newbuf)) {
newbuf.append(request->url.path().substr(1));
request->url.path(newbuf);
- safe_free(request->canonical);
}
- return urlCanonical(request);
+ return request->effectiveRequestUri();
}
void
class FwdState;
class HttpRequest;
+class SBuf;
class AsyncJob;
template <class Cbc> class CbcPointer;
*
* \todo Should be a URL class API call.
*/
-const char *UrlWith2f(HttpRequest *);
+const SBuf &UrlWith2f(HttpRequest *);
} // namespace Ftp
case 'B':
if (building_deny_info_url) break;
- p = request ? Ftp::UrlWith2f(request) : "[no URL]";
+ if (request) {
+ const SBuf &tmp = Ftp::UrlWith2f(request);
+ mb.append(tmp.rawContent(), tmp.length());
+ } else
+ p = "[no URL]";
break;
case 'c':
case 's':
/* for backward compat we make %s show the full URL. Drop this in some future release. */
if (building_deny_info_url) {
- p = request ? urlCanonical(request) : url;
+ if (request) {
+ const SBuf &tmp = request->effectiveRequestUri();
+ mb.append(tmp.rawContent(), tmp.length());
+ } else
+ p = url;
debugs(0, DBG_CRITICAL, "WARNING: deny_info now accepts coded tags. Use %u to get the full URL instead of %s");
} else
p = visible_appname_string;
break;
case 'U':
- /* Using the fake-https version of canonical so error pages see https:// */
+ /* Using the fake-https version of absolute-URI so error pages see https:// */
/* even when the url-path cannot be shown as more than '*' */
if (request)
p = urlCanonicalFakeHttps(request);
break;
case 'u':
- if (request)
- p = urlCanonical(request);
- else if (url)
+ if (request) {
+ const SBuf &tmp = request->effectiveRequestUri();
+ mb.append(tmp.rawContent(), tmp.length());
+ } else if (url)
p = url;
else if (!building_deny_info_url)
p = "[no URL]";
break;
case Format::LFT_CLIENT_REQ_URI:
- str = urlCanonical(request);
+ snprintf(buf, sizeof(buf), SQUIDSBUFPH, SQUIDSBUFPRINT(request->effectiveRequestUri()));
+ str = buf;
break;
case Format::LFT_CLIENT_REQ_URLDOMAIN:
case LFT_CLIENT_REQ_URI:
// original client URI
if (al->request) {
- out = urlCanonical(al->request);
+ const SBuf &s = al->request->effectiveRequestUri();
+ sb.append(s.rawContent(), s.length());
+ out = sb.termedBuf();
quote = 1;
}
break;
case LFT_SERVER_REQ_URI:
// adapted request URI sent to server/peer
if (al->adapted_request) {
- out = urlCanonical(al->adapted_request);
+ const SBuf &s = al->adapted_request->effectiveRequestUri();
+ sb.append(s.rawContent(), s.length());
+ out = sb.termedBuf();
quote = 1;
}
break;
static int warnedCount = 0;
if (warnedCount++ < 100) {
- const char *url = entry ? entry->url() : urlCanonical(request);
+ const SBuf url(entry ? SBuf(entry->url()) : request->effectiveRequestUri());
debugs(11, DBG_IMPORTANT, "Warning: likely forwarding loop with " << url);
}
}
/* Add max-age only without no-cache */
if (!cc->hasMaxAge() && !cc->hasNoCache()) {
- const char *url =
- entry ? entry->url() : urlCanonical(request);
- cc->maxAge(getMaxAge(url));
-
+ // XXX: performance regression. c_str() reallocates
+ SBuf tmp(request->effectiveRequestUri());
+ cc->maxAge(getMaxAge(entry ? entry->url() : tmp.c_str()));
}
/* Enforce sibling relations */
* not the one we are sending. Needs checking.
*/
const AnyP::ProtocolVersion httpver = Http::ProtocolVersion();
- const bool canonical = (_peer && !_peer->options.originserver);
- const SBuf url = canonical ? SBuf(urlCanonical(request)) : request->url.path();
+ const SBuf url(_peer && !_peer->options.originserver ? request->effectiveRequestUri() : request->url.path());
mb->appendf(SQUIDSBUFPH " " SQUIDSBUFPH " %s/%d.%d\r\n",
SQUIDSBUFPRINT(request->method.image()),
SQUIDSBUFPRINT(url),
if (p->login)
ex->r->url.userInfo(SBuf(p->login));
- urlCanonical(ex->r);
-
FwdState::fwdStart(Comm::ConnectionPointer(), ex->e, ex->r);
#endif
; // no local defaults.
}
-const char *
+const SBuf
ps_state::url() const
{
if (entry)
- return entry->url();
+ return SBuf(entry->url());
if (request)
- return urlCanonical(request);
+ return request->effectiveRequestUri();
- return "[no URL]";
+ static const SBuf noUrl("[no URL]");
+ return noUrl;
}
ping_data::ping_data() :
static int
refreshCheck(const StoreEntry * entry, HttpRequest * request, time_t delta)
{
- const char *uri = NULL;
time_t age = 0;
time_t check_time = squid_curtime + delta;
int staleness;
stale_flags sf;
// get the URL of this entry, if there is one
+ static const SBuf nilUri("<none>");
+ SBuf uri = nilUri;
if (entry->mem_obj)
uri = entry->mem_obj->storeId();
else if (request)
- uri = urlCanonical(request);
+ uri = request->effectiveRequestUri();
- debugs(22, 3, "checking freshness of '" << (uri ? uri : "<none>") << "'");
+ debugs(22, 3, "checking freshness of URI: " << uri);
// age is not necessarily the age now, but the age at the given check_time
if (check_time > entry->timestamp)
* 2. the "." rule from the config file
* 3. the default "." rule
*/
- const RefreshPattern *R = uri ? refreshLimits(uri) : refreshUncompiledPattern(".");
+ // XXX: performance regression. c_str() reallocates
+ const RefreshPattern *R = (uri != nilUri) ? refreshLimits(uri.c_str()) : refreshUncompiledPattern(".");
if (NULL == R)
R = &DefaultRefresh;
if (request->flags.sslPeek && !isConnectRequest) {
if (X509 *srvX509 = serverBump->serverCert.get()) {
if (const char *name = Ssl::CommonHostName(srvX509)) {
- request->SetHost(name);
+ request->url.host(name);
debugs(83, 3, "reset request host: " << name);
}
}
act.step1 = md;
act.step2 = act.step3 = Ssl::bumpNone;
- const char *uri = urlCanonical(request.getRaw());
if (e) {
entry = e;
entry->lock("Ssl::ServerBump");
- } else
- entry = storeCreateEntry(uri, uri, request->flags, request->method);
+ } else {
+ // XXX: Performance regression. c_str() reallocates
+ SBuf uri(request->effectiveRequestUri());
+ entry = storeCreateEntry(uri.c_str(), uri.c_str(), request->flags, request->method);
+ }
// We do not need to be a client because the error contents will be used
// later, but an entry without any client will trim all its contents away.
sc = storeClientListAdd(entry, this);
{
static cache_key digest[SQUID_MD5_DIGEST_LENGTH];
unsigned char m = (unsigned char) method.id();
- const char *url = request->storeId(); /* storeId returns the right storeID\canonical URL for the md5 calc */
+ const SBuf url = request->storeId(); /* returns the right storeID\URL for the MD5 calc */
SquidMD5_CTX M;
SquidMD5Init(&M);
SquidMD5Update(&M, &m, sizeof(m));
- SquidMD5Update(&M, (unsigned char *) url, strlen(url));
+ SquidMD5Update(&M, (unsigned char *) url.rawContent(), url.length());
if (request->vary_headers) {
SquidMD5Update(&M, (unsigned char *) request->vary_headers, strlen(request->vary_headers));
{
tlv *TLV = NULL; /* we'll return this */
tlv **T = &TLV;
- const char *url;
const char *vary;
assert(e->mem_obj != NULL);
const int64_t objsize = e->mem_obj->expectedReplySize();
assert(e->swap_status == SWAPOUT_WRITING);
// e->mem_obj->request may be nil in this context
+ SBuf url;
if (e->mem_obj->request)
url = e->mem_obj->request->storeId();
else
return NULL;
}
+ // XXX: do TLV without the c_str() termination. check readers first though
T = StoreMeta::Add(T, t);
- t = StoreMeta::Factory(STORE_META_URL, strlen(url) + 1, url);
+ t = StoreMeta::Factory(STORE_META_URL, url.length()+1, url.c_str());
if (!t) {
storeSwapTLVFree(TLV);
#define STUB_API "HttpRequest.cc"
#include "tests/STUB.h"
-HttpRequest::HttpRequest() : HttpMsg(hoRequest) STUB
- HttpRequest::HttpRequest(const HttpRequestMethod& aMethod, AnyP::ProtocolType aProtocol, const char *aUrlpath) : HttpMsg(hoRequest) STUB
+// void httpRequestPack(void *obj, Packable *p);
+
+HttpRequest::HttpRequest() : HttpMsg(hoRequest) {STUB}
+ HttpRequest::HttpRequest(const HttpRequestMethod &, AnyP::ProtocolType, const char *) : HttpMsg(hoRequest) {STUB}
HttpRequest::~HttpRequest() STUB
- void HttpRequest::packFirstLineInto(Packable *, bool) const STUB
- bool HttpRequest::sanityCheckStartLine(const char*buf, const size_t hdr_len, Http::StatusCode *error) STUB_RETVAL(false)
- void HttpRequest::hdrCacheInit() STUB
void HttpRequest::reset() STUB
- bool HttpRequest::expectingBody(const HttpRequestMethod& unused, int64_t&) const STUB_RETVAL(false)
- void HttpRequest::initHTTP(const HttpRequestMethod& aMethod, AnyP::ProtocolType aProtocol, const char *aUrlpath) STUB
- bool HttpRequest::parseFirstLine(const char *start, const char *end) STUB_RETVAL(false)
+ void HttpRequest::initHTTP(const HttpRequestMethod &, AnyP::ProtocolType, const char *) STUB
HttpRequest * HttpRequest::clone() const STUB_RETVAL(NULL)
- bool HttpRequest::inheritProperties(const HttpMsg *aMsg) STUB_RETVAL(false)
+ bool HttpRequest::maybeCacheable() STUB_RETVAL(false)
+ bool HttpRequest::conditional() const STUB_RETVAL(false)
+ bool HttpRequest::canHandle1xx() const STUB_RETVAL(false)
+#if USE_ADAPTATION
+ Adaptation::History::Pointer HttpRequest::adaptLogHistory() const STUB_RETVAL(Adaptation::History::Pointer())
+ Adaptation::History::Pointer HttpRequest::adaptHistory(bool) const STUB_RETVAL(Adaptation::History::Pointer())
+ void HttpRequest::adaptHistoryImport(const HttpRequest &) STUB
+#endif
+#if ICAP_CLIENT
+ Adaptation::Icap::History::Pointer HttpRequest::icapHistory() const STUB_RETVAL(Adaptation::Icap::History::Pointer())
+#endif
+ void HttpRequest::recordLookup(const Dns::LookupDetails &) STUB
+ void HttpRequest::detailError(err_type, int) STUB
+ void HttpRequest::clearError() STUB
+ void HttpRequest::clean() STUB
+ void HttpRequest::init() STUB
+ static const SBuf nilSBuf;
+ const SBuf &HttpRequest::effectiveRequestUri() const STUB_RETVAL(nilSBuf)
+ bool HttpRequest::multipartRangeRequest() const STUB_RETVAL(false)
+ bool HttpRequest::parseFirstLine(const char *, const char *) STUB_RETVAL(false)
+ bool HttpRequest::parseHeader(Http1::RequestParser &) STUB_RETVAL(false)
+ bool HttpRequest::expectingBody(const HttpRequestMethod &, int64_t &) const STUB_RETVAL(false)
+ bool HttpRequest::bodyNibbled() const STUB_RETVAL(false)
+ int HttpRequest::prefixLen() const STUB_RETVAL(0)
+ void HttpRequest::swapOut(StoreEntry *) STUB
+ void HttpRequest::pack(Packable *) STUB
+ void HttpRequest::httpRequestPack(void *, Packable *) STUB
+ HttpRequest * HttpRequest::CreateFromUrlAndMethod(char *, const HttpRequestMethod &) STUB_RETVAL(NULL)
+ HttpRequest * HttpRequest::CreateFromUrl(char *) STUB_RETVAL(NULL)
+ ConnStateData *HttpRequest::pinnedConnection() STUB_RETVAL(NULL)
+ const SBuf HttpRequest::storeId() STUB_RETVAL(SBuf("."))
+ void HttpRequest::ignoreRange(const char *) STUB
int64_t HttpRequest::getRangeOffsetLimit() STUB_RETVAL(0)
- const char *HttpRequest::storeId() STUB_RETVAL(".")
-
+ void HttpRequest::packFirstLineInto(Packable *, bool) const STUB
+ bool HttpRequest::sanityCheckStartLine(const char *, const size_t, Http::StatusCode *) STUB_RETVAL(false)
+ void HttpRequest::hdrCacheInit() STUB
+ bool HttpRequest::inheritProperties(const HttpMsg *) STUB_RETVAL(false)
debugs(26,5, "Revert to tunnel FD " << clientConn->fd << " with FD " << srvConn->fd);
/* Create state structure. */
TunnelStateData *tunnelState = NULL;
- const char *url = urlCanonical(request);
+ const SBuf url(request->effectiveRequestUri());
debugs(26, 3, request->method << " " << url << " " << request->http_ver);
++statCounter.server.all.requests;
++statCounter.server.other.requests;
tunnelState = new TunnelStateData;
- tunnelState->url = xstrdup(url);
+ tunnelState->url = xstrndup(url.rawContent(), url.length()+1);
tunnelState->request = request;
tunnelState->server.size_ptr = NULL; //Set later if ClientSocketContext is available
request = new HttpRequest(method, protocol, urlpath);
else {
request->initHTTP(method, protocol, urlpath);
- safe_free(request->canonical);
}
- request->SetHost(host);
+ request->url.host(host);
request->url.userInfo(login);
request->url.port(port);
return request;
debugs(50, 5, "urnParse: " << urn);
if (request) {
request->initHTTP(method, AnyP::PROTO_URN, urn + 4);
- safe_free(request->canonical);
return request;
}
return absolute_;
}
-const char *
-urlCanonical(HttpRequest * request)
-{
- if (request->canonical)
- return request->canonical;
-
- SBuf url;
- if (request->method.id() == Http::METHOD_CONNECT)
- url = request->url.authority(true); // host:port
- else
- url = request->url.absolute();
-
- return (request->canonical = xstrndup(url.rawContent(), url.length()+1));
-}
-
-/** \todo AYJ: Performance: This is an *almost* duplicate of urlCanonical. But elides the query-string.
+/** \todo AYJ: Performance: This is an *almost* duplicate of HttpRequest::effectiveRequestUri(). But elides the query-string.
* After copying it on in the first place! Would be less code to merge the two with a flag parameter.
* and never copy the query-string part in the first place
*/
{
LOCAL_ARRAY(char, buf, MAX_URL);
- snprintf(buf, sizeof(buf), "%s", urlCanonical(const_cast<HttpRequest *>(request)));
+ snprintf(buf, sizeof(buf), SQUIDSBUFPH, SQUIDSBUFPRINT(request->effectiveRequestUri()));
buf[sizeof(buf)-1] = '\0';
// URN, CONNECT method, and non-stripped URIs can go straight out
- if (!(request->url.getScheme() == AnyP::PROTO_URN ||
- !Config.onoff.strip_query_terms ||
- request->method == Http::METHOD_CONNECT
- )) {
-
+ if (Config.onoff.strip_query_terms && !(request->method == Http::METHOD_CONNECT || request->url.getScheme() == AnyP::PROTO_URN)) {
// strip anything AFTER a question-mark
// leaving the '?' in place
if (auto t = strchr(buf, '?')) {