]>
Commit | Line | Data |
---|---|---|
a0ec9f68 | 1 | /* |
bbc27441 | 2 | * Copyright (C) 1996-2014 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 | |
a0ec9f68 | 20 | static void aclParseHTTPStatusList(SplayNode<acl_httpstatus_data *> **curlist); |
21 | static int aclHTTPStatusCompare(acl_httpstatus_data * const &a, acl_httpstatus_data * const &b); | |
955394ce | 22 | static int aclMatchHTTPStatus(SplayNode<acl_httpstatus_data*> **dataptr, Http::StatusCode status); |
a0ec9f68 | 23 | |
24 | acl_httpstatus_data::acl_httpstatus_data(int x) : status1(x), status2(x) { ; } | |
25 | ||
26 | acl_httpstatus_data::acl_httpstatus_data(int x, int y) : status1(x), status2(y) { ; } | |
27 | ||
8966008b | 28 | SBuf |
2cb8d372 | 29 | acl_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 | ||
41 | int 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 | 60 | ACL * |
61 | ACLHTTPStatus::clone() const | |
62 | { | |
63 | return new ACLHTTPStatus(*this); | |
64 | } | |
65 | ||
66 | ACLHTTPStatus::ACLHTTPStatus (char const *theClass) : data(NULL), class_ (theClass) | |
67 | {} | |
68 | ||
69 | ACLHTTPStatus::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 | ||
75 | ACLHTTPStatus::~ACLHTTPStatus() | |
76 | { | |
77 | if (data) | |
78 | data->destroy(SplayNode<acl_httpstatus_data*>::DefaultFree); | |
79 | } | |
80 | ||
81 | char const * | |
82 | ACLHTTPStatus::typeString() const | |
83 | { | |
84 | return class_; | |
85 | } | |
86 | ||
87 | bool | |
88 | ACLHTTPStatus::empty () const | |
89 | { | |
90 | return data->empty(); | |
91 | } | |
92 | ||
93 | acl_httpstatus_data* | |
94 | aclParseHTTPStatusData(const char *t) | |
95 | { | |
96 | int status; | |
97 | status = atoi(t); | |
98 | t = strchr(t, '-'); | |
99 | ||
100 | if (!t) | |
101 | return new acl_httpstatus_data(status); | |
102 | ||
103 | if (*(++t)) | |
104 | return new acl_httpstatus_data(status, atoi(t)); | |
105 | ||
106 | return new acl_httpstatus_data(status, INT_MAX); | |
107 | } | |
108 | ||
a0ec9f68 | 109 | void |
110 | ACLHTTPStatus::parse() | |
111 | { | |
112 | aclParseHTTPStatusList (&data); | |
113 | } | |
114 | ||
115 | void | |
116 | aclParseHTTPStatusList(SplayNode<acl_httpstatus_data *> **curlist) | |
117 | { | |
118 | char *t = NULL; | |
119 | SplayNode<acl_httpstatus_data*> **Top = curlist; | |
120 | acl_httpstatus_data *q = NULL; | |
121 | ||
122 | while ((t = strtokFile())) { | |
123 | if ((q = aclParseHTTPStatusData(t)) == NULL) | |
124 | continue; | |
125 | ||
126 | *Top = (*Top)->insert(q, acl_httpstatus_data::compare); | |
127 | } | |
128 | } | |
129 | ||
130 | int | |
131 | ACLHTTPStatus::match(ACLChecklist *checklist) | |
132 | { | |
9b769c67 | 133 | return aclMatchHTTPStatus(&data, Filled(checklist)->reply->sline.status()); |
a0ec9f68 | 134 | } |
135 | ||
136 | int | |
9b769c67 | 137 | aclMatchHTTPStatus(SplayNode<acl_httpstatus_data*> **dataptr, const Http::StatusCode status) |
a0ec9f68 | 138 | { |
139 | ||
140 | acl_httpstatus_data X(status); | |
141 | SplayNode<acl_httpstatus_data*> **Top = dataptr; | |
142 | *Top = Top[0]->splay(&X, aclHTTPStatusCompare); | |
143 | ||
bf8fe701 | 144 | debugs(28, 3, "aclMatchHTTPStatus: '" << status << "' " << (splayLastResult ? "NOT found" : "found")); |
a0ec9f68 | 145 | return (0 == splayLastResult); |
146 | } | |
147 | ||
148 | static int | |
149 | aclHTTPStatusCompare(acl_httpstatus_data * const &a, acl_httpstatus_data * const &b) | |
150 | { | |
151 | if (a->status1 < b->status1) | |
152 | return 1; | |
153 | ||
154 | if (a->status1 > b->status2) | |
155 | return -1; | |
156 | ||
157 | return 0; | |
158 | } | |
159 | ||
160 | static void | |
161 | aclDumpHTTPStatusListWalkee(acl_httpstatus_data * const &node, void *state) | |
162 | { | |
8966008b | 163 | // state is a SBufList* |
2cb8d372 | 164 | static_cast<SBufList *>(state)->push_back(node->toStr()); |
a0ec9f68 | 165 | } |
166 | ||
8966008b | 167 | SBufList |
a0ec9f68 | 168 | ACLHTTPStatus::dump() const |
169 | { | |
8966008b | 170 | SBufList w; |
a0ec9f68 | 171 | data->walk(aclDumpHTTPStatusListWalkee, &w); |
172 | return w; | |
173 | } | |
174 |