Move WebTransportEchoServer from test_tools to tools.
So that it can be used from QUIC test servers.
Add `enable_webtransport` flag in QuicToyServer. If true, QuicMemoryCacheBackend
is set up to handle WebTransport requests.
PiperOrigin-RevId: 370638467
Change-Id: I0f3555fa7da6cb1e4ca211134f5123eed8ae56e3
diff --git a/quic/tools/web_transport_test_visitors.h b/quic/tools/web_transport_test_visitors.h
index 9bf6e6b..c9efcb7 100644
--- a/quic/tools/web_transport_test_visitors.h
+++ b/quic/tools/web_transport_test_visitors.h
@@ -7,6 +7,8 @@
#include <string>
+#include "quic/core/quic_circular_deque.h"
+#include "quic/core/quic_simple_buffer_allocator.h"
#include "quic/core/web_transport_interface.h"
#include "quic/platform/api/quic_logging.h"
@@ -132,6 +134,95 @@
std::string data_;
};
+// A session visitor which sets unidirectional or bidirectional stream visitors
+// to echo.
+class EchoWebTransportSessionVisitor : public WebTransportVisitor {
+ public:
+ EchoWebTransportSessionVisitor(WebTransportSession* session)
+ : session_(session) {}
+
+ void OnSessionReady() override {
+ if (session_->CanOpenNextOutgoingBidirectionalStream()) {
+ OnCanCreateNewOutgoingBidirectionalStream();
+ }
+ }
+
+ void OnIncomingBidirectionalStreamAvailable() override {
+ while (true) {
+ WebTransportStream* stream =
+ session_->AcceptIncomingBidirectionalStream();
+ if (stream == nullptr) {
+ return;
+ }
+ QUIC_DVLOG(1)
+ << "EchoWebTransportSessionVisitor received a bidirectional stream "
+ << stream->GetStreamId();
+ stream->SetVisitor(
+ std::make_unique<WebTransportBidirectionalEchoVisitor>(stream));
+ stream->visitor()->OnCanRead();
+ }
+ }
+
+ void OnIncomingUnidirectionalStreamAvailable() override {
+ while (true) {
+ WebTransportStream* stream =
+ session_->AcceptIncomingUnidirectionalStream();
+ if (stream == nullptr) {
+ return;
+ }
+ QUIC_DVLOG(1)
+ << "EchoWebTransportSessionVisitor received a unidirectional stream";
+ stream->SetVisitor(
+ std::make_unique<WebTransportUnidirectionalEchoReadVisitor>(
+ stream, [this](const std::string& data) {
+ streams_to_echo_back_.push_back(data);
+ TrySendingUnidirectionalStreams();
+ }));
+ stream->visitor()->OnCanRead();
+ }
+ }
+
+ void OnDatagramReceived(absl::string_view datagram) override {
+ auto buffer = MakeUniqueBuffer(&allocator_, datagram.size());
+ memcpy(buffer.get(), datagram.data(), datagram.size());
+ QuicMemSlice slice(std::move(buffer), datagram.size());
+ session_->SendOrQueueDatagram(std::move(slice));
+ }
+
+ void OnCanCreateNewOutgoingBidirectionalStream() override {
+ if (!echo_stream_opened_) {
+ WebTransportStream* stream = session_->OpenOutgoingBidirectionalStream();
+ stream->SetVisitor(
+ std::make_unique<WebTransportBidirectionalEchoVisitor>(stream));
+ echo_stream_opened_ = true;
+ }
+ }
+ void OnCanCreateNewOutgoingUnidirectionalStream() override {
+ TrySendingUnidirectionalStreams();
+ }
+
+ void TrySendingUnidirectionalStreams() {
+ while (!streams_to_echo_back_.empty() &&
+ session_->CanOpenNextOutgoingUnidirectionalStream()) {
+ QUIC_DVLOG(1)
+ << "EchoWebTransportServer echoed a unidirectional stream back";
+ WebTransportStream* stream = session_->OpenOutgoingUnidirectionalStream();
+ stream->SetVisitor(
+ std::make_unique<WebTransportUnidirectionalEchoWriteVisitor>(
+ stream, streams_to_echo_back_.front()));
+ streams_to_echo_back_.pop_front();
+ stream->visitor()->OnCanWrite();
+ }
+ }
+
+ private:
+ WebTransportSession* session_;
+ SimpleBufferAllocator allocator_;
+ bool echo_stream_opened_ = false;
+
+ QuicCircularDeque<std::string> streams_to_echo_back_;
+};
+
} // namespace quic
#endif // QUICHE_QUIC_TOOLS_WEB_TRANSPORT_TEST_VISITORS_H_