2 * Copyright (C) 1996-2018 The Squid Software Foundation and contributors
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.
9 /* DEBUG: section 28 Access Control */
12 #include "acl/FilledChecklist.h"
13 #include "acl/HttpStatus.h"
15 #include "HttpReply.h"
19 static void aclParseHTTPStatusList(Splay
<acl_httpstatus_data
*> **curlist
);
20 static int aclHTTPStatusCompare(acl_httpstatus_data
* const &a
, acl_httpstatus_data
* const &b
);
21 static int aclMatchHTTPStatus(Splay
<acl_httpstatus_data
*> **dataptr
, Http::StatusCode status
);
23 acl_httpstatus_data::acl_httpstatus_data(int x
) : status1(x
), status2(x
) { ; }
25 acl_httpstatus_data::acl_httpstatus_data(int x
, int y
) : status1(x
), status2(y
) { ; }
28 acl_httpstatus_data::toStr() const
31 if (status2
== INT_MAX
)
32 rv
.Printf("%d-", status1
);
33 else if (status1
== status2
)
34 rv
.Printf("%d", status1
);
36 rv
.Printf("%d-%d", status1
, status2
);
40 int acl_httpstatus_data::compare(acl_httpstatus_data
* const& a
, acl_httpstatus_data
* const& b
)
43 ret
= aclHTTPStatusCompare(b
, a
);
46 ret
= aclHTTPStatusCompare(a
, b
);
49 const SBuf sa
= a
->toStr();
50 const SBuf sb
= b
->toStr();
51 debugs(28, DBG_CRITICAL
, "WARNING: '" << sa
<< "' is a subrange of '" << sb
<< "'");
52 debugs(28, DBG_CRITICAL
, "WARNING: because of this '" << sa
<< "' is ignored to keep splay tree searching predictable");
53 debugs(28, DBG_CRITICAL
, "WARNING: You should probably remove '" << sb
<< "' from the ACL named '" << AclMatchedName
<< "'");
60 ACLHTTPStatus::clone() const
62 return new ACLHTTPStatus(*this);
65 ACLHTTPStatus::ACLHTTPStatus (char const *theClass
) : data(NULL
), class_ (theClass
)
68 ACLHTTPStatus::ACLHTTPStatus (ACLHTTPStatus
const & old
) : data(NULL
), class_ (old
.class_
)
70 /* we don't have copy constructors for the data yet */
74 ACLHTTPStatus::~ACLHTTPStatus()
83 ACLHTTPStatus::typeString() const
89 ACLHTTPStatus::empty () const
95 aclParseHTTPStatusData(const char *t
)
102 return new acl_httpstatus_data(status
);
105 return new acl_httpstatus_data(status
, atoi(t
));
107 return new acl_httpstatus_data(status
, INT_MAX
);
111 ACLHTTPStatus::parse()
114 data
= new Splay
<acl_httpstatus_data
*>();
116 aclParseHTTPStatusList (&data
);
120 aclParseHTTPStatusList(Splay
<acl_httpstatus_data
*> **curlist
)
122 while (char *t
= ConfigParser::strtokFile()) {
123 if (acl_httpstatus_data
*q
= aclParseHTTPStatusData(t
))
124 (*curlist
)->insert(q
, acl_httpstatus_data::compare
);
129 ACLHTTPStatus::match(ACLChecklist
*checklist
)
131 return aclMatchHTTPStatus(&data
, Filled(checklist
)->reply
->sline
.status());
135 aclMatchHTTPStatus(Splay
<acl_httpstatus_data
*> **dataptr
, const Http::StatusCode status
)
137 acl_httpstatus_data
X(status
);
138 const acl_httpstatus_data
* const * result
= (*dataptr
)->find(&X
, aclHTTPStatusCompare
);
140 debugs(28, 3, "aclMatchHTTPStatus: '" << status
<< "' " << (result
? "found" : "NOT found"));
141 return (result
!= NULL
);
145 aclHTTPStatusCompare(acl_httpstatus_data
* const &a
, acl_httpstatus_data
* const &b
)
147 if (a
->status1
< b
->status1
)
150 if (a
->status1
> b
->status2
)
156 struct HttpStatusAclDumpVisitor
{
158 void operator() (const acl_httpstatus_data
* node
) {
159 contents
.push_back(node
->toStr());
164 ACLHTTPStatus::dump() const
166 HttpStatusAclDumpVisitor visitor
;
167 data
->visit(visitor
);
168 return visitor
.contents
;