]> git.ipfire.org Git - thirdparty/squid.git/blame - src/http/Stream.h
SourceFormat Enforcement
[thirdparty/squid.git] / src / http / Stream.h
CommitLineData
8d664cb0 1/*
f6e9a3ee 2 * Copyright (C) 1996-2019 The Squid Software Foundation and contributors
8d664cb0
AJ
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
d3dddfb5
AJ
9#ifndef SQUID_SRC_HTTP_STREAM_H
10#define SQUID_SRC_HTTP_STREAM_H
8d664cb0
AJ
11
12#include "http/forward.h"
13#include "mem/forward.h"
14#include "StoreIOBuffer.h"
b27668ec
EB
15#if USE_DELAY_POOLS
16#include "MessageBucket.h"
17#endif
8d664cb0
AJ
18
19class clientStreamNode;
20class ClientHttpRequest;
21
22namespace Http
23{
24
25/**
26 * The processing context for a single HTTP transaction (stream).
27 *
898d1a09 28 * A stream lifetime extends from directly after a request has been parsed
8d664cb0 29 * off the client connection buffer, until the last byte of both request
898d1a09
AJ
30 * and reply payload (if any) have been written, or it is otherwise
31 * explicitly terminated.
8d664cb0 32 *
898d1a09 33 * Streams self-register with the Http::Server Pipeline being managed by the
8d664cb0
AJ
34 * Server for the connection on which the request was received.
35 *
36 * The socket level management and I/O is done by a Server which owns us.
37 * The scope of this objects control over a socket consists of the data
38 * buffer received from the Server with an initially unknown length.
39 * When that length is known it sets the end boundary of our access to the
40 * buffer.
41 *
42 * The individual processing actions are done by other Jobs which we start.
43 *
898d1a09 44 * When a stream is completed the finished() method needs to be called which
8d664cb0
AJ
45 * will perform all cleanup and deregistration operations. If the reason for
46 * finishing is an error, then notifyIoError() needs to be called prior to
47 * the finished() method.
48 * The caller should follow finished() with a call to ConnStateData::kick()
49 * to resume processing of other transactions or I/O on the connection.
50 *
51 * Alternatively the initiateClose() method can be called to terminate the
898d1a09 52 * whole client connection and all other pending streams.
8d664cb0
AJ
53 *
54 * HTTP/1.x:
55 *
56 * When HTTP/1 pipeline is operating there may be multiple transactions using
898d1a09
AJ
57 * the client connection. Only the back() stream may read from the connection,
58 * and only the front() stream may write to it. A stream which needs to read
8d664cb0
AJ
59 * or write to the connection but does not meet those criteria must be shifted
60 * to the deferred state.
61 *
62 *
d3dddfb5 63 * XXX: If an async call ends the ClientHttpRequest job, Http::Stream
8d664cb0
AJ
64 * (and ConnStateData) may not know about it, leading to segfaults and
65 * assertions. This is difficult to fix
66 * because ClientHttpRequest lacks a good way to communicate its ongoing
d3dddfb5 67 * destruction back to the Http::Stream which pretends to "own" *http.
8d664cb0 68 */
d3dddfb5 69class Stream : public RefCountable
8d664cb0 70{
d3dddfb5 71 MEMPROXY_CLASS(Stream);
8d664cb0
AJ
72
73public:
74 /// construct with HTTP/1.x details
d3dddfb5
AJ
75 Stream(const Comm::ConnectionPointer &aConn, ClientHttpRequest *aReq);
76 ~Stream();
8d664cb0 77
d6fdeb41
AJ
78 /// register this stream with the Server
79 void registerWithConn();
80
6b2b6cfe
CT
81 /// whether it is registered with a Server
82 bool connRegistered() const {return connRegistered_;};
83
d6fdeb41 84 /// whether the reply has started being sent
8d664cb0 85 bool startOfOutput() const;
d6fdeb41
AJ
86
87 /// update stream state after a write, may initiate more I/O
8d664cb0
AJ
88 void writeComplete(size_t size);
89
d6fdeb41
AJ
90 /// get more data to send
91 void pullData();
92
93 /// \return true if the HTTP request is for multiple ranges
94 bool multipartRangeRequest() const;
95
96 int64_t getNextRangeOffset() const;
97 bool canPackMoreRanges() const;
98 size_t lengthToSend(Range<int64_t> const &available) const;
99
100 clientStream_status_t socketState();
101
102 /// send an HTTP reply message headers and maybe some initial payload
103 void sendStartOfMessage(HttpReply *, StoreIOBuffer bodyData);
104 /// send some HTTP reply message payload
105 void sendBody(StoreIOBuffer bodyData);
106 /// update stream state when N bytes are being sent.
107 /// NP: Http1Server bytes actually not sent yet, just packed into a MemBuf ready
108 void noteSentBodyBytes(size_t);
109
110 /// add Range headers (if any) to the given HTTP reply message
111 void buildRangeHeader(HttpReply *);
112
113 clientStreamNode * getTail() const;
114 clientStreamNode * getClientReplyContext() const;
115
116 ConnStateData *getConn() const;
117
118 /// update state to reflect I/O error
119 void noteIoError(const int xerrno);
120
121 /// cleanup when the transaction has finished. may destroy 'this'
122 void finished();
123
124 /// terminate due to a send/write error (may continue reading)
125 void initiateClose(const char *reason);
126
127 void deferRecipientForLater(clientStreamNode *, HttpReply *, StoreIOBuffer receivedData);
128
8d664cb0
AJ
129public: // HTTP/1.x state data
130
131 Comm::ConnectionPointer clientConnection; ///< details about the client connection socket
132 ClientHttpRequest *http; /* we pretend to own that Job */
133 HttpReply *reply;
942b1c39 134 char reqbuf[HTTP_REQBUF_SZ];
8d664cb0 135 struct {
d6fdeb41
AJ
136 unsigned deferred:1; ///< This is a pipelined request waiting for the current object to complete
137 unsigned parsed_ok:1; ///< Was this parsed correctly?
8d664cb0 138 } flags;
d6fdeb41 139
8d664cb0
AJ
140 bool mayUseConnection() const {return mayUseConnection_;}
141
142 void mayUseConnection(bool aBool) {
143 mayUseConnection_ = aBool;
d6fdeb41 144 debugs(33, 3, "This " << this << " marked " << aBool);
8d664cb0
AJ
145 }
146
147 class DeferredParams
148 {
149
150 public:
151 clientStreamNode *node;
152 HttpReply *rep;
153 StoreIOBuffer queuedBuffer;
154 };
155
156 DeferredParams deferredparams;
157 int64_t writtenToSocket;
158
8d664cb0 159private:
d6fdeb41
AJ
160 void prepareReply(HttpReply *);
161 void packChunk(const StoreIOBuffer &bodyData, MemBuf &);
162 void packRange(StoreIOBuffer const &, MemBuf *);
8d664cb0
AJ
163 void doClose();
164
8d664cb0
AJ
165 bool mayUseConnection_; /* This request may use the connection. Don't read anymore requests for now */
166 bool connRegistered_;
b27668ec
EB
167#if USE_DELAY_POOLS
168 MessageBucket::Pointer writeQuotaHandler; ///< response write limiter, if configured
169#endif
8d664cb0
AJ
170};
171
172} // namespace Http
173
d3dddfb5 174#endif /* SQUID_SRC_HTTP_STREAM_H */
abc18020 175