MessageRep.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1996-2018 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 /* DEBUG: section 93 eCAP Interface */
10 
11 #include "squid.h"
12 #include "BodyPipe.h"
13 #include "HttpReply.h"
14 #include "HttpRequest.h"
15 #include <libecap/common/names.h>
16 #include <libecap/common/area.h>
17 #include <libecap/common/version.h>
18 #include <libecap/common/named_values.h>
19 #include "adaptation/ecap/Host.h" /* for protocol constants */
22 #include "base/TextException.h"
23 
24 /* HeaderRep */
25 
26 Adaptation::Ecap::HeaderRep::HeaderRep(Http::Message &aMessage): theHeader(aMessage.header),
27  theMessage(aMessage)
28 {
29 }
30 
31 bool
33 {
34  const Http::HdrType squidId = TranslateHeaderId(name);
35  return squidId == Http::HdrType::OTHER ?
36  theHeader.hasNamed(name.image().c_str(), name.image().size()) :
37  static_cast<bool>(theHeader.has(squidId));
38 }
39 
40 Adaptation::Ecap::HeaderRep::Value
42 {
43  const Http::HdrType squidId = TranslateHeaderId(name);
44  const String value = squidId == Http::HdrType::OTHER ?
45  theHeader.getByName(name.image().c_str()) :
46  theHeader.getStrOrList(squidId);
47  return value.size() > 0 ?
48  Value::FromTempString(value.termedBuf()) : Value();
49 }
50 
51 void
52 Adaptation::Ecap::HeaderRep::add(const Name &name, const Value &value)
53 {
54  const Http::HdrType squidId = TranslateHeaderId(name); // Http::HdrType::OTHER OK
55  HttpHeaderEntry *e = new HttpHeaderEntry(squidId, SBuf(name.image()),
56  value.toString().c_str());
57  theHeader.addEntry(e);
58 
59  if (squidId == Http::HdrType::CONTENT_LENGTH)
60  theMessage.content_length = theHeader.getInt64(Http::HdrType::CONTENT_LENGTH);
61 }
62 
63 void
65 {
66  const Http::HdrType squidId = TranslateHeaderId(name);
67  if (squidId == Http::HdrType::OTHER)
68  theHeader.delByName(name.image().c_str());
69  else
70  theHeader.delById(squidId);
71 
72  if (squidId == Http::HdrType::CONTENT_LENGTH)
73  theMessage.content_length = theHeader.getInt64(Http::HdrType::CONTENT_LENGTH);
74 }
75 
76 void
77 Adaptation::Ecap::HeaderRep::visitEach(libecap::NamedValueVisitor &visitor) const
78 {
80  while (HttpHeaderEntry *e = theHeader.getEntry(&pos)) {
81  const Name name(std::string(e->name.rawContent(), e->name.length())); // optimize: find std Names
82  name.assignHostId(e->id);
83  visitor.visit(name, Value(e->value.rawBuf(), e->value.size()));
84  }
85 }
86 
87 libecap::Area
89 {
90  MemBuf mb;
91  mb.init();
92  theMessage.packInto(&mb, true);
93  return Area::FromTempBuffer(mb.content(), mb.contentSize());
94 }
95 
96 // throws on failures
97 void
99 {
101  Must(theMessage.parse(buf.start, buf.size, true, &error));
102 }
103 
106 {
107  if (name.assignedHostId())
108  return static_cast<Http::HdrType>(name.hostId());
109  return Http::HdrType::OTHER;
110 }
111 
112 /* FirstLineRep */
113 
115 {
116 }
117 
118 libecap::Version
120 {
121  return libecap::Version(theMessage.http_ver.major,
122  theMessage.http_ver.minor);
123 }
124 
125 void
126 Adaptation::Ecap::FirstLineRep::version(const libecap::Version &aVersion)
127 {
128  theMessage.http_ver.major = aVersion.majr;
129  theMessage.http_ver.minor = aVersion.minr;
130 }
131 
132 libecap::Name
134 {
135  // TODO: optimize?
136  switch (theMessage.http_ver.protocol) {
137  case AnyP::PROTO_HTTP:
138  return libecap::protocolHttp;
139  case AnyP::PROTO_HTTPS:
140  return libecap::protocolHttps;
141  case AnyP::PROTO_FTP:
142  return libecap::protocolFtp;
143  case AnyP::PROTO_GOPHER:
144  return libecap::protocolGopher;
145  case AnyP::PROTO_WAIS:
146  return libecap::protocolWais;
147  case AnyP::PROTO_WHOIS:
148  return libecap::protocolWhois;
149  case AnyP::PROTO_URN:
150  return libecap::protocolUrn;
151  case AnyP::PROTO_ICP:
152  return protocolIcp;
153 #if USE_HTCP
154  case AnyP::PROTO_HTCP:
155  return protocolHtcp;
156 #endif
158  return protocolCacheObj;
159  case AnyP::PROTO_ICY:
160  return protocolIcy;
161  case AnyP::PROTO_COAP:
162  case AnyP::PROTO_COAPS: // use 'unknown' until libecap supports coap:// and coaps://
163  // other protocols defined in Squid but not libecap use 'unknown'
165  case AnyP::PROTO_SSL:
166  case AnyP::PROTO_TLS:
167  case AnyP::PROTO_UNKNOWN:
168  return protocolUnknown; // until we remember the protocol image
169  case AnyP::PROTO_NONE:
170  return Name();
171 
172  case AnyP::PROTO_MAX:
173  break; // should not happen
174  // no default to catch AnyP::PROTO_ additions
175  }
176  Must(false); // not reached
177  return Name();
178 }
179 
180 void
182 {
183  // TODO: what happens if we fail to translate some protocol?
184  theMessage.http_ver.protocol = TranslateProtocolId(p);
185 }
186 
189 {
190  if (name.assignedHostId())
191  return static_cast<AnyP::ProtocolType>(name.hostId());
192  return AnyP::PROTO_UNKNOWN;
193 }
194 
195 /* RequestHeaderRep */
196 
198  FirstLineRep(aMessage), theMessage(aMessage)
199 {
200 }
201 
202 void
204 {
205  // TODO: if method is not set, AnyP::Uri::parse will assume it is not connect;
206  // Can we change AnyP::Uri::parse API to remove the method parameter?
207  const char *buf = aUri.toString().c_str();
208  const bool ok = theMessage.url.parse(theMessage.method, buf);
209  Must(ok);
210 }
211 
214 {
215  const SBuf &fullUrl = theMessage.effectiveRequestUri();
216  // XXX: effectiveRequestUri() cannot return NULL or even empty string, some other problem?
217  Must(!fullUrl.isEmpty());
218  // optimize: avoid copying by having an Area::Detail that locks theMessage
219  return Area::FromTempBuffer(fullUrl.rawContent(), fullUrl.length());
220 }
221 
222 void
224 {
225  if (aMethod.assignedHostId()) {
226  const int id = aMethod.hostId();
228  Must(id != Http::METHOD_OTHER);
229  theMessage.method = HttpRequestMethod(static_cast<Http::MethodType>(id));
230  } else {
231  const std::string &image = aMethod.image();
232  theMessage.method.HttpRequestMethodXXX(image.c_str());
233  }
234 }
235 
238 {
239  switch (theMessage.method.id()) {
240  case Http::METHOD_GET:
241  return libecap::methodGet;
242  case Http::METHOD_POST:
243  return libecap::methodPost;
244  case Http::METHOD_PUT:
245  return libecap::methodPut;
246  case Http::METHOD_HEAD:
247  return libecap::methodHead;
249  return libecap::methodConnect;
250  case Http::METHOD_DELETE:
251  return libecap::methodDelete;
252  case Http::METHOD_TRACE:
253  return libecap::methodTrace;
254  default:
255  return Name(theMessage.method.image().toStdString());
256  }
257 }
258 
259 libecap::Version
261 {
262  return FirstLineRep::version();
263 }
264 
265 void
266 Adaptation::Ecap::RequestLineRep::version(const libecap::Version &aVersion)
267 {
268  FirstLineRep::version(aVersion);
269 }
270 
271 libecap::Name
273 {
274  return FirstLineRep::protocol();
275 }
276 
277 void
279 {
281 }
282 
283 /* ReplyHeaderRep */
284 
286  FirstLineRep(aMessage), theMessage(aMessage)
287 {
288 }
289 
290 void
292 {
293  theMessage.sline.set(theMessage.sline.version, static_cast<Http::StatusCode>(code), nullptr);
294 }
295 
296 int
298 {
299  // TODO: remove cast when possible
300  return static_cast<int>(theMessage.sline.status());
301 }
302 
303 void
305 {
306  // Squid does not support external custom reason phrases so we have
307  // to just reset it (in case there was a custom internal reason set)
308  theMessage.sline.resetReason();
309 }
310 
313 {
314  return Area::FromTempString(std::string(theMessage.sline.reason()));
315 }
316 
317 libecap::Version
319 {
320  return FirstLineRep::version();
321 }
322 
323 void
324 Adaptation::Ecap::StatusLineRep::version(const libecap::Version &aVersion)
325 {
326  FirstLineRep::version(aVersion);
327 }
328 
329 libecap::Name
331 {
332  return FirstLineRep::protocol();
333 }
334 
335 void
337 {
339 }
340 
341 /* BodyRep */
342 
344 {
345 }
346 
347 void
349 {
350  Must(!theBody);
351  Must(aBody != NULL);
352  theBody = aBody;
353 }
354 
357 {
358  return (theBody != nullptr && theBody->bodySizeKnown()) ? BodySize(theBody->bodySize()) : BodySize();
359 }
360 
361 /* MessageRep */
362 
364  theMessage(rawHeader), theFirstLineRep(NULL),
365  theHeaderRep(NULL), theBodyRep(NULL)
366 {
367  Must(theMessage.header); // we do not want to represent a missing message
368 
369  if (HttpRequest *req = dynamic_cast<HttpRequest*>(theMessage.header))
370  theFirstLineRep = new RequestLineRep(*req);
371  else if (HttpReply *rep = dynamic_cast<HttpReply*>(theMessage.header))
372  theFirstLineRep = new StatusLineRep(*rep);
373  else
374  Must(false); // unknown message header type
375 
377 
378  if (theMessage.body_pipe != NULL)
380 }
381 
383 {
384  delete theBodyRep;
385  delete theHeaderRep;
386  delete theFirstLineRep;
387 }
388 
389 libecap::shared_ptr<libecap::Message>
391 {
392  Http::Message *hdr = theMessage.header->clone();
393  hdr->body_pipe = NULL; // if any; TODO: remove pipe cloning from ::clone?
394  libecap::shared_ptr<libecap::Message> res(new MessageRep(hdr));
395 
396  // restore indication of a body if needed, but not the pipe
397  if (theMessage.header->body_pipe != NULL)
398  res->addBody();
399 
400  return res;
401 }
402 
403 libecap::FirstLine &
405 {
406  return *theFirstLineRep;
407 }
408 
409 const libecap::FirstLine &
411 {
412  return *theFirstLineRep;
413 }
414 
415 libecap::Header &
417 {
418  return *theHeaderRep;
419 }
420 
421 const libecap::Header &
423 {
424  return *theHeaderRep;
425 }
426 
427 libecap::Body *
429 {
430  return theBodyRep;
431 }
432 
433 void
435 {
436  Must(!theBodyRep);
437  Must(!theMessage.body_pipe); // set in tieBody()
438  theBodyRep = new BodyRep(NULL);
439 }
440 
441 void
443 {
444  Must(theBodyRep != NULL); // addBody must be called first
445  Must(!theMessage.header->body_pipe);
446  Must(!theMessage.body_pipe);
447  theMessage.header->body_pipe = new BodyPipe(x);
448  theMessage.body_pipe = theMessage.header->body_pipe;
449  theBodyRep->tie(theMessage.body_pipe);
450 }
451 
452 const libecap::Body *Adaptation::Ecap::MessageRep::body() const
453 {
454  return theBodyRep;
455 }
456 
BodyRep(const BodyPipe::Pointer &aBody)
Definition: MessageRep.cc:343
virtual void visitEach(libecap::NamedValueVisitor &visitor) const
Definition: MessageRep.cc:77
const libecap::Name protocolHtcp
#define HttpHeaderInitPos
Definition: HttpHeader.h:48
virtual Value value(const Name &name) const
Definition: MessageRep.cc:41
libecap::BodySize BodySize
Definition: MessageRep.h:132
Definition: SBuf.h:86
virtual Area reasonPhrase() const
Definition: MessageRep.cc:312
void error(char *format,...)
virtual libecap::FirstLine & firstLine()
Definition: MessageRep.cc:404
libecap::Version version() const
Definition: MessageRep.cc:119
void tie(const BodyPipe::Pointer &aBody)
Definition: MessageRep.cc:348
#define Must(condition)
Like assert() but throws an exception instead of aborting the process.
Definition: TextException.h:69
virtual void removeAny(const Name &name)
Definition: MessageRep.cc:64
virtual libecap::shared_ptr< libecap::Message > clone() const
Definition: MessageRep.cc:390
int64_t getInt64() const
Definition: HttpHeader.cc:1547
bool isEmpty() const
Definition: SBuf.h:420
char * p
Definition: membanger.c:43
virtual libecap::Body * body()
Definition: MessageRep.cc:428
virtual Name protocol() const
Definition: MessageRep.cc:330
virtual Area uri() const
Definition: MessageRep.cc:213
size_type size() const
Definition: SquidString.h:72
virtual libecap::Header & header()
Definition: MessageRep.cc:416
virtual Area image() const
Definition: MessageRep.cc:88
void init(mb_size_t szInit, mb_size_t szMax)
Definition: MemBuf.cc:96
const libecap::Name protocolUnknown
size_type length() const
Returns the number of bytes stored in SBuf.
Definition: SBuf.h:404
StatusCode
Definition: StatusCode.h:20
const libecap::Name protocolIcy
char const * termedBuf() const
Definition: SquidString.h:91
virtual void add(const Name &name, const Value &value)
Definition: MessageRep.cc:52
static AnyP::ProtocolType TranslateProtocolId(const Name &name)
Definition: MessageRep.cc:188
common parts of HttpRequest and HttpReply
Definition: Message.h:24
virtual int statusCode() const
Definition: MessageRep.cc:297
libecap::FirstLine * theFirstLineRep
Definition: MessageRep.h:170
const libecap::Name protocolCacheObj
const char * c_str()
Definition: SBuf.cc:526
FirstLineRep(Http::Message &aMessage)
Definition: MessageRep.cc:114
void tieBody(Ecap::XactionRep *x)
Definition: MessageRep.cc:442
virtual Name protocol() const
Definition: MessageRep.cc:272
char * content()
start of the added data
Definition: MemBuf.h:41
unsigned char code
Definition: html_quote.c:20
void const char * buf
Definition: stub_helper.cc:16
ssize_t HttpHeaderPos
Definition: HttpHeader.h:45
StatusLineRep(HttpReply &aMessage)
Definition: MessageRep.cc:285
mb_size_t contentSize() const
available data size
Definition: MemBuf.h:47
HttpHeader header
Definition: Message.h:74
virtual libecap::Version version() const
Definition: MessageRep.cc:318
BodyPipePointer body_pipe
Definition: Message.h:46
virtual bool hasAny(const Name &name) const
Definition: MessageRep.cc:32
virtual BodySize bodySize() const
Definition: MessageRep.cc:356
static Http::HdrType TranslateHeaderId(const Name &name)
Definition: MessageRep.cc:105
ProtocolType
Definition: ProtocolType.h:22
Definition: MemBuf.h:23
BodyPipe::Pointer body_pipe
optional pipeline to receive message body
Definition: Message.h:97
HeaderRep(Http::Message &aMessage)
Definition: MessageRep.cc:26
Adaptation::Message theMessage
Definition: MessageRep.h:169
const libecap::Name protocolIcp
MessageRep(Http::Message *rawHeader)
Definition: MessageRep.cc:363
const char * rawContent() const
Definition: SBuf.cc:519
virtual libecap::Version version() const
Definition: MessageRep.cc:260
virtual Name method() const
Definition: MessageRep.cc:237
RequestLineRep(HttpRequest &aMessage)
Definition: MessageRep.cc:197
#define NULL
Definition: types.h:166
virtual void parse(const Area &buf)
Definition: MessageRep.cc:98
Header * header
Definition: Message.h:42

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors