]> git.ipfire.org Git - thirdparty/squid.git/blame - src/ICAP/ICAPOptions.cc
Fixed testHttpRequest with --enable-referer-log & --enable-useragent-log and
[thirdparty/squid.git] / src / ICAP / ICAPOptions.cc
CommitLineData
774c051c 1#include "squid.h"
2#include "HttpReply.h"
3#include "ICAPOptions.h"
4#include "TextException.h"
78e8cfc4 5#include "ICAPConfig.h"
6
7extern ICAPConfig TheICAPConfig;
774c051c 8
eadded2e 9ICAPOptions::ICAPOptions(): error("unconfigured"),
774c051c 10 max_connections(-1), allow204(false),
8eeb99bf 11 preview(-1), theTTL(-1), transfer_ext(NULL)
774c051c 12{
13 transfers.preview = transfers.ignore = transfers.complete = NULL;
14 transfers.other = TRANSFER_NONE;
15};
16
17ICAPOptions::~ICAPOptions()
18{
19 delete transfers.preview;
20 delete transfers.ignore;
21 delete transfers.complete;
22 delete transfer_ext;
23};
24
25ICAPOptions::transfer_type ICAPOptions::getTransferExt(const char *s)
26{
27
28 if (transfer_ext) {
29 List<TransferPair> *data = transfer_ext;
30
31 while (data) {
32 if (*(data->element.ext) == *s) {
33 return data->element.type;
34 }
35
36 data = data->next;
37 }
38 }
39
40 return TRANSFER_NONE;
41}
42
774c051c 43void ICAPOptions::insertTransferExt(const char *t, transfer_type t_type)
44{
45 List<TransferPair> **Tail;
46 TransferPair t_ext;
47
48 if (t == "*") {
49 transfers.other = t_type;
50 return;
51 }
52
53 for (Tail = &transfer_ext; *Tail; Tail = &((*Tail)->next)) {
54 if (*(*Tail)->element.ext == *t) {
55 (*Tail)->element.type = t_type;
56 return;
57 }
58 }
59
60 t_ext.ext = xstrdup(t);
61 t_ext.type = t_type;
62 List<TransferPair> *q = new List<TransferPair>(t_ext);
63 *(Tail) = q;
64
65};
66
9d0cdbb9 67void ICAPOptions::cfgTransferListHeader(const HttpHeader *h, const char *fname, transfer_type t_type)
68{
69 const String s = httpHeaderGetByName(h, fname);
70
71 if (!s.size())
72 return;
73
74 if (t_type == TRANSFER_PREVIEW)
75 transfers.preview = parseExtFileList(s.buf(), s.buf() + s.size(), t_type);
76 else if (t_type == TRANSFER_IGNORE)
77 transfers.ignore = parseExtFileList(s.buf(), s.buf() + s.size(), t_type);
78 else if (t_type == TRANSFER_COMPLETE)
79 transfers.complete = parseExtFileList(s.buf(), s.buf() + s.size(), t_type);
80 else
81 fatalf("Unexpected transfer_type at %s:%d", __FILE__,__LINE__);
82}
83
774c051c 84List<String> *ICAPOptions::parseExtFileList(const char *start, const char *end, transfer_type t_type)
85{
9d0cdbb9 86 const String s = xstrndup(start, end - start + 1);
774c051c 87 const char *item;
88 const char *pos = NULL;
89 char *fext = NULL;
90 int ilen;
91 String t = NULL;
92
86c570cf 93 List<String> **Tail = NULL;
94 List<String> *H = NULL;
774c051c 95
96 for (Tail = &H; *Tail; Tail = &((*Tail)->next))
97
98 ;
99 while (strListGetItem(&s, ',', &item, &ilen, &pos)) {
100 fext = xstrndup(item, ilen + 1);
101 t = fext;
102 List<String> *q = new List<String> (t);
103 *(Tail) = q;
104 Tail = &q->next;
105 insertTransferExt(fext, t_type);
106 }
107
108 return H;
109}
110
774c051c 111bool ICAPOptions::valid() const
112{
113 return !error;
114}
115
116bool ICAPOptions::fresh() const
117{
118 return squid_curtime <= expire();
119}
120
121time_t ICAPOptions::expire() const
122{
123 Must(valid());
8eeb99bf 124 return theTTL >= 0 ? theTimestamp + theTTL : -1;
774c051c 125}
126
127void ICAPOptions::configure(const HttpReply *reply)
128{
129 error = NULL; // reset initial "unconfigured" value (or an old error?)
130
131 const HttpHeader *h = &reply->header;
132
133 if (reply->sline.status != 200)
134 error = "unsupported status code of OPTIONS response";
135
136 // Methods
9d0cdbb9 137 if (httpHeaderHasByNameListMember(h, "Methods", "REQMOD", ','))
774c051c 138 cfgMethod(ICAP::methodReqmod);
139
9d0cdbb9 140 if (httpHeaderHasByNameListMember(h, "Methods", "RESPMOD", ','))
774c051c 141 cfgMethod(ICAP::methodRespmod);
142
143 service = httpHeaderGetByName(h, "Service");
144
145 serviceId = httpHeaderGetByName(h, "ServiceId");
146
147 istag = httpHeaderGetByName(h, "ISTag");
148
149 if (httpHeaderGetByName(h, "Opt-body-type").size())
150 error = "ICAP service returns unsupported OPTIONS body";
151
152 cfgIntHeader(h, "Max-Connections", max_connections);
153
8eeb99bf 154 cfgIntHeader(h, "Options-TTL", theTTL);
774c051c 155
78e8cfc4 156 if (theTTL < 0)
157 theTTL = TheICAPConfig.default_options_ttl;
158
8eeb99bf 159 theTimestamp = httpHeaderGetTime(h, HDR_DATE);
774c051c 160
8eeb99bf 161 if (theTimestamp < 0)
162 theTimestamp = squid_curtime;
774c051c 163
9d0cdbb9 164 if (httpHeaderHasListMember(h, HDR_ALLOW, "204", ','))
774c051c 165 allow204 = true;
166
167 cfgIntHeader(h, "Preview", preview);
168
9d0cdbb9 169 cfgTransferListHeader(h, "Transfer-Preview", TRANSFER_PREVIEW);
774c051c 170
9d0cdbb9 171 cfgTransferListHeader(h, "Transfer-Ignore", TRANSFER_IGNORE);
774c051c 172
9d0cdbb9 173 cfgTransferListHeader(h, "Transfer-Complete", TRANSFER_COMPLETE);
774c051c 174}
175
176void ICAPOptions::cfgMethod(ICAP::Method m)
177{
178 Must(m != ICAP::methodNone);
eadded2e 179 methods += m;
774c051c 180}
181
182// TODO: HttpHeader should provide a general method for this type of conversion
183void ICAPOptions::cfgIntHeader(const HttpHeader *h, const char *fname, int &value)
184{
185 const String s = httpHeaderGetByName(h, fname);
186
187 if (s.size() && xisdigit(*s.buf()))
188 value = atoi(s.buf());
189 else
190 value = -1;
191}