]>
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 | |
4ac36eab | 20 | static void aclParseHTTPStatusList(Splay<acl_httpstatus_data *> **curlist); |
a0ec9f68 | 21 | static int aclHTTPStatusCompare(acl_httpstatus_data * const &a, acl_httpstatus_data * const &b); |
4ac36eab | 22 | static int aclMatchHTTPStatus(Splay<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 | { | |
f5dc4237 | 77 | if (data) { |
4ac36eab | 78 | data->destroy(); |
f5dc4237 FC |
79 | delete data; |
80 | } | |
a0ec9f68 | 81 | } |
82 | ||
83 | char const * | |
84 | ACLHTTPStatus::typeString() const | |
85 | { | |
86 | return class_; | |
87 | } | |
88 | ||
89 | bool | |
90 | ACLHTTPStatus::empty () const | |
91 | { | |
92 | return data->empty(); | |
93 | } | |
94 | ||
95 | acl_httpstatus_data* | |
96 | aclParseHTTPStatusData(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 | 111 | void |
112 | ACLHTTPStatus::parse() | |
113 | { | |
114 | aclParseHTTPStatusList (&data); | |
115 | } | |
116 | ||
117 | void | |
4ac36eab | 118 | aclParseHTTPStatusList(Splay<acl_httpstatus_data *> **curlist) |
a0ec9f68 | 119 | { |
120 | char *t = NULL; | |
a0ec9f68 | 121 | acl_httpstatus_data *q = NULL; |
122 | ||
123 | while ((t = strtokFile())) { | |
124 | if ((q = aclParseHTTPStatusData(t)) == NULL) | |
125 | continue; | |
126 | ||
4ac36eab | 127 | (*curlist)->insert(q, acl_httpstatus_data::compare); |
a0ec9f68 | 128 | } |
129 | } | |
130 | ||
131 | int | |
132 | ACLHTTPStatus::match(ACLChecklist *checklist) | |
133 | { | |
9b769c67 | 134 | return aclMatchHTTPStatus(&data, Filled(checklist)->reply->sline.status()); |
a0ec9f68 | 135 | } |
136 | ||
137 | int | |
4ac36eab | 138 | aclMatchHTTPStatus(Splay<acl_httpstatus_data*> **dataptr, const Http::StatusCode status) |
a0ec9f68 | 139 | { |
a0ec9f68 | 140 | acl_httpstatus_data X(status); |
4ac36eab | 141 | const acl_httpstatus_data * const * result = (*dataptr)->find(&X, aclHTTPStatusCompare); |
a0ec9f68 | 142 | |
4ac36eab FC |
143 | debugs(28, 3, "aclMatchHTTPStatus: '" << status << "' " << (result ? "found" : "NOT found")); |
144 | return (result != NULL); | |
a0ec9f68 | 145 | } |
146 | ||
147 | static int | |
148 | aclHTTPStatusCompare(acl_httpstatus_data * const &a, acl_httpstatus_data * const &b) | |
149 | { | |
150 | if (a->status1 < b->status1) | |
151 | return 1; | |
152 | ||
153 | if (a->status1 > b->status2) | |
154 | return -1; | |
155 | ||
156 | return 0; | |
157 | } | |
158 | ||
4ac36eab FC |
159 | struct HttpStatusAclDumpVisitor { |
160 | SBufList contents; | |
161 | void operator() (const acl_httpstatus_data * node) { | |
162 | contents.push_back(node->toStr()); | |
163 | } | |
164 | }; | |
a0ec9f68 | 165 | |
8966008b | 166 | SBufList |
a0ec9f68 | 167 | ACLHTTPStatus::dump() const |
168 | { | |
4ac36eab FC |
169 | HttpStatusAclDumpVisitor visitor; |
170 | data->visit(visitor); | |
171 | return visitor.contents; | |
a0ec9f68 | 172 | } |
173 |