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