]> git.ipfire.org Git - thirdparty/squid.git/blame - src/mgr/Inquirer.cc
SourceFormat Enforcement
[thirdparty/squid.git] / src / mgr / Inquirer.cc
CommitLineData
8822ebee 1/*
bbc27441 2 * Copyright (C) 1996-2014 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
31CBDATA_NAMESPACED_CLASS_INIT(Mgr, Inquirer);
32
51ea0904 33Mgr::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
49void
51ea0904 50Mgr::Inquirer::cleanup()
d9fc6862 51{
1b76e6c1 52 if (Comm::IsConnOpen(conn)) {
8822ebee 53 removeCloseHandler();
1b76e6c1 54 conn->close();
8822ebee
AR
55 }
56}
57
58void
59Mgr::Inquirer::removeCloseHandler()
60{
61 if (closer != NULL) {
1b76e6c1 62 comm_remove_close_handler(conn->fd, closer);
8822ebee
AR
63 closer = NULL;
64 }
65}
66
67void
68Mgr::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
AJ
75#if HAVE_UNIQUE_PTR
76 std::unique_ptr<MemBuf> replyBuf;
77#else
8c4f6de5 78 std::auto_ptr<MemBuf> replyBuf;
a203dec7 79#endif
8c4f6de5
CT
80 if (strands.empty()) {
81 LOCAL_ARRAY(char, url, MAX_URL);
82 snprintf(url, MAX_URL, "%s", aggrAction->command().params.httpUri.termedBuf());
83 HttpRequest *req = HttpRequest::CreateFromUrl(url);
955394ce 84 ErrorState err(ERR_INVALID_URL, Http::scNotFound, req);
a203dec7 85#if HAVE_UNIQUE_PTR
913524f0 86 std::unique_ptr<HttpReply> reply(err.BuildHttpReply());
a203dec7 87#else
913524f0 88 std::auto_ptr<HttpReply> reply(err.BuildHttpReply());
a203dec7 89#endif
8c4f6de5 90 replyBuf.reset(reply->pack());
10c40d99 91 } else {
a203dec7
AJ
92#if HAVE_UNIQUE_PTR
93 std::unique_ptr<HttpReply> reply(new HttpReply);
94#else
8c4f6de5 95 std::auto_ptr<HttpReply> reply(new HttpReply);
a203dec7 96#endif
955394ce 97 reply->setHeaders(Http::scOkay, NULL, "text/plain", -1, squid_curtime, squid_curtime);
8c4f6de5
CT
98 reply->header.putStr(HDR_CONNECTION, "close"); // until we chunk response
99 replyBuf.reset(reply->pack());
100 }
8822ebee 101 writer = asyncCall(16, 5, "Mgr::Inquirer::noteWroteHeader",
d9fc6862 102 CommCbMemFunT<Inquirer, CommIoCbParams>(this, &Inquirer::noteWroteHeader));
1b76e6c1 103 Comm::Write(conn, replyBuf.get(), writer);
8822ebee
AR
104}
105
106/// called when we wrote the response header
107void
108Mgr::Inquirer::noteWroteHeader(const CommIoCbParams& params)
109{
110 debugs(16, 5, HERE);
111 writer = NULL;
c8407295 112 Must(params.flag == Comm::OK);
1b76e6c1 113 Must(params.conn.getRaw() == conn.getRaw());
8822ebee
AR
114 Must(params.size != 0);
115 // start inquiries at the initial pos
116 inquire();
117}
118
8822ebee 119/// called when the HTTP client or some external force closed our socket
8822ebee 120void
8822ebee 121Mgr::Inquirer::noteCommClosed(const CommCloseCbParams& params)
8822ebee 122{
8822ebee 123 debugs(16, 5, HERE);
1b76e6c1
AJ
124 Must(!Comm::IsConnOpen(conn) && params.conn.getRaw() == conn.getRaw());
125 conn = NULL;
8822ebee 126 mustStop("commClosed");
8822ebee
AR
127}
128
51ea0904
CT
129bool
130Mgr::Inquirer::aggregate(Ipc::Response::Pointer aResponse)
8822ebee 131{
51ea0904 132 Mgr::Response& response = static_cast<Response&>(*aResponse);
8822ebee
AR
133 if (response.hasAction())
134 aggrAction->add(response.getAction());
51ea0904 135 return true;
8822ebee
AR
136}
137
138void
51ea0904 139Mgr::Inquirer::sendResponse()
8822ebee 140{
b8151fa1 141 if (!strands.empty() && aggrAction->aggregatable()) {
8822ebee 142 removeCloseHandler();
1b76e6c1
AJ
143 AsyncJob::Start(new ActionWriter(aggrAction, conn));
144 conn = NULL; // should not close because we passed it to ActionWriter
8822ebee 145 }
8822ebee
AR
146}
147
148bool
149Mgr::Inquirer::doneAll() const
150{
51ea0904 151 return !writer && Ipc::Inquirer::doneAll();
8822ebee 152}
b8151fa1
CT
153
154Ipc::StrandCoords
155Mgr::Inquirer::applyQueryParams(const Ipc::StrandCoords& aStrands, const QueryParams& aParams)
156{
ab2baff3 157 Ipc::StrandCoords sc;
b8151fa1 158
22b5be72
CT
159 QueryParam::Pointer processesParam = aParams.get("processes");
160 QueryParam::Pointer workersParam = aParams.get("workers");
b8151fa1
CT
161
162 if (processesParam == NULL || workersParam == NULL) {
163 if (processesParam != NULL) {
164 IntParam* param = dynamic_cast<IntParam*>(processesParam.getRaw());
165 if (param != NULL && param->type == QueryParam::ptInt) {
166 const std::vector<int>& processes = param->value();
167 for (Ipc::StrandCoords::const_iterator iter = aStrands.begin();
10c40d99 168 iter != aStrands.end(); ++iter) {
b8151fa1 169 if (std::find(processes.begin(), processes.end(), iter->kidId) != processes.end())
ab2baff3 170 sc.push_back(*iter);
b8151fa1
CT
171 }
172 }
173 } else if (workersParam != NULL) {
174 IntParam* param = dynamic_cast<IntParam*>(workersParam.getRaw());
175 if (param != NULL && param->type == QueryParam::ptInt) {
176 const std::vector<int>& workers = param->value();
10c40d99 177 for (int i = 0; i < (int)aStrands.size(); ++i) {
b8151fa1 178 if (std::find(workers.begin(), workers.end(), i + 1) != workers.end())
ab2baff3 179 sc.push_back(aStrands[i]);
b8151fa1
CT
180 }
181 }
182 } else {
ab2baff3 183 sc = aStrands;
b8151fa1 184 }
8822ebee 185 }
8822ebee 186
c90ba6c5 187 debugs(16, 4, HERE << "strands kid IDs = ");
ab2baff3 188 for (Ipc::StrandCoords::const_iterator iter = sc.begin(); iter != sc.end(); ++iter) {
c90ba6c5 189 debugs(16, 4, HERE << iter->kidId);
8822ebee 190 }
8822ebee 191
ab2baff3 192 return sc;
8822ebee 193}
f53969cc 194