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