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