netwerk/protocol/http/SpdyStream31.h

branch
TOR_BUG_9701
changeset 11
deefc01c0e14
equal deleted inserted replaced
-1:000000000000 0:cad7b057cf2b
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5
6 #ifndef mozilla_net_SpdyStream31_h
7 #define mozilla_net_SpdyStream31_h
8
9 #include "mozilla/Attributes.h"
10 #include "nsAHttpTransaction.h"
11
12 namespace mozilla { namespace net {
13
14 class SpdyStream31 : public nsAHttpSegmentReader
15 , public nsAHttpSegmentWriter
16 {
17 public:
18 NS_DECL_NSAHTTPSEGMENTREADER
19 NS_DECL_NSAHTTPSEGMENTWRITER
20
21 SpdyStream31(nsAHttpTransaction *, SpdySession31 *, int32_t);
22
23 uint32_t StreamID() { return mStreamID; }
24 SpdyPushedStream31 *PushSource() { return mPushSource; }
25
26 virtual nsresult ReadSegments(nsAHttpSegmentReader *, uint32_t, uint32_t *);
27 virtual nsresult WriteSegments(nsAHttpSegmentWriter *, uint32_t, uint32_t *);
28 virtual bool DeferCleanupOnSuccess() { return false; }
29
30 const nsAFlatCString &Origin() const { return mOrigin; }
31
32 bool RequestBlockedOnRead()
33 {
34 return static_cast<bool>(mRequestBlockedOnRead);
35 }
36
37 // returns false if called more than once
38 bool GetFullyOpen() {return mFullyOpen;}
39 void SetFullyOpen()
40 {
41 MOZ_ASSERT(!mFullyOpen);
42 mFullyOpen = 1;
43 }
44
45 bool HasRegisteredID() { return mStreamID != 0; }
46
47 nsAHttpTransaction *Transaction() { return mTransaction; }
48 virtual nsILoadGroupConnectionInfo *LoadGroupConnectionInfo()
49 {
50 return mTransaction ? mTransaction->LoadGroupConnectionInfo() : nullptr;
51 }
52
53 void Close(nsresult reason);
54
55 void SetRecvdFin(bool aStatus) { mRecvdFin = aStatus ? 1 : 0; }
56 bool RecvdFin() { return mRecvdFin; }
57
58 void SetRecvdData(bool aStatus) { mReceivedData = aStatus ? 1 : 0; }
59 bool RecvdData() { return mReceivedData; }
60
61 void UpdateTransportSendEvents(uint32_t count);
62 void UpdateTransportReadEvents(uint32_t count);
63
64 // The zlib header compression dictionary defined by SPDY.
65 static const unsigned char kDictionary[1423];
66
67 nsresult Uncompress(z_stream *, char *, uint32_t);
68 nsresult ConvertHeaders(nsACString &);
69
70 void UpdateRemoteWindow(int32_t delta);
71 int64_t RemoteWindow() { return mRemoteWindow; }
72
73 void DecrementLocalWindow(uint32_t delta) {
74 mLocalWindow -= delta;
75 mLocalUnacked += delta;
76 }
77
78 void IncrementLocalWindow(uint32_t delta) {
79 mLocalWindow += delta;
80 mLocalUnacked -= delta;
81 }
82
83 uint64_t LocalUnAcked() { return mLocalUnacked; }
84 int64_t LocalWindow() { return mLocalWindow; }
85
86 bool BlockedOnRwin() { return mBlockedOnRwin; }
87
88 // A pull stream has an implicit sink, a pushed stream has a sink
89 // once it is matched to a pull stream.
90 virtual bool HasSink() { return true; }
91
92 virtual ~SpdyStream31();
93
94 protected:
95 nsresult FindHeader(nsCString, nsDependentCSubstring &);
96
97 static void CreatePushHashKey(const nsCString &scheme,
98 const nsCString &hostHeader,
99 uint64_t serial,
100 const nsCSubstring &pathInfo,
101 nsCString &outOrigin,
102 nsCString &outKey);
103
104 enum stateType {
105 GENERATING_SYN_STREAM,
106 GENERATING_REQUEST_BODY,
107 SENDING_REQUEST_BODY,
108 SENDING_FIN_STREAM,
109 UPSTREAM_COMPLETE
110 };
111
112 uint32_t mStreamID;
113
114 // The session that this stream is a subset of
115 SpdySession31 *mSession;
116
117 nsCString mOrigin;
118
119 // Each stream goes from syn_stream to upstream_complete, perhaps
120 // looping on multiple instances of generating_request_body and
121 // sending_request_body for each SPDY chunk in the upload.
122 enum stateType mUpstreamState;
123
124 // Flag is set when all http request headers have been read and ID is stable
125 uint32_t mSynFrameComplete : 1;
126
127 // Flag is set when a FIN has been placed on a data or syn packet
128 // (i.e after the client has closed)
129 uint32_t mSentFinOnData : 1;
130
131 void ChangeState(enum stateType);
132
133 private:
134 friend class nsAutoPtr<SpdyStream31>;
135
136 static PLDHashOperator hdrHashEnumerate(const nsACString &,
137 nsAutoPtr<nsCString> &,
138 void *);
139
140 nsresult ParseHttpRequestHeaders(const char *, uint32_t, uint32_t *);
141 void AdjustInitialWindow();
142 nsresult TransmitFrame(const char *, uint32_t *, bool forceCommitment);
143 void GenerateDataFrameHeader(uint32_t, bool);
144
145 void CompressToFrame(const nsACString &);
146 void CompressToFrame(const nsACString *);
147 void CompressToFrame(const char *, uint32_t);
148 void CompressToFrame(uint32_t);
149 void CompressFlushFrame();
150 void ExecuteCompress(uint32_t);
151
152 // The underlying HTTP transaction. This pointer is used as the key
153 // in the SpdySession31 mStreamTransactionHash so it is important to
154 // keep a reference to it as long as this stream is a member of that hash.
155 // (i.e. don't change it or release it after it is set in the ctor).
156 nsRefPtr<nsAHttpTransaction> mTransaction;
157
158 // The underlying socket transport object is needed to propogate some events
159 nsISocketTransport *mSocketTransport;
160
161 // These are temporary state variables to hold the argument to
162 // Read/WriteSegments so it can be accessed by On(read/write)segment
163 // further up the stack.
164 nsAHttpSegmentReader *mSegmentReader;
165 nsAHttpSegmentWriter *mSegmentWriter;
166
167 // The quanta upstream data frames are chopped into
168 uint32_t mChunkSize;
169
170 // Flag is set when the HTTP processor has more data to send
171 // but has blocked in doing so.
172 uint32_t mRequestBlockedOnRead : 1;
173
174 // Flag is set after the response frame bearing the fin bit has
175 // been processed. (i.e. after the server has closed).
176 uint32_t mRecvdFin : 1;
177
178 // Flag is set after syn reply received
179 uint32_t mFullyOpen : 1;
180
181 // Flag is set after the WAITING_FOR Transport event has been generated
182 uint32_t mSentWaitingFor : 1;
183
184 // Flag is set after 1st DATA frame has been passed to stream, after
185 // which additional HEADERS data is invalid
186 uint32_t mReceivedData : 1;
187
188 // Flag is set after TCP send autotuning has been disabled
189 uint32_t mSetTCPSocketBuffer : 1;
190
191 // The InlineFrame and associated data is used for composing control
192 // frames and data frame headers.
193 nsAutoArrayPtr<uint8_t> mTxInlineFrame;
194 uint32_t mTxInlineFrameSize;
195 uint32_t mTxInlineFrameUsed;
196
197 // mTxStreamFrameSize tracks the progress of
198 // transmitting a request body data frame. The data frame itself
199 // is never copied into the spdy layer.
200 uint32_t mTxStreamFrameSize;
201
202 // Compression context and buffer for request header compression.
203 // This is a copy of SpdySession31::mUpstreamZlib because it needs
204 // to remain the same in all streams of a session.
205 z_stream *mZlib;
206 nsCString mFlatHttpRequestHeaders;
207
208 // These are used for decompressing downstream spdy response headers
209 uint32_t mDecompressBufferSize;
210 uint32_t mDecompressBufferUsed;
211 uint32_t mDecompressedBytes;
212 nsAutoArrayPtr<char> mDecompressBuffer;
213
214 // Track the content-length of a request body so that we can
215 // place the fin flag on the last data packet instead of waiting
216 // for a stream closed indication. Relying on stream close results
217 // in an extra 0-length runt packet and seems to have some interop
218 // problems with the google servers.
219 int64_t mRequestBodyLenRemaining;
220
221 // based on nsISupportsPriority definitions
222 int32_t mPriority;
223
224 // mLocalWindow, mRemoteWindow, and mLocalUnacked are for flow control.
225 // *window are signed because the race conditions in asynchronous SETTINGS
226 // messages can force them temporarily negative.
227
228 // LocalWindow is how much data the server will send without getting a
229 // window update
230 int64_t mLocalWindow;
231
232 // RemoteWindow is how much data the client is allowed to send without
233 // getting a window update
234 int64_t mRemoteWindow;
235
236 // LocalUnacked is the number of bytes received by the client but not
237 // yet reflected in a window update. Sending that update will increment
238 // LocalWindow
239 uint64_t mLocalUnacked;
240
241 // True when sending is suspended becuase the remote flow control window is
242 // <= 0
243 bool mBlockedOnRwin;
244
245 // For Progress Events
246 uint64_t mTotalSent;
247 uint64_t mTotalRead;
248
249 // For SpdyPush
250 SpdyPushedStream31 *mPushSource;
251 };
252
253 }} // namespace mozilla::net
254
255 #endif // mozilla_net_SpdyStream31_h

mercurial