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