~clint-fewbar/ubuntu/precise/squid3/ignore-sighup-early

« back to all changes in this revision

Viewing changes to src/adaptation/ecap/MessageRep.cc

  • Committer: Bazaar Package Importer
  • Author(s): Luigi Gangitano
  • Date: 2009-09-24 14:51:06 UTC
  • mfrom: (1.1.12 upstream)
  • mto: (20.2.1 sid)
  • mto: This revision was merged to the branch mainline in revision 21.
  • Revision ID: james.westby@ubuntu.com-20090924145106-38jgrzmj0d73pha5
Tags: 3.1.0.13-1
* Upload to experimental

* New upstream release
  - Fixes Follow-X-Forwarded-For support (Closes: #523943)
  - Adds IPv6 support (Closes: #432351)

* debian/rules
  - Removed obsolete configuration options
  - Enable db and radius basic authentication modules

* debian/patches/01-cf.data.debian
  - Adapted to new upstream version

* debian/patches/02-makefile-defaults
  - Adapted to new upstream version

* debian/{squid.postinst,squid.rc,README.Debian,watch}
  - Updated references to squid 3.1

* debian/squid3.install
  - Install CSS file for error pages
  - Install manual pages for new authentication modules

* debian/squid3-common.install
  - Install documented version of configuration file in /usr/share/doc/squid3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * DEBUG: section XXX
 
3
 */
 
4
 
 
5
#include "squid.h"
 
6
#include "HttpRequest.h"
 
7
#include "HttpReply.h"
 
8
#include "BodyPipe.h"
 
9
#include "TextException.h"
 
10
#include <libecap/common/names.h>
 
11
#include <libecap/common/area.h>
 
12
#include <libecap/common/version.h>
 
13
#include "adaptation/ecap/MessageRep.h"
 
14
#include "adaptation/ecap/XactionRep.h"
 
15
#include "adaptation/ecap/Host.h" /* for protocol constants */
 
16
 
 
17
/* HeaderRep */
 
18
 
 
19
Adaptation::Ecap::HeaderRep::HeaderRep(HttpMsg &aMessage): theHeader(aMessage.header),
 
20
        theMessage(aMessage)
 
21
{
 
22
}
 
23
 
 
24
bool
 
25
Adaptation::Ecap::HeaderRep::hasAny(const Name &name) const
 
26
{
 
27
    const http_hdr_type squidId = TranslateHeaderId(name);
 
28
    // XXX: optimize to remove getByName: we do not need the value here
 
29
    return squidId == HDR_OTHER ?
 
30
           theHeader.getByName(name.image().c_str()).size() > 0:
 
31
           (bool)theHeader.has(squidId);
 
32
}
 
33
 
 
34
Adaptation::Ecap::HeaderRep::Value
 
35
Adaptation::Ecap::HeaderRep::value(const Name &name) const
 
36
{
 
37
    const http_hdr_type squidId = TranslateHeaderId(name);
 
38
    const String value = squidId == HDR_OTHER ?
 
39
                         theHeader.getByName(name.image().c_str()) :
 
40
                         theHeader.getStrOrList(squidId);
 
41
    return Value::FromTempString(value.termedBuf());
 
42
}
 
43
 
 
44
void
 
45
Adaptation::Ecap::HeaderRep::add(const Name &name, const Value &value)
 
46
{
 
47
    const http_hdr_type squidId = TranslateHeaderId(name); // HDR_OTHER OK
 
48
    HttpHeaderEntry *e = new HttpHeaderEntry(squidId, name.image().c_str(),
 
49
            value.toString().c_str());
 
50
    theHeader.addEntry(e);
 
51
}
 
52
 
 
53
void
 
54
Adaptation::Ecap::HeaderRep::removeAny(const Name &name)
 
55
{
 
56
    const http_hdr_type squidId = TranslateHeaderId(name);
 
57
    if (squidId == HDR_OTHER)
 
58
        theHeader.delByName(name.image().c_str());
 
59
    else
 
60
        theHeader.delById(squidId);
 
61
}
 
62
 
 
63
libecap::Area
 
64
Adaptation::Ecap::HeaderRep::image() const
 
65
{
 
66
    MemBuf mb;
 
67
    mb.init();
 
68
 
 
69
    Packer p;
 
70
    packerToMemInit(&p, &mb);
 
71
    theMessage.packInto(&p, true);
 
72
    packerClean(&p);
 
73
    return Area::FromTempBuffer(mb.content(), mb.contentSize());
 
74
}
 
75
 
 
76
// throws on failures
 
77
void
 
78
Adaptation::Ecap::HeaderRep::parse(const Area &buf)
 
79
{
 
80
    MemBuf mb;
 
81
    mb.init();
 
82
    mb.append(buf.start, buf.size);
 
83
    http_status error;
 
84
    Must(theMessage.parse(&mb, true, &error));
 
85
}
 
86
 
 
87
http_hdr_type
 
88
Adaptation::Ecap::HeaderRep::TranslateHeaderId(const Name &name)
 
89
{
 
90
    if (name.assignedHostId())
 
91
        return static_cast<http_hdr_type>(name.hostId());
 
92
    return HDR_OTHER;
 
93
}
 
94
 
 
95
 
 
96
/* FirstLineRep */
 
97
 
 
98
Adaptation::Ecap::FirstLineRep::FirstLineRep(HttpMsg &aMessage): theMessage(aMessage)
 
99
{
 
100
}
 
101
 
 
102
libecap::Version
 
103
Adaptation::Ecap::FirstLineRep::version() const
 
104
{
 
105
    return libecap::Version(theMessage.http_ver.major,
 
106
                            theMessage.http_ver.minor);
 
107
}
 
108
 
 
109
void
 
110
Adaptation::Ecap::FirstLineRep::version(const libecap::Version &aVersion)
 
111
{
 
112
    theMessage.http_ver.major = aVersion.majr;
 
113
    theMessage.http_ver.minor = aVersion.minr;
 
114
}
 
115
 
 
116
libecap::Name
 
117
Adaptation::Ecap::FirstLineRep::protocol() const
 
118
{
 
119
    // TODO: optimize?
 
120
    switch (theMessage.protocol) {
 
121
    case PROTO_HTTP:
 
122
        return libecap::protocolHttp;
 
123
    case PROTO_HTTPS:
 
124
        return libecap::protocolHttps;
 
125
    case PROTO_FTP:
 
126
        return libecap::protocolFtp;
 
127
    case PROTO_GOPHER:
 
128
        return libecap::protocolGopher;
 
129
    case PROTO_WAIS:
 
130
        return libecap::protocolWais;
 
131
    case PROTO_WHOIS:
 
132
        return libecap::protocolWhois;
 
133
    case PROTO_URN:
 
134
        return libecap::protocolUrn;
 
135
    case PROTO_ICP:
 
136
        return protocolIcp;
 
137
#if USE_HTCP
 
138
    case PROTO_HTCP:
 
139
        return protocolHtcp;
 
140
#endif
 
141
    case PROTO_CACHEOBJ:
 
142
        return protocolCacheObj;
 
143
    case PROTO_INTERNAL:
 
144
        return protocolInternal;
 
145
    case PROTO_NONE:
 
146
        return Name();
 
147
 
 
148
    case PROTO_MAX:
 
149
        break; // should not happen
 
150
        // no default to catch PROTO_ additions
 
151
    }
 
152
    Must(false); // not reached
 
153
    return Name();
 
154
}
 
155
 
 
156
void
 
157
Adaptation::Ecap::FirstLineRep::protocol(const Name &p)
 
158
{
 
159
    // TODO: what happens if we fail to translate some protocol?
 
160
    theMessage.protocol = TranslateProtocolId(p);
 
161
}
 
162
 
 
163
protocol_t
 
164
Adaptation::Ecap::FirstLineRep::TranslateProtocolId(const Name &name)
 
165
{
 
166
    if (name.assignedHostId())
 
167
        return static_cast<protocol_t>(name.hostId());
 
168
    return PROTO_NONE; // no PROTO_OTHER
 
169
}
 
170
 
 
171
 
 
172
/* RequestHeaderRep */
 
173
 
 
174
Adaptation::Ecap::RequestLineRep::RequestLineRep(HttpRequest &aMessage):
 
175
        FirstLineRep(aMessage), theMessage(aMessage)
 
176
{
 
177
}
 
178
 
 
179
void
 
180
Adaptation::Ecap::RequestLineRep::uri(const Area &aUri)
 
181
{
 
182
    // TODO: if method is not set, urlPath will assume it is not connect;
 
183
    // Can we change urlParse API to remove the method parameter?
 
184
    // TODO: optimize: urlPath should take constant URL buffer
 
185
    char *buf = xstrdup(aUri.toString().c_str());
 
186
    const bool ok = urlParse(theMessage.method, buf, &theMessage);
 
187
    xfree(buf);
 
188
    Must(ok);
 
189
}
 
190
 
 
191
Adaptation::Ecap::RequestLineRep::Area
 
192
Adaptation::Ecap::RequestLineRep::uri() const
 
193
{
 
194
    return Area::FromTempBuffer(theMessage.urlpath.rawBuf(),
 
195
                                theMessage.urlpath.size());
 
196
}
 
197
 
 
198
void
 
199
Adaptation::Ecap::RequestLineRep::method(const Name &aMethod)
 
200
{
 
201
    if (aMethod.assignedHostId()) {
 
202
        const int id = aMethod.hostId();
 
203
        Must(METHOD_NONE < id && id < METHOD_ENUM_END);
 
204
        Must(id != METHOD_OTHER);
 
205
        theMessage.method = HttpRequestMethod(static_cast<_method_t>(id));
 
206
    } else {
 
207
        const std::string &image = aMethod.image();
 
208
        theMessage.method = HttpRequestMethod(image.data(),
 
209
                                              image.data() + image.size());
 
210
    }
 
211
}
 
212
 
 
213
Adaptation::Ecap::RequestLineRep::Name
 
214
Adaptation::Ecap::RequestLineRep::method() const
 
215
{
 
216
    switch (theMessage.method.id()) {
 
217
    case METHOD_GET:
 
218
        return libecap::methodGet;
 
219
    case METHOD_POST:
 
220
        return libecap::methodPost;
 
221
    case METHOD_PUT:
 
222
        return libecap::methodPut;
 
223
    case METHOD_HEAD:
 
224
        return libecap::methodHead;
 
225
    case METHOD_CONNECT:
 
226
        return libecap::methodConnect;
 
227
    case METHOD_DELETE:
 
228
        return libecap::methodDelete;
 
229
    case METHOD_TRACE:
 
230
        return libecap::methodTrace;
 
231
    default:
 
232
        return Name(theMessage.method.image());
 
233
    }
 
234
}
 
235
 
 
236
libecap::Version
 
237
Adaptation::Ecap::RequestLineRep::version() const
 
238
{
 
239
    return FirstLineRep::version();
 
240
}
 
241
 
 
242
void
 
243
Adaptation::Ecap::RequestLineRep::version(const libecap::Version &aVersion)
 
244
{
 
245
    FirstLineRep::version(aVersion);
 
246
}
 
247
 
 
248
libecap::Name
 
249
Adaptation::Ecap::RequestLineRep::protocol() const
 
250
{
 
251
    return FirstLineRep::protocol();
 
252
}
 
253
 
 
254
void
 
255
Adaptation::Ecap::RequestLineRep::protocol(const Name &p)
 
256
{
 
257
    FirstLineRep::protocol(p);
 
258
}
 
259
 
 
260
 
 
261
/* ReplyHeaderRep */
 
262
 
 
263
Adaptation::Ecap::StatusLineRep::StatusLineRep(HttpReply &aMessage):
 
264
        FirstLineRep(aMessage), theMessage(aMessage)
 
265
{
 
266
}
 
267
 
 
268
void
 
269
Adaptation::Ecap::StatusLineRep::statusCode(int code)
 
270
{
 
271
    // TODO: why is .status a enum? Do we not support unknown statuses?
 
272
    theMessage.sline.status = static_cast<http_status>(code);
 
273
}
 
274
 
 
275
int
 
276
Adaptation::Ecap::StatusLineRep::statusCode() const
 
277
{
 
278
    // TODO: see statusCode(code) TODO above
 
279
    return static_cast<int>(theMessage.sline.status);
 
280
}
 
281
 
 
282
void
 
283
Adaptation::Ecap::StatusLineRep::reasonPhrase(const Area &)
 
284
{
 
285
    // Squid does not support custom reason phrases
 
286
    theMessage.sline.reason = NULL;
 
287
}
 
288
 
 
289
Adaptation::Ecap::StatusLineRep::Area
 
290
Adaptation::Ecap::StatusLineRep::reasonPhrase() const
 
291
{
 
292
    return theMessage.sline.reason ?
 
293
           Area::FromTempString(std::string(theMessage.sline.reason)) : Area();
 
294
}
 
295
 
 
296
libecap::Version
 
297
Adaptation::Ecap::StatusLineRep::version() const
 
298
{
 
299
    return FirstLineRep::version();
 
300
}
 
301
 
 
302
void
 
303
Adaptation::Ecap::StatusLineRep::version(const libecap::Version &aVersion)
 
304
{
 
305
    FirstLineRep::version(aVersion);
 
306
}
 
307
 
 
308
libecap::Name
 
309
Adaptation::Ecap::StatusLineRep::protocol() const
 
310
{
 
311
    return FirstLineRep::protocol();
 
312
}
 
313
 
 
314
void
 
315
Adaptation::Ecap::StatusLineRep::protocol(const Name &p)
 
316
{
 
317
    FirstLineRep::protocol(p);
 
318
}
 
319
 
 
320
/* BodyRep */
 
321
 
 
322
Adaptation::Ecap::BodyRep::BodyRep(const BodyPipe::Pointer &aBody): theBody(aBody)
 
323
{
 
324
}
 
325
 
 
326
void
 
327
Adaptation::Ecap::BodyRep::tie(const BodyPipe::Pointer &aBody)
 
328
{
 
329
    Must(!theBody);
 
330
    Must(aBody != NULL);
 
331
    theBody = aBody;
 
332
}
 
333
 
 
334
Adaptation::Ecap::BodyRep::BodySize
 
335
Adaptation::Ecap::BodyRep::bodySize() const
 
336
{
 
337
    return !theBody ? BodySize() : BodySize(theBody->bodySize());
 
338
}
 
339
 
 
340
 
 
341
/* MessageRep */
 
342
 
 
343
Adaptation::Ecap::MessageRep::MessageRep(HttpMsg *rawHeader):
 
344
        theMessage(rawHeader), theFirstLineRep(NULL),
 
345
        theHeaderRep(NULL), theBodyRep(NULL)
 
346
{
 
347
    Must(theMessage.header); // we do not want to represent a missing message
 
348
 
 
349
    if (HttpRequest *req = dynamic_cast<HttpRequest*>(theMessage.header))
 
350
        theFirstLineRep = new RequestLineRep(*req);
 
351
    else
 
352
        if (HttpReply *rep = dynamic_cast<HttpReply*>(theMessage.header))
 
353
            theFirstLineRep = new StatusLineRep(*rep);
 
354
        else
 
355
            Must(false); // unknown message header type
 
356
 
 
357
    theHeaderRep = new HeaderRep(*theMessage.header);
 
358
 
 
359
    if (theMessage.body_pipe != NULL)
 
360
        theBodyRep = new BodyRep(theMessage.body_pipe);
 
361
}
 
362
 
 
363
Adaptation::Ecap::MessageRep::~MessageRep()
 
364
{
 
365
    delete theBodyRep;
 
366
    delete theHeaderRep;
 
367
    delete theFirstLineRep;
 
368
}
 
369
 
 
370
libecap::shared_ptr<libecap::Message>
 
371
Adaptation::Ecap::MessageRep::clone() const
 
372
{
 
373
    HttpMsg *hdr = theMessage.header->clone();
 
374
    hdr->body_pipe = NULL; // if any; TODO: remove pipe cloning from ::clone?
 
375
    libecap::shared_ptr<libecap::Message> res(new MessageRep(hdr));
 
376
 
 
377
    // restore indication of a body if needed, but not the pipe
 
378
    if (theMessage.header->body_pipe != NULL)
 
379
        res->addBody();
 
380
 
 
381
    return res;
 
382
}
 
383
 
 
384
libecap::FirstLine &
 
385
Adaptation::Ecap::MessageRep::firstLine()
 
386
{
 
387
    return *theFirstLineRep;
 
388
}
 
389
 
 
390
const libecap::FirstLine &
 
391
Adaptation::Ecap::MessageRep::firstLine() const
 
392
{
 
393
    return *theFirstLineRep;
 
394
}
 
395
 
 
396
libecap::Header &
 
397
Adaptation::Ecap::MessageRep::header()
 
398
{
 
399
    return *theHeaderRep;
 
400
}
 
401
 
 
402
const libecap::Header &
 
403
Adaptation::Ecap::MessageRep::header() const
 
404
{
 
405
    return *theHeaderRep;
 
406
}
 
407
 
 
408
libecap::Body *
 
409
Adaptation::Ecap::MessageRep::body()
 
410
{
 
411
    return theBodyRep;
 
412
}
 
413
 
 
414
void
 
415
Adaptation::Ecap::MessageRep::addBody()
 
416
{
 
417
    Must(!theBodyRep);
 
418
    Must(!theMessage.body_pipe); // set in tieBody()
 
419
    theBodyRep = new BodyRep(NULL);
 
420
}
 
421
 
 
422
void
 
423
Adaptation::Ecap::MessageRep::tieBody(Adaptation::Ecap::XactionRep *x)
 
424
{
 
425
    Must(theBodyRep != NULL); // addBody must be called first
 
426
    Must(!theMessage.header->body_pipe);
 
427
    Must(!theMessage.body_pipe);
 
428
    theMessage.header->body_pipe = new BodyPipe(x);
 
429
    theMessage.body_pipe = theMessage.header->body_pipe;
 
430
    theBodyRep->tie(theMessage.body_pipe);
 
431
}
 
432
 
 
433
const libecap::Body *Adaptation::Ecap::MessageRep::body() const
 
434
{
 
435
    return theBodyRep;
 
436
}