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