]>
Commit | Line | Data |
---|---|---|
a0ec9f68 | 1 | /* |
262a0e14 | 2 | * $Id$ |
a0ec9f68 | 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. | |
26ac0430 | 23 | * |
a0ec9f68 | 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. | |
26ac0430 | 28 | * |
a0ec9f68 | 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 | ||
f7f3304a | 37 | #include "squid.h" |
c0941a6a AR |
38 | #include "acl/HttpStatus.h" |
39 | #include "acl/FilledChecklist.h" | |
582c2af2 | 40 | #include "Debug.h" |
a0ec9f68 | 41 | #include "HttpReply.h" |
582c2af2 | 42 | #include "protos.h" |
d295d770 | 43 | #include "wordlist.h" |
a0ec9f68 | 44 | |
582c2af2 FC |
45 | #if HAVE_LIMITS_H |
46 | #include <limits.h> | |
47 | #endif | |
48 | ||
a0ec9f68 | 49 | static void aclParseHTTPStatusList(SplayNode<acl_httpstatus_data *> **curlist); |
50 | static int aclHTTPStatusCompare(acl_httpstatus_data * const &a, acl_httpstatus_data * const &b); | |
51 | static int aclMatchHTTPStatus(SplayNode<acl_httpstatus_data*> **dataptr, http_status status); | |
52 | ||
53 | acl_httpstatus_data::acl_httpstatus_data(int x) : status1(x), status2(x) { ; } | |
54 | ||
55 | acl_httpstatus_data::acl_httpstatus_data(int x, int y) : status1(x), status2(y) { ; } | |
56 | ||
57 | void acl_httpstatus_data::toStr(char* buf, int len) const | |
58 | { | |
59 | if (status2 == INT_MAX) | |
60 | snprintf(buf, len, "%d-", status1); | |
61 | else if (status1 == status2) | |
62 | snprintf(buf, len, "%d", status1); | |
63 | else | |
64 | snprintf(buf, len, "%d-%d", status1, status2); | |
65 | } | |
66 | ||
67 | int acl_httpstatus_data::compare(acl_httpstatus_data* const& a, acl_httpstatus_data* const& b) | |
68 | { | |
69 | int ret; | |
70 | ret = aclHTTPStatusCompare(b, a); | |
71 | ||
72 | if (ret != 0) | |
73 | ret = aclHTTPStatusCompare(a, b); | |
74 | ||
75 | if (ret == 0) { | |
76 | char bufa[8]; | |
77 | char bufb[8]; | |
78 | a->toStr(bufa, sizeof(bufa)); | |
79 | b->toStr(bufb, sizeof(bufb)); | |
fa84c01d FC |
80 | debugs(28, DBG_CRITICAL, "WARNING: '" << bufa << "' is a subrange of '" << bufb << "'"); |
81 | debugs(28, DBG_CRITICAL, "WARNING: because of this '" << bufa << "' is ignored to keep splay tree searching predictable"); | |
82 | debugs(28, DBG_CRITICAL, "WARNING: You should probably remove '" << bufb << "' from the ACL named '" << AclMatchedName << "'"); | |
a0ec9f68 | 83 | } |
84 | ||
85 | return ret; | |
86 | } | |
87 | ||
a0ec9f68 | 88 | ACL * |
89 | ACLHTTPStatus::clone() const | |
90 | { | |
91 | return new ACLHTTPStatus(*this); | |
92 | } | |
93 | ||
94 | ACLHTTPStatus::ACLHTTPStatus (char const *theClass) : data(NULL), class_ (theClass) | |
95 | {} | |
96 | ||
97 | ACLHTTPStatus::ACLHTTPStatus (ACLHTTPStatus const & old) : data(NULL), class_ (old.class_) | |
98 | { | |
99 | /* we don't have copy constructors for the data yet */ | |
100 | assert(!old.data); | |
101 | } | |
102 | ||
103 | ACLHTTPStatus::~ACLHTTPStatus() | |
104 | { | |
105 | if (data) | |
106 | data->destroy(SplayNode<acl_httpstatus_data*>::DefaultFree); | |
107 | } | |
108 | ||
109 | char const * | |
110 | ACLHTTPStatus::typeString() const | |
111 | { | |
112 | return class_; | |
113 | } | |
114 | ||
115 | bool | |
116 | ACLHTTPStatus::empty () const | |
117 | { | |
118 | return data->empty(); | |
119 | } | |
120 | ||
121 | acl_httpstatus_data* | |
122 | aclParseHTTPStatusData(const char *t) | |
123 | { | |
124 | int status; | |
125 | status = atoi(t); | |
126 | t = strchr(t, '-'); | |
127 | ||
128 | if (!t) | |
129 | return new acl_httpstatus_data(status); | |
130 | ||
131 | if (*(++t)) | |
132 | return new acl_httpstatus_data(status, atoi(t)); | |
133 | ||
134 | return new acl_httpstatus_data(status, INT_MAX); | |
135 | } | |
136 | ||
a0ec9f68 | 137 | void |
138 | ACLHTTPStatus::parse() | |
139 | { | |
140 | aclParseHTTPStatusList (&data); | |
141 | } | |
142 | ||
143 | void | |
144 | aclParseHTTPStatusList(SplayNode<acl_httpstatus_data *> **curlist) | |
145 | { | |
146 | char *t = NULL; | |
147 | SplayNode<acl_httpstatus_data*> **Top = curlist; | |
148 | acl_httpstatus_data *q = NULL; | |
149 | ||
150 | while ((t = strtokFile())) { | |
151 | if ((q = aclParseHTTPStatusData(t)) == NULL) | |
152 | continue; | |
153 | ||
154 | *Top = (*Top)->insert(q, acl_httpstatus_data::compare); | |
155 | } | |
156 | } | |
157 | ||
158 | int | |
159 | ACLHTTPStatus::match(ACLChecklist *checklist) | |
160 | { | |
c0941a6a | 161 | return aclMatchHTTPStatus(&data, Filled(checklist)->reply->sline.status); |
a0ec9f68 | 162 | } |
163 | ||
164 | int | |
165 | aclMatchHTTPStatus(SplayNode<acl_httpstatus_data*> **dataptr, http_status status) | |
166 | { | |
167 | ||
168 | acl_httpstatus_data X(status); | |
169 | SplayNode<acl_httpstatus_data*> **Top = dataptr; | |
170 | *Top = Top[0]->splay(&X, aclHTTPStatusCompare); | |
171 | ||
bf8fe701 | 172 | debugs(28, 3, "aclMatchHTTPStatus: '" << status << "' " << (splayLastResult ? "NOT found" : "found")); |
a0ec9f68 | 173 | return (0 == splayLastResult); |
174 | } | |
175 | ||
176 | static int | |
177 | aclHTTPStatusCompare(acl_httpstatus_data * const &a, acl_httpstatus_data * const &b) | |
178 | { | |
179 | if (a->status1 < b->status1) | |
180 | return 1; | |
181 | ||
182 | if (a->status1 > b->status2) | |
183 | return -1; | |
184 | ||
185 | return 0; | |
186 | } | |
187 | ||
188 | static void | |
189 | aclDumpHTTPStatusListWalkee(acl_httpstatus_data * const &node, void *state) | |
190 | { | |
191 | static char buf[8]; | |
192 | node->toStr(buf, sizeof(buf)); | |
193 | wordlistAdd((wordlist **)state, buf); | |
194 | } | |
195 | ||
196 | wordlist * | |
197 | ACLHTTPStatus::dump() const | |
198 | { | |
199 | wordlist *w = NULL; | |
200 | data->walk(aclDumpHTTPStatusListWalkee, &w); | |
201 | return w; | |
202 | } | |
203 |