]> git.ipfire.org Git - thirdparty/squid.git/blob - src/mgr/Forwarder.cc
Author: Leonid Evdokimov <leon@darkk.net.ru>
[thirdparty/squid.git] / src / mgr / Forwarder.cc
1 /*
2 * $Id$
3 *
4 * DEBUG: section 16 Cache Manager API
5 *
6 */
7
8 #include "config.h"
9 #include "base/AsyncJobCalls.h"
10 #include "base/TextException.h"
11 #include "CommCalls.h"
12 #include "errorpage.h"
13 #include "HttpReply.h"
14 #include "HttpRequest.h"
15 #include "ipc/Port.h"
16 #include "mgr/Forwarder.h"
17 #include "mgr/Request.h"
18 #include "SquidTime.h"
19 #include "Store.h"
20
21
22 CBDATA_NAMESPACED_CLASS_INIT(Mgr, Forwarder);
23
24
25 Mgr::Forwarder::Forwarder(int aFd, const ActionParams &aParams,
26 HttpRequest* aRequest, StoreEntry* anEntry):
27 Ipc::Forwarder(new Request(KidIdentifier, 0, aFd, aParams), 10),
28 httpRequest(aRequest), entry(anEntry), fd(aFd)
29 {
30 debugs(16, 5, HERE << "FD " << fd);
31 Must(fd >= 0);
32 Must(httpRequest != NULL);
33 Must(entry != NULL);
34
35 HTTPMSGLOCK(httpRequest);
36 entry->lock();
37 EBIT_SET(entry->flags, ENTRY_FWD_HDR_WAIT);
38
39 closer = asyncCall(16, 5, "Mgr::Forwarder::noteCommClosed",
40 CommCbMemFunT<Forwarder, CommCloseCbParams>(this, &Forwarder::noteCommClosed));
41 comm_add_close_handler(fd, closer);
42 }
43
44 Mgr::Forwarder::~Forwarder()
45 {
46 debugs(16, 5, HERE);
47 Must(httpRequest != NULL);
48 Must(entry != NULL);
49
50 HTTPMSGUNLOCK(httpRequest);
51 entry->unregisterAbort();
52 entry->unlock();
53 cleanup();
54 }
55
56 /// closes our copy of the client HTTP connection socket
57 void
58 Mgr::Forwarder::cleanup()
59 {
60 if (fd >= 0) {
61 if (closer != NULL) {
62 comm_remove_close_handler(fd, closer);
63 closer = NULL;
64 }
65 comm_close(fd);
66 fd = -1;
67 }
68 }
69
70 void
71 Mgr::Forwarder::handleError()
72 {
73 debugs(16, DBG_CRITICAL, "ERROR: uri " << entry->url() << " exceeds buffer size");
74 sendError(errorCon(ERR_INVALID_URL, HTTP_REQUEST_URI_TOO_LARGE, httpRequest));
75 mustStop("long URI");
76 }
77
78 void
79 Mgr::Forwarder::handleTimeout()
80 {
81 sendError(errorCon(ERR_LIFETIME_EXP, HTTP_REQUEST_TIMEOUT, httpRequest));
82 Ipc::Forwarder::handleTimeout();
83 }
84
85 void
86 Mgr::Forwarder::handleException(const std::exception& e)
87 {
88 if (entry != NULL && httpRequest != NULL && fd >= 0)
89 sendError(errorCon(ERR_INVALID_RESP, HTTP_INTERNAL_SERVER_ERROR, httpRequest));
90 Ipc::Forwarder::handleException(e);
91 }
92
93 /// called when the client socket gets closed by some external force
94 void
95 Mgr::Forwarder::noteCommClosed(const CommCloseCbParams& params)
96 {
97 debugs(16, 5, HERE);
98 Must(fd == params.fd);
99 fd = -1;
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 errorStateFree(error);
128 entry->flush();
129 entry->complete();
130 }