2 * Copyright (C) 1996-2019 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_CLIENT_H
10 #define SQUID_SRC_CLIENTS_CLIENT_H
12 #include "base/AsyncJob.h"
14 #include "CommCalls.h"
16 #include "http/forward.h"
17 #include "StoreIOBuffer.h"
19 #include "adaptation/forward.h"
20 #include "adaptation/Initiator.h"
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.
31 public Adaptation::Initiator
,
41 /// \return primary or "request data connection"
42 virtual const Comm::ConnectionPointer
& dataConnection() const = 0;
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
);
51 /// read response data from the network
52 virtual void maybeReadVirginBody() = 0;
54 /// abnormal transaction termination; reason is for debugging only
55 virtual void abortAll(const char *reason
) = 0;
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
);
62 /// a hack to reach HttpStateData::orignal_request
63 virtual HttpRequestPointer
originalRequest();
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
);
70 // BodyProducer: provide virgin response body to ICAP.
71 virtual void noteMoreBodySpaceAvailable(BodyPipe::Pointer
);
72 virtual void noteBodyConsumerAborted(BodyPipe::Pointer
);
74 virtual bool getMoreRequestBody(MemBuf
&buf
);
75 virtual void processReplyBody() = 0;
77 //AsyncJob virtual methods
78 virtual void swanSong();
79 virtual bool doneAll() const;
81 public: // should be protected
82 void serverComplete(); /**< call when no server communication is expected */
85 void serverComplete2(); /**< Continuation of serverComplete */
86 bool completed
= false; /**< serverComplete() has been called */
89 // kids customize these
90 virtual void haveParsedReplyHeaders(); /**< called when got final headers */
91 virtual void completeForwarding(); /**< default calls fwd->complete() */
93 // BodyConsumer for HTTP: consume request body.
94 bool startRequestBodyFlow();
95 void handleMoreRequestBodyAvailable();
96 void handleRequestBodyProductionEnded();
97 virtual void handleRequestBodyProducerAborted() = 0;
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;
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;
112 /// Entry-dependent callbacks use this check to quit if the entry went bad
113 bool abortOnBadEntry(const char *abortReason
);
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? */
123 // BodyConsumer for ICAP: consume adapted response body.
124 void handleMoreAdaptedBodyAvailable();
125 void handleAdaptedBodyProductionEnded();
126 void handleAdaptedBodyProducerAborted();
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();
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();
141 const HttpReply
*virginReply() const;
142 HttpReply
*virginReply();
143 HttpReply
*setVirginReply(HttpReply
*r
);
145 HttpReply
*finalReply();
146 HttpReply
*setFinalReply(HttpReply
*r
);
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;
157 void adjustBodyBytesRead(const int64_t delta
);
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 */
163 public: // should not be
164 StoreEntry
*entry
= nullptr;
165 FwdState::Pointer fwd
;
166 HttpRequestPointer request
;
169 BodyPipe::Pointer requestBodySource
; /**< to consume request body */
170 AsyncCall::Pointer requestSender
; /**< set if we are expecting Comm::Write to call us back */
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 */
177 bool adaptationAccessCheckPending
= false;
178 bool startedAdaptation
= false;
180 bool receivedWholeRequestBody
= false; ///< handleRequestBodyProductionEnded called
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;
187 void sendBodyIsTooLargeError();
188 void maybePurgeOthers();
190 HttpReply
*theVirginReply
= nullptr; /**< reply received from the origin server */
191 HttpReply
*theFinalReply
= nullptr; /**< adapted reply from ICAP or virgin reply */
194 #endif /* SQUID_SRC_CLIENTS_CLIENT_H */