]> git.ipfire.org Git - thirdparty/squid.git/blob - src/acl/HttpStatus.cc
Removed squid-old.h
[thirdparty/squid.git] / src / acl / HttpStatus.cc
1 /*
2 * $Id$
3 *
4 * DEBUG: section 28 Access Control
5 * AUTHOR: Duane Wessels
6 *
7 * SQUID Web Proxy Cache http://www.squid-cache.org/
8 * ----------------------------------------------------------
9 *
10 * Squid is the result of efforts by numerous individuals from
11 * the Internet community; see the CONTRIBUTORS file for full
12 * details. Many organizations have provided support for Squid's
13 * development; see the SPONSORS file for full details. Squid is
14 * Copyrighted (C) 2001 by the Regents of the University of
15 * California; see the COPYRIGHT file for full details. Squid
16 * incorporates software developed and/or copyrighted by other
17 * sources; see the CREDITS file for full details.
18 *
19 * This program is free software; you can redistribute it and/or modify
20 * it under the terms of the GNU General Public License as published by
21 * the Free Software Foundation; either version 2 of the License, or
22 * (at your option) any later version.
23 *
24 * This program is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 * GNU General Public License for more details.
28 *
29 * You should have received a copy of the GNU General Public License
30 * along with this program; if not, write to the Free Software
31 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
32 *
33 *
34 * Copyright (c) 2003, Robert Collins <robertc@squid-cache.org>
35 */
36
37 #include "squid.h"
38
39 #include "acl/HttpStatus.h"
40 #include "acl/FilledChecklist.h"
41 #include "Debug.h"
42 #include "HttpReply.h"
43 #include "protos.h"
44 #include "wordlist.h"
45
46 #if HAVE_LIMITS_H
47 #include <limits.h>
48 #endif
49
50 static void aclParseHTTPStatusList(SplayNode<acl_httpstatus_data *> **curlist);
51 static int aclHTTPStatusCompare(acl_httpstatus_data * const &a, acl_httpstatus_data * const &b);
52 static int aclMatchHTTPStatus(SplayNode<acl_httpstatus_data*> **dataptr, http_status status);
53
54 acl_httpstatus_data::acl_httpstatus_data(int x) : status1(x), status2(x) { ; }
55
56 acl_httpstatus_data::acl_httpstatus_data(int x, int y) : status1(x), status2(y) { ; }
57
58 void acl_httpstatus_data::toStr(char* buf, int len) const
59 {
60 if (status2 == INT_MAX)
61 snprintf(buf, len, "%d-", status1);
62 else if (status1 == status2)
63 snprintf(buf, len, "%d", status1);
64 else
65 snprintf(buf, len, "%d-%d", status1, status2);
66 }
67
68 int acl_httpstatus_data::compare(acl_httpstatus_data* const& a, acl_httpstatus_data* const& b)
69 {
70 int ret;
71 ret = aclHTTPStatusCompare(b, a);
72
73 if (ret != 0)
74 ret = aclHTTPStatusCompare(a, b);
75
76 if (ret == 0) {
77 char bufa[8];
78 char bufb[8];
79 a->toStr(bufa, sizeof(bufa));
80 b->toStr(bufb, sizeof(bufb));
81 debugs(28, DBG_CRITICAL, "WARNING: '" << bufa << "' is a subrange of '" << bufb << "'");
82 debugs(28, DBG_CRITICAL, "WARNING: because of this '" << bufa << "' is ignored to keep splay tree searching predictable");
83 debugs(28, DBG_CRITICAL, "WARNING: You should probably remove '" << bufb << "' from the ACL named '" << AclMatchedName << "'");
84 }
85
86 return ret;
87 }
88
89
90
91 ACL *
92 ACLHTTPStatus::clone() const
93 {
94 return new ACLHTTPStatus(*this);
95 }
96
97 ACLHTTPStatus::ACLHTTPStatus (char const *theClass) : data(NULL), class_ (theClass)
98 {}
99
100 ACLHTTPStatus::ACLHTTPStatus (ACLHTTPStatus const & old) : data(NULL), class_ (old.class_)
101 {
102 /* we don't have copy constructors for the data yet */
103 assert(!old.data);
104 }
105
106 ACLHTTPStatus::~ACLHTTPStatus()
107 {
108 if (data)
109 data->destroy(SplayNode<acl_httpstatus_data*>::DefaultFree);
110 }
111
112 char const *
113 ACLHTTPStatus::typeString() const
114 {
115 return class_;
116 }
117
118 bool
119 ACLHTTPStatus::empty () const
120 {
121 return data->empty();
122 }
123
124 acl_httpstatus_data*
125 aclParseHTTPStatusData(const char *t)
126 {
127 int status;
128 status = atoi(t);
129 t = strchr(t, '-');
130
131 if (!t)
132 return new acl_httpstatus_data(status);
133
134 if (*(++t))
135 return new acl_httpstatus_data(status, atoi(t));
136
137 return new acl_httpstatus_data(status, INT_MAX);
138 }
139
140
141 void
142 ACLHTTPStatus::parse()
143 {
144 aclParseHTTPStatusList (&data);
145 }
146
147 void
148 aclParseHTTPStatusList(SplayNode<acl_httpstatus_data *> **curlist)
149 {
150 char *t = NULL;
151 SplayNode<acl_httpstatus_data*> **Top = curlist;
152 acl_httpstatus_data *q = NULL;
153
154 while ((t = strtokFile())) {
155 if ((q = aclParseHTTPStatusData(t)) == NULL)
156 continue;
157
158 *Top = (*Top)->insert(q, acl_httpstatus_data::compare);
159 }
160 }
161
162 int
163 ACLHTTPStatus::match(ACLChecklist *checklist)
164 {
165 return aclMatchHTTPStatus(&data, Filled(checklist)->reply->sline.status);
166 }
167
168 int
169 aclMatchHTTPStatus(SplayNode<acl_httpstatus_data*> **dataptr, http_status status)
170 {
171
172 acl_httpstatus_data X(status);
173 SplayNode<acl_httpstatus_data*> **Top = dataptr;
174 *Top = Top[0]->splay(&X, aclHTTPStatusCompare);
175
176 debugs(28, 3, "aclMatchHTTPStatus: '" << status << "' " << (splayLastResult ? "NOT found" : "found"));
177 return (0 == splayLastResult);
178 }
179
180 static int
181 aclHTTPStatusCompare(acl_httpstatus_data * const &a, acl_httpstatus_data * const &b)
182 {
183 if (a->status1 < b->status1)
184 return 1;
185
186 if (a->status1 > b->status2)
187 return -1;
188
189 return 0;
190 }
191
192 static void
193 aclDumpHTTPStatusListWalkee(acl_httpstatus_data * const &node, void *state)
194 {
195 static char buf[8];
196 node->toStr(buf, sizeof(buf));
197 wordlistAdd((wordlist **)state, buf);
198 }
199
200 wordlist *
201 ACLHTTPStatus::dump() const
202 {
203 wordlist *w = NULL;
204 data->walk(aclDumpHTTPStatusListWalkee, &w);
205 return w;
206 }
207