Http3Stream.h (5719B)
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_Http3Stream_h 7 #define mozilla_net_Http3Stream_h 8 9 #include "nsAHttpTransaction.h" 10 #include "ARefBase.h" 11 #include "Http3StreamBase.h" 12 #include "nsIClassOfService.h" 13 14 namespace mozilla { 15 namespace net { 16 17 class Http3Session; 18 19 class Http3Stream : public nsAHttpSegmentReader, 20 public nsAHttpSegmentWriter, 21 public Http3StreamBase { 22 public: 23 NS_DECL_NSAHTTPSEGMENTREADER 24 NS_DECL_NSAHTTPSEGMENTWRITER 25 // for RefPtr 26 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(Http3Stream, override) 27 28 Http3Stream(nsAHttpTransaction*, Http3Session*, const ClassOfService&, 29 uint64_t); 30 31 Http3WebTransportSession* GetHttp3WebTransportSession() override { 32 return nullptr; 33 } 34 Http3WebTransportStream* GetHttp3WebTransportStream() override { 35 return nullptr; 36 } 37 Http3Stream* GetHttp3Stream() override { return this; } 38 Http3ConnectUDPStream* GetHttp3ConnectUDPStream() override { return nullptr; } 39 Http3StreamTunnel* GetHttp3StreamTunnel() override { return nullptr; } 40 41 virtual nsresult TryActivating(); 42 43 void CurrentBrowserIdChanged(uint64_t id); 44 45 [[nodiscard]] nsresult ReadSegments() override; 46 [[nodiscard]] nsresult WriteSegments() override; 47 48 bool Done() const override { return mRecvState == RECV_DONE; } 49 50 void Close(nsresult aResult) override; 51 bool RecvdData() const { return mDataReceived; } 52 53 void StopSending(); 54 55 void SetResponseHeaders(nsTArray<uint8_t>& aResponseHeaders, bool fin, 56 bool interim) override; 57 58 // Mirrors nsAHttpTransaction 59 bool Do0RTT() override; 60 nsresult Finish0RTT(bool aRestart) override; 61 62 uint8_t PriorityUrgency(); 63 bool PriorityIncremental(); 64 65 protected: 66 ~Http3Stream() = default; 67 68 bool GetHeadersString(const char* buf, uint32_t avail, uint32_t* countUsed); 69 nsresult StartRequest(); 70 71 void SetIncremental(bool incremental); 72 73 /** 74 * SendStreamState: 75 * While sending request: 76 * - PREPARING_HEADERS: 77 * In this state we are collecting the headers and in some cases also 78 * waiting to be able to create a new stream. 79 * We need to read all headers into a buffer before calling 80 * Http3Session::TryActivating. Neqo may not have place for a new 81 * stream if it hits MAX_STREAMS limit. In that case the steam will be 82 * queued and dequeue when neqo can again create new stream 83 * (RequestsCreatable will be called). 84 * If transaction has data to send state changes to SENDING_BODY, 85 * otherwise the state transfers to READING_HEADERS. 86 * - SENDING_BODY: 87 * The stream will be in this state while the transaction is sending 88 * request body. Http3Session::SendRequestBody will be call to give 89 * the data to neqo. 90 * After SENDING_BODY, the state transfers to READING_HEADERS. 91 * - EARLY_RESPONSE: 92 * The server may send STOP_SENDING frame with error HTTP_NO_ERROR. 93 * That error means that the server is not interested in the request 94 * body. In this state the server will just ignore the request body. 95 **/ 96 enum SendStreamState { 97 PREPARING_HEADERS, 98 WAITING_TO_ACTIVATE, 99 SENDING_BODY, 100 EARLY_RESPONSE, 101 SEND_DONE 102 } mSendState{PREPARING_HEADERS}; 103 104 /** 105 * RecvStreamState: 106 * - BEFORE_HEADERS: 107 * The stream has not received headers yet. 108 * - READING_HEADERS and READING_INTERIM_HEADERS: 109 * In this state Http3Session::ReadResponseHeaders will be called to 110 * read the response headers. All headers will be read at once into 111 * mFlatResponseHeaders. The stream will be in this state until all 112 * headers are given to the transaction. 113 * If the steam was in the READING_INTERIM_HEADERS state it will 114 * change back to the BEFORE_HEADERS state. If the stream has been 115 * in the READING_HEADERS state it will change to the READING_DATA 116 * state. If the stream was closed by the server after sending headers 117 * the stream will transit into RECEIVED_FIN state. neqo makes sure 118 * that response headers and data are received in the right order, 119 * e.g. 1xx cannot be received after a non-1xx response, fin cannot 120 * follow 1xx response, etc. 121 * - READING_DATA: 122 * In this state Http3Session::ReadResponseData will be called and the 123 * response body will be given to the transaction. 124 * This state may transfer to RECEIVED_FIN or DONE state. 125 * - DONE: 126 * The transaction is done. 127 **/ 128 enum RecvStreamState { 129 BEFORE_HEADERS, 130 READING_HEADERS, 131 READING_INTERIM_HEADERS, 132 READING_DATA, 133 RECEIVED_FIN, 134 RECV_DONE 135 } mRecvState{BEFORE_HEADERS}; 136 137 nsCString mFlatHttpRequestHeaders; 138 bool mDataReceived{false}; 139 nsTArray<uint8_t> mFlatResponseHeaders; 140 uint64_t mTransactionBrowserId{0}; 141 uint64_t mCurrentBrowserId; 142 uint8_t mPriorityUrgency{3}; // urgency field of http priority 143 bool mPriorityIncremental{false}; 144 145 // For Progress Events 146 uint64_t mTotalSent{0}; 147 uint64_t mTotalRead{0}; 148 149 bool mAttempting0RTT = false; 150 151 uint32_t mSendingBlockedByFlowControlCount = 0; 152 153 nsresult mSocketInCondition = NS_ERROR_NOT_INITIALIZED; 154 nsresult mSocketOutCondition = NS_ERROR_NOT_INITIALIZED; 155 156 #ifdef DEBUG 157 uint32_t mRequestBodyLenExpected{0}; 158 uint32_t mRequestBodyLenSent{0}; 159 #endif 160 }; 161 162 } // namespace net 163 } // namespace mozilla 164 165 #endif // mozilla_net_Http3Stream_h