Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/netwerk/protocol/http/Http2Session.h
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 2; 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_Http2Session_h
7
#define mozilla_net_Http2Session_h
8
9
// HTTP/2 - RFC 7540
10
// https://www.rfc-editor.org/rfc/rfc7540.txt
11
12
#include "ASpdySession.h"
13
#include "mozilla/Attributes.h"
14
#include "mozilla/UniquePtr.h"
15
#include "mozilla/WeakPtr.h"
16
#include "nsAHttpConnection.h"
17
#include "nsClassHashtable.h"
18
#include "nsDataHashtable.h"
19
#include "nsDeque.h"
20
#include "nsHashKeys.h"
21
#include "nsHttpRequestHead.h"
22
#include "nsICacheEntryOpenCallback.h"
23
24
#include "Http2Compression.h"
25
26
class nsISocketTransport;
27
28
namespace mozilla {
29
namespace net {
30
31
class Http2PushedStream;
32
class Http2Stream;
33
class nsHttpTransaction;
34
35
class Http2Session final : public ASpdySession
36
                         , public nsAHttpConnection
37
                         , public nsAHttpSegmentReader
38
                         , public nsAHttpSegmentWriter
39
{
40
  ~Http2Session();
41
42
public:
43
  NS_DECL_THREADSAFE_ISUPPORTS
44
  NS_DECL_NSAHTTPTRANSACTION
45
  NS_DECL_NSAHTTPCONNECTION(mConnection)
46
  NS_DECL_NSAHTTPSEGMENTREADER
47
  NS_DECL_NSAHTTPSEGMENTWRITER
48
49
  Http2Session(nsISocketTransport *, enum SpdyVersion version, bool attemptingEarlyData);
50
51
  MOZ_MUST_USE bool AddStream(nsAHttpTransaction *, int32_t,
52
                              bool, nsIInterfaceRequestor *) override;
53
0
  bool CanReuse() override { return !mShouldGoAway && !mClosed; }
54
  bool RoomForMoreStreams() override;
55
  enum SpdyVersion SpdyVersion() override;
56
  bool TestJoinConnection(const nsACString &hostname, int32_t port) override;
57
  bool JoinConnection(const nsACString &hostname, int32_t port) override;
58
59
  // When the connection is active this is called up to once every 1 second
60
  // return the interval (in seconds) that the connection next wants to
61
  // have this invoked. It might happen sooner depending on the needs of
62
  // other connections.
63
  uint32_t  ReadTimeoutTick(PRIntervalTime now) override;
64
65
  // Idle time represents time since "goodput".. e.g. a data or header frame
66
  PRIntervalTime IdleTime() override;
67
68
  // Registering with a newID of 0 means pick the next available odd ID
69
  uint32_t RegisterStreamID(Http2Stream *, uint32_t aNewID = 0);
70
71
/*
72
  HTTP/2 framing
73
74
  0                   1                   2                   3
75
  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
76
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
77
  |         Length (16)           |   Type (8)    |   Flags (8)   |
78
  +-+-------------+---------------+-------------------------------+
79
  |R|                 Stream Identifier (31)                      |
80
  +-+-------------------------------------------------------------+
81
  |                     Frame Data (0...)                       ...
82
  +---------------------------------------------------------------+
83
*/
84
85
  enum FrameType {
86
    FRAME_TYPE_DATA          = 0x0,
87
    FRAME_TYPE_HEADERS       = 0x1,
88
    FRAME_TYPE_PRIORITY      = 0x2,
89
    FRAME_TYPE_RST_STREAM    = 0x3,
90
    FRAME_TYPE_SETTINGS      = 0x4,
91
    FRAME_TYPE_PUSH_PROMISE  = 0x5,
92
    FRAME_TYPE_PING          = 0x6,
93
    FRAME_TYPE_GOAWAY        = 0x7,
94
    FRAME_TYPE_WINDOW_UPDATE = 0x8,
95
    FRAME_TYPE_CONTINUATION  = 0x9,
96
    FRAME_TYPE_ALTSVC        = 0xA,
97
    FRAME_TYPE_UNUSED        = 0xB,
98
    FRAME_TYPE_ORIGIN        = 0xC,
99
    FRAME_TYPE_LAST          = 0xD
100
  };
101
102
  // NO_ERROR is a macro defined on windows, so we'll name the HTTP2 goaway
103
  // code NO_ERROR to be NO_HTTP_ERROR
104
  enum errorType {
105
    NO_HTTP_ERROR = 0,
106
    PROTOCOL_ERROR = 1,
107
    INTERNAL_ERROR = 2,
108
    FLOW_CONTROL_ERROR = 3,
109
    SETTINGS_TIMEOUT_ERROR = 4,
110
    STREAM_CLOSED_ERROR = 5,
111
    FRAME_SIZE_ERROR = 6,
112
    REFUSED_STREAM_ERROR = 7,
113
    CANCEL_ERROR = 8,
114
    COMPRESSION_ERROR = 9,
115
    CONNECT_ERROR = 10,
116
    ENHANCE_YOUR_CALM = 11,
117
    INADEQUATE_SECURITY = 12,
118
    HTTP_1_1_REQUIRED = 13,
119
    UNASSIGNED = 31
120
  };
121
122
  // These are frame flags. If they, or other undefined flags, are
123
  // used on frames other than the comments indicate they MUST be ignored.
124
  const static uint8_t kFlag_END_STREAM = 0x01; // data, headers
125
  const static uint8_t kFlag_END_HEADERS = 0x04; // headers, continuation
126
  const static uint8_t kFlag_END_PUSH_PROMISE = 0x04; // push promise
127
  const static uint8_t kFlag_ACK = 0x01; // ping and settings
128
  const static uint8_t kFlag_PADDED = 0x08; // data, headers, push promise, continuation
129
  const static uint8_t kFlag_PRIORITY = 0x20; // headers
130
131
  enum {
132
    SETTINGS_TYPE_HEADER_TABLE_SIZE = 1, // compression table size
133
    SETTINGS_TYPE_ENABLE_PUSH = 2,     // can be used to disable push
134
    SETTINGS_TYPE_MAX_CONCURRENT = 3,  // streams recvr allowed to initiate
135
    SETTINGS_TYPE_INITIAL_WINDOW = 4,  // bytes for flow control default
136
    SETTINGS_TYPE_MAX_FRAME_SIZE = 5   // max frame size settings sender allows receipt of
137
  };
138
139
  // This should be big enough to hold all of your control packets,
140
  // but if it needs to grow for huge headers it can do so dynamically.
141
  const static uint32_t kDefaultBufferSize = 2048;
142
143
  // kDefaultQueueSize must be >= other queue size constants
144
  const static uint32_t kDefaultQueueSize =  32768;
145
  const static uint32_t kQueueMinimumCleanup = 24576;
146
  const static uint32_t kQueueTailRoom    =  4096;
147
  const static uint32_t kQueueReserved    =  1024;
148
149
  const static uint32_t kMaxStreamID = 0x7800000;
150
151
  // This is a sentinel for a deleted stream. It is not a valid
152
  // 31 bit stream ID.
153
  const static uint32_t kDeadStreamID = 0xffffdead;
154
155
  // below the emergency threshold of local window we ack every received
156
  // byte. Above that we coalesce bytes into the MinimumToAck size.
157
  const static int32_t  kEmergencyWindowThreshold = 96 * 1024;
158
  const static uint32_t kMinimumToAck = 4 * 1024 * 1024;
159
160
  // The default rwin is 64KB - 1 unless updated by a settings frame
161
  const static uint32_t kDefaultRwin = 65535;
162
163
  // We limit frames to 2^14 bytes of length in order to preserve responsiveness
164
  // This is the smallest allowed value for SETTINGS_MAX_FRAME_SIZE
165
  const static uint32_t kMaxFrameData = 0x4000;
166
167
  const static uint8_t kFrameLengthBytes = 3;
168
  const static uint8_t kFrameStreamIDBytes = 4;
169
  const static uint8_t kFrameFlagBytes = 1;
170
  const static uint8_t kFrameTypeBytes = 1;
171
  const static uint8_t kFrameHeaderBytes = kFrameLengthBytes + kFrameFlagBytes +
172
    kFrameTypeBytes + kFrameStreamIDBytes;
173
174
  enum {
175
    kLeaderGroupID =      0x3,
176
    kOtherGroupID =       0x5,
177
    kBackgroundGroupID =  0x7,
178
    kSpeculativeGroupID = 0x9,
179
    kFollowerGroupID =    0xB,
180
    kUrgentStartGroupID = 0xD
181
    // Hey, you! YES YOU! If you add/remove any groups here, you almost
182
    // certainly need to change the lookup of the stream/ID hash in
183
    // Http2Session::OnTransportStatus and |kPriorityGroupCount| below.
184
    // Yeah, that's right. YOU!
185
  };
186
  const static uint8_t kPriorityGroupCount = 6;
187
188
  static nsresult RecvHeaders(Http2Session *);
189
  static nsresult RecvPriority(Http2Session *);
190
  static nsresult RecvRstStream(Http2Session *);
191
  static nsresult RecvSettings(Http2Session *);
192
  static nsresult RecvPushPromise(Http2Session *);
193
  static nsresult RecvPing(Http2Session *);
194
  static nsresult RecvGoAway(Http2Session *);
195
  static nsresult RecvWindowUpdate(Http2Session *);
196
  static nsresult RecvContinuation(Http2Session *);
197
  static nsresult RecvAltSvc(Http2Session *);
198
  static nsresult RecvUnused(Http2Session *);
199
  static nsresult RecvOrigin(Http2Session *);
200
201
  char       *EnsureOutputBuffer(uint32_t needed);
202
203
  template<typename charType>
204
  void CreateFrameHeader(charType dest, uint16_t frameLength,
205
                         uint8_t frameType, uint8_t frameFlags,
206
                         uint32_t streamID);
207
208
  // For writing the data stream to LOG4
209
  static void LogIO(Http2Session *, Http2Stream *, const char *,
210
                    const char *, uint32_t);
211
212
  // overload of nsAHttpConnection
213
  void TransactionHasDataToWrite(nsAHttpTransaction *) override;
214
  void TransactionHasDataToRecv(nsAHttpTransaction *) override;
215
216
  // a similar version for Http2Stream
217
  void TransactionHasDataToWrite(Http2Stream *);
218
219
  // an overload of nsAHttpSegementReader
220
  virtual MOZ_MUST_USE nsresult CommitToSegmentSize(uint32_t size,
221
                                                    bool forceCommitment) override;
222
  MOZ_MUST_USE nsresult BufferOutput(const char *, uint32_t, uint32_t *);
223
  void     FlushOutputQueue();
224
0
  uint32_t AmountOfOutputBuffered() { return mOutputQueueUsed - mOutputQueueSent; }
225
226
0
  uint32_t GetServerInitialStreamWindow() { return mServerInitialStreamWindow; }
227
228
  MOZ_MUST_USE bool TryToActivate(Http2Stream *stream);
229
  void ConnectPushedStream(Http2Stream *stream);
230
  void ConnectSlowConsumer(Http2Stream *stream);
231
232
  MOZ_MUST_USE nsresult ConfirmTLSProfile();
233
  static MOZ_MUST_USE bool ALPNCallback(nsISupports *securityInfo);
234
235
0
  uint64_t Serial() { return mSerial; }
236
237
  void PrintDiagnostics (nsCString &log) override;
238
239
  // Streams need access to these
240
0
  uint32_t SendingChunkSize() { return mSendingChunkSize; }
241
0
  uint32_t PushAllowance() { return mPushAllowance; }
242
0
  Http2Compressor *Compressor() { return &mCompressor; }
243
0
  nsISocketTransport *SocketTransport() { return mSocketTransport; }
244
0
  int64_t ServerSessionWindow() { return mServerSessionWindow; }
245
0
  void DecrementServerSessionWindow (uint32_t bytes) { mServerSessionWindow -= bytes; }
246
0
  uint32_t InitialRwin() { return mInitialRwin; }
247
248
  void SendPing() override;
249
  MOZ_MUST_USE bool MaybeReTunnel(nsAHttpTransaction *) override;
250
0
  bool UseH2Deps() { return mUseH2Deps; }
251
252
  // overload of nsAHttpTransaction
253
  MOZ_MUST_USE nsresult ReadSegmentsAgain(nsAHttpSegmentReader *, uint32_t, uint32_t *, bool *) final;
254
  MOZ_MUST_USE nsresult WriteSegmentsAgain(nsAHttpSegmentWriter *, uint32_t , uint32_t *, bool *) final;
255
0
  MOZ_MUST_USE bool Do0RTT() final { return true; }
256
  MOZ_MUST_USE nsresult Finish0RTT(bool aRestart, bool aAlpnChanged) final;
257
  void SetFastOpenStatus(uint8_t aStatus) final;
258
259
  // For use by an HTTP2Stream
260
  void Received421(nsHttpConnectionInfo *ci);
261
262
  void SendPriorityFrame(uint32_t streamID, uint32_t dependsOn, uint8_t weight);
263
0
  void IncrementTrrCounter() { mTrrStreams++; }
264
265
private:
266
267
  // These internal states do not correspond to the states of the HTTP/2 specification
268
  enum internalStateType {
269
    BUFFERING_OPENING_SETTINGS,
270
    BUFFERING_FRAME_HEADER,
271
    BUFFERING_CONTROL_FRAME,
272
    PROCESSING_DATA_FRAME_PADDING_CONTROL,
273
    PROCESSING_DATA_FRAME,
274
    DISCARDING_DATA_FRAME_PADDING,
275
    DISCARDING_DATA_FRAME,
276
    PROCESSING_COMPLETE_HEADERS,
277
    PROCESSING_CONTROL_RST_STREAM,
278
    NOT_USING_NETWORK
279
  };
280
281
  static const uint8_t kMagicHello[24];
282
283
  MOZ_MUST_USE nsresult ResponseHeadersComplete();
284
  uint32_t    GetWriteQueueSize();
285
  void        ChangeDownstreamState(enum internalStateType);
286
  void        ResetDownstreamState();
287
  MOZ_MUST_USE nsresult ReadyToProcessDataFrame(enum internalStateType);
288
  MOZ_MUST_USE nsresult UncompressAndDiscard(bool);
289
  void        GeneratePing(bool);
290
  void        GenerateSettingsAck();
291
  void        GeneratePriority(uint32_t, uint8_t);
292
  void        GenerateRstStream(uint32_t, uint32_t);
293
  void        GenerateGoAway(uint32_t);
294
  void        CleanupStream(Http2Stream *, nsresult, errorType);
295
  void        CleanupStream(uint32_t, nsresult, errorType);
296
  void        CloseStream(Http2Stream *, nsresult);
297
  void        SendHello();
298
  void        RemoveStreamFromQueues(Http2Stream *);
299
  MOZ_MUST_USE nsresult ParsePadding(uint8_t &, uint16_t &);
300
301
  void        SetWriteCallbacks();
302
  void        RealignOutputQueue();
303
304
  void        ProcessPending();
305
  MOZ_MUST_USE nsresult ProcessConnectedPush(Http2Stream *,
306
                                             nsAHttpSegmentWriter *,
307
                                             uint32_t, uint32_t *);
308
  MOZ_MUST_USE nsresult ProcessSlowConsumer(Http2Stream *,
309
                                            nsAHttpSegmentWriter *,
310
                                            uint32_t, uint32_t *);
311
312
  MOZ_MUST_USE nsresult SetInputFrameDataStream(uint32_t);
313
  void        CreatePriorityNode(uint32_t, uint32_t, uint8_t, const char *);
314
  char        *CreatePriorityFrame(uint32_t, uint32_t, uint8_t);
315
  bool        VerifyStream(Http2Stream *, uint32_t);
316
  void        SetNeedsCleanup();
317
318
  void        UpdateLocalRwin(Http2Stream *stream, uint32_t bytes);
319
  void        UpdateLocalStreamWindow(Http2Stream *stream, uint32_t bytes);
320
  void        UpdateLocalSessionWindow(uint32_t bytes);
321
322
  void        MaybeDecrementConcurrent(Http2Stream *stream);
323
  bool        RoomForMoreConcurrent();
324
  void        IncrementConcurrent(Http2Stream *stream);
325
  void        QueueStream(Http2Stream *stream);
326
327
  // a wrapper for all calls to the nshttpconnection level segment writer. Used
328
  // to track network I/O for timeout purposes
329
  MOZ_MUST_USE nsresult NetworkRead(nsAHttpSegmentWriter *, char *, uint32_t, uint32_t *);
330
331
  void Shutdown();
332
333
  // This is intended to be nsHttpConnectionMgr:nsConnectionHandle taken
334
  // from the first transaction on this session. That object contains the
335
  // pointer to the real network-level nsHttpConnection object.
336
  RefPtr<nsAHttpConnection> mConnection;
337
338
  // The underlying socket transport object is needed to propogate some events
339
  nsISocketTransport         *mSocketTransport;
340
341
  // These are temporary state variables to hold the argument to
342
  // Read/WriteSegments so it can be accessed by On(read/write)segment
343
  // further up the stack.
344
  nsAHttpSegmentReader       *mSegmentReader;
345
  nsAHttpSegmentWriter       *mSegmentWriter;
346
347
  uint32_t          mSendingChunkSize;        /* the transmission chunk size */
348
  uint32_t          mNextStreamID;            /* 24 bits */
349
  uint32_t          mLastPushedID;
350
  uint32_t          mConcurrentHighWater;     /* max parallelism on session */
351
  uint32_t          mPushAllowance;           /* rwin for unmatched pushes */
352
353
  internalStateType mDownstreamState; /* in frame, between frames, etc..  */
354
355
  // Maintain 2 indexes - one by stream ID, one by transaction pointer.
356
  // There are also several lists of streams: ready to write, queued due to
357
  // max parallelism, streams that need to force a read for push, and the full
358
  // set of pushed streams.
359
  // The objects are not ref counted - they get destroyed
360
  // by the nsClassHashtable implementation when they are removed from
361
  // the transaction hash.
362
  nsDataHashtable<nsUint32HashKey, Http2Stream *>     mStreamIDHash;
363
  nsClassHashtable<nsPtrHashKey<nsAHttpTransaction>,
364
    Http2Stream>                                      mStreamTransactionHash;
365
366
  nsDeque                                             mReadyForWrite;
367
  nsDeque                                             mQueuedStreams;
368
  nsDeque                                             mPushesReadyForRead;
369
  nsDeque                                             mSlowConsumersReadyForRead;
370
  nsTArray<Http2PushedStream *>                       mPushedStreams;
371
372
  // Compression contexts for header transport.
373
  // HTTP/2 compresses only HTTP headers and does not reset the context in between
374
  // frames. Even data that is not associated with a stream (e.g invalid
375
  // stream ID) is passed through these contexts to keep the compression
376
  // context correct.
377
  Http2Compressor     mCompressor;
378
  Http2Decompressor   mDecompressor;
379
  nsCString           mDecompressBuffer;
380
381
  // mInputFrameBuffer is used to store received control packets and the 8 bytes
382
  // of header on data packets
383
  uint32_t             mInputFrameBufferSize; // buffer allocation
384
  uint32_t             mInputFrameBufferUsed; // amt of allocation used
385
  UniquePtr<char[]>    mInputFrameBuffer;
386
387
  // mInputFrameDataSize/Read are used for tracking the amount of data consumed
388
  // in a frame after the 8 byte header. Control frames are always fully buffered
389
  // and the fixed 8 byte leading header is at mInputFrameBuffer + 0, the first
390
  // data byte (i.e. the first settings/goaway/etc.. specific byte) is at
391
  // mInputFrameBuffer + 8
392
  // The frame size is mInputFrameDataSize + the constant 8 byte header
393
  uint32_t             mInputFrameDataSize;
394
  uint32_t             mInputFrameDataRead;
395
  bool                 mInputFrameFinal; // This frame was marked FIN
396
  uint8_t              mInputFrameType;
397
  uint8_t              mInputFrameFlags;
398
  uint32_t             mInputFrameID;
399
  uint16_t             mPaddingLength;
400
401
  // When a frame has been received that is addressed to a particular stream
402
  // (e.g. a data frame after the stream-id has been decoded), this points
403
  // to the stream.
404
  Http2Stream          *mInputFrameDataStream;
405
406
  // mNeedsCleanup is a state variable to defer cleanup of a closed stream
407
  // If needed, It is set in session::OnWriteSegments() and acted on and
408
  // cleared when the stack returns to session::WriteSegments(). The stream
409
  // cannot be destroyed directly out of OnWriteSegments because
410
  // stream::writeSegments() is on the stack at that time.
411
  Http2Stream          *mNeedsCleanup;
412
413
  // This reason code in the last processed RESET frame
414
  uint32_t             mDownstreamRstReason;
415
416
  // When HEADERS/PROMISE are chained together, this is the expected ID of the next
417
  // recvd frame which must be the same type
418
  uint32_t             mExpectedHeaderID;
419
  uint32_t             mExpectedPushPromiseID;
420
  uint32_t             mContinuedPromiseStream;
421
422
  // for the conversion of downstream http headers into http/2 formatted headers
423
  // The data here does not persist between frames
424
  nsCString            mFlatHTTPResponseHeaders;
425
  uint32_t             mFlatHTTPResponseHeadersOut;
426
427
  // when set, the session will go away when it reaches 0 streams. This flag
428
  // is set when: the stream IDs are running out (at either the client or the
429
  // server), when DontReuse() is called, a RST that is not specific to a
430
  // particular stream is received, a GOAWAY frame has been received from
431
  // the server.
432
  bool                 mShouldGoAway;
433
434
  // the session has received a nsAHttpTransaction::Close()  call
435
  bool                 mClosed;
436
437
  // the session received a GoAway frame with a valid GoAwayID
438
  bool                 mCleanShutdown;
439
440
  // the session received the opening SETTINGS frame from the server
441
  bool                 mReceivedSettings;
442
443
  // The TLS comlpiance checks are not done in the ctor beacuse of bad
444
  // exception handling - so we do them at IO time and cache the result
445
  bool                 mTLSProfileConfirmed;
446
447
  // A specifc reason code for the eventual GoAway frame. If set to NO_HTTP_ERROR
448
  // only NO_HTTP_ERROR, PROTOCOL_ERROR, or INTERNAL_ERROR will be sent.
449
  errorType            mGoAwayReason;
450
451
  // The error code sent/received on the session goaway frame. UNASSIGNED/31
452
  // if not transmitted.
453
  int32_t             mClientGoAwayReason;
454
  int32_t             mPeerGoAwayReason;
455
456
  // If a GoAway message was received this is the ID of the last valid
457
  // stream. 0 otherwise. (0 is never a valid stream id.)
458
  uint32_t             mGoAwayID;
459
460
  // The last stream processed ID we will send in our GoAway frame.
461
  uint32_t             mOutgoingGoAwayID;
462
463
  // The limit on number of concurrent streams for this session. Normally it
464
  // is basically unlimited, but the SETTINGS control message from the
465
  // server might bring it down.
466
  uint32_t             mMaxConcurrent;
467
468
  // The actual number of concurrent streams at this moment. Generally below
469
  // mMaxConcurrent, but the max can be lowered in real time to a value
470
  // below the current value
471
  uint32_t             mConcurrent;
472
473
  // The number of server initiated promises, tracked for telemetry
474
  uint32_t             mServerPushedResources;
475
476
  // The server rwin for new streams as determined from a SETTINGS frame
477
  uint32_t             mServerInitialStreamWindow;
478
479
  // The Local Session window is how much data the server is allowed to send
480
  // (across all streams) without getting a window update to stream 0. It is
481
  // signed because asynchronous changes via SETTINGS can drive it negative.
482
  int64_t              mLocalSessionWindow;
483
484
  // The Remote Session Window is how much data the client is allowed to send
485
  // (across all streams) without receiving a window update to stream 0. It is
486
  // signed because asynchronous changes via SETTINGS can drive it negative.
487
  int64_t              mServerSessionWindow;
488
489
  // The initial value of the local stream and session window
490
  uint32_t             mInitialRwin;
491
492
  // This is a output queue of bytes ready to be written to the SSL stream.
493
  // When that streams returns WOULD_BLOCK on direct write the bytes get
494
  // coalesced together here. This results in larger writes to the SSL layer.
495
  // The buffer is not dynamically grown to accomodate stream writes, but
496
  // does expand to accept infallible session wide frames like GoAway and RST.
497
  uint32_t             mOutputQueueSize;
498
  uint32_t             mOutputQueueUsed;
499
  uint32_t             mOutputQueueSent;
500
  UniquePtr<char[]>    mOutputQueueBuffer;
501
502
  PRIntervalTime       mPingThreshold;
503
  PRIntervalTime       mLastReadEpoch;     // used for ping timeouts
504
  PRIntervalTime       mLastDataReadEpoch; // used for IdleTime()
505
  PRIntervalTime       mPingSentEpoch;
506
507
  PRIntervalTime       mPreviousPingThreshold; // backup for the former value
508
  bool                 mPreviousUsed;          // true when backup is used
509
510
  // used as a temporary buffer while enumerating the stream hash during GoAway
511
  nsDeque  mGoAwayStreamsToRestart;
512
513
  // Each session gets a unique serial number because the push cache is correlated
514
  // by the load group and the serial number can be used as part of the cache key
515
  // to make sure streams aren't shared across sessions.
516
  uint64_t        mSerial;
517
518
  // Telemetry for continued headers (pushed and pulled) for quic design
519
  uint32_t        mAggregatedHeaderSize;
520
521
  // If push is disabled, we want to be able to send PROTOCOL_ERRORs if we
522
  // receive a PUSH_PROMISE, but we have to wait for the SETTINGS ACK before
523
  // we can actually tell the other end to go away. These help us keep track
524
  // of that state so we can behave appropriately.
525
  bool mWaitingForSettingsAck;
526
  bool mGoAwayOnPush;
527
528
  bool mUseH2Deps;
529
530
  bool mAttemptingEarlyData;
531
  // The ID(s) of the stream(s) that we are getting 0RTT data from.
532
  nsTArray<WeakPtr<Http2Stream>> m0RTTStreams;
533
  // The ID(s) of the stream(s) that are not able to send 0RTT data. We need to
534
  // remember them put them into mReadyForWrite queue when 0RTT finishes.
535
  nsTArray<WeakPtr<Http2Stream>> mCannotDo0RTTStreams;
536
537
  bool RealJoinConnection(const nsACString &hostname, int32_t port, bool jk);
538
  bool TestOriginFrame(const nsACString &name, int32_t port);
539
  bool mOriginFrameActivated;
540
  nsDataHashtable<nsCStringHashKey, bool> mOriginFrame;
541
542
  nsDataHashtable<nsCStringHashKey, bool> mJoinConnectionCache;
543
544
  uint64_t mCurrentForegroundTabOuterContentWindowId;
545
546
  class CachePushCheckCallback final : public nsICacheEntryOpenCallback
547
  {
548
  public:
549
    CachePushCheckCallback(Http2Session *session, uint32_t promisedID, const nsACString &requestString);
550
551
    NS_DECL_ISUPPORTS
552
    NS_DECL_NSICACHEENTRYOPENCALLBACK
553
554
  private:
555
0
    ~CachePushCheckCallback() = default;
556
557
    RefPtr<Http2Session> mSession;
558
    uint32_t mPromisedID;
559
    nsHttpRequestHead mRequestHead;
560
  };
561
562
  // A h2 session will be created before all socket events are trigered,
563
  // e.g. NS_NET_STATUS_TLS_HANDSHAKE_ENDED and for TFO many others.
564
  // We should propagate this events to the first nsHttpTransaction.
565
  RefPtr<nsHttpTransaction> mFirstHttpTransaction;
566
  bool mTlsHandshakeFinished;
567
568
  bool mCheckNetworkStallsWithTFO;
569
  PRIntervalTime mLastRequestBytesSentTime;
570
private:
571
/// connect tunnels
572
  void DispatchOnTunnel(nsAHttpTransaction *, nsIInterfaceRequestor *);
573
  void CreateTunnel(nsHttpTransaction *, nsHttpConnectionInfo *, nsIInterfaceRequestor *);
574
  void RegisterTunnel(Http2Stream *);
575
  void UnRegisterTunnel(Http2Stream *);
576
  uint32_t FindTunnelCount(nsHttpConnectionInfo *);
577
  nsDataHashtable<nsCStringHashKey, uint32_t> mTunnelHash;
578
  uint32_t mTrrStreams;
579
};
580
581
} // namespace net
582
} // namespace mozilla
583
584
#endif // mozilla_net_Http2Session_h