]> git.ipfire.org Git - thirdparty/squid.git/blob - src/mgr/Forwarder.cc
Enable source-formatting tools to collapse multiple whitelines in the source to one.
[thirdparty/squid.git] / src / mgr / Forwarder.cc
1 /*
2 * $Id$
3 *
4 * DEBUG: section 16 Cache Manager API
5 *
6 */
7
8 #include "squid.h"
9 #include "base/AsyncJobCalls.h"
10 #include "base/TextException.h"
11 #include "CommCalls.h"
12 #include "comm/Connection.h"
13 #include "errorpage.h"
14 #include "globals.h"
15 #include "HttpReply.h"
16 #include "HttpRequest.h"
17 #include "ipc/Port.h"
18 #include "mgr/Forwarder.h"
19 #include "mgr/Request.h"
20 #include "SquidTime.h"
21 #include "Store.h"
22
23
24 CBDATA_NAMESPACED_CLASS_INIT(Mgr, Forwarder);
25
26
27 Mgr::Forwarder::Forwarder(const Comm::ConnectionPointer &aConn, const ActionParams &aParams,
28 HttpRequest* aRequest, StoreEntry* anEntry):
29 Ipc::Forwarder(new Request(KidIdentifier, 0, aConn, aParams), 10),
30 httpRequest(aRequest), entry(anEntry), conn(aConn)
31 {
32 debugs(16, 5, HERE << conn);
33 Must(Comm::IsConnOpen(conn));
34 Must(httpRequest != NULL);
35 Must(entry != NULL);
36
37 HTTPMSGLOCK(httpRequest);
38 entry->lock();
39 EBIT_SET(entry->flags, ENTRY_FWD_HDR_WAIT);
40
41 closer = asyncCall(16, 5, "Mgr::Forwarder::noteCommClosed",
42 CommCbMemFunT<Forwarder, CommCloseCbParams>(this, &Forwarder::noteCommClosed));
43 comm_add_close_handler(conn->fd, closer);
44 }
45
46 Mgr::Forwarder::~Forwarder()
47 {
48 debugs(16, 5, HERE);
49 Must(httpRequest != NULL);
50 Must(entry != NULL);
51
52 HTTPMSGUNLOCK(httpRequest);
53 entry->unregisterAbort();
54 entry->unlock();
55 cleanup();
56 }
57
58 /// closes our copy of the client HTTP connection socket
59 void
60 Mgr::Forwarder::cleanup()
61 {
62 if (Comm::IsConnOpen(conn)) {
63 if (closer != NULL) {
64 comm_remove_close_handler(conn->fd, closer);
65 closer = NULL;
66 }
67 conn->close();
68 }
69 conn = NULL;
70 }
71
72 void
73 Mgr::Forwarder::handleError()
74 {
75 debugs(16, DBG_CRITICAL, "ERROR: uri " << entry->url() << " exceeds buffer size");
76 sendError(new ErrorState(ERR_INVALID_URL, HTTP_REQUEST_URI_TOO_LARGE, httpRequest));
77 mustStop("long URI");
78 }
79
80 void
81 Mgr::Forwarder::handleTimeout()
82 {
83 sendError(new ErrorState(ERR_LIFETIME_EXP, HTTP_REQUEST_TIMEOUT, httpRequest));
84 Ipc::Forwarder::handleTimeout();
85 }
86
87 void
88 Mgr::Forwarder::handleException(const std::exception& e)
89 {
90 if (entry != NULL && httpRequest != NULL && Comm::IsConnOpen(conn))
91 sendError(new ErrorState(ERR_INVALID_RESP, HTTP_INTERNAL_SERVER_ERROR, httpRequest));
92 Ipc::Forwarder::handleException(e);
93 }
94
95 /// called when the client socket gets closed by some external force
96 void
97 Mgr::Forwarder::noteCommClosed(const CommCloseCbParams& params)
98 {
99 debugs(16, 5, HERE);
100 conn = NULL; // needed?
101 mustStop("commClosed");
102 }
103
104 /// called when Coordinator starts processing the request
105 void
106 Mgr::Forwarder::handleRemoteAck()
107 {
108 Ipc::Forwarder::handleRemoteAck();
109
110 Must(entry != NULL);
111 EBIT_CLR(entry->flags, ENTRY_FWD_HDR_WAIT);
112 entry->complete();
113 }
114
115 /// send error page
116 void
117 Mgr::Forwarder::sendError(ErrorState *error)
118 {
119 debugs(16, 3, HERE);
120 Must(error != NULL);
121 Must(entry != NULL);
122 Must(httpRequest != NULL);
123
124 EBIT_CLR(entry->flags, ENTRY_FWD_HDR_WAIT);
125 entry->buffer();
126 entry->replaceHttpReply(error->BuildHttpReply());
127 entry->expires = squid_curtime;
128 delete error;
129 entry->flush();
130 entry->complete();
131 }