Options.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1996-2023 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 #include "squid.h"
10 #include "adaptation/icap/Config.h"
12 #include "base/TextException.h"
13 #include "HttpReply.h"
14 #include "StrList.h"
15 #include "wordlist.h"
16 
18  error("unconfigured"),
19  max_connections(-1),
20  allow204(false),
21  allow206(false),
22  preview(-1),
23  theTTL(-1),
24  theTimestamp(0)
25 {
26  theTransfers.preview.name = "Transfer-Preview";
28  theTransfers.ignore.name = "Transfer-Ignore";
30  theTransfers.complete.name = "Transfer-Complete";
32 
33  // Section 4.10.2 of RFC 3507 says that default is no Preview
34  // TODO: provide a squid.conf option to overwrite the default
36 }
37 
39 {
40 }
41 
42 // future optimization note: this method is called by ICAP ACL code at least
43 // twice for each HTTP message to see if the message should be ignored. For any
44 // non-ignored HTTP message, ICAP calls to check whether a preview is needed.
47 {
48  if (theTransfers.preview.matches(urlPath))
49  return xferPreview;
50 
51  if (theTransfers.complete.matches(urlPath))
52  return xferComplete;
53 
54  if (theTransfers.ignore.matches(urlPath))
55  return xferIgnore;
56 
57  debugs(93,7, "url " << urlPath << " matches no extensions; " <<
58  "using default: " << theTransfers.byDefault->name);
59  return theTransfers.byDefault->kind;
60 }
61 
63 {
64  return !error;
65 }
66 
68 {
69  return squid_curtime <= expire();
70 }
71 
73 {
74  Must(valid());
75  return theTTL >= 0 ? theTTL : TheConfig.default_options_ttl;
76 }
77 
79 {
80  Must(valid());
81  return theTimestamp + ttl();
82 }
83 
85 {
86  error = nullptr; // reset initial "unconfigured" value (or an old error?)
87 
88  const HttpHeader *h = &reply->header;
89 
90  if (reply->sline.status() != Http::scOkay)
91  error = "unsupported status code of OPTIONS response";
92 
93  // Methods
94  if (h->hasByNameListMember("Methods", "REQMOD", ','))
95  cfgMethod(ICAP::methodReqmod);
96 
97  if (h->hasByNameListMember("Methods", "RESPMOD", ','))
98  cfgMethod(ICAP::methodRespmod);
99 
100  service = h->getByName("Service");
101 
102  serviceId = h->getByName("ServiceId");
103 
104  istag = h->getByName("ISTag");
105 
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.
111  }
112 
113  cfgIntHeader(h, "Max-Connections", max_connections);
114  if (max_connections == 0)
115  debugs(93, DBG_IMPORTANT, "WARNING: Max-Connections is set to zero! ");
116 
117  cfgIntHeader(h, "Options-TTL", theTTL);
118 
119  theTimestamp = h->getTime(Http::HdrType::DATE);
120 
121  if (theTimestamp < 0)
122  theTimestamp = squid_curtime;
123 
124  if (h->hasListMember(Http::HdrType::ALLOW, "204", ','))
125  allow204 = true;
126 
127  if (h->hasListMember(Http::HdrType::ALLOW, "206", ','))
128  allow206 = true;
129 
130  cfgIntHeader(h, "Preview", preview);
131 
132  cfgTransferList(h, theTransfers.preview);
133  cfgTransferList(h, theTransfers.ignore);
134  cfgTransferList(h, theTransfers.complete);
135 }
136 
138 {
139  Must(m != ICAP::methodNone);
140  methods.push_back(m);
141 }
142 
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)
145 {
146  const String s = h->getByName(fname);
147 
148  if (s.size() && xisdigit(*s.termedBuf()))
149  value = atoi(s.termedBuf());
150  else
151  value = -1;
152 
153  debugs(93,5, "int header: " << fname << ": " << value);
154 }
155 
157 {
158  const String buf = h->getByName(list.name);
159  bool foundStar = false;
160  list.parse(buf, foundStar);
161 
162  if (foundStar) {
163  theTransfers.byDefault = &list;
164  debugs(93,5, "set default transfer to " << list.name);
165  }
166 
167  list.report(5, "Adaptation::Icap::Options::cfgTransferList: ");
168 }
169 
170 /* Adaptation::Icap::Options::TransferList */
171 
172 Adaptation::Icap::Options::TransferList::TransferList(): extensions(nullptr), name(nullptr),
173  kind(xferNone)
174 {
175 };
176 
178 {
179  wordlistDestroy(&extensions);
180 };
181 
183 {
184  wordlistAdd(&extensions, extension);
185 };
186 
188 {
189  const SBuf::size_type urlLen = urlPath.length();
190  for (wordlist *e = extensions; e; e = e->next) {
191  // optimize: store extension lengths
192  const size_t eLen = strlen(e->key);
193 
194  // assume URL contains at least '/' before the extension
195  if (eLen < urlLen) {
196  const size_t eOff = urlLen - eLen;
197  // RFC 3507 examples imply that extensions come without leading '.'
198  if (urlPath[eOff-1] == '.' && urlPath.substr(eOff).cmp(e->key, eLen) == 0) {
199  debugs(93,7, "url " << urlPath << " matches " << name << " extension " << e->key);
200  return true;
201  }
202  }
203  }
204  debugs(93,8, "url " << urlPath << " matches no " << name << " extensions");
205  return false;
206 }
207 
209 {
210  foundStar = false;
211 
212  const char *item;
213  const char *pos = nullptr;
214  int ilen;
215  while (strListGetItem(&buf, ',', &item, &ilen, &pos)) {
216  if (ilen == 1 && *item == '*')
217  foundStar = true;
218  else {
219  const char *tmp = xstrndup(item, ilen+1);
220  add(tmp);
221  xfree(tmp);
222  }
223  }
224 }
225 
226 void Adaptation::Icap::Options::TransferList::report(int level, const char *prefix) const
227 {
228  if (extensions) {
229  for (wordlist *e = extensions; e; e = e->next)
230  debugs(93,level, prefix << name << ": " << e->key);
231  } else {
232  debugs(93,level, prefix << "no " << name << " extensions");
233  }
234 }
235 
void wordlistDestroy(wordlist **list)
destroy a wordlist
Definition: wordlist.cc:16
void cfgIntHeader(const HttpHeader *h, const char *fname, int &value)
Definition: Options.cc:144
Config TheConfig
Definition: Config.cc:19
HttpHeader header
Definition: Message.h:74
int hasListMember(Http::HdrType id, const char *member, const char separator) const
Definition: HttpHeader.cc:1662
void error(char *format,...)
Definition: SBuf.h:93
time_t expire() const
Definition: Options.cc:78
Http::StatusLine sline
Definition: HttpReply.h:56
int hasByNameListMember(const char *name, const char *member, const char separator) const
Definition: HttpHeader.cc:1686
SBuf substr(size_type pos, size_type n=npos) const
Definition: SBuf.cc:576
void parse(const String &buf, bool &foundStar)
Definition: Options.cc:208
void configure(const HttpReply *reply)
Definition: Options.cc:84
TransferKind transferKind(const SBuf &urlPath) const
Definition: Options.cc:46
Http::StatusCode status() const
retrieve the status code for this status line
Definition: StatusLine.h:45
MemBlob::size_type size_type
Definition: SBuf.h:96
time_t getTime(Http::HdrType id) const
Definition: HttpHeader.cc:1146
bool valid() const
Definition: Options.cc:62
void cfgMethod(ICAP::Method m)
Definition: Options.cc:137
#define xisdigit(x)
Definition: xis.h:18
void add(const char *extension)
Definition: Options.cc:182
@ methodNone
Definition: Elements.h:17
size_type length() const
Returns the number of bytes stored in SBuf.
Definition: SBuf.h:419
time_t squid_curtime
Definition: stub_libtime.cc:20
bool matches(const SBuf &urlPath) const
Definition: Options.cc:187
char * xstrndup(const char *s, size_t n)
Definition: xstring.cc:56
#define xfree
wordlist * next
Definition: wordlist.h:60
void cfgTransferList(const HttpHeader *h, TransferList &l)
Definition: Options.cc:156
String getByName(const SBuf &name) const
Definition: HttpHeader.cc:848
const char * termedBuf() const
Definition: SquidString.h:92
@ methodRespmod
Definition: Elements.h:17
void report(int level, const char *prefix) const
Definition: Options.cc:226
int cmp(const SBuf &S, const size_type n) const
shorthand version for compare()
Definition: SBuf.h:279
size_type size() const
Definition: SquidString.h:73
#define Must(condition)
Definition: TextException.h:75
bool fresh() const
Definition: Options.cc:67
#define DBG_IMPORTANT
Definition: Stream.h:38
struct Adaptation::Icap::Options::Transfers theTransfers
@ methodReqmod
Definition: Elements.h:17
@ scOkay
Definition: StatusCode.h:27
const char * wordlistAdd(wordlist **list, const char *key)
Definition: wordlist.cc:25
#define debugs(SECTION, LEVEL, CONTENT)
Definition: Stream.h:192
int strListGetItem(const String *str, char del, const char **item, int *ilen, const char **pos)
Definition: StrList.cc:78

 

Introduction

Documentation

Support

Miscellaneous