]> git.ipfire.org Git - thirdparty/squid.git/blob - src/clients/HttpTunneler.h
Source Format Enforcement (#763)
[thirdparty/squid.git] / src / clients / HttpTunneler.h
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 #ifndef SQUID_SRC_CLIENTS_HTTP_TUNNELER_H
10 #define SQUID_SRC_CLIENTS_HTTP_TUNNELER_H
11
12 #include "base/AsyncCbdataCalls.h"
13 #include "base/AsyncJob.h"
14 #include "clients/forward.h"
15 #include "clients/HttpTunnelerAnswer.h"
16 #include "CommCalls.h"
17 #if USE_DELAY_POOLS
18 #include "DelayId.h"
19 #endif
20 #include "http/forward.h"
21
22 class ErrorState;
23 class AccessLogEntry;
24 typedef RefCount<AccessLogEntry> AccessLogEntryPointer;
25
26 namespace Http
27 {
28
29 /// Negotiates an HTTP CONNECT tunnel through a forward proxy using a given
30 /// (open and, if needed, encrypted) TCP connection to that proxy. Owns the
31 /// connection during these negotiations. The caller receives TunnelerAnswer.
32 class Tunneler: virtual public AsyncJob
33 {
34 CBDATA_CLASS(Tunneler);
35
36 public:
37 /// Callback dialer API to allow Tunneler to set the answer.
38 template <class Initiator>
39 class CbDialer: public CallDialer, public Http::TunnelerAnswer
40 {
41 public:
42 // initiator method to receive our answer
43 typedef void (Initiator::*Method)(Http::TunnelerAnswer &);
44
45 CbDialer(Method method, Initiator *initiator): initiator_(initiator), method_(method) {}
46 virtual ~CbDialer() = default;
47
48 /* CallDialer API */
49 bool canDial(AsyncCall &) { return initiator_.valid(); }
50 void dial(AsyncCall &) {((*initiator_).*method_)(*this); }
51 virtual void print(std::ostream &os) const override {
52 os << '(' << static_cast<const Http::TunnelerAnswer&>(*this) << ')';
53 }
54 private:
55 CbcPointer<Initiator> initiator_; ///< object to deliver the answer to
56 Method method_; ///< initiator_ method to call with the answer
57 };
58
59 public:
60 Tunneler(const Comm::ConnectionPointer &conn, const HttpRequestPointer &req, AsyncCall::Pointer &aCallback, time_t timeout, const AccessLogEntryPointer &alp);
61 Tunneler(const Tunneler &) = delete;
62 Tunneler &operator =(const Tunneler &) = delete;
63
64 #if USE_DELAY_POOLS
65 void setDelayId(DelayId delay_id) {delayId = delay_id;}
66 #endif
67
68 /// hack: whether the connection requires fwdPconnPool->noteUses()
69 bool noteFwdPconnUse;
70
71 protected:
72 /* AsyncJob API */
73 virtual ~Tunneler();
74 virtual void start();
75 virtual bool doneAll() const;
76 virtual void swanSong();
77 virtual const char *status() const;
78
79 void handleConnectionClosure(const CommCloseCbParams&);
80 void watchForClosures();
81 void handleTimeout(const CommTimeoutCbParams &);
82 void startReadingResponse();
83 void writeRequest();
84 void handleWrittenRequest(const CommIoCbParams&);
85 void handleReadyRead(const CommIoCbParams&);
86 void readMore();
87 void handleResponse(const bool eof);
88 void bailOnResponseError(const char *error, HttpReply *);
89
90 /// sends the given error to the initiator
91 void bailWith(ErrorState*);
92
93 /// sends the ready-to-use tunnel to the initiator
94 void sendSuccess();
95
96 /// a bailWith(), sendSuccess() helper: sends results to the initiator
97 void callBack();
98
99 /// a bailWith(), sendSuccess() helper: stops monitoring the connection
100 void disconnect();
101
102 TunnelerAnswer &answer();
103
104 private:
105 AsyncCall::Pointer writer; ///< called when the request has been written
106 AsyncCall::Pointer reader; ///< called when the response should be read
107 AsyncCall::Pointer closer; ///< called when the connection is being closed
108
109 Comm::ConnectionPointer connection; ///< TCP connection to the cache_peer
110 HttpRequestPointer request; ///< peer connection trigger or cause
111 AsyncCall::Pointer callback; ///< we call this with the results
112 SBuf url; ///< request-target for the CONNECT request
113 time_t lifetimeLimit; ///< do not run longer than this
114 AccessLogEntryPointer al; ///< info for the future access.log entry
115 #if USE_DELAY_POOLS
116 DelayId delayId;
117 #endif
118
119 SBuf readBuf; ///< either unparsed response or post-response bytes
120 /// Parser being used at present to parse the HTTP peer response.
121 Http1::ResponseParserPointer hp;
122
123 const time_t startTime; ///< when the tunnel establishment started
124
125 bool requestWritten; ///< whether we successfully wrote the request
126 bool tunnelEstablished; ///< whether we got a 200 OK response
127 };
128
129 } // namespace Http
130
131 #endif /* SQUID_SRC_CLIENTS_HTTP_TUNNELER_H */
132