]> git.ipfire.org Git - thirdparty/squid.git/blame - src/acl/HttpStatus.cc
SourceFormat Enforcement
[thirdparty/squid.git] / src / acl / HttpStatus.cc
CommitLineData
a0ec9f68 1/*
4ac4a490 2 * Copyright (C) 1996-2017 The Squid Software Foundation and contributors
a0ec9f68 3 *
bbc27441
AJ
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.
a0ec9f68 7 */
8
bbc27441
AJ
9/* DEBUG: section 28 Access Control */
10
f7f3304a 11#include "squid.h"
c0941a6a 12#include "acl/FilledChecklist.h"
602d9612 13#include "acl/HttpStatus.h"
582c2af2 14#include "Debug.h"
a0ec9f68 15#include "HttpReply.h"
16
074d6a40 17#include <climits>
582c2af2 18
4ac36eab 19static void aclParseHTTPStatusList(Splay<acl_httpstatus_data *> **curlist);
a0ec9f68 20static int aclHTTPStatusCompare(acl_httpstatus_data * const &a, acl_httpstatus_data * const &b);
4ac36eab 21static int aclMatchHTTPStatus(Splay<acl_httpstatus_data*> **dataptr, Http::StatusCode status);
a0ec9f68 22
23acl_httpstatus_data::acl_httpstatus_data(int x) : status1(x), status2(x) { ; }
24
25acl_httpstatus_data::acl_httpstatus_data(int x, int y) : status1(x), status2(y) { ; }
26
8966008b 27SBuf
2cb8d372 28acl_httpstatus_data::toStr() const
a0ec9f68 29{
8966008b 30 SBuf rv;
a0ec9f68 31 if (status2 == INT_MAX)
8966008b 32 rv.Printf("%d-", status1);
a0ec9f68 33 else if (status1 == status2)
8966008b 34 rv.Printf("%d", status1);
a0ec9f68 35 else
8966008b
FC
36 rv.Printf("%d-%d", status1, status2);
37 return rv;
a0ec9f68 38}
39
40int acl_httpstatus_data::compare(acl_httpstatus_data* const& a, acl_httpstatus_data* const& b)
41{
42 int ret;
43 ret = aclHTTPStatusCompare(b, a);
44
45 if (ret != 0)
46 ret = aclHTTPStatusCompare(a, b);
47
48 if (ret == 0) {
2cb8d372
FC
49 const SBuf sa = a->toStr();
50 const SBuf sb = b->toStr();
8966008b
FC
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 << "'");
a0ec9f68 54 }
55
56 return ret;
57}
58
a0ec9f68 59ACL *
60ACLHTTPStatus::clone() const
61{
62 return new ACLHTTPStatus(*this);
63}
64
65ACLHTTPStatus::ACLHTTPStatus (char const *theClass) : data(NULL), class_ (theClass)
66{}
67
68ACLHTTPStatus::ACLHTTPStatus (ACLHTTPStatus const & old) : data(NULL), class_ (old.class_)
69{
70 /* we don't have copy constructors for the data yet */
71 assert(!old.data);
72}
73
74ACLHTTPStatus::~ACLHTTPStatus()
75{
f5dc4237 76 if (data) {
4ac36eab 77 data->destroy();
f5dc4237
FC
78 delete data;
79 }
a0ec9f68 80}
81
82char const *
83ACLHTTPStatus::typeString() const
84{
85 return class_;
86}
87
88bool
89ACLHTTPStatus::empty () const
90{
91 return data->empty();
92}
93
94acl_httpstatus_data*
95aclParseHTTPStatusData(const char *t)
96{
97 int status;
98 status = atoi(t);
99 t = strchr(t, '-');
100
101 if (!t)
102 return new acl_httpstatus_data(status);
103
104 if (*(++t))
105 return new acl_httpstatus_data(status, atoi(t));
106
107 return new acl_httpstatus_data(status, INT_MAX);
108}
109
a0ec9f68 110void
111ACLHTTPStatus::parse()
112{
5bc2be30
FC
113 if (!data)
114 data = new Splay<acl_httpstatus_data*>();
115
a0ec9f68 116 aclParseHTTPStatusList (&data);
117}
118
119void
4ac36eab 120aclParseHTTPStatusList(Splay<acl_httpstatus_data *> **curlist)
a0ec9f68 121{
16c5ad96
AJ
122 while (char *t = ConfigParser::strtokFile()) {
123 if (acl_httpstatus_data *q = aclParseHTTPStatusData(t))
124 (*curlist)->insert(q, acl_httpstatus_data::compare);
a0ec9f68 125 }
126}
127
128int
129ACLHTTPStatus::match(ACLChecklist *checklist)
130{
9b769c67 131 return aclMatchHTTPStatus(&data, Filled(checklist)->reply->sline.status());
a0ec9f68 132}
133
134int
4ac36eab 135aclMatchHTTPStatus(Splay<acl_httpstatus_data*> **dataptr, const Http::StatusCode status)
a0ec9f68 136{
a0ec9f68 137 acl_httpstatus_data X(status);
4ac36eab 138 const acl_httpstatus_data * const * result = (*dataptr)->find(&X, aclHTTPStatusCompare);
a0ec9f68 139
4ac36eab
FC
140 debugs(28, 3, "aclMatchHTTPStatus: '" << status << "' " << (result ? "found" : "NOT found"));
141 return (result != NULL);
a0ec9f68 142}
143
144static int
145aclHTTPStatusCompare(acl_httpstatus_data * const &a, acl_httpstatus_data * const &b)
146{
147 if (a->status1 < b->status1)
148 return 1;
149
150 if (a->status1 > b->status2)
151 return -1;
152
153 return 0;
154}
155
4ac36eab
FC
156struct HttpStatusAclDumpVisitor {
157 SBufList contents;
158 void operator() (const acl_httpstatus_data * node) {
159 contents.push_back(node->toStr());
160 }
161};
a0ec9f68 162
8966008b 163SBufList
a0ec9f68 164ACLHTTPStatus::dump() const
165{
4ac36eab
FC
166 HttpStatusAclDumpVisitor visitor;
167 data->visit(visitor);
168 return visitor.contents;
a0ec9f68 169}
170