summaryrefslogtreecommitdiff
path: root/chromium/net/third_party/quiche/src/quic/test_tools/web_transport_resets_backend.cc
blob: 512619fee0a7e3ace95bc957d9670bba6ce7d96d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
// Copyright (c) 2021 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "quic/test_tools/web_transport_resets_backend.h"

#include <memory>

#include "quic/core/web_transport_interface.h"
#include "quic/tools/web_transport_test_visitors.h"
#include "common/quiche_circular_deque.h"

namespace quic {
namespace test {

namespace {

class ResetsVisitor;

class BidirectionalEchoVisitorWithLogging
    : public WebTransportBidirectionalEchoVisitor {
 public:
  BidirectionalEchoVisitorWithLogging(WebTransportStream* stream,
                                      ResetsVisitor* session_visitor)
      : WebTransportBidirectionalEchoVisitor(stream),
        session_visitor_(session_visitor) {}

  void OnResetStreamReceived(WebTransportStreamError error) override;
  void OnStopSendingReceived(WebTransportStreamError error) override;

 private:
  ResetsVisitor* session_visitor_;  // Not owned.
};

class ResetsVisitor : public WebTransportVisitor {
 public:
  ResetsVisitor(WebTransportSession* session) : session_(session) {}

  void OnSessionReady(const spdy::SpdyHeaderBlock& /*headers*/) override {}
  void OnSessionClosed(WebTransportSessionError /*error_code*/,
                       const std::string& /*error_message*/) override {}

  void OnIncomingBidirectionalStreamAvailable() override {
    while (true) {
      WebTransportStream* stream =
          session_->AcceptIncomingBidirectionalStream();
      if (stream == nullptr) {
        return;
      }
      stream->SetVisitor(
          std::make_unique<BidirectionalEchoVisitorWithLogging>(stream, this));
      stream->visitor()->OnCanRead();
    }
  }
  void OnIncomingUnidirectionalStreamAvailable() override {}

  void OnDatagramReceived(absl::string_view /*datagram*/) override {}

  void OnCanCreateNewOutgoingBidirectionalStream() override {}
  void OnCanCreateNewOutgoingUnidirectionalStream() override {
    MaybeSendLogsBack();
  }

  void Log(std::string line) {
    log_.push_back(std::move(line));
    MaybeSendLogsBack();
  }

 private:
  void MaybeSendLogsBack() {
    while (!log_.empty() &&
           session_->CanOpenNextOutgoingUnidirectionalStream()) {
      WebTransportStream* stream = session_->OpenOutgoingUnidirectionalStream();
      stream->SetVisitor(
          std::make_unique<WebTransportUnidirectionalEchoWriteVisitor>(
              stream, log_.front()));
      log_.pop_front();
      stream->visitor()->OnCanWrite();
    }
  }

  WebTransportSession* session_;  // Not owned.
  quiche::QuicheCircularDeque<std::string> log_;
};

void BidirectionalEchoVisitorWithLogging::OnResetStreamReceived(
    WebTransportStreamError error) {
  session_visitor_->Log(absl::StrCat("Received reset for stream ",
                                     stream()->GetStreamId(),
                                     " with error code ", error));
  WebTransportBidirectionalEchoVisitor::OnResetStreamReceived(error);
}
void BidirectionalEchoVisitorWithLogging::OnStopSendingReceived(
    WebTransportStreamError error) {
  session_visitor_->Log(absl::StrCat("Received stop sending for stream ",
                                     stream()->GetStreamId(),
                                     " with error code ", error));
  WebTransportBidirectionalEchoVisitor::OnStopSendingReceived(error);
}

}  // namespace

QuicSimpleServerBackend::WebTransportResponse WebTransportResetsBackend(
    const spdy::Http2HeaderBlock& /*request_headers*/,
    WebTransportSession* session) {
  QuicSimpleServerBackend::WebTransportResponse response;
  response.response_headers[":status"] = "200";
  response.visitor = std::make_unique<ResetsVisitor>(session);
  return response;
}

}  // namespace test
}  // namespace quic