From: hno <> Date: Mon, 26 Sep 2005 02:58:23 +0000 (+0000) Subject: Bug #1369: New http_status acl type X-Git-Tag: SQUID_3_0_PRE4~600 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a0ec9f6893f17a73c2f0d98e715511f93b1ec78e;p=thirdparty%2Fsquid.git Bug #1369: New http_status acl type by Gonzalo Arana --- diff --git a/CONTRIBUTORS b/CONTRIBUTORS index 6a2c375f4b..4f29b13491 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -93,5 +93,6 @@ and ideas to make this software available. Francis Daly Joachim Bauch Thomas Ristic + Gonzalo Arana Duane Wessels diff --git a/src/ACLHTTPStatus.cc b/src/ACLHTTPStatus.cc new file mode 100644 index 0000000000..ed32909a10 --- /dev/null +++ b/src/ACLHTTPStatus.cc @@ -0,0 +1,208 @@ +/* + * $Id: ACLHTTPStatus.cc,v 1.1 2005/09/25 20:58:23 hno Exp $ + * + * DEBUG: section 28 Access Control + * AUTHOR: Duane Wessels + * + * SQUID Web Proxy Cache http://www.squid-cache.org/ + * ---------------------------------------------------------- + * + * Squid is the result of efforts by numerous individuals from + * the Internet community; see the CONTRIBUTORS file for full + * details. Many organizations have provided support for Squid's + * development; see the SPONSORS file for full details. Squid is + * Copyrighted (C) 2001 by the Regents of the University of + * California; see the COPYRIGHT file for full details. Squid + * incorporates software developed and/or copyrighted by other + * sources; see the CREDITS file for full details. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. + * + * + * Copyright (c) 2003, Robert Collins + */ + +#include "config.h" +#ifdef _SQUID_CYGWIN_ +#include +#endif +#include "squid.h" + +#include "ACLHTTPStatus.h" +#include "HttpReply.h" + +static void aclParseHTTPStatusList(SplayNode **curlist); +static int aclHTTPStatusCompare(acl_httpstatus_data * const &a, acl_httpstatus_data * const &b); +static int aclMatchHTTPStatus(SplayNode **dataptr, http_status status); + +acl_httpstatus_data::acl_httpstatus_data(int x) : status1(x), status2(x) { ; } + +acl_httpstatus_data::acl_httpstatus_data(int x, int y) : status1(x), status2(y) { ; } + +void acl_httpstatus_data::toStr(char* buf, int len) const +{ + if (status2 == INT_MAX) + snprintf(buf, len, "%d-", status1); + else if (status1 == status2) + snprintf(buf, len, "%d", status1); + else + snprintf(buf, len, "%d-%d", status1, status2); +} + +int acl_httpstatus_data::compare(acl_httpstatus_data* const& a, acl_httpstatus_data* const& b) +{ + int ret; + ret = aclHTTPStatusCompare(b, a); + + if (ret != 0) + ret = aclHTTPStatusCompare(a, b); + + if (ret == 0) { + char bufa[8]; + char bufb[8]; + a->toStr(bufa, sizeof(bufa)); + b->toStr(bufb, sizeof(bufb)); + debug(28, 0) ("WARNING: '%s' is a subrange of '%s'\n", bufa, bufb); + debug(28, 0) ("WARNING: because of this '%s' is ignored " + "to keep splay tree searching predictable\n", bufa); + debug(28, 0) ("WARNING: You should probably remove '%s' " + "from the ACL named '%s'\n", bufb, AclMatchedName); + } + + return ret; +} + +ACL::Prototype ACLHTTPStatus::RegistryProtoype(&ACLHTTPStatus::RegistryEntry_, "http_status"); + +ACLHTTPStatus ACLHTTPStatus::RegistryEntry_("http_status"); + +ACL * +ACLHTTPStatus::clone() const +{ + return new ACLHTTPStatus(*this); +} + +ACLHTTPStatus::ACLHTTPStatus (char const *theClass) : data(NULL), class_ (theClass) +{} + +ACLHTTPStatus::ACLHTTPStatus (ACLHTTPStatus const & old) : data(NULL), class_ (old.class_) +{ + /* we don't have copy constructors for the data yet */ + assert(!old.data); +} + +ACLHTTPStatus::~ACLHTTPStatus() +{ + if (data) + data->destroy(SplayNode::DefaultFree); +} + +char const * +ACLHTTPStatus::typeString() const +{ + return class_; +} + +bool +ACLHTTPStatus::empty () const +{ + return data->empty(); +} + +acl_httpstatus_data* +aclParseHTTPStatusData(const char *t) +{ + int status; + status = atoi(t); + t = strchr(t, '-'); + + if (!t) + return new acl_httpstatus_data(status); + + if (*(++t)) + return new acl_httpstatus_data(status, atoi(t)); + + return new acl_httpstatus_data(status, INT_MAX); +} + + +void +ACLHTTPStatus::parse() +{ + aclParseHTTPStatusList (&data); +} + +void +aclParseHTTPStatusList(SplayNode **curlist) +{ + char *t = NULL; + SplayNode **Top = curlist; + acl_httpstatus_data *q = NULL; + + while ((t = strtokFile())) { + if ((q = aclParseHTTPStatusData(t)) == NULL) + continue; + + *Top = (*Top)->insert(q, acl_httpstatus_data::compare); + } +} + +int +ACLHTTPStatus::match(ACLChecklist *checklist) +{ + return aclMatchHTTPStatus(&data, checklist->reply->sline.status); +} + +int +aclMatchHTTPStatus(SplayNode **dataptr, http_status status) +{ + + acl_httpstatus_data X(status); + SplayNode **Top = dataptr; + *Top = Top[0]->splay(&X, aclHTTPStatusCompare); + + debug(28, 3) ("aclMatchHTTPStatus: '%d' %s\n", status, + splayLastResult ? "NOT found" : "found"); + return (0 == splayLastResult); +} + +static int +aclHTTPStatusCompare(acl_httpstatus_data * const &a, acl_httpstatus_data * const &b) +{ + if (a->status1 < b->status1) + return 1; + + if (a->status1 > b->status2) + return -1; + + return 0; +} + +static void +aclDumpHTTPStatusListWalkee(acl_httpstatus_data * const &node, void *state) +{ + static char buf[8]; + node->toStr(buf, sizeof(buf)); + wordlistAdd((wordlist **)state, buf); +} + +wordlist * +ACLHTTPStatus::dump() const +{ + wordlist *w = NULL; + data->walk(aclDumpHTTPStatusListWalkee, &w); + return w; +} + diff --git a/src/ACLHTTPStatus.h b/src/ACLHTTPStatus.h new file mode 100644 index 0000000000..c8d27cd972 --- /dev/null +++ b/src/ACLHTTPStatus.h @@ -0,0 +1,80 @@ + +/* + * $Id: ACLHTTPStatus.h,v 1.1 2005/09/25 20:58:23 hno Exp $ + * + * + * SQUID Web Proxy Cache http://www.squid-cache.org/ + * ---------------------------------------------------------- + * + * Squid is the result of efforts by numerous individuals from + * the Internet community; see the CONTRIBUTORS file for full + * details. Many organizations have provided support for Squid's + * development; see the SPONSORS file for full details. Squid is + * Copyrighted (C) 2001 by the Regents of the University of + * California; see the COPYRIGHT file for full details. Squid + * incorporates software developed and/or copyrighted by other + * sources; see the CREDITS file for full details. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. + * + * + * Copyright (c) 2003, Robert Collins + */ + +#ifndef SQUID_ACLHTTPSTATUS_H +#define SQUID_ACLHTTPSTATUS_H +#include "ACL.h" +#include "ACLChecklist.h" +#include "splay.h" + +struct acl_httpstatus_data +{ + int status1, status2; + acl_httpstatus_data(int); + acl_httpstatus_data(int, int); + void toStr(char* buf, int len) const; + + static int compare(acl_httpstatus_data* const& a, acl_httpstatus_data* const& b); +}; + +class ACLHTTPStatus : public ACL +{ + +public: + MEMPROXY_CLASS(ACLHTTPStatus); + + ACLHTTPStatus(char const *); + ACLHTTPStatus(ACLHTTPStatus const &); + ~ACLHTTPStatus(); + ACLHTTPStatus&operator=(ACLHTTPStatus const &); + + virtual ACL *clone()const; + virtual char const *typeString() const; + virtual void parse(); + virtual int match(ACLChecklist *checklist); + virtual wordlist *dump() const; + virtual bool empty () const; + virtual bool requiresRequest() { return true; } + +protected: + static Prototype RegistryProtoype; + static ACLHTTPStatus RegistryEntry_; + SplayNode *data; + char const *class_; +}; + +MEMPROXY_CLASS_INLINE(ACLHTTPStatus) + +#endif /* SQUID_ACLHTTPSTATUS_H */ diff --git a/src/Makefile.am b/src/Makefile.am index 6bd0c2c306..8bb8438634 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,7 +1,7 @@ # # Makefile for the Squid Object Cache server # -# $Id: Makefile.am,v 1.110 2005/09/12 23:28:57 wessels Exp $ +# $Id: Makefile.am,v 1.111 2005/09/25 20:58:23 hno Exp $ # # Uncomment and customize the following to suit your needs: # @@ -270,6 +270,8 @@ squid_ACLSOURCES = \ ACLDomainData.cc \ ACLExtUser.h \ ACLExtUser.cc \ + ACLHTTPStatus.h \ + ACLHTTPStatus.cc \ ACLIntRange.cc \ ACLIntRange.h \ ACLIP.cc \ diff --git a/src/cf.data.pre b/src/cf.data.pre index a46f6500be..193bf8b1b7 100644 --- a/src/cf.data.pre +++ b/src/cf.data.pre @@ -1,6 +1,6 @@ # -# $Id: cf.data.pre,v 1.396 2005/09/25 20:25:55 hno Exp $ +# $Id: cf.data.pre,v 1.397 2005/09/25 20:58:23 hno Exp $ # # # SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -2495,6 +2495,8 @@ DOC_START # based URL is used and no match is found. The name "none" is used # if the reverse lookup fails. + acl aclname http_status 200 301 500- 400-403 ... # status code in reply + acl aclname time [day-abbrevs] [h1:m1-h2:m2] day-abbrevs: S - Sunday