]>
Commit | Line | Data |
---|---|---|
9cef6668 | 1 | /* |
b8ae064d | 2 | * Copyright (C) 1996-2023 The Squid Software Foundation and contributors |
9cef6668 | 3 | * |
bbc27441 AJ |
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. | |
9cef6668 | 7 | */ |
8 | ||
bbc27441 AJ |
9 | /* DEBUG: section 76 Internal Squid Object handling */ |
10 | ||
582c2af2 | 11 | #include "squid.h" |
7e6eabbc | 12 | #include "AccessLogEntry.h" |
92a5adb7 | 13 | #include "base/Assure.h" |
e37bd29b AJ |
14 | #include "CacheManager.h" |
15 | #include "comm/Connection.h" | |
aa839030 | 16 | #include "errorpage.h" |
528b2c61 | 17 | #include "HttpReply.h" |
602d9612 A |
18 | #include "HttpRequest.h" |
19 | #include "icmp/net_db.h" | |
8b082ed9 | 20 | #include "internal.h" |
0eb49b6d | 21 | #include "MemBuf.h" |
4d5904f7 | 22 | #include "SquidConfig.h" |
602d9612 | 23 | #include "Store.h" |
4e540555 | 24 | #include "tools.h" |
ed6e9fb9 | 25 | #include "util.h" |
1da5651f | 26 | |
a1f5c896 | 27 | /* called when we "miss" on an internal object; |
26ac0430 | 28 | * generate known dynamic objects, |
955394ce | 29 | * return Http::scNotFound for others |
a1f5c896 | 30 | */ |
1da5651f | 31 | void |
7e6eabbc | 32 | internalStart(const Comm::ConnectionPointer &clientConn, HttpRequest * request, StoreEntry * entry, const AccessLogEntry::Pointer &ale) |
1da5651f | 33 | { |
865094d7 | 34 | ErrorState *err; |
92a5adb7 AR |
35 | |
36 | Assure(request); | |
51b5dcf5 AJ |
37 | const SBuf upath = request->url.path(); |
38 | debugs(76, 3, clientConn << " requesting '" << upath << "'"); | |
62e76326 | 39 | |
92a5adb7 AR |
40 | Assure(request->flags.internal); |
41 | ||
51b5dcf5 AJ |
42 | static const SBuf netdbUri("/squid-internal-dynamic/netdb"); |
43 | static const SBuf storeDigestUri("/squid-internal-periodic/store_digest"); | |
51b5dcf5 AJ |
44 | |
45 | if (upath == netdbUri) { | |
62e76326 | 46 | netdbBinaryExchange(entry); |
51b5dcf5 | 47 | } else if (upath == storeDigestUri) { |
1f38f50a | 48 | #if USE_CACHE_DIGESTS |
62e76326 | 49 | const char *msgbuf = "This cache is currently building its digest.\n"; |
1f38f50a | 50 | #else |
62e76326 | 51 | |
9b5c4a9a | 52 | const char *msgbuf = "This cache does not support Cache Digests.\n"; |
1f38f50a | 53 | #endif |
62e76326 | 54 | |
06a5ae20 | 55 | HttpReply *reply = new HttpReply; |
955394ce | 56 | reply->setHeaders(Http::scNotFound, "Not Found", "text/plain", strlen(msgbuf), squid_curtime, -2); |
db237875 | 57 | entry->replaceHttpReply(reply); |
3900307b | 58 | entry->append(msgbuf, strlen(msgbuf)); |
62e76326 | 59 | entry->complete(); |
92a5adb7 AR |
60 | } else if (ForSomeCacheManager(upath)) { |
61 | debugs(17, 2, "calling CacheManager due to URL-path"); | |
7e6eabbc | 62 | CacheManager::GetInstance()->start(clientConn, request, entry, ale); |
1f38f50a | 63 | } else { |
62e76326 | 64 | debugObj(76, 1, "internalStart: unknown request:\n", |
65 | request, (ObjPackMethod) & httpRequestPack); | |
7e6eabbc | 66 | err = new ErrorState(ERR_INVALID_REQ, Http::scNotFound, request, ale); |
62e76326 | 67 | errorAppendEntry(entry, err); |
865094d7 | 68 | } |
1da5651f | 69 | } |
70 | ||
51b5dcf5 AJ |
71 | bool |
72 | internalCheck(const SBuf &urlPath) | |
1da5651f | 73 | { |
51b5dcf5 AJ |
74 | static const SBuf InternalPfx("/squid-internal-"); |
75 | return urlPath.startsWith(InternalPfx); | |
1da5651f | 76 | } |
77 | ||
51b5dcf5 AJ |
78 | bool |
79 | internalStaticCheck(const SBuf &urlPath) | |
ba26bca4 | 80 | { |
51b5dcf5 AJ |
81 | static const SBuf InternalStaticPfx("/squid-internal-static"); |
82 | return urlPath.startsWith(InternalStaticPfx); | |
ba26bca4 | 83 | } |
84 | ||
92a5adb7 AR |
85 | bool |
86 | ForSomeCacheManager(const SBuf &urlPath) | |
87 | { | |
3c383cc3 | 88 | return urlPath.startsWith(CacheManager::WellKnownUrlPathPrefix()); |
92a5adb7 AR |
89 | } |
90 | ||
1da5651f | 91 | /* |
92 | * makes internal url with a given host and port (remote internal url) | |
93 | */ | |
94 | char * | |
c002f0e7 | 95 | internalRemoteUri(bool encrypt, const char *host, unsigned short port, const char *dir, const SBuf &name) |
1da5651f | 96 | { |
1da5651f | 97 | static char lc_host[SQUIDHOSTNAMELEN]; |
51b5dcf5 | 98 | assert(host && !name.isEmpty()); |
137ee196 | 99 | /* convert host name to lower case */ |
c8918a58 | 100 | xstrncpy(lc_host, host, SQUIDHOSTNAMELEN); |
1da5651f | 101 | Tolower(lc_host); |
cc192b50 | 102 | |
cc192b50 | 103 | /* check for an IP address and format appropriately if found */ |
b7ac5457 | 104 | Ip::Address test = lc_host; |
4dd643d5 AJ |
105 | if ( !test.isAnyAddr() ) { |
106 | test.toHostStr(lc_host,SQUIDHOSTNAMELEN); | |
cc192b50 | 107 | } |
cc192b50 | 108 | |
1224d740 | 109 | /* |
110 | * append the domain in order to mirror the requests with appended | |
38aa10ef | 111 | * domains. If that fails, just use the hostname anyway. |
1224d740 | 112 | */ |
38aa10ef | 113 | (void)urlAppendDomain(lc_host); |
62e76326 | 114 | |
5c51bffb | 115 | /* build URI */ |
c8ab5ec6 | 116 | AnyP::Uri tmp(AnyP::PROTO_HTTP); |
5c51bffb AJ |
117 | tmp.host(lc_host); |
118 | if (port) | |
119 | tmp.port(port); | |
120 | ||
032785bf | 121 | static MemBuf mb; |
122 | ||
2fe7eff9 | 123 | mb.reset(); |
c002f0e7 | 124 | mb.appendf("%s://" SQUIDSBUFPH, encrypt ? "https" : "http", SQUIDSBUFPRINT(tmp.authority())); |
62e76326 | 125 | |
1da5651f | 126 | if (dir) |
4391cd15 | 127 | mb.append(dir, strlen(dir)); |
62e76326 | 128 | |
51b5dcf5 | 129 | mb.append(name.rawContent(), name.length()); |
62e76326 | 130 | |
137ee196 | 131 | /* return a pointer to a local static buffer */ |
132 | return mb.buf; | |
1da5651f | 133 | } |
134 | ||
135 | /* | |
136 | * makes internal url with local host and port | |
137 | */ | |
138 | char * | |
51b5dcf5 | 139 | internalLocalUri(const char *dir, const SBuf &name) |
1da5651f | 140 | { |
c002f0e7 | 141 | // XXX: getMy*() may return https_port info, but we force http URIs |
142 | // because we have not checked whether the callers can handle https. | |
143 | const bool secure = false; | |
144 | return internalRemoteUri(secure, getMyHostname(), | |
62e76326 | 145 | getMyPort(), dir, name); |
1da5651f | 146 | } |
c68e9c6b | 147 | |
148 | const char * | |
149 | internalHostname(void) | |
150 | { | |
151 | LOCAL_ARRAY(char, host, SQUIDHOSTNAMELEN + 1); | |
152 | xstrncpy(host, getMyHostname(), SQUIDHOSTNAMELEN); | |
b3ef8c0d | 153 | |
055421ee | 154 | /* For IPv6 addresses also check for a colon */ |
532e5dd4 | 155 | if (Config.appendDomain && !strchr(host, '.') && !strchr(host, ':')) |
b3ef8c0d | 156 | strncat(host, Config.appendDomain, SQUIDHOSTNAMELEN - |
157 | strlen(host) - 1); | |
158 | ||
c68e9c6b | 159 | Tolower(host); |
b3ef8c0d | 160 | |
c68e9c6b | 161 | return host; |
162 | } | |
1f38f50a | 163 | |
6793ad05 AJ |
164 | bool |
165 | internalHostnameIs(const SBuf &arg) | |
1f38f50a | 166 | { |
6793ad05 AJ |
167 | if (arg.caseCmp(internalHostname()) == 0) |
168 | return true; | |
62e76326 | 169 | |
6793ad05 AJ |
170 | for (const auto &w : Config.hostnameAliases) { |
171 | if (w.caseCmp(arg) == 0) | |
172 | return true; | |
173 | } | |
62e76326 | 174 | |
6793ad05 | 175 | return false; |
1f38f50a | 176 | } |
f53969cc | 177 |