]> git.ipfire.org Git - thirdparty/squid.git/blob - src/mgr/Forwarder.cc
Source Format Enforcement (#763)
[thirdparty/squid.git] / src / mgr / Forwarder.cc
1 /*
2 * Copyright (C) 1996-2021 The Squid Software Foundation and contributors
3 *
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.
7 */
8
9 /* DEBUG: section 16 Cache Manager API */
10
11 #include "squid.h"
12 #include "AccessLogEntry.h"
13 #include "base/AsyncJobCalls.h"
14 #include "base/TextException.h"
15 #include "comm/Connection.h"
16 #include "CommCalls.h"
17 #include "errorpage.h"
18 #include "globals.h"
19 #include "HttpReply.h"
20 #include "HttpRequest.h"
21 #include "ipc/Port.h"
22 #include "mgr/Forwarder.h"
23 #include "mgr/Request.h"
24 #include "SquidTime.h"
25 #include "Store.h"
26
27 CBDATA_NAMESPACED_CLASS_INIT(Mgr, Forwarder);
28
29 Mgr::Forwarder::Forwarder(const Comm::ConnectionPointer &aConn, const ActionParams &aParams,
30 HttpRequest* aRequest, StoreEntry* anEntry, const AccessLogEntryPointer &anAle):
31 // TODO: Add virtual Forwarder::makeRequest() to avoid prematurely creating
32 // this dummy request with a dummy ID that are finalized by Ipc::Forwarder.
33 // Same for Snmp::Forwarder.
34 Ipc::Forwarder(new Request(KidIdentifier, Ipc::RequestId(/*XXX*/), aConn, aParams), 10),
35 httpRequest(aRequest), entry(anEntry), conn(aConn), ale(anAle)
36 {
37 debugs(16, 5, HERE << conn);
38 Must(Comm::IsConnOpen(conn));
39 Must(httpRequest != NULL);
40 Must(entry != NULL);
41
42 HTTPMSGLOCK(httpRequest);
43 entry->lock("Mgr::Forwarder");
44
45 closer = asyncCall(16, 5, "Mgr::Forwarder::noteCommClosed",
46 CommCbMemFunT<Forwarder, CommCloseCbParams>(this, &Forwarder::noteCommClosed));
47 comm_add_close_handler(conn->fd, closer);
48 }
49
50 Mgr::Forwarder::~Forwarder()
51 {
52 SWALLOW_EXCEPTIONS({
53 Must(entry);
54 entry->unlock("Mgr::Forwarder");
55 Must(httpRequest);
56 HTTPMSGUNLOCK(httpRequest);
57 });
58 }
59
60 /// closes our copy of the client HTTP connection socket
61 void
62 Mgr::Forwarder::swanSong()
63 {
64 if (Comm::IsConnOpen(conn)) {
65 if (closer != NULL) {
66 comm_remove_close_handler(conn->fd, closer);
67 closer = NULL;
68 }
69 conn->close();
70 }
71 conn = NULL;
72 Ipc::Forwarder::swanSong();
73 }
74
75 void
76 Mgr::Forwarder::handleError()
77 {
78 debugs(16, DBG_CRITICAL, "ERROR: uri " << entry->url() << " exceeds buffer size");
79 sendError(new ErrorState(ERR_INVALID_URL, Http::scUriTooLong, httpRequest, ale));
80 mustStop("long URI");
81 }
82
83 void
84 Mgr::Forwarder::handleTimeout()
85 {
86 sendError(new ErrorState(ERR_LIFETIME_EXP, Http::scRequestTimeout, httpRequest, ale));
87 Ipc::Forwarder::handleTimeout();
88 }
89
90 void
91 Mgr::Forwarder::handleException(const std::exception &e)
92 {
93 if (entry != NULL && httpRequest != NULL && Comm::IsConnOpen(conn))
94 sendError(new ErrorState(ERR_INVALID_RESP, Http::scInternalServerError, httpRequest, ale));
95 Ipc::Forwarder::handleException(e);
96 }
97
98 /// called when the client socket gets closed by some external force
99 void
100 Mgr::Forwarder::noteCommClosed(const CommCloseCbParams &)
101 {
102 debugs(16, 5, HERE);
103 conn = NULL; // needed?
104 mustStop("commClosed");
105 }
106
107 /// send error page
108 void
109 Mgr::Forwarder::sendError(ErrorState *error)
110 {
111 debugs(16, 3, HERE);
112 Must(error != NULL);
113 Must(entry != NULL);
114 Must(httpRequest != NULL);
115
116 entry->buffer();
117 entry->replaceHttpReply(error->BuildHttpReply());
118 entry->expires = squid_curtime;
119 delete error;
120 entry->flush();
121 entry->complete();
122 }
123