]>
git.ipfire.org Git - thirdparty/squid.git/blob - src/adaptation/icap/Options.cc
2 * Copyright (C) 1996-2014 The Squid Software Foundation and contributors
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.
10 #include "adaptation/icap/Config.h"
11 #include "adaptation/icap/Options.h"
12 #include "base/TextException.h"
13 #include "HttpReply.h"
14 #include "SquidTime.h"
18 Adaptation::Icap::Options::Options() :
19 error("unconfigured"),
27 theTransfers
.preview
.name
= "Transfer-Preview";
28 theTransfers
.preview
.kind
= xferPreview
;
29 theTransfers
.ignore
.name
= "Transfer-Ignore";
30 theTransfers
.ignore
.kind
= xferIgnore
;
31 theTransfers
.complete
.name
= "Transfer-Complete";
32 theTransfers
.complete
.kind
= xferComplete
;
34 // Section 4.10.2 of RFC 3507 says that default is no Preview
35 // TODO: provide a squid.conf option to overwrite the default
36 theTransfers
.byDefault
= &theTransfers
.complete
;
39 Adaptation::Icap::Options::~Options()
43 // future optimization note: this method is called by ICAP ACL code at least
44 // twice for each HTTP message to see if the message should be ignored. For any
45 // non-ignored HTTP message, ICAP calls to check whether a preview is needed.
46 Adaptation::Icap::Options::TransferKind
Adaptation::Icap::Options::transferKind(const String
&urlPath
) const
48 if (theTransfers
.preview
.matches(urlPath
))
51 if (theTransfers
.complete
.matches(urlPath
))
54 if (theTransfers
.ignore
.matches(urlPath
))
57 debugs(93,7, HERE
<< "url " << urlPath
<< " matches no extensions; " <<
58 "using default: " << theTransfers
.byDefault
->name
);
59 return theTransfers
.byDefault
->kind
;
62 bool Adaptation::Icap::Options::valid() const
67 bool Adaptation::Icap::Options::fresh() const
69 return squid_curtime
<= expire();
72 int Adaptation::Icap::Options::ttl() const
75 return theTTL
>= 0 ? theTTL
: TheConfig
.default_options_ttl
;
78 time_t Adaptation::Icap::Options::expire() const
81 return theTimestamp
+ ttl();
84 void Adaptation::Icap::Options::configure(const HttpReply
*reply
)
86 error
= NULL
; // reset initial "unconfigured" value (or an old error?)
88 const HttpHeader
*h
= &reply
->header
;
90 if (reply
->sline
.status() != Http::scOkay
)
91 error
= "unsupported status code of OPTIONS response";
94 if (h
->hasByNameListMember("Methods", "REQMOD", ','))
95 cfgMethod(ICAP::methodReqmod
);
97 if (h
->hasByNameListMember("Methods", "RESPMOD", ','))
98 cfgMethod(ICAP::methodRespmod
);
100 service
= h
->getByName("Service");
102 serviceId
= h
->getByName("ServiceId");
104 istag
= h
->getByName("ISTag");
106 if (h
->getByName("Opt-body-type").size()) {
107 // TODO: add a class to rate-limit such warnings using FadingCounter
108 debugs(93,DBG_IMPORTANT
, "WARNING: Ignoring unsupported ICAP " <<
109 "OPTIONS body; type: " << h
->getByName("Opt-body-type"));
110 // Do not set error, assuming the response headers are valid.
113 cfgIntHeader(h
, "Max-Connections", max_connections
);
114 if (max_connections
== 0)
115 debugs(93, DBG_IMPORTANT
, "WARNING: Max-Connections is set to zero! ");
117 cfgIntHeader(h
, "Options-TTL", theTTL
);
119 theTimestamp
= h
->getTime(HDR_DATE
);
121 if (theTimestamp
< 0)
122 theTimestamp
= squid_curtime
;
124 if (h
->hasListMember(HDR_ALLOW
, "204", ','))
127 if (h
->hasListMember(HDR_ALLOW
, "206", ','))
130 cfgIntHeader(h
, "Preview", preview
);
132 cfgTransferList(h
, theTransfers
.preview
);
133 cfgTransferList(h
, theTransfers
.ignore
);
134 cfgTransferList(h
, theTransfers
.complete
);
137 void Adaptation::Icap::Options::cfgMethod(ICAP::Method m
)
139 Must(m
!= ICAP::methodNone
);
140 methods
.push_back(m
);
143 // TODO: HttpHeader should provide a general method for this type of conversion
144 void Adaptation::Icap::Options::cfgIntHeader(const HttpHeader
*h
, const char *fname
, int &value
)
146 const String s
= h
->getByName(fname
);
148 if (s
.size() && xisdigit(*s
.termedBuf()))
149 value
= atoi(s
.termedBuf());
153 debugs(93,5, HERE
<< "int header: " << fname
<< ": " << value
);
156 void Adaptation::Icap::Options::cfgTransferList(const HttpHeader
*h
, TransferList
&list
)
158 const String buf
= h
->getByName(list
.name
);
159 bool foundStar
= false;
160 list
.parse(buf
, foundStar
);
163 theTransfers
.byDefault
= &list
;
164 debugs(93,5, HERE
<< "set default transfer to " << list
.name
);
167 list
.report(5, "Adaptation::Icap::Options::cfgTransferList: ");
170 /* Adaptation::Icap::Options::TransferList */
172 Adaptation::Icap::Options::TransferList::TransferList(): extensions(NULL
), name(NULL
),
177 Adaptation::Icap::Options::TransferList::~TransferList()
179 wordlistDestroy(&extensions
);
182 void Adaptation::Icap::Options::TransferList::add(const char *extension
)
184 wordlistAdd(&extensions
, extension
);
187 bool Adaptation::Icap::Options::TransferList::matches(const String
&urlPath
) const
189 const int urlLen
= urlPath
.size();
190 for (wordlist
*e
= extensions
; e
; e
= e
->next
) {
191 // optimize: store extension lengths
192 const int eLen
= strlen(e
->key
);
194 // assume URL contains at least '/' before the extension
196 const int eOff
= urlLen
- eLen
;
197 // RFC 3507 examples imply that extensions come without leading '.'
198 if (urlPath
[eOff
-1] == '.' &&
199 strcmp(urlPath
.termedBuf() + eOff
, e
->key
) == 0) {
200 debugs(93,7, HERE
<< "url " << urlPath
<< " matches " <<
201 name
<< " extension " << e
->key
);
206 debugs(93,8, HERE
<< "url " << urlPath
<< " matches no " << name
<< " extensions");
210 void Adaptation::Icap::Options::TransferList::parse(const String
&buf
, bool &foundStar
)
215 const char *pos
= NULL
;
217 while (strListGetItem(&buf
, ',', &item
, &ilen
, &pos
)) {
218 if (ilen
== 1 && *item
== '*')
221 const char *tmp
= xstrndup(item
, ilen
+1);
228 void Adaptation::Icap::Options::TransferList::report(int level
, const char *prefix
) const
231 for (wordlist
*e
= extensions
; e
; e
= e
->next
)
232 debugs(93,level
, prefix
<< name
<< ": " << e
->key
);
234 debugs(93,level
, prefix
<< "no " << name
<< " extensions");