Skip to content

Commit

Permalink
Update webtransport example
Browse files Browse the repository at this point in the history
  • Loading branch information
chrislearn committed Aug 9, 2023
1 parent f3e02bb commit 49bc41e
Show file tree
Hide file tree
Showing 6 changed files with 326 additions and 63 deletions.
2 changes: 2 additions & 0 deletions examples/static-dir-list/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ async fn main() {
StaticDir::new([
"static-dir-list/static/boy",
"static-dir-list/static/girl",
"static/boy",
"static/girl",
])
.defaults("index.html")
.listing(true),
Expand Down
2 changes: 1 addition & 1 deletion examples/webtransport/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ publish.workspace = true
[dependencies]
anyhow.workspace = true
futures-util.workspace = true
salvo = { workspace = true, features = ["quinn", "anyhow"] }
salvo = { workspace = true, features = ["quinn", "anyhow", "serve-static"] }
tokio = { workspace = true, features = ["macros"] }
tracing.workspace = true
tracing-subscriber.workspace = true
Expand Down
67 changes: 5 additions & 62 deletions examples/webtransport/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::{time::Duration};
use std::time::Duration;

use anyhow::{Context, Result};
use bytes::{BufMut, Bytes, BytesMut};
Expand Down Expand Up @@ -113,20 +113,16 @@ where
Ok(())
}

#[handler]
async fn index(res: &mut Response) {
res.render(Text::Html(INDEX_HTML));
}

#[tokio::main]
async fn main() {
tracing_subscriber::fmt().init();

let cert = include_bytes!("../certs/cert.pem").to_vec();
let key = include_bytes!("../certs/key.pem").to_vec();

let router = Router::new()
.get(index)
.push(Router::with_path("webtransport").handle(connect));
let router = Router::new().push(Router::with_path("counter").handle(connect)).push(
Router::with_path("<**path>").get(StaticDir::new(["webtransport/static", "./static"]).defaults("client.html")),
);

let config = RustlsConfig::new(Keycert::new().cert(cert.as_slice()).key(key.as_slice()));
let listener = TcpListener::new(("127.0.0.1", 5800)).rustls(config.clone());
Expand All @@ -138,56 +134,3 @@ async fn main() {

Server::new(acceptor).serve(router).await;
}

static INDEX_HTML: &str = r#"<!DOCTYPE html>
<html>
<head>
<title>WebTransport</title>
</head>
<body>
<h1>WebTransport</h1>
<div id="status">
<p><em>Connecting...</em></p>
</div>
<script>
const status = document.getElementById('status');
const url = `https://${location.host}/webtransport`;
useTransport(url);
status.innerHTML = '<p><em>Connected!</em></p>';
async function useTransport(url) {
const transport = await initTransport(url);
let writer = transport.datagrams.writable.getWriter();
let encoder = new TextEncoder('utf-8');
let data = encoder.encode("Hello data");
await writer.write(data);
// When done, close the transport
await closeTransport(transport);
}
async function initTransport(url) {
// Initialize transport connection
const transport = new WebTransport(url);
// The connection can be used once ready fulfills
await transport.ready;
return transport;
}
async function closeTransport(transport) {
// Respond to connection closing
try {
await transport.closed;
console.log(`The HTTP/3 connection to ${url} closed gracefully.`);
} catch (error) {
console.error(`The HTTP/3 connection to ${url} closed due to ${error}.`);
}
}
</script>
</body>
</html>
"#;
84 changes: 84 additions & 0 deletions examples/webtransport/static/client.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
body {
font-family: sans-serif;
}

h1 {
margin: 0 auto;
width: fit-content;
}

h2 {
border-bottom: 1px dotted #333;
font-size: 120%;
font-weight: normal;
padding-bottom: 0.2em;
padding-top: 0.5em;
}

code {
background-color: #eee;
}

input[type=text], textarea {
font-family: monospace;
}

#top {
display: flex;
flex-direction: row-reverse;
flex-wrap: wrap;
justify-content: center;
}

#explanation {
border: 1px dotted black;
font-size: 90%;
height: fit-content;
margin-bottom: 1em;
padding: 1em;
width: 13em;
}

#tool {
flex-grow: 1;
margin: 0 auto;
max-width: 26em;
padding: 0 1em;
width: 26em;
}

.input-line {
display: flex;
}

.input-line input[type=text] {
flex-grow: 1;
margin: 0 0.5em;
}

textarea {
height: 3em;
width: 100%;
}

#send {
margin-top: 0.5em;
width: 15em;
}

#event-log {
border: 1px dotted black;
font-family: monospace;
height: 12em;
overflow: scroll;
padding-bottom: 1em;
padding-top: 1em;
}

.log-error {
color: darkred;
}

#explanation ul {
padding-left: 1em;
}
66 changes: 66 additions & 0 deletions examples/webtransport/static/client.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<!doctype html>
<html lang="en">
<title>WebTransport over HTTP/3 client</title>
<meta charset="utf-8">
<!-- WebTransport origin trial token. See https://developer.chrome.com/origintrials/#/view_trial/793759434324049921 -->
<meta http-equiv="origin-trial" content="AkSQvBVsfMTgBtlakApX94hWGyBPQJXerRc2Aq8g/sKTMF+yG62+bFUB2yIxaK1furrNH3KNNeJV00UZSZHicw4AAABceyJvcmlnaW4iOiJodHRwczovL2dvb2dsZWNocm9tZS5naXRodWIuaW86NDQzIiwiZmVhdHVyZSI6IldlYlRyYW5zcG9ydCIsImV4cGlyeSI6MTY0Mzc1OTk5OX0=">
<script src="client.js"></script>
<link rel="stylesheet" href="client.css">
<meta name="viewport" content="width=device-width, initial-scale=1">
<body>
<div id="top">
<div id="explanation">
This tool can be used to connect to an arbitrary WebTransport server.
It has several limitations:
<ul>
<li>It can only send an entirety of a stream at once. Once the stream
is opened, all of the data is immediately sent, and the write side of
the steam is closed.</li>
<li>This tool does not listen to server-initiated bidirectional
streams.</li>
<li>Stream IDs are different from the one used by QUIC on the wire, as
the on-the-wire IDs are not exposed via the Web API.</li>
<li>The <code>WebTransport</code> object can be accessed using the developer console via <code>currentTransport</code>.</li>
</ul>
</div>
<div id="tool">
<h1>WebTransport over HTTP/3 client</h1>
<div>
<h2>Establish WebTransport connection</h2>
<div class="input-line">
<label for="url">URL:</label>
<input type="text" name="url" id="url"
value="https://127.0.0.1:5800/counter">
<input type="button" id="connect" value="Connect" onclick="connect()">
</div>
</div>
<div>
<h2>Send data over WebTransport</h2>
<form name="sending">
<textarea name="data" id="data"></textarea>
<div>
<input type="radio" name="sendtype" value="datagram"
id="datagram" checked>
<label for="datagram">Send a datagram</label>
</div>
<div>
<input type="radio" name="sendtype" value="unidi" id="unidi-stream">
<label for="unidi-stream">Open a unidirectional stream</label>
</div>
<div>
<input type="radio" name="sendtype" value="bidi" id="bidi-stream">
<label for="bidi-stream">Open a bidirectional stream</label>
</div>
<input type="button" id="send" name="send" value="Send data"
disabled onclick="sendData()">
</form>
</div>
<div>
<h2>Event log</h2>
<ul id="event-log">
</ul>
</div>
</div>
</div>
</body>
</html>
Loading

0 comments on commit 49bc41e

Please sign in to comment.