]>
git.ipfire.org Git - thirdparty/squid.git/blob - src/adaptation/ecap/MessageRep.cc
6 #include "HttpRequest.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 */
19 Adaptation::Ecap::HeaderRep::HeaderRep(HttpMsg
&aMessage
): theHeader(aMessage
.header
),
25 Adaptation::Ecap::HeaderRep::hasAny(const Name
&name
) const
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
);
34 Adaptation::Ecap::HeaderRep::Value
35 Adaptation::Ecap::HeaderRep::value(const Name
&name
) const
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());
45 Adaptation::Ecap::HeaderRep::add(const Name
&name
, const Value
&value
)
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
);
54 Adaptation::Ecap::HeaderRep::removeAny(const Name
&name
)
56 const http_hdr_type squidId
= TranslateHeaderId(name
);
57 if (squidId
== HDR_OTHER
)
58 theHeader
.delByName(name
.image().c_str());
60 theHeader
.delById(squidId
);
64 Adaptation::Ecap::HeaderRep::image() const
70 packerToMemInit(&p
, &mb
);
71 theMessage
.packInto(&p
, true);
73 return Area::FromTempBuffer(mb
.content(), mb
.contentSize());
78 Adaptation::Ecap::HeaderRep::parse(const Area
&buf
)
82 mb
.append(buf
.start
, buf
.size
);
84 Must(theMessage
.parse(&mb
, true, &error
));
88 Adaptation::Ecap::HeaderRep::TranslateHeaderId(const Name
&name
)
90 if (name
.assignedHostId())
91 return static_cast<http_hdr_type
>(name
.hostId());
98 Adaptation::Ecap::FirstLineRep::FirstLineRep(HttpMsg
&aMessage
): theMessage(aMessage
)
103 Adaptation::Ecap::FirstLineRep::version() const
105 return libecap::Version(theMessage
.http_ver
.major
,
106 theMessage
.http_ver
.minor
);
110 Adaptation::Ecap::FirstLineRep::version(const libecap::Version
&aVersion
)
112 theMessage
.http_ver
.major
= aVersion
.majr
;
113 theMessage
.http_ver
.minor
= aVersion
.minr
;
117 Adaptation::Ecap::FirstLineRep::protocol() const
120 switch (theMessage
.protocol
) {
122 return libecap::protocolHttp
;
124 return libecap::protocolHttps
;
126 return libecap::protocolFtp
;
128 return libecap::protocolGopher
;
130 return libecap::protocolWais
;
132 return libecap::protocolWhois
;
134 return libecap::protocolUrn
;
142 return protocolCacheObj
;
144 return protocolInternal
;
149 break; // should not happen
150 // no default to catch PROTO_ additions
152 Must(false); // not reached
157 Adaptation::Ecap::FirstLineRep::protocol(const Name
&p
)
159 // TODO: what happens if we fail to translate some protocol?
160 theMessage
.protocol
= TranslateProtocolId(p
);
164 Adaptation::Ecap::FirstLineRep::TranslateProtocolId(const Name
&name
)
166 if (name
.assignedHostId())
167 return static_cast<protocol_t
>(name
.hostId());
168 return PROTO_NONE
; // no PROTO_OTHER
172 /* RequestHeaderRep */
174 Adaptation::Ecap::RequestLineRep::RequestLineRep(HttpRequest
&aMessage
):
175 FirstLineRep(aMessage
), theMessage(aMessage
)
180 Adaptation::Ecap::RequestLineRep::uri(const Area
&aUri
)
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
);
191 Adaptation::Ecap::RequestLineRep::Area
192 Adaptation::Ecap::RequestLineRep::uri() const
194 return Area::FromTempBuffer(theMessage
.urlpath
.rawBuf(),
195 theMessage
.urlpath
.size());
199 Adaptation::Ecap::RequestLineRep::method(const Name
&aMethod
)
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
));
207 const std::string
&image
= aMethod
.image();
208 theMessage
.method
= HttpRequestMethod(image
.data(),
209 image
.data() + image
.size());
213 Adaptation::Ecap::RequestLineRep::Name
214 Adaptation::Ecap::RequestLineRep::method() const
216 switch (theMessage
.method
.id()) {
218 return libecap::methodGet
;
220 return libecap::methodPost
;
222 return libecap::methodPut
;
224 return libecap::methodHead
;
226 return libecap::methodConnect
;
228 return libecap::methodDelete
;
230 return libecap::methodTrace
;
232 return Name(theMessage
.method
.image());
237 Adaptation::Ecap::RequestLineRep::version() const
239 return FirstLineRep::version();
243 Adaptation::Ecap::RequestLineRep::version(const libecap::Version
&aVersion
)
245 FirstLineRep::version(aVersion
);
249 Adaptation::Ecap::RequestLineRep::protocol() const
251 return FirstLineRep::protocol();
255 Adaptation::Ecap::RequestLineRep::protocol(const Name
&p
)
257 FirstLineRep::protocol(p
);
263 Adaptation::Ecap::StatusLineRep::StatusLineRep(HttpReply
&aMessage
):
264 FirstLineRep(aMessage
), theMessage(aMessage
)
269 Adaptation::Ecap::StatusLineRep::statusCode(int code
)
271 // TODO: why is .status a enum? Do we not support unknown statuses?
272 theMessage
.sline
.status
= static_cast<http_status
>(code
);
276 Adaptation::Ecap::StatusLineRep::statusCode() const
278 // TODO: see statusCode(code) TODO above
279 return static_cast<int>(theMessage
.sline
.status
);
283 Adaptation::Ecap::StatusLineRep::reasonPhrase(const Area
&)
285 // Squid does not support custom reason phrases
286 theMessage
.sline
.reason
= NULL
;
289 Adaptation::Ecap::StatusLineRep::Area
290 Adaptation::Ecap::StatusLineRep::reasonPhrase() const
292 return theMessage
.sline
.reason
?
293 Area::FromTempString(std::string(theMessage
.sline
.reason
)) : Area();
297 Adaptation::Ecap::StatusLineRep::version() const
299 return FirstLineRep::version();
303 Adaptation::Ecap::StatusLineRep::version(const libecap::Version
&aVersion
)
305 FirstLineRep::version(aVersion
);
309 Adaptation::Ecap::StatusLineRep::protocol() const
311 return FirstLineRep::protocol();
315 Adaptation::Ecap::StatusLineRep::protocol(const Name
&p
)
317 FirstLineRep::protocol(p
);
322 Adaptation::Ecap::BodyRep::BodyRep(const BodyPipe::Pointer
&aBody
): theBody(aBody
)
327 Adaptation::Ecap::BodyRep::tie(const BodyPipe::Pointer
&aBody
)
334 Adaptation::Ecap::BodyRep::BodySize
335 Adaptation::Ecap::BodyRep::bodySize() const
337 return !theBody
? BodySize() : BodySize(theBody
->bodySize());
343 Adaptation::Ecap::MessageRep::MessageRep(HttpMsg
*rawHeader
):
344 theMessage(rawHeader
), theFirstLineRep(NULL
),
345 theHeaderRep(NULL
), theBodyRep(NULL
)
347 Must(theMessage
.header
); // we do not want to represent a missing message
349 if (HttpRequest
*req
= dynamic_cast<HttpRequest
*>(theMessage
.header
))
350 theFirstLineRep
= new RequestLineRep(*req
);
351 else if (HttpReply
*rep
= dynamic_cast<HttpReply
*>(theMessage
.header
))
352 theFirstLineRep
= new StatusLineRep(*rep
);
354 Must(false); // unknown message header type
356 theHeaderRep
= new HeaderRep(*theMessage
.header
);
358 if (theMessage
.body_pipe
!= NULL
)
359 theBodyRep
= new BodyRep(theMessage
.body_pipe
);
362 Adaptation::Ecap::MessageRep::~MessageRep()
366 delete theFirstLineRep
;
369 libecap::shared_ptr
<libecap::Message
>
370 Adaptation::Ecap::MessageRep::clone() const
372 HttpMsg
*hdr
= theMessage
.header
->clone();
373 hdr
->body_pipe
= NULL
; // if any; TODO: remove pipe cloning from ::clone?
374 libecap::shared_ptr
<libecap::Message
> res(new MessageRep(hdr
));
376 // restore indication of a body if needed, but not the pipe
377 if (theMessage
.header
->body_pipe
!= NULL
)
384 Adaptation::Ecap::MessageRep::firstLine()
386 return *theFirstLineRep
;
389 const libecap::FirstLine
&
390 Adaptation::Ecap::MessageRep::firstLine() const
392 return *theFirstLineRep
;
396 Adaptation::Ecap::MessageRep::header()
398 return *theHeaderRep
;
401 const libecap::Header
&
402 Adaptation::Ecap::MessageRep::header() const
404 return *theHeaderRep
;
408 Adaptation::Ecap::MessageRep::body()
414 Adaptation::Ecap::MessageRep::addBody()
417 Must(!theMessage
.body_pipe
); // set in tieBody()
418 theBodyRep
= new BodyRep(NULL
);
422 Adaptation::Ecap::MessageRep::tieBody(Adaptation::Ecap::XactionRep
*x
)
424 Must(theBodyRep
!= NULL
); // addBody must be called first
425 Must(!theMessage
.header
->body_pipe
);
426 Must(!theMessage
.body_pipe
);
427 theMessage
.header
->body_pipe
= new BodyPipe(x
);
428 theMessage
.body_pipe
= theMessage
.header
->body_pipe
;
429 theBodyRep
->tie(theMessage
.body_pipe
);
432 const libecap::Body
*Adaptation::Ecap::MessageRep::body() const