tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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