1 // Copyright (c) 2021 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "quiche/quic/test_tools/web_transport_resets_backend.h"
6
7 #include <memory>
8
9 #include "quiche/quic/core/web_transport_interface.h"
10 #include "quiche/quic/tools/web_transport_test_visitors.h"
11 #include "quiche/common/quiche_circular_deque.h"
12
13 namespace quic {
14 namespace test {
15
16 namespace {
17
18 class ResetsVisitor;
19
20 class BidirectionalEchoVisitorWithLogging
21 : public WebTransportBidirectionalEchoVisitor {
22 public:
BidirectionalEchoVisitorWithLogging(WebTransportStream * stream,ResetsVisitor * session_visitor)23 BidirectionalEchoVisitorWithLogging(WebTransportStream* stream,
24 ResetsVisitor* session_visitor)
25 : WebTransportBidirectionalEchoVisitor(stream),
26 session_visitor_(session_visitor) {}
27
28 void OnResetStreamReceived(WebTransportStreamError error) override;
29 void OnStopSendingReceived(WebTransportStreamError error) override;
30
31 private:
32 ResetsVisitor* session_visitor_; // Not owned.
33 };
34
35 class ResetsVisitor : public WebTransportVisitor {
36 public:
ResetsVisitor(WebTransportSession * session)37 ResetsVisitor(WebTransportSession* session) : session_(session) {}
38
OnSessionReady()39 void OnSessionReady() override {}
OnSessionClosed(WebTransportSessionError,const std::string &)40 void OnSessionClosed(WebTransportSessionError /*error_code*/,
41 const std::string& /*error_message*/) override {}
42
OnIncomingBidirectionalStreamAvailable()43 void OnIncomingBidirectionalStreamAvailable() override {
44 while (true) {
45 WebTransportStream* stream =
46 session_->AcceptIncomingBidirectionalStream();
47 if (stream == nullptr) {
48 return;
49 }
50 stream->SetVisitor(
51 std::make_unique<BidirectionalEchoVisitorWithLogging>(stream, this));
52 stream->visitor()->OnCanRead();
53 }
54 }
OnIncomingUnidirectionalStreamAvailable()55 void OnIncomingUnidirectionalStreamAvailable() override {}
56
OnDatagramReceived(absl::string_view)57 void OnDatagramReceived(absl::string_view /*datagram*/) override {}
58
OnCanCreateNewOutgoingBidirectionalStream()59 void OnCanCreateNewOutgoingBidirectionalStream() override {}
OnCanCreateNewOutgoingUnidirectionalStream()60 void OnCanCreateNewOutgoingUnidirectionalStream() override {
61 MaybeSendLogsBack();
62 }
63
Log(std::string line)64 void Log(std::string line) {
65 log_.push_back(std::move(line));
66 MaybeSendLogsBack();
67 }
68
69 private:
MaybeSendLogsBack()70 void MaybeSendLogsBack() {
71 while (!log_.empty() &&
72 session_->CanOpenNextOutgoingUnidirectionalStream()) {
73 WebTransportStream* stream = session_->OpenOutgoingUnidirectionalStream();
74 stream->SetVisitor(
75 std::make_unique<WebTransportUnidirectionalEchoWriteVisitor>(
76 stream, log_.front()));
77 log_.pop_front();
78 stream->visitor()->OnCanWrite();
79 }
80 }
81
82 WebTransportSession* session_; // Not owned.
83 quiche::QuicheCircularDeque<std::string> log_;
84 };
85
OnResetStreamReceived(WebTransportStreamError error)86 void BidirectionalEchoVisitorWithLogging::OnResetStreamReceived(
87 WebTransportStreamError error) {
88 session_visitor_->Log(absl::StrCat("Received reset for stream ",
89 stream()->GetStreamId(),
90 " with error code ", error));
91 WebTransportBidirectionalEchoVisitor::OnResetStreamReceived(error);
92 }
OnStopSendingReceived(WebTransportStreamError error)93 void BidirectionalEchoVisitorWithLogging::OnStopSendingReceived(
94 WebTransportStreamError error) {
95 session_visitor_->Log(absl::StrCat("Received stop sending for stream ",
96 stream()->GetStreamId(),
97 " with error code ", error));
98 WebTransportBidirectionalEchoVisitor::OnStopSendingReceived(error);
99 }
100
101 } // namespace
102
WebTransportResetsBackend(const spdy::Http2HeaderBlock &,WebTransportSession * session)103 QuicSimpleServerBackend::WebTransportResponse WebTransportResetsBackend(
104 const spdy::Http2HeaderBlock& /*request_headers*/,
105 WebTransportSession* session) {
106 QuicSimpleServerBackend::WebTransportResponse response;
107 response.response_headers[":status"] = "200";
108 response.visitor = std::make_unique<ResetsVisitor>(session);
109 return response;
110 }
111
112 } // namespace test
113 } // namespace quic
114