Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 13 additions & 6 deletions src/client_side_reply.cc
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "globals.h"
#include "HeaderMangling.h"
#include "http/Stream.h"
#include "HttpHdrCc.h"
#include "HttpHeaderTools.h"
#include "HttpReply.h"
#include "HttpRequest.h"
Expand Down Expand Up @@ -1002,12 +1003,18 @@ clientReplyContext::traceReply()
triggerInitialStoreRead();
http->storeEntry()->releaseRequest();
http->storeEntry()->buffer();
MemBuf content;
content.init();
http->request->pack(&content, true /* hide authorization data */);
const HttpReplyPointer rep(new HttpReply);
rep->setHeaders(Http::scOkay, nullptr, "message/http", content.contentSize(), 0, squid_curtime);
rep->body.set(SBuf(content.buf, content.size));

ErrorState err(HTTP_TRACE_REPLY, Http::scOkay, http->request, http->al);
auto rep = err.BuildHttpReply();
// RFC 9110 specifies that TRACE response is not cacheable
// Reinforce that with explicit caching controls
HttpHdrCc cc;
cc.noStore(true);
cc.mustRevalidate(true);
cc.maxAge(0);
rep->putCc(cc);
// Reinforce that with explicit Expires for old HTTP/1.0 agents
rep->header.putTime(Http::HdrType::EXPIRES, squid_curtime);
http->storeEntry()->replaceHttpReply(rep);
http->storeEntry()->completeSuccessfully("traceReply() stored the entire response");
}
Expand Down
3 changes: 3 additions & 0 deletions src/error/forward.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,9 @@ typedef enum {
ERR_REQUEST_PARSE_TIMEOUT, // Aborts the connection instead of error page
ERR_RELAY_REMOTE, // Sends server reply instead of error page

/* TRACE Response is optional, but SHOULD be equivalent to '%R\n' if sent */
HTTP_TRACE_REPLY,

/* Cache Manager GUI can install a manager index/home page */
MGR_INDEX,

Expand Down
29 changes: 27 additions & 2 deletions src/errorpage.cc
Original file line number Diff line number Diff line change
Expand Up @@ -381,12 +381,17 @@ TemplateFile::loadDefault()
}
#endif

/* test default location if failed (templates == English translation base templates) */
/** test default templates if failed (templates == English translation base templates) */
if (!loaded()) {
tryLoadTemplate("templates");
}

/* giving up if failed */
/** test for any 'soft-coded' template available as default-if-none. */
if (!loaded()) {
tryInternalDefault();
}

/** giving up if failed. Will result in "Internal Error" production. */
if (!loaded()) {
debugs(1, (templateCode < TCP_RESET ? DBG_CRITICAL : 3), "WARNING: failed to find or read error text file " << templateName);
template_.clear();
Expand Down Expand Up @@ -420,6 +425,26 @@ TemplateFile::tryLoadTemplate(const char *lang)
return false;
}

void
TemplateFile::tryInternalDefault()
{
if (loaded())
return; // admin has provided a template.

// Default templates if no file is found.
static const std::list<std::pair<err_type, const SBuf>> SoftCodedErrors = {
{ HTTP_TRACE_REPLY, SBuf("%R\n") }
};

for (const auto &m: SoftCodedErrors) {
if (m.first == templateCode) {
template_ = m.second;
wasLoaded = parse();
return;
}
}
}

bool
TemplateFile::loadFromFile(const char *path)
{
Expand Down
3 changes: 3 additions & 0 deletions src/errorpage.h
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,9 @@ class TemplateFile
*/
bool tryLoadTemplate(const char *lang);

/// Try to load a built-in template, if none is configured.
void tryInternalDefault();

SBuf template_; ///< raw template contents
bool wasLoaded; ///< True if the template data read from disk without any problem
String errLanguage; ///< The error language of the template.
Expand Down
Loading