]> git.ipfire.org Git - thirdparty/squid.git/blame - src/adaptation/ecap/Host.cc
Move compat/unsafe.h protections from libcompat to source maintenance
[thirdparty/squid.git] / src / adaptation / ecap / Host.cc
CommitLineData
b510f3a1
AJ
1/*
2 * DEBUG: section 93 eCAP Interface
3 */
582c2af2 4#include "squid.h"
fdc96a39 5#include <libecap/adapter/service.h>
530f96dd 6#include <libecap/common/names.h>
76fc7e57 7#include <libecap/common/registry.h>
1f3c65fc 8#include "adaptation/ecap/Host.h"
cc7b2f6c 9#include "adaptation/ecap/MessageRep.h"
602d9612
A
10#include "adaptation/ecap/ServiceRep.h"
11#include "base/TextException.h"
cc7b2f6c 12#include "HttpReply.h"
602d9612 13#include "HttpRequest.h"
fdc96a39 14
574b508c
AR
15const libecap::Name Adaptation::Ecap::protocolInternal("internal", libecap::Name::NextId());
16const libecap::Name Adaptation::Ecap::protocolCacheObj("cache_object", libecap::Name::NextId());
17const libecap::Name Adaptation::Ecap::protocolIcp("ICP", libecap::Name::NextId());
530f96dd 18#if USE_HTCP
574b508c 19const libecap::Name Adaptation::Ecap::protocolHtcp("Htcp", libecap::Name::NextId());
530f96dd 20#endif
555aedbf
AR
21const libecap::Name Adaptation::Ecap::protocolIcy("ICY", libecap::Name::NextId());
22const libecap::Name Adaptation::Ecap::protocolUnknown("_unknown_", libecap::Name::NextId());
23
22fff3bf 24const libecap::Name Adaptation::Ecap::metaBypassable("bypassable", libecap::Name::NextId());
530f96dd 25
76fc7e57
AJ
26/// the host application (i.e., Squid) wrapper registered with libecap
27static libecap::shared_ptr<Adaptation::Ecap::Host> TheHost;
28
574b508c 29Adaptation::Ecap::Host::Host()
530f96dd
AR
30{
31 // assign our host-specific IDs to well-known names
76fc7e57
AJ
32 // this code can run only once
33
3c266848 34 libecap::headerTransferEncoding.assignHostId(HDR_TRANSFER_ENCODING);
530f96dd 35 libecap::headerReferer.assignHostId(HDR_REFERER);
0b3a8137 36 libecap::headerContentLength.assignHostId(HDR_CONTENT_LENGTH);
3c266848
AR
37 libecap::headerVia.assignHostId(HDR_VIA);
38 // TODO: libecap::headerXClientIp.assignHostId(HDR_X_CLIENT_IP);
39 // TODO: libecap::headerXServerIp.assignHostId(HDR_X_SERVER_IP);
530f96dd 40
39a19cb7
AJ
41 libecap::protocolHttp.assignHostId(AnyP::PROTO_HTTP);
42 libecap::protocolHttps.assignHostId(AnyP::PROTO_HTTPS);
43 libecap::protocolFtp.assignHostId(AnyP::PROTO_FTP);
44 libecap::protocolGopher.assignHostId(AnyP::PROTO_GOPHER);
45 libecap::protocolWais.assignHostId(AnyP::PROTO_WAIS);
46 libecap::protocolUrn.assignHostId(AnyP::PROTO_URN);
47 libecap::protocolWhois.assignHostId(AnyP::PROTO_WHOIS);
48 protocolInternal.assignHostId(AnyP::PROTO_INTERNAL);
49 protocolCacheObj.assignHostId(AnyP::PROTO_CACHE_OBJECT);
50 protocolIcp.assignHostId(AnyP::PROTO_ICP);
530f96dd 51#if USE_HTCP
39a19cb7 52 protocolHtcp.assignHostId(AnyP::PROTO_HTCP);
530f96dd 53#endif
555aedbf
AR
54 protocolIcy.assignHostId(AnyP::PROTO_ICY);
55 protocolUnknown.assignHostId(AnyP::PROTO_UNKNOWN);
22fff3bf
AR
56
57 // allows adapter to safely ignore this in adapter::Service::configure()
58 metaBypassable.assignHostId(1);
530f96dd 59}
fdc96a39
AR
60
61std::string
574b508c 62Adaptation::Ecap::Host::uri() const
fdc96a39
AR
63{
64 return "ecap://squid-cache.org/ecap/hosts/squid";
65}
66
67void
574b508c 68Adaptation::Ecap::Host::describe(std::ostream &os) const
fdc96a39
AR
69{
70 os << PACKAGE_NAME << " v" << PACKAGE_VERSION;
71}
72
0a720258
AR
73/// Strips libecap version components not affecting compatibility decisions.
74static SBuf
75EssentialVersion(const SBuf &raw)
76{
77 // all libecap x.y.* releases are supposed to be compatible so we strip
78 // everything after the second period
79 const SBuf::size_type minorPos = raw.find('.');
80 const SBuf::size_type microPos = minorPos == SBuf::npos ?
81 SBuf::npos : raw.find('.', minorPos+1);
82 return raw.substr(0, microPos); // becomes raw if microPos is npos
83}
84
85/// If "their" libecap version is not compatible with what Squid has been built
86/// with, then complain and return false.
87static bool
88SupportedVersion(const char *vTheir, const char *them)
89{
90 if (!vTheir || !*vTheir) {
91 debugs(93, DBG_CRITICAL, "ERROR: Cannot use " << them <<
92 " with libecap prior to v1.0.");
93 return false;
94 }
95
96 // we support what we are built with
97 const SBuf vSupported(LIBECAP_VERSION);
98 debugs(93, 2, them << " with libecap v" << vTheir << "; us: v" << vSupported);
99
100 if (EssentialVersion(SBuf(vTheir)) == EssentialVersion(vSupported))
101 return true; // their version is supported
102
103 debugs(93, DBG_CRITICAL, "ERROR: Cannot use " << them <<
104 " with libecap v" << vTheir <<
105 ": incompatible with supported libecap v" << vSupported);
106 return false;
107}
108
fdc96a39 109void
0a720258 110Adaptation::Ecap::Host::noteVersionedService(const char *vGiven, const libecap::weak_ptr<libecap::adapter::Service> &weak)
fdc96a39 111{
0a720258
AR
112 /*
113 * Check that libecap used to build the service is compatible with ours.
114 * This has to be done using vGiven string and not Service object itself
115 * because dereferencing a Service pointer coming from an unsupported
116 * version is unsafe.
117 */
118 if (SupportedVersion(vGiven, "eCAP service built")) {
119 Must(!weak.expired());
120 RegisterAdapterService(weak.lock());
121 }
fdc96a39
AR
122}
123
124static int
125SquidLogLevel(libecap::LogVerbosity lv)
126{
26ac0430
AJ
127 if (lv.critical())
128 return DBG_CRITICAL; // is it a good idea to ignore other flags?
fdc96a39 129
26ac0430
AJ
130 if (lv.large())
131 return DBG_DATA; // is it a good idea to ignore other flags?
fdc96a39 132
26ac0430 133 if (lv.application())
ac6e678f 134 return DBG_IMPORTANT; // is it a good idea to ignore other flags?
fdc96a39 135
26ac0430 136 return 2 + 2*lv.debugging() + 3*lv.operation() + 2*lv.xaction();
fdc96a39
AR
137}
138
139std::ostream *
574b508c 140Adaptation::Ecap::Host::openDebug(libecap::LogVerbosity lv)
fdc96a39
AR
141{
142 const int squidLevel = SquidLogLevel(lv);
143 const int squidSection = 93; // XXX: this should be a global constant
144 // XXX: Debug.h should provide this to us
26ac0430
AJ
145 if ((Debug::level = squidLevel) <= Debug::Levels[squidSection])
146 return &Debug::getDebugOut();
147 else
148 return NULL;
fdc96a39
AR
149}
150
151void
574b508c 152Adaptation::Ecap::Host::closeDebug(std::ostream *debug)
fdc96a39 153{
26ac0430
AJ
154 if (debug)
155 Debug::finishDebug();
fdc96a39 156}
76fc7e57 157
cc7b2f6c
AR
158Adaptation::Ecap::Host::MessagePtr
159Adaptation::Ecap::Host::newRequest() const
160{
161 return MessagePtr(new Adaptation::Ecap::MessageRep(new HttpRequest));
162}
163
164Adaptation::Ecap::Host::MessagePtr
165Adaptation::Ecap::Host::newResponse() const
166{
167 return MessagePtr(new Adaptation::Ecap::MessageRep(new HttpReply));
168}
169
76fc7e57
AJ
170void
171Adaptation::Ecap::Host::Register()
172{
0a720258
AR
173 if (!TheHost && SupportedVersion(libecap::VersionString(),
174 "Squid executable dynamically linked")) {
76fc7e57
AJ
175 TheHost.reset(new Adaptation::Ecap::Host);
176 libecap::RegisterHost(TheHost);
177 }
178}