netwerk/protocol/http/Http2Session.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/netwerk/protocol/http/Http2Session.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,449 @@
     1.4 +/* -*- Mode: C++; tab-width: 2; 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_Http2Session_h
    1.10 +#define mozilla_net_Http2Session_h
    1.11 +
    1.12 +// HTTP/2
    1.13 +
    1.14 +#include "ASpdySession.h"
    1.15 +#include "mozilla/Attributes.h"
    1.16 +#include "nsAHttpConnection.h"
    1.17 +#include "nsClassHashtable.h"
    1.18 +#include "nsDataHashtable.h"
    1.19 +#include "nsDeque.h"
    1.20 +#include "nsHashKeys.h"
    1.21 +
    1.22 +#include "Http2Compression.h"
    1.23 +
    1.24 +class nsISocketTransport;
    1.25 +
    1.26 +namespace mozilla {
    1.27 +namespace net {
    1.28 +
    1.29 +class Http2PushedStream;
    1.30 +class Http2Stream;
    1.31 +
    1.32 +class Http2Session MOZ_FINAL : public ASpdySession
    1.33 +  , public nsAHttpConnection
    1.34 +  , public nsAHttpSegmentReader
    1.35 +  , public nsAHttpSegmentWriter
    1.36 +{
    1.37 +public:
    1.38 +  NS_DECL_ISUPPORTS
    1.39 +    NS_DECL_NSAHTTPTRANSACTION
    1.40 +    NS_DECL_NSAHTTPCONNECTION(mConnection)
    1.41 +    NS_DECL_NSAHTTPSEGMENTREADER
    1.42 +    NS_DECL_NSAHTTPSEGMENTWRITER
    1.43 +
    1.44 +   Http2Session(nsAHttpTransaction *, nsISocketTransport *, int32_t);
    1.45 +  ~Http2Session();
    1.46 +
    1.47 +  bool AddStream(nsAHttpTransaction *, int32_t);
    1.48 +  bool CanReuse() { return !mShouldGoAway && !mClosed; }
    1.49 +  bool RoomForMoreStreams();
    1.50 +
    1.51 +  // When the connection is active this is called up to once every 1 second
    1.52 +  // return the interval (in seconds) that the connection next wants to
    1.53 +  // have this invoked. It might happen sooner depending on the needs of
    1.54 +  // other connections.
    1.55 +  uint32_t  ReadTimeoutTick(PRIntervalTime now);
    1.56 +
    1.57 +  // Idle time represents time since "goodput".. e.g. a data or header frame
    1.58 +  PRIntervalTime IdleTime();
    1.59 +
    1.60 +  // Registering with a newID of 0 means pick the next available odd ID
    1.61 +  uint32_t RegisterStreamID(Http2Stream *, uint32_t aNewID = 0);
    1.62 +
    1.63 +/*
    1.64 +  HTTP/2 framing
    1.65 +
    1.66 +  0                   1                   2                   3
    1.67 +  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
    1.68 +  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    1.69 +  |         Length (16)           |   Type (8)    |   Flags (8)   |
    1.70 +  +-+-------------+---------------+-------------------------------+
    1.71 +  |R|                 Stream Identifier (31)                      |
    1.72 +  +-+-------------------------------------------------------------+
    1.73 +  |                     Frame Data (0...)                       ...
    1.74 +  +---------------------------------------------------------------+
    1.75 +*/
    1.76 +
    1.77 +  enum frameType {
    1.78 +    FRAME_TYPE_DATA = 0,
    1.79 +    FRAME_TYPE_HEADERS = 1,
    1.80 +    FRAME_TYPE_PRIORITY = 2,
    1.81 +    FRAME_TYPE_RST_STREAM = 3,
    1.82 +    FRAME_TYPE_SETTINGS = 4,
    1.83 +    FRAME_TYPE_PUSH_PROMISE = 5,
    1.84 +    FRAME_TYPE_PING = 6,
    1.85 +    FRAME_TYPE_GOAWAY = 7,
    1.86 +    FRAME_TYPE_WINDOW_UPDATE = 8,
    1.87 +    FRAME_TYPE_CONTINUATION = 9,
    1.88 +    FRAME_TYPE_LAST = 10
    1.89 +  };
    1.90 +
    1.91 +  // NO_ERROR is a macro defined on windows, so we'll name the HTTP2 goaway
    1.92 +  // code NO_ERROR to be NO_HTTP_ERROR
    1.93 +  enum errorType {
    1.94 +    NO_HTTP_ERROR = 0,
    1.95 +    PROTOCOL_ERROR = 1,
    1.96 +    INTERNAL_ERROR = 2,
    1.97 +    FLOW_CONTROL_ERROR = 3,
    1.98 +    SETTINGS_TIMEOUT_ERROR = 4,
    1.99 +    STREAM_CLOSED_ERROR = 5,
   1.100 +    FRAME_SIZE_ERROR = 6,
   1.101 +    REFUSED_STREAM_ERROR = 7,
   1.102 +    CANCEL_ERROR = 8,
   1.103 +    COMPRESSION_ERROR = 9,
   1.104 +    CONNECT_ERROR = 10,
   1.105 +    ENHANCE_YOUR_CALM = 11,
   1.106 +    INADEQUATE_SECURITY = 12
   1.107 +  };
   1.108 +
   1.109 +  // These are frame flags. If they, or other undefined flags, are
   1.110 +  // used on frames other than the comments indicate they MUST be ignored.
   1.111 +  const static uint8_t kFlag_END_STREAM = 0x01; // data, headers
   1.112 +  const static uint8_t kFlag_END_HEADERS = 0x04; // headers, continuation
   1.113 +  const static uint8_t kFlag_PRIORITY = 0x08; //headers
   1.114 +  const static uint8_t kFlag_END_PUSH_PROMISE = 0x04; // push promise
   1.115 +  const static uint8_t kFlag_ACK = 0x01; // ping and settings
   1.116 +  const static uint8_t kFlag_END_SEGMENT = 0x02; // data
   1.117 +  const static uint8_t kFlag_PAD_LOW = 0x10; // data, headers, continuation
   1.118 +  const static uint8_t kFlag_PAD_HIGH = 0x20; // data, headers, continuation
   1.119 +
   1.120 +  enum {
   1.121 +    SETTINGS_TYPE_HEADER_TABLE_SIZE = 1, // compression table size
   1.122 +    SETTINGS_TYPE_ENABLE_PUSH = 2,     // can be used to disable push
   1.123 +    SETTINGS_TYPE_MAX_CONCURRENT = 3,  // streams recvr allowed to initiate
   1.124 +    SETTINGS_TYPE_INITIAL_WINDOW = 4  // bytes for flow control default
   1.125 +  };
   1.126 +
   1.127 +  // This should be big enough to hold all of your control packets,
   1.128 +  // but if it needs to grow for huge headers it can do so dynamically.
   1.129 +  const static uint32_t kDefaultBufferSize = 2048;
   1.130 +
   1.131 +  // kDefaultQueueSize must be >= other queue size constants
   1.132 +  const static uint32_t kDefaultQueueSize =  32768;
   1.133 +  const static uint32_t kQueueMinimumCleanup = 24576;
   1.134 +  const static uint32_t kQueueTailRoom    =  4096;
   1.135 +  const static uint32_t kQueueReserved    =  1024;
   1.136 +
   1.137 +  const static uint32_t kDefaultMaxConcurrent = 100;
   1.138 +  const static uint32_t kMaxStreamID = 0x7800000;
   1.139 +
   1.140 +  // This is a sentinel for a deleted stream. It is not a valid
   1.141 +  // 31 bit stream ID.
   1.142 +  const static uint32_t kDeadStreamID = 0xffffdead;
   1.143 +
   1.144 +  // below the emergency threshold of local window we ack every received
   1.145 +  // byte. Above that we coalesce bytes into the MinimumToAck size.
   1.146 +  const static int32_t  kEmergencyWindowThreshold = 256 * 1024;
   1.147 +  const static uint32_t kMinimumToAck = 4 * 1024 * 1024;
   1.148 +
   1.149 +  // The default rwin is 64KB - 1 unless updated by a settings frame
   1.150 +  const static uint32_t kDefaultRwin = 65535;
   1.151 +
   1.152 +  // Frames with HTTP semantics are limited to 2^14 - 1 bytes of length in
   1.153 +  // order to preserve responsiveness
   1.154 +  const static uint32_t kMaxFrameData = 16383;
   1.155 +
   1.156 +  static nsresult RecvHeaders(Http2Session *);
   1.157 +  static nsresult RecvPriority(Http2Session *);
   1.158 +  static nsresult RecvRstStream(Http2Session *);
   1.159 +  static nsresult RecvSettings(Http2Session *);
   1.160 +  static nsresult RecvPushPromise(Http2Session *);
   1.161 +  static nsresult RecvPing(Http2Session *);
   1.162 +  static nsresult RecvGoAway(Http2Session *);
   1.163 +  static nsresult RecvWindowUpdate(Http2Session *);
   1.164 +  static nsresult RecvContinuation(Http2Session *);
   1.165 +
   1.166 +  template<typename T>
   1.167 +  static void EnsureBuffer(nsAutoArrayPtr<T> &,
   1.168 +                           uint32_t, uint32_t, uint32_t &);
   1.169 +  char       *EnsureOutputBuffer(uint32_t needed);
   1.170 +
   1.171 +  template<typename charType>
   1.172 +  void CreateFrameHeader(charType dest, uint16_t frameLength,
   1.173 +                         uint8_t frameType, uint8_t frameFlags,
   1.174 +                         uint32_t streamID);
   1.175 +
   1.176 +  // For writing the data stream to LOG4
   1.177 +  static void LogIO(Http2Session *, Http2Stream *, const char *,
   1.178 +                    const char *, uint32_t);
   1.179 +
   1.180 +  // an overload of nsAHttpConnection
   1.181 +  void TransactionHasDataToWrite(nsAHttpTransaction *);
   1.182 +
   1.183 +  // a similar version for Http2Stream
   1.184 +  void TransactionHasDataToWrite(Http2Stream *);
   1.185 +
   1.186 +  // an overload of nsAHttpSegementReader
   1.187 +  virtual nsresult CommitToSegmentSize(uint32_t size, bool forceCommitment);
   1.188 +  nsresult BufferOutput(const char *, uint32_t, uint32_t *);
   1.189 +  void     FlushOutputQueue();
   1.190 +  uint32_t AmountOfOutputBuffered() { return mOutputQueueUsed - mOutputQueueSent; }
   1.191 +
   1.192 +  uint32_t GetServerInitialStreamWindow() { return mServerInitialStreamWindow; }
   1.193 +
   1.194 +  void ConnectPushedStream(Http2Stream *stream);
   1.195 +  void MaybeDecrementConcurrent(Http2Stream *stream);
   1.196 +
   1.197 +  nsresult ConfirmTLSProfile();
   1.198 +
   1.199 +  uint64_t Serial() { return mSerial; }
   1.200 +
   1.201 +  void PrintDiagnostics (nsCString &log);
   1.202 +
   1.203 +  // Streams need access to these
   1.204 +  uint32_t SendingChunkSize() { return mSendingChunkSize; }
   1.205 +  uint32_t PushAllowance() { return mPushAllowance; }
   1.206 +  Http2Compressor *Compressor() { return &mCompressor; }
   1.207 +  nsISocketTransport *SocketTransport() { return mSocketTransport; }
   1.208 +  int64_t ServerSessionWindow() { return mServerSessionWindow; }
   1.209 +  void DecrementServerSessionWindow (uint32_t bytes) { mServerSessionWindow -= bytes; }
   1.210 +
   1.211 +private:
   1.212 +
   1.213 +  // These internal states do not correspond to the states of the HTTP/2 specification
   1.214 +  enum internalStateType {
   1.215 +    BUFFERING_OPENING_SETTINGS,
   1.216 +    BUFFERING_FRAME_HEADER,
   1.217 +    BUFFERING_CONTROL_FRAME,
   1.218 +    PROCESSING_DATA_FRAME_PADDING_CONTROL,
   1.219 +    PROCESSING_DATA_FRAME,
   1.220 +    DISCARDING_DATA_FRAME_PADDING,
   1.221 +    DISCARDING_DATA_FRAME,
   1.222 +    PROCESSING_COMPLETE_HEADERS,
   1.223 +    PROCESSING_CONTROL_RST_STREAM
   1.224 +  };
   1.225 +
   1.226 +  static const uint8_t kMagicHello[24];
   1.227 +
   1.228 +  nsresult    ResponseHeadersComplete();
   1.229 +  uint32_t    GetWriteQueueSize();
   1.230 +  void        ChangeDownstreamState(enum internalStateType);
   1.231 +  void        ResetDownstreamState();
   1.232 +  nsresult    ReadyToProcessDataFrame(enum internalStateType);
   1.233 +  nsresult    UncompressAndDiscard();
   1.234 +  void        GeneratePing(bool);
   1.235 +  void        GenerateSettingsAck();
   1.236 +  void        GeneratePriority(uint32_t, uint32_t);
   1.237 +  void        GenerateRstStream(uint32_t, uint32_t);
   1.238 +  void        GenerateGoAway(uint32_t);
   1.239 +  void        CleanupStream(Http2Stream *, nsresult, errorType);
   1.240 +  void        CloseStream(Http2Stream *, nsresult);
   1.241 +  void        SendHello();
   1.242 +  void        RemoveStreamFromQueues(Http2Stream *);
   1.243 +  nsresult    ParsePadding(uint8_t &, uint16_t &);
   1.244 +
   1.245 +  void        SetWriteCallbacks();
   1.246 +  void        RealignOutputQueue();
   1.247 +
   1.248 +  bool        RoomForMoreConcurrent();
   1.249 +  void        ActivateStream(Http2Stream *);
   1.250 +  void        ProcessPending();
   1.251 +  nsresult    SetInputFrameDataStream(uint32_t);
   1.252 +  bool        VerifyStream(Http2Stream *, uint32_t);
   1.253 +  void        SetNeedsCleanup();
   1.254 +
   1.255 +  void        UpdateLocalRwin(Http2Stream *stream, uint32_t bytes);
   1.256 +  void        UpdateLocalStreamWindow(Http2Stream *stream, uint32_t bytes);
   1.257 +  void        UpdateLocalSessionWindow(uint32_t bytes);
   1.258 +
   1.259 +  // a wrapper for all calls to the nshttpconnection level segment writer. Used
   1.260 +  // to track network I/O for timeout purposes
   1.261 +  nsresult   NetworkRead(nsAHttpSegmentWriter *, char *, uint32_t, uint32_t *);
   1.262 +
   1.263 +  static PLDHashOperator ShutdownEnumerator(nsAHttpTransaction *,
   1.264 +                                            nsAutoPtr<Http2Stream> &,
   1.265 +                                            void *);
   1.266 +
   1.267 +  static PLDHashOperator GoAwayEnumerator(nsAHttpTransaction *,
   1.268 +                                          nsAutoPtr<Http2Stream> &,
   1.269 +                                          void *);
   1.270 +
   1.271 +  static PLDHashOperator UpdateServerRwinEnumerator(nsAHttpTransaction *,
   1.272 +                                                    nsAutoPtr<Http2Stream> &,
   1.273 +                                                    void *);
   1.274 +
   1.275 +  static PLDHashOperator RestartBlockedOnRwinEnumerator(nsAHttpTransaction *,
   1.276 +                                                        nsAutoPtr<Http2Stream> &,
   1.277 +                                                        void *);
   1.278 +
   1.279 +  // This is intended to be nsHttpConnectionMgr:nsConnectionHandle taken
   1.280 +  // from the first transaction on this session. That object contains the
   1.281 +  // pointer to the real network-level nsHttpConnection object.
   1.282 +  nsRefPtr<nsAHttpConnection> mConnection;
   1.283 +
   1.284 +  // The underlying socket transport object is needed to propogate some events
   1.285 +  nsISocketTransport         *mSocketTransport;
   1.286 +
   1.287 +  // These are temporary state variables to hold the argument to
   1.288 +  // Read/WriteSegments so it can be accessed by On(read/write)segment
   1.289 +  // further up the stack.
   1.290 +  nsAHttpSegmentReader       *mSegmentReader;
   1.291 +  nsAHttpSegmentWriter       *mSegmentWriter;
   1.292 +
   1.293 +  uint32_t          mSendingChunkSize;        /* the transmission chunk size */
   1.294 +  uint32_t          mNextStreamID;            /* 24 bits */
   1.295 +  uint32_t          mConcurrentHighWater;     /* max parallelism on session */
   1.296 +  uint32_t          mPushAllowance;           /* rwin for unmatched pushes */
   1.297 +
   1.298 +  internalStateType mDownstreamState; /* in frame, between frames, etc..  */
   1.299 +
   1.300 +  // Maintain 2 indexes - one by stream ID, one by transaction pointer.
   1.301 +  // There are also several lists of streams: ready to write, queued due to
   1.302 +  // max parallelism, streams that need to force a read for push, and the full
   1.303 +  // set of pushed streams.
   1.304 +  // The objects are not ref counted - they get destroyed
   1.305 +  // by the nsClassHashtable implementation when they are removed from
   1.306 +  // the transaction hash.
   1.307 +  nsDataHashtable<nsUint32HashKey, Http2Stream *>     mStreamIDHash;
   1.308 +  nsClassHashtable<nsPtrHashKey<nsAHttpTransaction>,
   1.309 +    Http2Stream>                                      mStreamTransactionHash;
   1.310 +
   1.311 +  nsDeque                                             mReadyForWrite;
   1.312 +  nsDeque                                             mQueuedStreams;
   1.313 +  nsDeque                                             mReadyForRead;
   1.314 +  nsTArray<Http2PushedStream *>                       mPushedStreams;
   1.315 +
   1.316 +  // Compression contexts for header transport.
   1.317 +  // HTTP/2 compresses only HTTP headers and does not reset the context in between
   1.318 +  // frames. Even data that is not associated with a stream (e.g invalid
   1.319 +  // stream ID) is passed through these contexts to keep the compression
   1.320 +  // context correct.
   1.321 +  Http2Compressor     mCompressor;
   1.322 +  Http2Decompressor   mDecompressor;
   1.323 +  nsCString           mDecompressBuffer;
   1.324 +
   1.325 +  // mInputFrameBuffer is used to store received control packets and the 8 bytes
   1.326 +  // of header on data packets
   1.327 +  uint32_t             mInputFrameBufferSize; // buffer allocation
   1.328 +  uint32_t             mInputFrameBufferUsed; // amt of allocation used
   1.329 +  nsAutoArrayPtr<char> mInputFrameBuffer;
   1.330 +
   1.331 +  // mInputFrameDataSize/Read are used for tracking the amount of data consumed
   1.332 +  // in a frame after the 8 byte header. Control frames are always fully buffered
   1.333 +  // and the fixed 8 byte leading header is at mInputFrameBuffer + 0, the first
   1.334 +  // data byte (i.e. the first settings/goaway/etc.. specific byte) is at
   1.335 +  // mInputFrameBuffer + 8
   1.336 +  // The frame size is mInputFrameDataSize + the constant 8 byte header
   1.337 +  uint32_t             mInputFrameDataSize;
   1.338 +  uint32_t             mInputFrameDataRead;
   1.339 +  bool                 mInputFrameFinal; // This frame was marked FIN
   1.340 +  uint8_t              mInputFrameType;
   1.341 +  uint8_t              mInputFrameFlags;
   1.342 +  uint32_t             mInputFrameID;
   1.343 +  uint16_t             mPaddingLength;
   1.344 +
   1.345 +  // When a frame has been received that is addressed to a particular stream
   1.346 +  // (e.g. a data frame after the stream-id has been decoded), this points
   1.347 +  // to the stream.
   1.348 +  Http2Stream          *mInputFrameDataStream;
   1.349 +
   1.350 +  // mNeedsCleanup is a state variable to defer cleanup of a closed stream
   1.351 +  // If needed, It is set in session::OnWriteSegments() and acted on and
   1.352 +  // cleared when the stack returns to session::WriteSegments(). The stream
   1.353 +  // cannot be destroyed directly out of OnWriteSegments because
   1.354 +  // stream::writeSegments() is on the stack at that time.
   1.355 +  Http2Stream          *mNeedsCleanup;
   1.356 +
   1.357 +  // This reason code in the last processed RESET frame
   1.358 +  uint32_t             mDownstreamRstReason;
   1.359 +
   1.360 +  // When HEADERS/PROMISE are chained together, this is the expected ID of the next
   1.361 +  // recvd frame which must be the same type
   1.362 +  uint32_t             mExpectedHeaderID;
   1.363 +  uint32_t             mExpectedPushPromiseID;
   1.364 +  uint32_t             mContinuedPromiseStream;
   1.365 +
   1.366 +  // for the conversion of downstream http headers into http/2 formatted headers
   1.367 +  // The data here does not persist between frames
   1.368 +  nsCString            mFlatHTTPResponseHeaders;
   1.369 +  uint32_t             mFlatHTTPResponseHeadersOut;
   1.370 +
   1.371 +  // when set, the session will go away when it reaches 0 streams. This flag
   1.372 +  // is set when: the stream IDs are running out (at either the client or the
   1.373 +  // server), when DontReuse() is called, a RST that is not specific to a
   1.374 +  // particular stream is received, a GOAWAY frame has been received from
   1.375 +  // the server.
   1.376 +  bool                 mShouldGoAway;
   1.377 +
   1.378 +  // the session has received a nsAHttpTransaction::Close()  call
   1.379 +  bool                 mClosed;
   1.380 +
   1.381 +  // the session received a GoAway frame with a valid GoAwayID
   1.382 +  bool                 mCleanShutdown;
   1.383 +
   1.384 +  // The TLS comlpiance checks are not done in the ctor beacuse of bad
   1.385 +  // exception handling - so we do them at IO time and cache the result
   1.386 +  bool                 mTLSProfileConfirmed;
   1.387 +
   1.388 +  // A specifc reason code for the eventual GoAway frame. If set to NO_HTTP_ERROR
   1.389 +  // only NO_HTTP_ERROR, PROTOCOL_ERROR, or INTERNAL_ERROR will be sent.
   1.390 +  errorType            mGoAwayReason;
   1.391 +
   1.392 +  // If a GoAway message was received this is the ID of the last valid
   1.393 +  // stream. 0 otherwise. (0 is never a valid stream id.)
   1.394 +  uint32_t             mGoAwayID;
   1.395 +
   1.396 +  // The last stream processed ID we will send in our GoAway frame.
   1.397 +  uint32_t             mOutgoingGoAwayID;
   1.398 +
   1.399 +  // The limit on number of concurrent streams for this session. Normally it
   1.400 +  // is basically unlimited, but the SETTINGS control message from the
   1.401 +  // server might bring it down.
   1.402 +  uint32_t             mMaxConcurrent;
   1.403 +
   1.404 +  // The actual number of concurrent streams at this moment. Generally below
   1.405 +  // mMaxConcurrent, but the max can be lowered in real time to a value
   1.406 +  // below the current value
   1.407 +  uint32_t             mConcurrent;
   1.408 +
   1.409 +  // The number of server initiated promises, tracked for telemetry
   1.410 +  uint32_t             mServerPushedResources;
   1.411 +
   1.412 +  // The server rwin for new streams as determined from a SETTINGS frame
   1.413 +  uint32_t             mServerInitialStreamWindow;
   1.414 +
   1.415 +  // The Local Session window is how much data the server is allowed to send
   1.416 +  // (across all streams) without getting a window update to stream 0. It is
   1.417 +  // signed because asynchronous changes via SETTINGS can drive it negative.
   1.418 +  int64_t              mLocalSessionWindow;
   1.419 +
   1.420 +  // The Remote Session Window is how much data the client is allowed to send
   1.421 +  // (across all streams) without receiving a window update to stream 0. It is
   1.422 +  // signed because asynchronous changes via SETTINGS can drive it negative.
   1.423 +  int64_t              mServerSessionWindow;
   1.424 +
   1.425 +  // This is a output queue of bytes ready to be written to the SSL stream.
   1.426 +  // When that streams returns WOULD_BLOCK on direct write the bytes get
   1.427 +  // coalesced together here. This results in larger writes to the SSL layer.
   1.428 +  // The buffer is not dynamically grown to accomodate stream writes, but
   1.429 +  // does expand to accept infallible session wide frames like GoAway and RST.
   1.430 +  uint32_t             mOutputQueueSize;
   1.431 +  uint32_t             mOutputQueueUsed;
   1.432 +  uint32_t             mOutputQueueSent;
   1.433 +  nsAutoArrayPtr<char> mOutputQueueBuffer;
   1.434 +
   1.435 +  PRIntervalTime       mPingThreshold;
   1.436 +  PRIntervalTime       mLastReadEpoch;     // used for ping timeouts
   1.437 +  PRIntervalTime       mLastDataReadEpoch; // used for IdleTime()
   1.438 +  PRIntervalTime       mPingSentEpoch;
   1.439 +
   1.440 +  // used as a temporary buffer while enumerating the stream hash during GoAway
   1.441 +  nsDeque  mGoAwayStreamsToRestart;
   1.442 +
   1.443 +  // Each session gets a unique serial number because the push cache is correlated
   1.444 +  // by the load group and the serial number can be used as part of the cache key
   1.445 +  // to make sure streams aren't shared across sessions.
   1.446 +  uint64_t        mSerial;
   1.447 +};
   1.448 +
   1.449 +} // namespace mozilla::net
   1.450 +} // namespace mozilla
   1.451 +
   1.452 +#endif // mozilla_net_Http2Session_h

mercurial