1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/netwerk/protocol/http/SpdyStream3.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,260 @@ 1.4 +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#ifndef mozilla_net_SpdyStream3_h 1.10 +#define mozilla_net_SpdyStream3_h 1.11 + 1.12 +#include "nsAHttpTransaction.h" 1.13 +#include "zlib.h" 1.14 + 1.15 +class nsISocketTransport; 1.16 + 1.17 +namespace mozilla { namespace net { 1.18 + 1.19 +class SpdySession3; 1.20 +class SpdyPushedStream3; 1.21 + 1.22 +class SpdyStream3 : public nsAHttpSegmentReader 1.23 + , public nsAHttpSegmentWriter 1.24 +{ 1.25 +public: 1.26 + NS_DECL_NSAHTTPSEGMENTREADER 1.27 + NS_DECL_NSAHTTPSEGMENTWRITER 1.28 + 1.29 + SpdyStream3(nsAHttpTransaction *, SpdySession3 *, int32_t); 1.30 + 1.31 + uint32_t StreamID() { return mStreamID; } 1.32 + SpdyPushedStream3 *PushSource() { return mPushSource; } 1.33 + 1.34 + virtual nsresult ReadSegments(nsAHttpSegmentReader *, uint32_t, uint32_t *); 1.35 + virtual nsresult WriteSegments(nsAHttpSegmentWriter *, uint32_t, uint32_t *); 1.36 + virtual bool DeferCleanupOnSuccess() { return false; } 1.37 + 1.38 + const nsAFlatCString &Origin() const { return mOrigin; } 1.39 + 1.40 + bool RequestBlockedOnRead() 1.41 + { 1.42 + return static_cast<bool>(mRequestBlockedOnRead); 1.43 + } 1.44 + 1.45 + // returns false if called more than once 1.46 + bool GetFullyOpen() {return mFullyOpen;} 1.47 + void SetFullyOpen() 1.48 + { 1.49 + MOZ_ASSERT(!mFullyOpen); 1.50 + mFullyOpen = 1; 1.51 + } 1.52 + 1.53 + bool HasRegisteredID() { return mStreamID != 0; } 1.54 + 1.55 + nsAHttpTransaction *Transaction() { return mTransaction; } 1.56 + virtual nsILoadGroupConnectionInfo *LoadGroupConnectionInfo() 1.57 + { 1.58 + return mTransaction ? mTransaction->LoadGroupConnectionInfo() : nullptr; 1.59 + } 1.60 + 1.61 + void Close(nsresult reason); 1.62 + 1.63 + void SetRecvdFin(bool aStatus) { mRecvdFin = aStatus ? 1 : 0; } 1.64 + bool RecvdFin() { return mRecvdFin; } 1.65 + 1.66 + void SetRecvdData(bool aStatus) { mReceivedData = aStatus ? 1 : 0; } 1.67 + bool RecvdData() { return mReceivedData; } 1.68 + 1.69 + void UpdateTransportSendEvents(uint32_t count); 1.70 + void UpdateTransportReadEvents(uint32_t count); 1.71 + 1.72 + // The zlib header compression dictionary defined by SPDY. 1.73 + static const unsigned char kDictionary[1423]; 1.74 + 1.75 + nsresult Uncompress(z_stream *, char *, uint32_t); 1.76 + nsresult ConvertHeaders(nsACString &); 1.77 + 1.78 + void UpdateRemoteWindow(int32_t delta); 1.79 + int64_t RemoteWindow() { return mRemoteWindow; } 1.80 + 1.81 + void DecrementLocalWindow(uint32_t delta) { 1.82 + mLocalWindow -= delta; 1.83 + mLocalUnacked += delta; 1.84 + } 1.85 + 1.86 + void IncrementLocalWindow(uint32_t delta) { 1.87 + mLocalWindow += delta; 1.88 + mLocalUnacked -= delta; 1.89 + } 1.90 + 1.91 + uint64_t LocalUnAcked() { return mLocalUnacked; } 1.92 + int64_t LocalWindow() { return mLocalWindow; } 1.93 + 1.94 + bool BlockedOnRwin() { return mBlockedOnRwin; } 1.95 + 1.96 + // A pull stream has an implicit sink, a pushed stream has a sink 1.97 + // once it is matched to a pull stream. 1.98 + virtual bool HasSink() { return true; } 1.99 + 1.100 + virtual ~SpdyStream3(); 1.101 + 1.102 +protected: 1.103 + nsresult FindHeader(nsCString, nsDependentCSubstring &); 1.104 + 1.105 + static void CreatePushHashKey(const nsCString &scheme, 1.106 + const nsCString &hostHeader, 1.107 + uint64_t serial, 1.108 + const nsCSubstring &pathInfo, 1.109 + nsCString &outOrigin, 1.110 + nsCString &outKey); 1.111 + 1.112 + enum stateType { 1.113 + GENERATING_SYN_STREAM, 1.114 + GENERATING_REQUEST_BODY, 1.115 + SENDING_REQUEST_BODY, 1.116 + SENDING_FIN_STREAM, 1.117 + UPSTREAM_COMPLETE 1.118 + }; 1.119 + 1.120 + uint32_t mStreamID; 1.121 + 1.122 + // The session that this stream is a subset of 1.123 + SpdySession3 *mSession; 1.124 + 1.125 + nsCString mOrigin; 1.126 + 1.127 + // Each stream goes from syn_stream to upstream_complete, perhaps 1.128 + // looping on multiple instances of generating_request_body and 1.129 + // sending_request_body for each SPDY chunk in the upload. 1.130 + enum stateType mUpstreamState; 1.131 + 1.132 + // Flag is set when all http request headers have been read and ID is stable 1.133 + uint32_t mSynFrameComplete : 1; 1.134 + 1.135 + // Flag is set when a FIN has been placed on a data or syn packet 1.136 + // (i.e after the client has closed) 1.137 + uint32_t mSentFinOnData : 1; 1.138 + 1.139 + void ChangeState(enum stateType); 1.140 + 1.141 +private: 1.142 + friend class nsAutoPtr<SpdyStream3>; 1.143 + 1.144 + static PLDHashOperator hdrHashEnumerate(const nsACString &, 1.145 + nsAutoPtr<nsCString> &, 1.146 + void *); 1.147 + 1.148 + nsresult ParseHttpRequestHeaders(const char *, uint32_t, uint32_t *); 1.149 + void AdjustInitialWindow(); 1.150 + nsresult TransmitFrame(const char *, uint32_t *, bool forceCommitment); 1.151 + void GenerateDataFrameHeader(uint32_t, bool); 1.152 + 1.153 + void CompressToFrame(const nsACString &); 1.154 + void CompressToFrame(const nsACString *); 1.155 + void CompressToFrame(const char *, uint32_t); 1.156 + void CompressToFrame(uint32_t); 1.157 + void CompressFlushFrame(); 1.158 + void ExecuteCompress(uint32_t); 1.159 + 1.160 + // The underlying HTTP transaction. This pointer is used as the key 1.161 + // in the SpdySession3 mStreamTransactionHash so it is important to 1.162 + // keep a reference to it as long as this stream is a member of that hash. 1.163 + // (i.e. don't change it or release it after it is set in the ctor). 1.164 + nsRefPtr<nsAHttpTransaction> mTransaction; 1.165 + 1.166 + // The underlying socket transport object is needed to propogate some events 1.167 + nsISocketTransport *mSocketTransport; 1.168 + 1.169 + // These are temporary state variables to hold the argument to 1.170 + // Read/WriteSegments so it can be accessed by On(read/write)segment 1.171 + // further up the stack. 1.172 + nsAHttpSegmentReader *mSegmentReader; 1.173 + nsAHttpSegmentWriter *mSegmentWriter; 1.174 + 1.175 + // The quanta upstream data frames are chopped into 1.176 + uint32_t mChunkSize; 1.177 + 1.178 + // Flag is set when the HTTP processor has more data to send 1.179 + // but has blocked in doing so. 1.180 + uint32_t mRequestBlockedOnRead : 1; 1.181 + 1.182 + // Flag is set after the response frame bearing the fin bit has 1.183 + // been processed. (i.e. after the server has closed). 1.184 + uint32_t mRecvdFin : 1; 1.185 + 1.186 + // Flag is set after syn reply received 1.187 + uint32_t mFullyOpen : 1; 1.188 + 1.189 + // Flag is set after the WAITING_FOR Transport event has been generated 1.190 + uint32_t mSentWaitingFor : 1; 1.191 + 1.192 + // Flag is set after 1st DATA frame has been passed to stream, after 1.193 + // which additional HEADERS data is invalid 1.194 + uint32_t mReceivedData : 1; 1.195 + 1.196 + // Flag is set after TCP send autotuning has been disabled 1.197 + uint32_t mSetTCPSocketBuffer : 1; 1.198 + 1.199 + // The InlineFrame and associated data is used for composing control 1.200 + // frames and data frame headers. 1.201 + nsAutoArrayPtr<uint8_t> mTxInlineFrame; 1.202 + uint32_t mTxInlineFrameSize; 1.203 + uint32_t mTxInlineFrameUsed; 1.204 + 1.205 + // mTxStreamFrameSize tracks the progress of 1.206 + // transmitting a request body data frame. The data frame itself 1.207 + // is never copied into the spdy layer. 1.208 + uint32_t mTxStreamFrameSize; 1.209 + 1.210 + // Compression context and buffer for request header compression. 1.211 + // This is a copy of SpdySession3::mUpstreamZlib because it needs 1.212 + // to remain the same in all streams of a session. 1.213 + z_stream *mZlib; 1.214 + nsCString mFlatHttpRequestHeaders; 1.215 + 1.216 + // These are used for decompressing downstream spdy response headers 1.217 + uint32_t mDecompressBufferSize; 1.218 + uint32_t mDecompressBufferUsed; 1.219 + uint32_t mDecompressedBytes; 1.220 + nsAutoArrayPtr<char> mDecompressBuffer; 1.221 + 1.222 + // Track the content-length of a request body so that we can 1.223 + // place the fin flag on the last data packet instead of waiting 1.224 + // for a stream closed indication. Relying on stream close results 1.225 + // in an extra 0-length runt packet and seems to have some interop 1.226 + // problems with the google servers. 1.227 + int64_t mRequestBodyLenRemaining; 1.228 + 1.229 + // based on nsISupportsPriority definitions 1.230 + int32_t mPriority; 1.231 + 1.232 + // mLocalWindow, mRemoteWindow, and mLocalUnacked are for flow control. 1.233 + // *window are signed because they race conditions in asynchronous SETTINGS 1.234 + // messages can force them temporarily negative. 1.235 + 1.236 + // LocalWindow is how much data the server will send without getting a 1.237 + // window update 1.238 + int64_t mLocalWindow; 1.239 + 1.240 + // RemoteWindow is how much data the client is allowed to send without 1.241 + // getting a window update 1.242 + int64_t mRemoteWindow; 1.243 + 1.244 + // LocalUnacked is the number of bytes received by the client but not 1.245 + // yet reflected in a window update. Sending that update will increment 1.246 + // LocalWindow 1.247 + uint64_t mLocalUnacked; 1.248 + 1.249 + // True when sending is suspended becuase the remote flow control window is 1.250 + // <= 0 1.251 + bool mBlockedOnRwin; 1.252 + 1.253 + // For Progress Events 1.254 + uint64_t mTotalSent; 1.255 + uint64_t mTotalRead; 1.256 + 1.257 + // For SpdyPush 1.258 + SpdyPushedStream3 *mPushSource; 1.259 +}; 1.260 + 1.261 +}} // namespace mozilla::net 1.262 + 1.263 +#endif // mozilla_net_SpdyStream3_h