]> git.ipfire.org Git - thirdparty/squid.git/blob - src/clients/Client.h
SourceFormat Enforcement
[thirdparty/squid.git] / src / clients / Client.h
1 /*
2 * Copyright (C) 1996-2019 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_CLIENT_H
10 #define SQUID_SRC_CLIENTS_CLIENT_H
11
12 #include "base/AsyncJob.h"
13 #include "BodyPipe.h"
14 #include "CommCalls.h"
15 #include "FwdState.h"
16 #include "http/forward.h"
17 #include "StoreIOBuffer.h"
18 #if USE_ADAPTATION
19 #include "adaptation/forward.h"
20 #include "adaptation/Initiator.h"
21 #endif
22
23 /**
24 * Client is a common base for classes such as HttpStateData and FtpStateData.
25 * All such classes must be able to consume request bodies from a BodyPipe
26 * or ICAP producer, adapt virgin responses using ICAP, and provide a
27 * consumer with responses.
28 */
29 class Client:
30 #if USE_ADAPTATION
31 public Adaptation::Initiator,
32 public BodyProducer,
33 #endif
34 public BodyConsumer
35 {
36
37 public:
38 Client(FwdState *);
39 virtual ~Client();
40
41 /// \return primary or "request data connection"
42 virtual const Comm::ConnectionPointer & dataConnection() const = 0;
43
44 // BodyConsumer: consume request body or adapted response body.
45 // The implementation just calls the corresponding HTTP or ICAP handle*()
46 // method, depending on the pipe.
47 virtual void noteMoreBodyDataAvailable(BodyPipe::Pointer);
48 virtual void noteBodyProductionEnded(BodyPipe::Pointer);
49 virtual void noteBodyProducerAborted(BodyPipe::Pointer);
50
51 /// read response data from the network
52 virtual void maybeReadVirginBody() = 0;
53
54 /// abnormal transaction termination; reason is for debugging only
55 virtual void abortAll(const char *reason) = 0;
56
57 /// abnormal data transfer termination
58 /// \retval true the transaction will be terminated (abortAll called)
59 /// \retval false the transaction will survive
60 virtual bool abortOnData(const char *reason);
61
62 /// a hack to reach HttpStateData::orignal_request
63 virtual HttpRequestPointer originalRequest();
64
65 #if USE_ADAPTATION
66 // Adaptation::Initiator API: start an ICAP transaction and receive adapted headers.
67 virtual void noteAdaptationAnswer(const Adaptation::Answer &answer);
68 virtual void noteAdaptationAclCheckDone(Adaptation::ServiceGroupPointer group);
69
70 // BodyProducer: provide virgin response body to ICAP.
71 virtual void noteMoreBodySpaceAvailable(BodyPipe::Pointer );
72 virtual void noteBodyConsumerAborted(BodyPipe::Pointer );
73 #endif
74 virtual bool getMoreRequestBody(MemBuf &buf);
75 virtual void processReplyBody() = 0;
76
77 //AsyncJob virtual methods
78 virtual void swanSong();
79 virtual bool doneAll() const;
80
81 public: // should be protected
82 void serverComplete(); /**< call when no server communication is expected */
83
84 private:
85 void serverComplete2(); /**< Continuation of serverComplete */
86 bool completed = false; /**< serverComplete() has been called */
87
88 protected:
89 // kids customize these
90 virtual void haveParsedReplyHeaders(); /**< called when got final headers */
91 virtual void completeForwarding(); /**< default calls fwd->complete() */
92
93 // BodyConsumer for HTTP: consume request body.
94 bool startRequestBodyFlow();
95 void handleMoreRequestBodyAvailable();
96 void handleRequestBodyProductionEnded();
97 virtual void handleRequestBodyProducerAborted() = 0;
98
99 // sending of the request body to the server
100 void sendMoreRequestBody();
101 // has body; kids overwrite to increment I/O stats counters
102 virtual void sentRequestBody(const CommIoCbParams &io) = 0;
103 virtual void doneSendingRequestBody() = 0;
104
105 /// Use this to end communication with the server. The call cancels our
106 /// closure handler and tells FwdState to forget about the connection.
107 virtual void closeServer() = 0;
108 virtual bool doneWithServer() const = 0; /**< did we end communication? */
109 /// whether we may receive more virgin response body bytes
110 virtual bool mayReadVirginReplyBody() const = 0;
111
112 /// Entry-dependent callbacks use this check to quit if the entry went bad
113 bool abortOnBadEntry(const char *abortReason);
114
115 bool blockCaching();
116
117 #if USE_ADAPTATION
118 void startAdaptation(const Adaptation::ServiceGroupPointer &group, HttpRequest *cause);
119 void adaptVirginReplyBody(const char *buf, ssize_t len);
120 void cleanAdaptation();
121 virtual bool doneWithAdaptation() const; /**< did we end ICAP communication? */
122
123 // BodyConsumer for ICAP: consume adapted response body.
124 void handleMoreAdaptedBodyAvailable();
125 void handleAdaptedBodyProductionEnded();
126 void handleAdaptedBodyProducerAborted();
127
128 void handleAdaptedHeader(Http::Message *msg);
129 void handleAdaptationCompleted();
130 void handleAdaptationBlocked(const Adaptation::Answer &answer);
131 void handleAdaptationAborted(bool bypassable = false);
132 bool handledEarlyAdaptationAbort();
133
134 /// called by StoreEntry when it has more buffer space available
135 void resumeBodyStorage();
136 /// called when the entire adapted response body is consumed
137 void endAdaptedBodyConsumption();
138 #endif
139
140 protected:
141 const HttpReply *virginReply() const;
142 HttpReply *virginReply();
143 HttpReply *setVirginReply(HttpReply *r);
144
145 HttpReply *finalReply();
146 HttpReply *setFinalReply(HttpReply *r);
147
148 // Kids use these to stuff data into the response instead of messing with the entry directly
149 void adaptOrFinalizeReply();
150 void addVirginReplyBody(const char *buf, ssize_t len);
151 void storeReplyBody(const char *buf, ssize_t len);
152 /// \deprecated use SBuf I/O API and calcBufferSpaceToReserve() instead
153 size_t replyBodySpace(const MemBuf &readBuf, const size_t minSpace) const;
154 /// determine how much space the buffer needs to reserve
155 size_t calcBufferSpaceToReserve(const size_t space, const size_t wantSpace) const;
156
157 void adjustBodyBytesRead(const int64_t delta);
158
159 // These should be private
160 int64_t currentOffset = 0; /**< Our current offset in the StoreEntry */
161 MemBuf *responseBodyBuffer = nullptr; /**< Data temporarily buffered for ICAP */
162
163 public: // should not be
164 StoreEntry *entry = nullptr;
165 FwdState::Pointer fwd;
166 HttpRequestPointer request;
167
168 protected:
169 BodyPipe::Pointer requestBodySource; /**< to consume request body */
170 AsyncCall::Pointer requestSender; /**< set if we are expecting Comm::Write to call us back */
171
172 #if USE_ADAPTATION
173 BodyPipe::Pointer virginBodyDestination; /**< to provide virgin response body */
174 CbcPointer<Adaptation::Initiate> adaptedHeadSource; /**< to get adapted response headers */
175 BodyPipe::Pointer adaptedBodySource; /**< to consume adated response body */
176
177 bool adaptationAccessCheckPending = false;
178 bool startedAdaptation = false;
179 #endif
180 bool receivedWholeRequestBody = false; ///< handleRequestBodyProductionEnded called
181
182 /// whether we should not be talking to FwdState; XXX: clear fwd instead
183 /// points to a string literal which is used only for debugging
184 const char *doneWithFwd = nullptr;
185
186 private:
187 void sendBodyIsTooLargeError();
188 void maybePurgeOthers();
189
190 HttpReply *theVirginReply = nullptr; /**< reply received from the origin server */
191 HttpReply *theFinalReply = nullptr; /**< adapted reply from ICAP or virgin reply */
192 };
193
194 #endif /* SQUID_SRC_CLIENTS_CLIENT_H */
195