source: squid-ssl/trunk/fuentes/src/acl/HttpStatus.cc @ 5495

Last change on this file since 5495 was 5495, checked in by Juanma, 2 years ago

Initial release

File size: 4.1 KB
Line 
1/*
2 * Copyright (C) 1996-2015 The Squid Software Foundation and contributors
3 *
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.
7 */
8
9/* DEBUG: section 28    Access Control */
10
11#include "squid.h"
12#include "acl/FilledChecklist.h"
13#include "acl/HttpStatus.h"
14#include "cache_cf.h"
15#include "Debug.h"
16#include "HttpReply.h"
17
18#include <climits>
19
20static void aclParseHTTPStatusList(Splay<acl_httpstatus_data *> **curlist);
21static int aclHTTPStatusCompare(acl_httpstatus_data * const &a, acl_httpstatus_data * const &b);
22static int aclMatchHTTPStatus(Splay<acl_httpstatus_data*> **dataptr, Http::StatusCode status);
23
24acl_httpstatus_data::acl_httpstatus_data(int x) : status1(x), status2(x) { ; }
25
26acl_httpstatus_data::acl_httpstatus_data(int x, int y) : status1(x), status2(y) { ; }
27
28SBuf
29acl_httpstatus_data::toStr() const
30{
31    SBuf rv;
32    if (status2 == INT_MAX)
33        rv.Printf("%d-", status1);
34    else if (status1 == status2)
35        rv.Printf("%d", status1);
36    else
37        rv.Printf("%d-%d", status1, status2);
38    return rv;
39}
40
41int 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) {
50        const SBuf sa = a->toStr();
51        const SBuf sb = b->toStr();
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 << "'");
55    }
56
57    return ret;
58}
59
60ACL *
61ACLHTTPStatus::clone() const
62{
63    return new ACLHTTPStatus(*this);
64}
65
66ACLHTTPStatus::ACLHTTPStatus (char const *theClass) : data(NULL), class_ (theClass)
67{}
68
69ACLHTTPStatus::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
75ACLHTTPStatus::~ACLHTTPStatus()
76{
77    if (data) {
78        data->destroy();
79        delete data;
80    }
81}
82
83char const *
84ACLHTTPStatus::typeString() const
85{
86    return class_;
87}
88
89bool
90ACLHTTPStatus::empty () const
91{
92    return data->empty();
93}
94
95acl_httpstatus_data*
96aclParseHTTPStatusData(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
111void
112ACLHTTPStatus::parse()
113{
114    if (!data)
115        data = new Splay<acl_httpstatus_data*>();
116
117    aclParseHTTPStatusList (&data);
118}
119
120void
121aclParseHTTPStatusList(Splay<acl_httpstatus_data *> **curlist)
122{
123    char *t = NULL;
124    acl_httpstatus_data *q = NULL;
125
126    while ((t = strtokFile())) {
127        if ((q = aclParseHTTPStatusData(t)) == NULL)
128            continue;
129
130        (*curlist)->insert(q, acl_httpstatus_data::compare);
131    }
132}
133
134int
135ACLHTTPStatus::match(ACLChecklist *checklist)
136{
137    return aclMatchHTTPStatus(&data, Filled(checklist)->reply->sline.status());
138}
139
140int
141aclMatchHTTPStatus(Splay<acl_httpstatus_data*> **dataptr, const Http::StatusCode status)
142{
143    acl_httpstatus_data X(status);
144    const acl_httpstatus_data * const * result = (*dataptr)->find(&X, aclHTTPStatusCompare);
145
146    debugs(28, 3, "aclMatchHTTPStatus: '" << status << "' " << (result ? "found" : "NOT found"));
147    return (result != NULL);
148}
149
150static int
151aclHTTPStatusCompare(acl_httpstatus_data * const &a, acl_httpstatus_data * const &b)
152{
153    if (a->status1 < b->status1)
154        return 1;
155
156    if (a->status1 > b->status2)
157        return -1;
158
159    return 0;
160}
161
162struct HttpStatusAclDumpVisitor {
163    SBufList contents;
164    void operator() (const acl_httpstatus_data * node) {
165        contents.push_back(node->toStr());
166    }
167};
168
169SBufList
170ACLHTTPStatus::dump() const
171{
172    HttpStatusAclDumpVisitor visitor;
173    data->visit(visitor);
174    return visitor.contents;
175}
176
Note: See TracBrowser for help on using the repository browser.