]> git.ipfire.org Git - thirdparty/squid.git/blob - src/acl/HttpHeaderData.cc
Source Format Enforcement (#763)
[thirdparty/squid.git] / src / acl / HttpHeaderData.cc
1 /*
2 * Copyright (C) 1996-2021 The Squid Software Foundation and contributors
3 *
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
7 */
8
9 /* DEBUG: section 28 Access Control */
10
11 #include "squid.h"
12 #include "acl/Acl.h"
13 #include "acl/Checklist.h"
14 #include "acl/HttpHeaderData.h"
15 #include "acl/RegexData.h"
16 #include "base/RegexPattern.h"
17 #include "ConfigParser.h"
18 #include "Debug.h"
19 #include "HttpHeaderTools.h"
20 #include "sbuf/SBuf.h"
21 #include "sbuf/StringConvert.h"
22
23 /* Construct an ACLHTTPHeaderData that uses an ACLRegex rule with the value of the
24 * selected header from a given request.
25 *
26 * TODO: This can be generalised by making the type of the regex_rule into a
27 * template parameter - so that we can use different rules types in future.
28 */
29 ACLHTTPHeaderData::ACLHTTPHeaderData() : hdrId(Http::HdrType::BAD_HDR), regex_rule(new ACLRegexData)
30 {}
31
32 ACLHTTPHeaderData::~ACLHTTPHeaderData()
33 {
34 delete regex_rule;
35 }
36
37 bool
38 ACLHTTPHeaderData::match(HttpHeader* hdr)
39 {
40 if (hdr == NULL)
41 return false;
42
43 debugs(28, 3, "aclHeaderData::match: checking '" << hdrName << "'");
44
45 String value;
46 if (hdrId != Http::HdrType::BAD_HDR) {
47 if (!hdr->has(hdrId))
48 return false;
49 value = hdr->getStrOrList(hdrId);
50 } else {
51 if (!hdr->hasNamed(hdrName, &value))
52 return false;
53 }
54
55 auto cvalue = StringToSBuf(value);
56 return regex_rule->match(cvalue.c_str());
57 }
58
59 SBufList
60 ACLHTTPHeaderData::dump() const
61 {
62 SBufList sl;
63 sl.push_back(SBuf(hdrName));
64 sl.splice(sl.end(), regex_rule->dump());
65 return sl;
66 }
67
68 void
69 ACLHTTPHeaderData::parse()
70 {
71 char* t = ConfigParser::strtokFile();
72 if (!t) {
73 debugs(28, DBG_CRITICAL, "ERROR: " << cfg_filename << " line " << config_lineno << ": " << config_input_line);
74 debugs(28, DBG_CRITICAL, "ERROR: Missing header name in ACL");
75 return;
76 }
77
78 if (hdrName.isEmpty()) {
79 hdrName = t;
80 hdrId = Http::HeaderLookupTable.lookup(hdrName).id;
81 } else if (hdrName.caseCmp(t) != 0) {
82 debugs(28, DBG_CRITICAL, "ERROR: " << cfg_filename << " line " << config_lineno << ": " << config_input_line);
83 debugs(28, DBG_CRITICAL, "ERROR: ACL cannot match both " << hdrName << " and " << t << " headers. Use 'anyof' ACL instead.");
84 return;
85 }
86
87 regex_rule->parse();
88 }
89
90 bool
91 ACLHTTPHeaderData::empty() const
92 {
93 return (hdrId == Http::HdrType::BAD_HDR && hdrName.isEmpty()) || regex_rule->empty();
94 }
95
96 ACLData<HttpHeader*> *
97 ACLHTTPHeaderData::clone() const
98 {
99 /* Header's don't clone yet. */
100 ACLHTTPHeaderData * result = new ACLHTTPHeaderData;
101 result->regex_rule = regex_rule->clone();
102 result->hdrId = hdrId;
103 result->hdrName = hdrName;
104 return result;
105 }
106