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