#include <vector>
class HttpRequest;
+class HttpReply;
/**
* a CacheManager - the menu system for interacting with squid.
static CacheManager* GetInstance();
const char *ActionProtection(const Mgr::ActionProfilePointer &profile);
+ /// Add HTTP response headers specific/common to all cache manager replies,
+ /// including cache manager errors and Action reports.
+ /// \param httpOrigin the value of Origin header in the trigger HTTP request (or nil)
+ static void PutCommonResponseHeaders(HttpReply &, const char *httpOrigin);
+
protected:
CacheManager() {} ///< use Instance() instead
/// This applies to TPROXY traffic that has not had spoofing disabled through
/// the spoof_client_ip squid.conf ACL.
bool spoofClientIp = false;
- /** set if the request is internal (\see ClientHttpRequest::flags.internal)*/
+
+ /// whether the request targets a /squid-internal- resource (e.g., a MIME
+ /// icon or a cache manager page) served by this Squid instance
+ /// \sa ClientHttpRequest::flags.internal
+ /// TODO: Rename to avoid a false implication that this flag is true for
+ /// requests for /squid-internal- resources served by other Squid instances.
bool internal = false;
+
/** if set, request to try very hard to keep the connection alive */
bool mustKeepalive = false;
/** set if the request wants connection oriented auth */
#include "error/ExceptionErrorDetail.h"
#include "errorpage.h"
#include "fde.h"
+#include "HttpHdrCc.h"
#include "HttpReply.h"
#include "HttpRequest.h"
#include "mgr/Action.h"
#include "wordlist.h"
#include <algorithm>
+#include <memory>
/// \ingroup CacheManagerInternal
#define MGR_PASSWD_SZ 128
*/
rep->header.putAuth("Basic", actionName);
#endif
- // Allow cachemgr and other XHR scripts access to our version string
- if (request->header.has(Http::HdrType::ORIGIN)) {
- rep->header.putExt("Access-Control-Allow-Origin",request->header.getStr(Http::HdrType::ORIGIN));
-#if HAVE_AUTH_MODULE_BASIC
- rep->header.putExt("Access-Control-Allow-Credentials","true");
-#endif
- rep->header.putExt("Access-Control-Expose-Headers","Server");
- }
+
+ const auto originOrNil = request->header.getStr(Http::HdrType::ORIGIN);
+ PutCommonResponseHeaders(*rep, originOrNil);
/* store the reply */
entry->replaceHttpReply(rep);
HttpReply *rep = err.BuildHttpReply();
if (strncmp(rep->body.content(),"Internal Error:", 15) == 0)
rep->sline.set(Http::ProtocolVersion(1,1), Http::scNotFound);
- // Allow cachemgr and other XHR scripts access to our version string
- if (request->header.has(Http::HdrType::ORIGIN)) {
- rep->header.putExt("Access-Control-Allow-Origin",request->header.getStr(Http::HdrType::ORIGIN));
-#if HAVE_AUTH_MODULE_BASIC
- rep->header.putExt("Access-Control-Allow-Credentials","true");
-#endif
- rep->header.putExt("Access-Control-Expose-Headers","Server");
- }
+
+ const auto originOrNil = request->header.getStr(Http::HdrType::ORIGIN);
+ PutCommonResponseHeaders(*rep, originOrNil);
+
entry->replaceHttpReply(rep);
entry->complete();
return;
return nullptr;
}
+void
+CacheManager::PutCommonResponseHeaders(HttpReply &response, const char *httpOrigin)
+{
+ // Allow cachemgr and other XHR scripts access to our version string
+ if (httpOrigin) {
+ response.header.putExt("Access-Control-Allow-Origin", httpOrigin);
+#if HAVE_AUTH_MODULE_BASIC
+ response.header.putExt("Access-Control-Allow-Credentials", "true");
+#endif
+ response.header.putExt("Access-Control-Expose-Headers", "Server");
+ }
+
+ std::unique_ptr<HttpHdrCc> cc(new HttpHdrCc());
+ // this is honored by more caches but allows pointless revalidation;
+ // revalidation will always fail because we do not support it (yet?)
+ cc->noCache(String());
+ // this is honored by fewer caches but prohibits pointless revalidation
+ cc->noStore(true);
+ response.putCc(cc.release());
+}
+
CacheManager*
CacheManager::GetInstance()
{
http->setLogUriToRequestUri();
} else
debugs(33, 2, "internal URL found: " << request->url.getScheme() << "://" << request->url.authority(true) << " (not this proxy)");
+
+ if (ForSomeCacheManager(request->url.path()))
+ request->flags.disableCacheUse("cache manager URL");
}
request->flags.internal = http->flags.internal;
+ if (request->url.getScheme() == AnyP::PROTO_CACHE_OBJECT)
+ request->flags.disableCacheUse("cache_object URL scheme");
+
if (!isFtp) {
// XXX: for non-HTTP messages instantiate a different Http::Message child type
// for now Squid only supports HTTP requests
// client sent CC:no-cache or some other condition has been
// encountered which prevents delivering a public/cached object.
+ // XXX: The above text does not match the condition below. It might describe
+ // the opposite condition, but the condition itself should be adjusted
+ // (e.g., to honor flags.noCache in cache manager requests).
if (!r->flags.noCache || r->flags.internal) {
const auto e = storeGetPublicByRequest(r);
identifyFoundObject(e, storeLookupString(bool(e)));
#include "squid.h"
#include "AccessLogEntry.h"
+#include "base/Assure.h"
#include "CacheManager.h"
#include "comm/Connection.h"
#include "errorpage.h"
internalStart(const Comm::ConnectionPointer &clientConn, HttpRequest * request, StoreEntry * entry, const AccessLogEntry::Pointer &ale)
{
ErrorState *err;
+
+ Assure(request);
const SBuf upath = request->url.path();
debugs(76, 3, clientConn << " requesting '" << upath << "'");
+ Assure(request->flags.internal);
+
static const SBuf netdbUri("/squid-internal-dynamic/netdb");
static const SBuf storeDigestUri("/squid-internal-periodic/store_digest");
- static const SBuf mgrPfx("/squid-internal-mgr/");
if (upath == netdbUri) {
netdbBinaryExchange(entry);
entry->replaceHttpReply(reply);
entry->append(msgbuf, strlen(msgbuf));
entry->complete();
- } else if (upath.startsWith(mgrPfx)) {
- debugs(17, 2, "calling CacheManager due to URL-path " << mgrPfx);
+ } else if (ForSomeCacheManager(upath)) {
+ debugs(17, 2, "calling CacheManager due to URL-path");
CacheManager::GetInstance()->start(clientConn, request, entry, ale);
} else {
debugObj(76, 1, "internalStart: unknown request:\n",
return urlPath.startsWith(InternalStaticPfx);
}
+bool
+ForSomeCacheManager(const SBuf &urlPath)
+{
+ static const SBuf mgrPfx("/squid-internal-mgr");
+ return urlPath.startsWith(mgrPfx);
+}
+
/*
* makes internal url with a given host and port (remote internal url)
*/
const char *internalHostname(void);
int internalHostnameIs(const char *);
+/// whether the given request URL path points to a cache manager (not
+/// necessarily running on this Squid instance)
+bool ForSomeCacheManager(const SBuf &);
+
#endif /* SQUID_INTERNAL_H_ */
/* DEBUG: section 16 Cache Manager API */
#include "squid.h"
+#include "CacheManager.h"
#include "comm/Connection.h"
#include "HttpReply.h"
#include "ipc/Port.h"
if (writeHttpHeader) {
HttpReply *rep = new HttpReply;
rep->setHeaders(Http::scOkay, nullptr, contentType(), -1, squid_curtime, squid_curtime);
- // Allow cachemgr and other XHR scripts access to our version string
- const ActionParams ¶ms = command().params;
- if (params.httpOrigin.size() > 0) {
- rep->header.putExt("Access-Control-Allow-Origin", params.httpOrigin.termedBuf());
-#if HAVE_AUTH_MODULE_BASIC
- rep->header.putExt("Access-Control-Allow-Credentials","true");
-#endif
- rep->header.putExt("Access-Control-Expose-Headers","Server");
- }
+
+ const auto &origin = command().params.httpOrigin;
+ const auto originOrNil = origin.size() ? origin.termedBuf() : nullptr;
+ CacheManager::PutCommonResponseHeaders(*rep, originOrNil);
+
entry->replaceHttpReply(rep);
}
#include "squid.h"
#include "AccessLogEntry.h"
#include "base/TextException.h"
+#include "CacheManager.h"
#include "comm.h"
#include "comm/Connection.h"
#include "comm/Write.h"
Must(Comm::IsConnOpen(conn));
Must(aggrAction != nullptr);
+ const auto &origin = aggrAction->command().params.httpOrigin;
+ const auto originOrNil = origin.size() ? origin.termedBuf() : nullptr;
+
std::unique_ptr<MemBuf> replyBuf;
if (strands.empty()) {
const char *url = aggrAction->command().params.httpUri.termedBuf();
auto *req = HttpRequest::FromUrlXXX(url, mx);
ErrorState err(ERR_INVALID_URL, Http::scNotFound, req, nullptr);
std::unique_ptr<HttpReply> reply(err.BuildHttpReply());
+ CacheManager::PutCommonResponseHeaders(*reply, originOrNil);
replyBuf.reset(reply->pack());
} else {
std::unique_ptr<HttpReply> reply(new HttpReply);
reply->setHeaders(Http::scOkay, nullptr, "text/plain", -1, squid_curtime, squid_curtime);
+ CacheManager::PutCommonResponseHeaders(*reply, originOrNil);
reply->header.putStr(Http::HdrType::CONNECTION, "close"); // until we chunk response
replyBuf.reset(reply->pack());
}
void Mgr::RegisterAction(char const *, char const *, Mgr::ClassActionCreationHandler *, int, int) {}
Mgr::Action::Pointer CacheManager::createRequestedAction(const Mgr::ActionParams &) STUB_RETVAL(nullptr)
+void CacheManager::PutCommonResponseHeaders(HttpReply &, const char *) STUB