Thu, 15 Jan 2015 21:03:48 +0100
Integrate friendly tips from Tor colleagues to make (or not) 4.5 alpha 3;
This includes removal of overloaded (but unused) methods, and addition of
a overlooked call to DataStruct::SetData(nsISupports, uint32_t, bool.)
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/. */
6 #ifndef mozilla_net_SpdyStream31_h
7 #define mozilla_net_SpdyStream31_h
9 #include "mozilla/Attributes.h"
10 #include "nsAHttpTransaction.h"
12 namespace mozilla { namespace net {
14 class SpdyStream31 : public nsAHttpSegmentReader
15 , public nsAHttpSegmentWriter
16 {
17 public:
18 NS_DECL_NSAHTTPSEGMENTREADER
19 NS_DECL_NSAHTTPSEGMENTWRITER
21 SpdyStream31(nsAHttpTransaction *, SpdySession31 *, int32_t);
23 uint32_t StreamID() { return mStreamID; }
24 SpdyPushedStream31 *PushSource() { return mPushSource; }
26 virtual nsresult ReadSegments(nsAHttpSegmentReader *, uint32_t, uint32_t *);
27 virtual nsresult WriteSegments(nsAHttpSegmentWriter *, uint32_t, uint32_t *);
28 virtual bool DeferCleanupOnSuccess() { return false; }
30 const nsAFlatCString &Origin() const { return mOrigin; }
32 bool RequestBlockedOnRead()
33 {
34 return static_cast<bool>(mRequestBlockedOnRead);
35 }
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 }
45 bool HasRegisteredID() { return mStreamID != 0; }
47 nsAHttpTransaction *Transaction() { return mTransaction; }
48 virtual nsILoadGroupConnectionInfo *LoadGroupConnectionInfo()
49 {
50 return mTransaction ? mTransaction->LoadGroupConnectionInfo() : nullptr;
51 }
53 void Close(nsresult reason);
55 void SetRecvdFin(bool aStatus) { mRecvdFin = aStatus ? 1 : 0; }
56 bool RecvdFin() { return mRecvdFin; }
58 void SetRecvdData(bool aStatus) { mReceivedData = aStatus ? 1 : 0; }
59 bool RecvdData() { return mReceivedData; }
61 void UpdateTransportSendEvents(uint32_t count);
62 void UpdateTransportReadEvents(uint32_t count);
64 // The zlib header compression dictionary defined by SPDY.
65 static const unsigned char kDictionary[1423];
67 nsresult Uncompress(z_stream *, char *, uint32_t);
68 nsresult ConvertHeaders(nsACString &);
70 void UpdateRemoteWindow(int32_t delta);
71 int64_t RemoteWindow() { return mRemoteWindow; }
73 void DecrementLocalWindow(uint32_t delta) {
74 mLocalWindow -= delta;
75 mLocalUnacked += delta;
76 }
78 void IncrementLocalWindow(uint32_t delta) {
79 mLocalWindow += delta;
80 mLocalUnacked -= delta;
81 }
83 uint64_t LocalUnAcked() { return mLocalUnacked; }
84 int64_t LocalWindow() { return mLocalWindow; }
86 bool BlockedOnRwin() { return mBlockedOnRwin; }
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; }
92 virtual ~SpdyStream31();
94 protected:
95 nsresult FindHeader(nsCString, nsDependentCSubstring &);
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);
104 enum stateType {
105 GENERATING_SYN_STREAM,
106 GENERATING_REQUEST_BODY,
107 SENDING_REQUEST_BODY,
108 SENDING_FIN_STREAM,
109 UPSTREAM_COMPLETE
110 };
112 uint32_t mStreamID;
114 // The session that this stream is a subset of
115 SpdySession31 *mSession;
117 nsCString mOrigin;
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;
124 // Flag is set when all http request headers have been read and ID is stable
125 uint32_t mSynFrameComplete : 1;
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;
131 void ChangeState(enum stateType);
133 private:
134 friend class nsAutoPtr<SpdyStream31>;
136 static PLDHashOperator hdrHashEnumerate(const nsACString &,
137 nsAutoPtr<nsCString> &,
138 void *);
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);
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);
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;
158 // The underlying socket transport object is needed to propogate some events
159 nsISocketTransport *mSocketTransport;
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;
167 // The quanta upstream data frames are chopped into
168 uint32_t mChunkSize;
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;
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;
178 // Flag is set after syn reply received
179 uint32_t mFullyOpen : 1;
181 // Flag is set after the WAITING_FOR Transport event has been generated
182 uint32_t mSentWaitingFor : 1;
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;
188 // Flag is set after TCP send autotuning has been disabled
189 uint32_t mSetTCPSocketBuffer : 1;
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;
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;
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;
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;
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;
221 // based on nsISupportsPriority definitions
222 int32_t mPriority;
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.
228 // LocalWindow is how much data the server will send without getting a
229 // window update
230 int64_t mLocalWindow;
232 // RemoteWindow is how much data the client is allowed to send without
233 // getting a window update
234 int64_t mRemoteWindow;
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;
241 // True when sending is suspended becuase the remote flow control window is
242 // <= 0
243 bool mBlockedOnRwin;
245 // For Progress Events
246 uint64_t mTotalSent;
247 uint64_t mTotalRead;
249 // For SpdyPush
250 SpdyPushedStream31 *mPushSource;
251 };
253 }} // namespace mozilla::net
255 #endif // mozilla_net_SpdyStream31_h