]>
Commit | Line | Data |
---|---|---|
8822ebee | 1 | /* |
f70aedc4 | 2 | * Copyright (C) 1996-2021 The Squid Software Foundation and contributors |
8822ebee | 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. | |
8822ebee AR |
7 | */ |
8 | ||
bbc27441 AJ |
9 | /* DEBUG: section 16 Cache Manager API */ |
10 | ||
f7f3304a | 11 | #include "squid.h" |
7e6eabbc | 12 | #include "AccessLogEntry.h" |
8822ebee | 13 | #include "base/TextException.h" |
582c2af2 | 14 | #include "comm.h" |
1b76e6c1 | 15 | #include "comm/Connection.h" |
ec41b64c | 16 | #include "comm/Write.h" |
8822ebee | 17 | #include "CommCalls.h" |
602d9612 | 18 | #include "errorpage.h" |
8822ebee | 19 | #include "HttpReply.h" |
8c4f6de5 | 20 | #include "HttpRequest.h" |
51ea0904 | 21 | #include "ipc/UdsOp.h" |
8822ebee | 22 | #include "mgr/ActionWriter.h" |
995eb827 | 23 | #include "mgr/Command.h" |
602d9612 A |
24 | #include "mgr/Inquirer.h" |
25 | #include "mgr/IntParam.h" | |
8822ebee AR |
26 | #include "mgr/Request.h" |
27 | #include "mgr/Response.h" | |
28 | #include "SquidTime.h" | |
29 | #include <memory> | |
30 | #include <algorithm> | |
31 | ||
8822ebee AR |
32 | CBDATA_NAMESPACED_CLASS_INIT(Mgr, Inquirer); |
33 | ||
51ea0904 | 34 | Mgr::Inquirer::Inquirer(Action::Pointer anAction, |
d9fc6862 | 35 | const Request &aCause, const Ipc::StrandCoords &coords): |
f53969cc SM |
36 | Ipc::Inquirer(aCause.clone(), applyQueryParams(coords, aCause.params.queryParams), anAction->atomic() ? 10 : 100), |
37 | aggrAction(anAction) | |
8822ebee | 38 | { |
1b76e6c1 AJ |
39 | conn = aCause.conn; |
40 | Ipc::ImportFdIntoComm(conn, SOCK_STREAM, IPPROTO_TCP, Ipc::fdnHttpSocket); | |
8822ebee | 41 | |
1b76e6c1 | 42 | debugs(16, 5, HERE << conn << " action: " << aggrAction); |
8822ebee AR |
43 | |
44 | closer = asyncCall(16, 5, "Mgr::Inquirer::noteCommClosed", | |
d9fc6862 | 45 | CommCbMemFunT<Inquirer, CommCloseCbParams>(this, &Inquirer::noteCommClosed)); |
1b76e6c1 | 46 | comm_add_close_handler(conn->fd, closer); |
8822ebee AR |
47 | } |
48 | ||
49 | /// closes our copy of the client HTTP connection socket | |
50 | void | |
51ea0904 | 51 | Mgr::Inquirer::cleanup() |
d9fc6862 | 52 | { |
1b76e6c1 | 53 | if (Comm::IsConnOpen(conn)) { |
8822ebee | 54 | removeCloseHandler(); |
1b76e6c1 | 55 | conn->close(); |
8822ebee AR |
56 | } |
57 | } | |
58 | ||
59 | void | |
60 | Mgr::Inquirer::removeCloseHandler() | |
61 | { | |
62 | if (closer != NULL) { | |
1b76e6c1 | 63 | comm_remove_close_handler(conn->fd, closer); |
8822ebee AR |
64 | closer = NULL; |
65 | } | |
66 | } | |
67 | ||
68 | void | |
69 | Mgr::Inquirer::start() | |
70 | { | |
71 | debugs(16, 5, HERE); | |
51ea0904 | 72 | Ipc::Inquirer::start(); |
1b76e6c1 | 73 | Must(Comm::IsConnOpen(conn)); |
8822ebee AR |
74 | Must(aggrAction != NULL); |
75 | ||
a203dec7 | 76 | std::unique_ptr<MemBuf> replyBuf; |
8c4f6de5 | 77 | if (strands.empty()) { |
8babada0 | 78 | const char *url = aggrAction->command().params.httpUri.termedBuf(); |
5ceaee75 | 79 | const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initIpc); |
6c880a16 | 80 | auto *req = HttpRequest::FromUrlXXX(url, mx); |
7e6eabbc | 81 | ErrorState err(ERR_INVALID_URL, Http::scNotFound, req, nullptr); |
913524f0 | 82 | std::unique_ptr<HttpReply> reply(err.BuildHttpReply()); |
8c4f6de5 | 83 | replyBuf.reset(reply->pack()); |
10c40d99 | 84 | } else { |
a203dec7 | 85 | std::unique_ptr<HttpReply> reply(new HttpReply); |
955394ce | 86 | reply->setHeaders(Http::scOkay, NULL, "text/plain", -1, squid_curtime, squid_curtime); |
789217a2 | 87 | reply->header.putStr(Http::HdrType::CONNECTION, "close"); // until we chunk response |
8c4f6de5 CT |
88 | replyBuf.reset(reply->pack()); |
89 | } | |
8822ebee | 90 | writer = asyncCall(16, 5, "Mgr::Inquirer::noteWroteHeader", |
d9fc6862 | 91 | CommCbMemFunT<Inquirer, CommIoCbParams>(this, &Inquirer::noteWroteHeader)); |
1b76e6c1 | 92 | Comm::Write(conn, replyBuf.get(), writer); |
8822ebee AR |
93 | } |
94 | ||
95 | /// called when we wrote the response header | |
96 | void | |
97 | Mgr::Inquirer::noteWroteHeader(const CommIoCbParams& params) | |
98 | { | |
99 | debugs(16, 5, HERE); | |
100 | writer = NULL; | |
c8407295 | 101 | Must(params.flag == Comm::OK); |
1b76e6c1 | 102 | Must(params.conn.getRaw() == conn.getRaw()); |
8822ebee AR |
103 | Must(params.size != 0); |
104 | // start inquiries at the initial pos | |
105 | inquire(); | |
106 | } | |
107 | ||
8822ebee | 108 | /// called when the HTTP client or some external force closed our socket |
8822ebee | 109 | void |
8822ebee | 110 | Mgr::Inquirer::noteCommClosed(const CommCloseCbParams& params) |
8822ebee | 111 | { |
8822ebee | 112 | debugs(16, 5, HERE); |
1b76e6c1 AJ |
113 | Must(!Comm::IsConnOpen(conn) && params.conn.getRaw() == conn.getRaw()); |
114 | conn = NULL; | |
8822ebee | 115 | mustStop("commClosed"); |
8822ebee AR |
116 | } |
117 | ||
51ea0904 CT |
118 | bool |
119 | Mgr::Inquirer::aggregate(Ipc::Response::Pointer aResponse) | |
8822ebee | 120 | { |
51ea0904 | 121 | Mgr::Response& response = static_cast<Response&>(*aResponse); |
8822ebee AR |
122 | if (response.hasAction()) |
123 | aggrAction->add(response.getAction()); | |
51ea0904 | 124 | return true; |
8822ebee AR |
125 | } |
126 | ||
127 | void | |
51ea0904 | 128 | Mgr::Inquirer::sendResponse() |
8822ebee | 129 | { |
b8151fa1 | 130 | if (!strands.empty() && aggrAction->aggregatable()) { |
8822ebee | 131 | removeCloseHandler(); |
1b76e6c1 AJ |
132 | AsyncJob::Start(new ActionWriter(aggrAction, conn)); |
133 | conn = NULL; // should not close because we passed it to ActionWriter | |
8822ebee | 134 | } |
8822ebee AR |
135 | } |
136 | ||
137 | bool | |
138 | Mgr::Inquirer::doneAll() const | |
139 | { | |
51ea0904 | 140 | return !writer && Ipc::Inquirer::doneAll(); |
8822ebee | 141 | } |
b8151fa1 CT |
142 | |
143 | Ipc::StrandCoords | |
144 | Mgr::Inquirer::applyQueryParams(const Ipc::StrandCoords& aStrands, const QueryParams& aParams) | |
145 | { | |
ab2baff3 | 146 | Ipc::StrandCoords sc; |
b8151fa1 | 147 | |
22b5be72 CT |
148 | QueryParam::Pointer processesParam = aParams.get("processes"); |
149 | QueryParam::Pointer workersParam = aParams.get("workers"); | |
b8151fa1 CT |
150 | |
151 | if (processesParam == NULL || workersParam == NULL) { | |
152 | if (processesParam != NULL) { | |
153 | IntParam* param = dynamic_cast<IntParam*>(processesParam.getRaw()); | |
154 | if (param != NULL && param->type == QueryParam::ptInt) { | |
155 | const std::vector<int>& processes = param->value(); | |
156 | for (Ipc::StrandCoords::const_iterator iter = aStrands.begin(); | |
10c40d99 | 157 | iter != aStrands.end(); ++iter) { |
b8151fa1 | 158 | if (std::find(processes.begin(), processes.end(), iter->kidId) != processes.end()) |
ab2baff3 | 159 | sc.push_back(*iter); |
b8151fa1 CT |
160 | } |
161 | } | |
162 | } else if (workersParam != NULL) { | |
163 | IntParam* param = dynamic_cast<IntParam*>(workersParam.getRaw()); | |
164 | if (param != NULL && param->type == QueryParam::ptInt) { | |
165 | const std::vector<int>& workers = param->value(); | |
10c40d99 | 166 | for (int i = 0; i < (int)aStrands.size(); ++i) { |
b8151fa1 | 167 | if (std::find(workers.begin(), workers.end(), i + 1) != workers.end()) |
ab2baff3 | 168 | sc.push_back(aStrands[i]); |
b8151fa1 CT |
169 | } |
170 | } | |
171 | } else { | |
ab2baff3 | 172 | sc = aStrands; |
b8151fa1 | 173 | } |
8822ebee | 174 | } |
8822ebee | 175 | |
c90ba6c5 | 176 | debugs(16, 4, HERE << "strands kid IDs = "); |
ab2baff3 | 177 | for (Ipc::StrandCoords::const_iterator iter = sc.begin(); iter != sc.end(); ++iter) { |
c90ba6c5 | 178 | debugs(16, 4, HERE << iter->kidId); |
8822ebee | 179 | } |
8822ebee | 180 | |
ab2baff3 | 181 | return sc; |
8822ebee | 182 | } |
f53969cc | 183 |