2 * Copyright (C) 1996-2014 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"
16 #include "HttpReply.h"
20 static void aclParseHTTPStatusList(Splay
<acl_httpstatus_data
*> **curlist
);
21 static int aclHTTPStatusCompare(acl_httpstatus_data
* const &a
, acl_httpstatus_data
* const &b
);
22 static int aclMatchHTTPStatus(Splay
<acl_httpstatus_data
*> **dataptr
, Http::StatusCode status
);
24 acl_httpstatus_data::acl_httpstatus_data(int x
) : status1(x
), status2(x
) { ; }
26 acl_httpstatus_data::acl_httpstatus_data(int x
, int y
) : status1(x
), status2(y
) { ; }
29 acl_httpstatus_data::toStr() const
32 if (status2
== INT_MAX
)
33 rv
.Printf("%d-", status1
);
34 else if (status1
== status2
)
35 rv
.Printf("%d", status1
);
37 rv
.Printf("%d-%d", status1
, status2
);
41 int acl_httpstatus_data::compare(acl_httpstatus_data
* const& a
, acl_httpstatus_data
* const& b
)
44 ret
= aclHTTPStatusCompare(b
, a
);
47 ret
= aclHTTPStatusCompare(a
, b
);
50 const SBuf sa
= a
->toStr();
51 const SBuf sb
= b
->toStr();
52 debugs(28, DBG_CRITICAL
, "WARNING: '" << sa
<< "' is a subrange of '" << sb
<< "'");
53 debugs(28, DBG_CRITICAL
, "WARNING: because of this '" << sa
<< "' is ignored to keep splay tree searching predictable");
54 debugs(28, DBG_CRITICAL
, "WARNING: You should probably remove '" << sb
<< "' from the ACL named '" << AclMatchedName
<< "'");
61 ACLHTTPStatus::clone() const
63 return new ACLHTTPStatus(*this);
66 ACLHTTPStatus::ACLHTTPStatus (char const *theClass
) : data(NULL
), class_ (theClass
)
69 ACLHTTPStatus::ACLHTTPStatus (ACLHTTPStatus
const & old
) : data(NULL
), class_ (old
.class_
)
71 /* we don't have copy constructors for the data yet */
75 ACLHTTPStatus::~ACLHTTPStatus()
84 ACLHTTPStatus::typeString() const
90 ACLHTTPStatus::empty () const
96 aclParseHTTPStatusData(const char *t
)
103 return new acl_httpstatus_data(status
);
106 return new acl_httpstatus_data(status
, atoi(t
));
108 return new acl_httpstatus_data(status
, INT_MAX
);
112 ACLHTTPStatus::parse()
115 data
= new Splay
<acl_httpstatus_data
*>();
117 aclParseHTTPStatusList (&data
);
121 aclParseHTTPStatusList(Splay
<acl_httpstatus_data
*> **curlist
)
124 acl_httpstatus_data
*q
= NULL
;
126 while ((t
= strtokFile())) {
127 if ((q
= aclParseHTTPStatusData(t
)) == NULL
)
130 (*curlist
)->insert(q
, acl_httpstatus_data::compare
);
135 ACLHTTPStatus::match(ACLChecklist
*checklist
)
137 return aclMatchHTTPStatus(&data
, Filled(checklist
)->reply
->sline
.status());
141 aclMatchHTTPStatus(Splay
<acl_httpstatus_data
*> **dataptr
, const Http::StatusCode status
)
143 acl_httpstatus_data
X(status
);
144 const acl_httpstatus_data
* const * result
= (*dataptr
)->find(&X
, aclHTTPStatusCompare
);
146 debugs(28, 3, "aclMatchHTTPStatus: '" << status
<< "' " << (result
? "found" : "NOT found"));
147 return (result
!= NULL
);
151 aclHTTPStatusCompare(acl_httpstatus_data
* const &a
, acl_httpstatus_data
* const &b
)
153 if (a
->status1
< b
->status1
)
156 if (a
->status1
> b
->status2
)
162 struct HttpStatusAclDumpVisitor
{
164 void operator() (const acl_httpstatus_data
* node
) {
165 contents
.push_back(node
->toStr());
170 ACLHTTPStatus::dump() const
172 HttpStatusAclDumpVisitor visitor
;
173 data
->visit(visitor
);
174 return visitor
.contents
;