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