2 * Copyright (C) 1996-2021 The Squid Software Foundation and contributors
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.
9 #ifndef SQUID_SRC_CLIENTS_HTTP_TUNNELER_H
10 #define SQUID_SRC_CLIENTS_HTTP_TUNNELER_H
12 #include "base/AsyncCbdataCalls.h"
13 #include "base/AsyncJob.h"
14 #include "clients/forward.h"
15 #include "clients/HttpTunnelerAnswer.h"
16 #include "CommCalls.h"
20 #include "http/forward.h"
24 typedef RefCount
<AccessLogEntry
> AccessLogEntryPointer
;
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
34 CBDATA_CLASS(Tunneler
);
37 /// Callback dialer API to allow Tunneler to set the answer.
38 template <class Initiator
>
39 class CbDialer
: public CallDialer
, public Http::TunnelerAnswer
42 // initiator method to receive our answer
43 typedef void (Initiator::*Method
)(Http::TunnelerAnswer
&);
45 CbDialer(Method method
, Initiator
*initiator
): initiator_(initiator
), method_(method
) {}
46 virtual ~CbDialer() = default;
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) << ')';
55 CbcPointer
<Initiator
> initiator_
; ///< object to deliver the answer to
56 Method method_
; ///< initiator_ method to call with the answer
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;
65 void setDelayId(DelayId delay_id
) {delayId
= delay_id
;}
68 /// hack: whether the connection requires fwdPconnPool->noteUses()
75 virtual bool doneAll() const;
76 virtual void swanSong();
77 virtual const char *status() const;
79 void handleConnectionClosure(const CommCloseCbParams
&);
80 void watchForClosures();
81 void handleTimeout(const CommTimeoutCbParams
&);
82 void startReadingResponse();
84 void handleWrittenRequest(const CommIoCbParams
&);
85 void handleReadyRead(const CommIoCbParams
&);
87 void handleResponse(const bool eof
);
88 void bailOnResponseError(const char *error
, HttpReply
*);
90 /// sends the given error to the initiator
91 void bailWith(ErrorState
*);
93 /// sends the ready-to-use tunnel to the initiator
96 /// a bailWith(), sendSuccess() helper: sends results to the initiator
99 /// a bailWith(), sendSuccess() helper: stops monitoring the connection
102 TunnelerAnswer
&answer();
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
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
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
;
123 const time_t startTime
; ///< when the tunnel establishment started
125 bool requestWritten
; ///< whether we successfully wrote the request
126 bool tunnelEstablished
; ///< whether we got a 200 OK response
131 #endif /* SQUID_SRC_CLIENTS_HTTP_TUNNELER_H */