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