strnstr.cc \
strsep.h \
strtoll.h \
+ strnrchr.h \
+ strnrchr.c \
tempnam.h \
types.h \
unsafe.h \
--- /dev/null
+/*
+ * strnrchr.c
+ *
+ * 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.
+ */
+
+#include "config.h"
+#include "strnrchr.h"
+
+const char *
+strnrchr(const char *s, size_t count, int c)
+{
+ const char *rv=NULL;
+ const char *l=s;
+ while (count > 0 && *l != 0) {
+ if (*l==c)
+ rv=l;
+ ++l;
+ --count;
+ }
+ return rv;
+}
--- /dev/null
+/*
+ * strnrchr.h
+ *
+ * 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.
+ */
+
+#ifndef COMPAT_STRNRCHR_H_
+#define COMPAT_STRNRCHR_H_
+
+#if HAVE_STDDEF_H
+#include <stddef.h>
+#endif
+
+/**
+ * look for the last occurrence of a character in a c-string.
+ *
+ * Scanning starts at the beginning of the c-string, and ends
+ * after count bytes or at the end of the c-string, whichever happens first
+ */
+SQUIDCEXTERN const char *strnrchr(const char *s, size_t count, int c);
+
+#endif /* COMPAT_STRNRCHR_H_ */
* AUTHOR: Alex Rousskov
* Robert Collins (Surrogate-Control is derived from
* Cache-Control).
+ * Francesco Chemolli (c++ refactoring)
*
* SQUID Web Proxy Cache http://www.squid-cache.org/
* ----------------------------------------------------------
#include "HttpHeader.h"
#include "HttpHdrSc.h"
+#if HAVE_MAP
+#include <map>
+#endif
+
+/* a row in the table used for parsing surrogate-control header and statistics */
+typedef struct {
+ const char *name;
+ http_hdr_sc_type id;
+ HttpHeaderFieldStat stat;
+} HttpHeaderScFields;
+
/* this table is used for parsing surrogate control header */
+/* order must match that of enum http_hdr_sc_type. The constraint is verified at initialization time */
+//todo: implement constraint
static const HttpHeaderFieldAttrs ScAttrs[SC_ENUM_END] = {
{"no-store", (http_hdr_type)SC_NO_STORE},
-
{"no-store-remote", (http_hdr_type)SC_NO_STORE_REMOTE},
{"max-age", (http_hdr_type)SC_MAX_AGE},
{"content", (http_hdr_type)SC_CONTENT},
}
-/* local prototypes */
-static int httpHdrScParseInit(HttpHdrSc * sc, const String * str);
-
/* module initialization */
void
/* implementation */
-HttpHdrSc *
-httpHdrScCreate(void)
-{
- return new HttpHdrSc();
-}
-
/* creates an sc object from a 0-terminating string */
HttpHdrSc *
-httpHdrScParseCreate(const String * str)
+httpHdrScParseCreate(const String & str)
{
- HttpHdrSc *sc = httpHdrScCreate();
+ HttpHdrSc *sc = new HttpHdrSc();
- if (!httpHdrScParseInit(sc, str)) {
- httpHdrScDestroy(sc);
+ if (!sc->parse(&str)) {
+ delete sc;
sc = NULL;
}
}
/* parses a 0-terminating string and inits sc */
-static int
-httpHdrScParseInit(HttpHdrSc * sc, const String * str)
+bool
+HttpHdrSc::parse(const String * str)
{
+ HttpHdrSc * sc=this;
const char *item;
const char *p; /* '=' parameter */
const char *pos = NULL;
int ilen, vlen;
int initiallen;
HttpHdrScTarget *sct;
- assert(sc && str);
+ assert(str);
/* iterate through comma separated list */
ilen = p++ - item;
/* find type */
+ /* TODO: use a type-safe map-based lookup */
type = httpHeaderIdByName(item, ilen,
ScFieldsInfo, SC_ENUM_END);
}
/* Is this a targeted directive? */
- /* TODO sometime: implement a strnrchr that looks at a substring */
+ /* TODO: remove the temporary useage and use memrchr and the information we have instead */
temp = xstrndup (item, initiallen + 1);
if (!((target = strrchr (temp, ';')) && !strchr (target, '"') && *(target + 1) != '\0'))
else
++target;
- sct = httpHdrScFindTarget (sc, target);
+ sct = sc->findTarget(target);
if (!sct) {
- sct = httpHdrScTargetCreate (target);
- dlinkAdd(sct, &sct->node, &sc->targets);
+ sct = new HttpHdrScTarget(target);
+ addTarget(sct);
}
safe_free (temp);
- if (EBIT_TEST(sct->mask, type)) {
+ if (sct->isSet(static_cast<http_hdr_sc_type>(type))) {
if (type != SC_OTHER)
debugs(90, 2, "hdr sc: ignoring duplicate control-directive: near '" << item << "' in '" << str << "'");
continue;
}
- /* update mask */
- EBIT_SET(sct->mask, type);
-
- /* post-processing special cases */
+ /* process directives */
switch (type) {
+ case SC_NO_STORE:
+ sct->noStore(true);
+ break;
- case SC_MAX_AGE:
+ case SC_NO_STORE_REMOTE:
+ sct->noStoreRemote(true);
+ break;
- if (!p || !httpHeaderParseInt(p, &sct->max_age)) {
+ case SC_MAX_AGE: {
+ int ma;
+ if (p && httpHeaderParseInt(p, &ma)) {
+ sct->maxAge(ma);
+ } else {
debugs(90, 2, "sc: invalid max-age specs near '" << item << "'");
- sct->max_age = -1;
- EBIT_CLR(sct->mask, type);
+ sct->clearMaxAge();
}
- if ((p = strchr (p, '+')))
- if (!httpHeaderParseInt(++p, &sct->max_stale)) {
+ if ((p = strchr (p, '+'))) {
+ int ms;
+ ++p; //skip the + char
+ if (httpHeaderParseInt(p, &ms)) {
+ sct->maxStale(ms);
+ } else {
debugs(90, 2, "sc: invalid max-stale specs near '" << item << "'");
- sct->max_stale = 0;
+ sct->clearMaxStale();
/* leave the max-age alone */
}
-
+ }
break;
+ }
case SC_CONTENT:
- if (!p || !httpHeaderParseQuotedString(p, vlen, &sct->content)) {
+ if ( p && httpHeaderParseQuotedString(p, vlen, &sct->content_)) {
+ sct->setMask(SC_CONTENT,true); // ugly but saves a copy
+ } else {
debugs(90, 2, "sc: invalid content= quoted string near '" << item << "'");
- sct->content.clean();
- EBIT_CLR(sct->mask, type);
+ sct->clearContent();
}
+ break;
+ case SC_OTHER:
default:
break;
}
return sc->targets.head != NULL;
}
-void
-httpHdrScDestroy(HttpHdrSc * sc)
+HttpHdrSc::~HttpHdrSc()
{
- assert(sc);
-
- if (sc->targets.head) {
- dlink_node *sct = sc->targets.head;
+ if (targets.head) {
+ dlink_node *sct = targets.head;
while (sct) {
- HttpHdrScTarget *t = (HttpHdrScTarget *)sct->data;
+ HttpHdrScTarget *t = static_cast<HttpHdrScTarget *>(sct->data);
sct = sct->next;
- dlinkDelete (&t->node, &sc->targets);
- httpHdrScTargetDestroy (t);
+ dlinkDelete (&t->node, &targets);
+ delete t;
}
}
-
- delete sc;
}
-HttpHdrSc *
-httpHdrScDup(const HttpHdrSc * sc)
+
+HttpHdrSc::HttpHdrSc(const HttpHdrSc &sc)
{
- HttpHdrSc *dup;
- dlink_node *node;
- assert(sc);
- node = sc->targets.head;
- dup = httpHdrScCreate();
+ dlink_node *node = sc.targets.head;
while (node) {
- HttpHdrScTarget *dupsct;
- dupsct = httpHdrScTargetDup ((HttpHdrScTarget *)node->data);
- dlinkAddTail (dupsct, &dupsct->node, &dup->targets);
+ HttpHdrScTarget *dupsct = new HttpHdrScTarget(*static_cast<HttpHdrScTarget *>(node->data));
+ addTargetAtTail(dupsct);
node = node->next;
}
-
- return dup;
}
void
-httpHdrScTargetPackInto(const HttpHdrScTarget * sc, Packer * p)
+HttpHdrScTarget::packInto(Packer * p) const
{
http_hdr_sc_type flag;
int pcount = 0;
- assert(sc && p);
+ assert (p);
for (flag = SC_NO_STORE; flag < SC_ENUM_END; ++flag) {
- if (EBIT_TEST(sc->mask, flag) && flag != SC_OTHER) {
+ if (isSet(flag) && flag != SC_OTHER) {
/* print option name */
packerPrintf(p, (pcount ? ", " SQUIDSTRINGPH : SQUIDSTRINGPH),
/* handle options with values */
if (flag == SC_MAX_AGE)
- packerPrintf(p, "=%d", (int) sc->max_age);
+ packerPrintf(p, "=%d", (int) max_age);
if (flag == SC_CONTENT)
- packerPrintf(p, "=\"" SQUIDSTRINGPH "\"", SQUIDSTRINGPRINT(sc->content));
+ packerPrintf(p, "=\"" SQUIDSTRINGPH "\"", SQUIDSTRINGPRINT(content_));
pcount++;
}
}
- if (sc->target.size())
- packerPrintf (p, ";" SQUIDSTRINGPH, SQUIDSTRINGPRINT(sc->target));
+ if (hasTarget())
+ packerPrintf (p, ";" SQUIDSTRINGPH, SQUIDSTRINGPRINT(target));
}
void
-httpHdrScPackInto(const HttpHdrSc * sc, Packer * p)
+HttpHdrSc::packInto(Packer * p) const
{
dlink_node *node;
- assert(sc && p);
- node = sc->targets.head;
+ assert(p);
+ node = targets.head;
while (node) {
- httpHdrScTargetPackInto((HttpHdrScTarget *)node->data, p);
+ static_cast<HttpHdrScTarget *>(node->data)->packInto(p);
node = node->next;
}
}
-void
-httpHdrScJoinWith(HttpHdrSc * sc, const HttpHdrSc * new_sc)
-{
- assert(sc && new_sc);
-#if 0
- /* RC TODO: check that both have the same target */
-
- if (sc->max_age < 0)
- sc->max_age = new_sc->max_age;
-
- /* RC TODO: copy unique missing stringlist entries */
- cc->mask |= new_cc->mask;
-
-#endif
-}
-
/* negative max_age will clean old max_Age setting */
void
-httpHdrScSetMaxAge(HttpHdrSc * sc, char const *target, int max_age)
+HttpHdrSc::setMaxAge(char const *target, int max_age)
{
- HttpHdrScTarget *sct;
- assert(sc);
- sct = httpHdrScFindTarget (sc, target);
+ HttpHdrScTarget *sct = findTarget(target);
if (!sct) {
- sct = httpHdrScTargetCreate (target);
- dlinkAddTail (sct, &sct->node, &sc->targets);
+ sct = new HttpHdrScTarget(target);
+ dlinkAddTail (sct, &sct->node, &targets);
}
- httpHdrScTargetSetMaxAge(sct, max_age);
+ sct->maxAge(max_age);
}
void
-httpHdrScUpdateStats(const HttpHdrSc * sc, StatHist * hist)
+HttpHdrSc::updateStats(StatHist * hist) const
{
- dlink_node *sct;
- assert(sc);
- sct = sc->targets.head;
+ dlink_node *sct = targets.head;
while (sct) {
- httpHdrScTargetUpdateStats((HttpHdrScTarget *)sct->data, hist);
+ static_cast<HttpHdrScTarget *>(sct->data)->updateStats(hist);
sct = sct->next;
}
}
}
HttpHdrScTarget *
-httpHdrScFindTarget (HttpHdrSc *sc, const char *target)
+HttpHdrSc::findTarget(const char *target)
{
dlink_node *node;
- assert (sc);
- node = sc->targets.head;
+ node = targets.head;
while (node) {
HttpHdrScTarget *sct = (HttpHdrScTarget *)node->data;
}
HttpHdrScTarget *
-httpHdrScGetMergedTarget (HttpHdrSc *sc, const char *ourtarget)
+HttpHdrSc::getMergedTarget(const char *ourtarget)
{
- HttpHdrScTarget *sctus = httpHdrScFindTarget (sc, ourtarget);
- HttpHdrScTarget *sctgeneric = httpHdrScFindTarget (sc, NULL);
+ HttpHdrScTarget *sctus = findTarget(ourtarget);
+ HttpHdrScTarget *sctgeneric = findTarget(NULL);
if (sctgeneric || sctus) {
- HttpHdrScTarget *sctusable = httpHdrScTargetCreate (NULL);
+ HttpHdrScTarget *sctusable = new HttpHdrScTarget(NULL);
if (sctgeneric)
- httpHdrScTargetMergeWith (sctusable, sctgeneric);
+ sctusable->mergeWith(sctgeneric);
if (sctus)
- httpHdrScTargetMergeWith (sctusable, sctus);
+ sctusable->mergeWith(sctus);
return sctusable;
}
{
public:
+ HttpHdrSc(const HttpHdrSc &);
+ HttpHdrSc() {}
+ ~HttpHdrSc();
+
+ bool parse(const String *str);
+ void packInto(Packer * p) const;
+ void updateStats(StatHist *) const;
+ HttpHdrScTarget * getMergedTarget (const char *ourtarget); //todo: make const?
+ void setMaxAge(char const *target, int max_age);
+ void addTarget(HttpHdrScTarget *t) {
+ dlinkAdd(t, &t->node, &targets);
+ }
+ void addTargetAtTail(HttpHdrScTarget *t) {
+ dlinkAddTail (t, &t->node, &targets);
+ }
+
MEMPROXY_CLASS(HttpHdrSc);
dlink_list targets;
+private:
+ HttpHdrScTarget * findTarget (const char *target);
+
};
MEMPROXY_CLASS_INLINE(HttpHdrSc);
extern void httpHdrScStatDumper(StoreEntry * sentry, int idx, double val, double size, int count);
extern void httpHdrScInitModule (void);
extern void httpHdrScCleanModule (void);
-extern HttpHdrSc *httpHdrScCreate(void);
-extern HttpHdrSc *httpHdrScParseCreate(String const *);
-extern void httpHdrScDestroy(HttpHdrSc * sc);
-extern HttpHdrSc *httpHdrScDup(const HttpHdrSc * sc);
-extern void httpHdrScPackInto(const HttpHdrSc * sc, Packer * p);
-extern void httpHdrScJoinWith(HttpHdrSc *, const HttpHdrSc *);
+extern HttpHdrSc *httpHdrScParseCreate(String const &);
extern void httpHdrScSetMaxAge(HttpHdrSc *, char const *, int);
-extern void httpHdrScUpdateStats(const HttpHdrSc *, StatHist *);
-extern HttpHdrScTarget * httpHdrScFindTarget (HttpHdrSc *sc, const char *target);
-extern HttpHdrScTarget * httpHdrScGetMergedTarget (HttpHdrSc *sc, const char *ourtarget);
-
-extern void httpHeaderPutSc(HttpHeader *hdr, const HttpHdrSc *sc);
-extern HttpHdrSc *httpHeaderGetSc(const HttpHeader *hdr);
#endif /* SQUID_HTTPHDRSURROGATECONTROL_H */
#include "squid.h"
#include "HttpHdrSc.h"
-/* local prototypes */
-
-/* module initialization */
-
-/* implementation */
-
-HttpHdrScTarget *
-httpHdrScTargetCreate(char const *target)
-{
- HttpHdrScTarget *sc = new HttpHdrScTarget();
- sc->max_age = -1;
- /* max_stale is specified as 0 if not specified in the header */
- sc->target = target;
- return sc;
-}
-
-void
-httpHdrScTargetDestroy(HttpHdrScTarget * sc)
-{
- assert(sc);
- sc->target.clean();
- sc->content.clean();
- delete sc;
-}
-
-HttpHdrScTarget *
-httpHdrScTargetDup(const HttpHdrScTarget * sc)
-{
- HttpHdrScTarget *dup;
- assert(sc);
- dup = httpHdrScTargetCreate(sc->target.termedBuf());
- dup->mask = sc->mask;
- dup->max_age = sc->max_age;
- dup->content = sc->content;
- return dup;
-}
-
-/* union of two targets */
-void
-httpHdrScTargetJoinWith(HttpHdrScTarget * sc, const HttpHdrScTarget * new_sc)
-{
- assert(sc && new_sc);
- /* TODO: check both targets are the same */
-
- if (sc->max_age < 0)
- sc->max_age = new_sc->max_age;
-
- if (sc->max_stale < new_sc->max_stale)
- sc->max_stale = new_sc->max_stale;
-
- /* RC TODO: copy unique missing content stringlist entries */
- sc->mask |= new_sc->mask;
-}
-
extern http_hdr_sc_type &operator++ (http_hdr_sc_type &aHeader);
-extern int operator - (http_hdr_sc_type const &anSc, http_hdr_sc_type const &anSc2);
/* copies non-extant fields from new_sc to this sc */
void
-httpHdrScTargetMergeWith(HttpHdrScTarget * sc, const HttpHdrScTarget * new_sc)
+HttpHdrScTarget::mergeWith(const HttpHdrScTarget * new_sc)
{
- http_hdr_sc_type c;
- assert(sc && new_sc);
+ assert(new_sc);
/* Don't touch the target - this is used to get the operations for a
* single surrogate
*/
- for (c = SC_NO_STORE; c < SC_ENUM_END; ++c)
- if (!EBIT_TEST(sc->mask, c) && EBIT_TEST(new_sc->mask,c)) {
- EBIT_SET(sc->mask, c);
-
- switch (c) {
-
- case SC_MAX_AGE:
- sc->max_age = new_sc->max_age;
- sc->max_stale = new_sc->max_stale;
- break;
+ if (new_sc->hasNoStore())
+ noStore(true);
- case SC_CONTENT:
- assert (sc->content.size() == 0);
- sc->content = new_sc->content;
- break;
+ if (new_sc->hasNoStoreRemote())
+ noStoreRemote(true);
- default:
- break;
- }
- }
-}
+ if (new_sc->hasMaxAge() && !hasMaxAge()) {
+ maxAge(new_sc->maxAge());
+ maxStale(new_sc->maxStale());
+ }
-/* negative max_age will clean old max_Age setting */
-void
-httpHdrScTargetSetMaxAge(HttpHdrScTarget * sc, int max_age)
-{
- assert(sc);
- sc->max_age = max_age;
+ if (new_sc->hasContent() && !hasContent())
+ Content(new_sc->content());
- if (max_age >= 0)
- EBIT_SET(sc->mask, SC_MAX_AGE);
- else
- EBIT_CLR(sc->mask, SC_MAX_AGE);
}
void
-httpHdrScTargetUpdateStats(const HttpHdrScTarget * sc, StatHist * hist)
+HttpHdrScTarget::updateStats(StatHist * hist) const
{
http_hdr_sc_type c;
- assert(sc);
for (c = SC_NO_STORE; c < SC_ENUM_END; ++c)
- if (EBIT_TEST(sc->mask, c))
+ if (isSet(c))
statHistCount(hist, c);
}
class Packer;
class StoreEntry;
-/* for MEMPROXY_CLASS() macros */
#include "MemPool.h"
-/* for dlink_node */
#include "dlink.h"
-/* for String */
#include "SquidString.h"
+#include "typedefs.h"
-/** HTTP Surogate-Control: header field */
+/** Representation of HTTP Surogate-Control header field targeted directive
+ *
+ * \see HttpHdrSc
+ */
class HttpHdrScTarget
{
+ // parsing is done in HttpHdrSc, need to grant them access.
+ friend class HttpHdrSc;
public:
+ static const int MAX_AGE_UNSET=-1; //max-age is unset
+ static const int MAX_STALE_UNSET=0; //max-stale is unset
+
+ HttpHdrScTarget(const char *target_):
+ mask(0), max_age(MAX_AGE_UNSET), max_stale(MAX_STALE_UNSET),target(target_) {}
+ HttpHdrScTarget(const String &target_):
+ mask(0), max_age(MAX_AGE_UNSET), max_stale(MAX_STALE_UNSET),target(target_) {}
+ HttpHdrScTarget(const HttpHdrScTarget &t):
+ mask(t.mask), max_age(t.max_age), max_stale(t.max_stale),
+ content_(t.content_), target(t.target) {}
+
+ bool hasNoStore() const {return isSet(SC_NO_STORE); }
+ void noStore(bool v) { setMask(SC_NO_STORE,v); }
+ bool noStore() const { return isSet(SC_NO_STORE); }
+ void clearNoStore() { setMask(SC_NO_STORE, false); }
+
+ bool hasNoStoreRemote() const {return isSet(SC_NO_STORE_REMOTE); }
+ void noStoreRemote(bool v) { setMask(SC_NO_STORE_REMOTE,v); }
+ bool noStoreRemote() const { return isSet(SC_NO_STORE_REMOTE); }
+ void clearNoStoreRemote() { setMask(SC_NO_STORE_REMOTE, false); }
+
+ bool hasMaxAge() const { return isSet(SC_MAX_AGE); }
+ void maxAge(int v) {
+ if (v >= 0) { //setting
+ setMask(SC_MAX_AGE,true);
+ max_age=v;
+ } else {
+ setMask(SC_MAX_AGE,false);
+ max_age=MAX_AGE_UNSET;
+ }
+ }
+ int maxAge() const { return max_age; }
+ void clearMaxAge() { setMask(SC_MAX_AGE,false); max_age=MAX_AGE_UNSET; }
+
+ //max_stale has no associated status-bit
+ bool hasMaxStale() const { return max_stale != MAX_STALE_UNSET; }
+ void maxStale(int v) { max_stale=v; }
+ int maxStale() const { return max_stale; }
+ void clearMaxStale() { max_stale=MAX_STALE_UNSET; }
+
+ bool hasContent() const { return isSet(SC_CONTENT); }
+ void Content(const String &v) {
+ setMask(SC_CONTENT,true);
+ content_=v;
+ }
+ String content() const { return content_; }
+ void clearContent() { setMask(SC_CONTENT,false); content_.clean(); }
+
+ bool hasTarget() const { return target.size() != 0; }
+ String Target() const { return target; }
+
+ void mergeWith(const HttpHdrScTarget * new_sc);
+ void packInto (Packer *p) const;
+ void updateStats(StatHist *) const;
+
MEMPROXY_CLASS(HttpHdrScTarget);
- dlink_node node;
+private:
+ bool isSet(http_hdr_sc_type id) const {
+ assert (id >= SC_NO_STORE && id < SC_ENUM_END);
+ return EBIT_TEST(mask,id);
+ }
+
+ void setMask(http_hdr_sc_type id, bool newval) {
+ if (newval) EBIT_SET(mask,id);
+ else EBIT_CLR(mask,id);
+ }
+
int mask;
int max_age;
int max_stale;
- String content;
+ String content_;
String target;
+ dlink_node node;
};
MEMPROXY_CLASS_INLINE(HttpHdrScTarget);
-/* Http Surrogate control header field 'targets' */
-extern HttpHdrScTarget * httpHdrScTargetCreate (const char *);
-extern void httpHdrScTargetDestroy(HttpHdrScTarget *);
-extern HttpHdrScTarget *httpHdrScTargetDup(const HttpHdrScTarget *);
-extern void httpHdrScTargetPackInto(const HttpHdrScTarget *, Packer *);
-extern void httpHdrScTargetSetMaxAge(HttpHdrScTarget *, int);
-extern void httpHdrScTargetJoinWith(HttpHdrScTarget *, const HttpHdrScTarget *);
-extern void httpHdrScTargetMergeWith(HttpHdrScTarget *, const HttpHdrScTarget *);
extern void httpHdrScTargetStatDumper(StoreEntry * sentry, int idx, double val, double size, int count);
-/* for StatHist */
-#include "typedefs.h"
-
-extern void httpHdrScTargetUpdateStats(const HttpHdrScTarget *, StatHist *);
#endif /* SQUID_HTTPHDRSURROGATECONTROLTARGET_H */
/* pack into mb */
mb.init();
packerToMemInit(&p, &mb);
- httpHdrScPackInto(sc, &p);
+ sc->packInto(&p);
/* put */
addEntry(new HttpHeaderEntry(HDR_SURROGATE_CONTROL, NULL, mb.buf));
/* cleanup */
(void) getList(HDR_SURROGATE_CONTROL, &s);
- HttpHdrSc *sc = httpHdrScParseCreate(&s);
+ HttpHdrSc *sc = httpHdrScParseCreate(s);
- HttpHeaderStats[owner].ccParsedCount++;
+ ++HttpHeaderStats[owner].ccParsedCount;
if (sc)
- httpHdrScUpdateStats(sc, &HttpHeaderStats[owner].scTypeDistr);
+ sc->updateStats(&HttpHeaderStats[owner].scTypeDistr);
httpHeaderNoteParsedEntry(HDR_SURROGATE_CONTROL, s, !sc);
}
if (surrogate_control) {
- httpHdrScDestroy(surrogate_control);
+ delete surrogate_control;
surrogate_control = NULL;
}
int rv = 0;
if (rep->surrogate_control) {
- HttpHdrScTarget *sctusable = httpHdrScGetMergedTarget (rep->surrogate_control,
- Config.Accel.surrogate_id);
+ HttpHdrScTarget *sctusable =
+ rep->surrogate_control->getMergedTarget(Config.Accel.surrogate_id);
- if (!sctusable || sctusable->content.size() == 0)
+ if (!sctusable || !sctusable->hasContent())
/* Nothing generic or targeted at us, or no
* content processing requested
*/
return 0;
- if (sctusable->content.pos("ESI/1.0") != NULL)
+ if (sctusable->content().pos("ESI/1.0") != NULL)
rv = 1;
- httpHdrScTargetDestroy (sctusable);
+ delete sctusable;
}
return rv;
#include "SquidTime.h"
#include "Store.h"
#include "StoreClient.h"
+#include "compat/xalloc.h"
/// dials htcpIncomingConnectionOpened call
class HtcpListeningStartedDialer: public CallDialer,
HttpStateData::processSurrogateControl(HttpReply *reply)
{
if (request->flags.accelerated && reply->surrogate_control) {
- HttpHdrScTarget *sctusable = httpHdrScGetMergedTarget(reply->surrogate_control, Config.Accel.surrogate_id);
+ HttpHdrScTarget *sctusable = reply->surrogate_control->getMergedTarget(Config.Accel.surrogate_id);
if (sctusable) {
- if (EBIT_TEST(sctusable->mask, SC_NO_STORE) ||
+ if (sctusable->noStore() ||
(Config.onoff.surrogate_is_remote
- && EBIT_TEST(sctusable->mask, SC_NO_STORE_REMOTE))) {
+ && sctusable->noStoreRemote())) {
surrogateNoStore = true;
entry->makePrivate();
}
* accelerated request or not...
* Still, this is an abstraction breach. - RC
*/
- if (sctusable->max_age != -1) {
- if (sctusable->max_age < sctusable->max_stale)
- reply->expires = reply->date + sctusable->max_age;
+ if (sctusable->hasMaxAge()) {
+ if (sctusable->maxAge() < sctusable->maxStale())
+ reply->expires = reply->date + sctusable->maxAge();
else
- reply->expires = reply->date + sctusable->max_stale;
+ reply->expires = reply->date + sctusable->maxStale();
/* And update the timestamps */
entry->timestampsSet();
/* We ignore cache-control directives as per the Surrogate specification */
ignoreCacheControl = true;
- httpHdrScTargetDestroy(sctusable);
+ delete sctusable;
}
}
}