forked from mirrors/gecko-dev
It was unhappy about the new LICENSE (fuchsia-cprng) but it's the same as the other fuschia crates. Since I don't think this is used at build time but has the same license as the other fuschia crates, I put it in the RUNTIME_LICENSE_PACKAGE_WHITELIST list. I also removed sha1 from that list as it's not used anymore Differential Revision: https://phabricator.services.mozilla.com/D30746 --HG-- rename : third_party/rust/httparse/Cargo.toml => third_party/rust/autocfg/Cargo.toml rename : third_party/rust/rand/LICENSE-APACHE => third_party/rust/autocfg/LICENSE-APACHE rename : third_party/rust/rand/LICENSE-MIT => third_party/rust/autocfg/LICENSE-MIT rename : third_party/rust/httparse/Cargo.toml => third_party/rust/cloudabi/Cargo.toml rename : third_party/rust/httparse/Cargo.toml => third_party/rust/fuchsia-cprng/Cargo.toml rename : third_party/rust/sha1/LICENSE => third_party/rust/fuchsia-cprng/LICENSE rename : third_party/rust/rand/LICENSE-APACHE => third_party/rust/mio-extras/LICENSE-APACHE rename : third_party/rust/rand/LICENSE-MIT => third_party/rust/mio-extras/LICENSE-MIT rename : third_party/rust/rand/.cargo-checksum.json => third_party/rust/rand-0.4.3/.cargo-checksum.json rename : third_party/rust/rand/CHANGELOG.md => third_party/rust/rand-0.4.3/CHANGELOG.md rename : third_party/rust/rand/Cargo.toml => third_party/rust/rand-0.4.3/Cargo.toml rename : third_party/rust/rand/LICENSE-APACHE => third_party/rust/rand-0.4.3/LICENSE-APACHE rename : third_party/rust/rand/LICENSE-MIT => third_party/rust/rand-0.4.3/LICENSE-MIT rename : third_party/rust/rand/README.md => third_party/rust/rand-0.4.3/README.md rename : third_party/rust/rand/appveyor.yml => third_party/rust/rand-0.4.3/appveyor.yml rename : third_party/rust/rand/benches/bench.rs => third_party/rust/rand-0.4.3/benches/bench.rs rename : third_party/rust/rand/benches/distributions/exponential.rs => third_party/rust/rand-0.4.3/benches/distributions/exponential.rs rename : third_party/rust/rand/benches/distributions/gamma.rs => third_party/rust/rand-0.4.3/benches/distributions/gamma.rs rename : third_party/rust/rand/benches/distributions/mod.rs => third_party/rust/rand-0.4.3/benches/distributions/mod.rs rename : third_party/rust/rand/benches/distributions/normal.rs => third_party/rust/rand-0.4.3/benches/distributions/normal.rs rename : third_party/rust/rand/benches/generators.rs => third_party/rust/rand-0.4.3/benches/generators.rs rename : third_party/rust/rand/benches/misc.rs => third_party/rust/rand-0.4.3/benches/misc.rs rename : third_party/rust/rand/src/distributions/exponential.rs => third_party/rust/rand-0.4.3/src/distributions/exponential.rs rename : third_party/rust/rand/src/distributions/gamma.rs => third_party/rust/rand-0.4.3/src/distributions/gamma.rs rename : third_party/rust/rand/src/distributions/mod.rs => third_party/rust/rand-0.4.3/src/distributions/mod.rs rename : third_party/rust/rand/src/distributions/normal.rs => third_party/rust/rand-0.4.3/src/distributions/normal.rs rename : third_party/rust/rand/src/distributions/range.rs => third_party/rust/rand-0.4.3/src/distributions/range.rs rename : third_party/rust/rand/src/distributions/ziggurat_tables.rs => third_party/rust/rand-0.4.3/src/distributions/ziggurat_tables.rs rename : third_party/rust/rand/src/jitter.rs => third_party/rust/rand-0.4.3/src/jitter.rs rename : third_party/rust/rand/src/lib.rs => third_party/rust/rand-0.4.3/src/lib.rs rename : third_party/rust/rand/src/os.rs => third_party/rust/rand-0.4.3/src/os.rs rename : third_party/rust/rand/src/prng/chacha.rs => third_party/rust/rand-0.4.3/src/prng/chacha.rs rename : third_party/rust/rand/src/prng/isaac.rs => third_party/rust/rand-0.4.3/src/prng/isaac.rs rename : third_party/rust/rand/src/prng/isaac64.rs => third_party/rust/rand-0.4.3/src/prng/isaac64.rs rename : third_party/rust/rand/src/prng/mod.rs => third_party/rust/rand-0.4.3/src/prng/mod.rs rename : third_party/rust/rand/src/prng/xorshift.rs => third_party/rust/rand-0.4.3/src/prng/xorshift.rs rename : third_party/rust/rand/src/rand_impls.rs => third_party/rust/rand-0.4.3/src/rand_impls.rs rename : third_party/rust/rand/src/read.rs => third_party/rust/rand-0.4.3/src/read.rs rename : third_party/rust/rand/src/reseeding.rs => third_party/rust/rand-0.4.3/src/reseeding.rs rename : third_party/rust/rand/src/seq.rs => third_party/rust/rand-0.4.3/src/seq.rs rename : third_party/rust/rand/utils/ziggurat_tables.py => third_party/rust/rand-0.4.3/utils/ziggurat_tables.py rename : third_party/rust/rand/LICENSE-APACHE => third_party/rust/rand_chacha/LICENSE-APACHE rename : third_party/rust/rand/LICENSE-MIT => third_party/rust/rand_chacha/LICENSE-MIT rename : third_party/rust/rand/LICENSE-APACHE => third_party/rust/rand_core-0.3.1/LICENSE-APACHE rename : third_party/rust/rand/LICENSE-MIT => third_party/rust/rand_core-0.3.1/LICENSE-MIT rename : third_party/rust/rand/LICENSE-APACHE => third_party/rust/rand_core/LICENSE-APACHE rename : third_party/rust/rand/LICENSE-MIT => third_party/rust/rand_core/LICENSE-MIT rename : third_party/rust/httparse/Cargo.toml => third_party/rust/rand_hc/Cargo.toml rename : third_party/rust/rand/LICENSE-APACHE => third_party/rust/rand_hc/LICENSE-APACHE rename : third_party/rust/rand/LICENSE-MIT => third_party/rust/rand_hc/LICENSE-MIT rename : third_party/rust/rand/LICENSE-APACHE => third_party/rust/rand_isaac/LICENSE-APACHE rename : third_party/rust/rand/LICENSE-MIT => third_party/rust/rand_isaac/LICENSE-MIT rename : third_party/rust/rand/LICENSE-APACHE => third_party/rust/rand_jitter/LICENSE-APACHE rename : third_party/rust/rand/LICENSE-MIT => third_party/rust/rand_jitter/LICENSE-MIT rename : third_party/rust/rand/src/jitter.rs => third_party/rust/rand_jitter/src/lib.rs rename : third_party/rust/rand/LICENSE-APACHE => third_party/rust/rand_os/LICENSE-APACHE rename : third_party/rust/rand/LICENSE-MIT => third_party/rust/rand_os/LICENSE-MIT rename : third_party/rust/rand/LICENSE-APACHE => third_party/rust/rand_pcg/LICENSE-APACHE rename : third_party/rust/rand/LICENSE-MIT => third_party/rust/rand_pcg/LICENSE-MIT rename : third_party/rust/rand/LICENSE-APACHE => third_party/rust/rand_xorshift/LICENSE-APACHE rename : third_party/rust/rand/LICENSE-MIT => third_party/rust/rand_xorshift/LICENSE-MIT rename : third_party/rust/httparse/Cargo.toml => third_party/rust/rdrand/Cargo.toml rename : third_party/rust/rand/LICENSE-APACHE => third_party/rust/sha-1/LICENSE-APACHE rename : third_party/rust/rand/LICENSE-MIT => third_party/rust/sha-1/LICENSE-MIT extra : moz-landing-system : lando
130 lines
4 KiB
Rust
130 lines
4 KiB
Rust
extern crate env_logger;
|
|
extern crate mio_extras;
|
|
extern crate time;
|
|
/// An example demonstrating how to send and recieve a custom ping/pong frame.
|
|
extern crate ws;
|
|
|
|
use std::str::from_utf8;
|
|
|
|
use mio_extras::timer::Timeout;
|
|
|
|
use ws::util::Token;
|
|
use ws::{listen, CloseCode, Error, ErrorKind, Frame, Handler, Handshake, Message, OpCode, Result,
|
|
Sender};
|
|
|
|
const PING: Token = Token(1);
|
|
const EXPIRE: Token = Token(2);
|
|
|
|
fn main() {
|
|
// Setup logging
|
|
env_logger::init();
|
|
|
|
// Run the WebSocket
|
|
listen("127.0.0.1:3012", |out| Server {
|
|
out,
|
|
ping_timeout: None,
|
|
expire_timeout: None,
|
|
}).unwrap();
|
|
}
|
|
|
|
// Server WebSocket handler
|
|
struct Server {
|
|
out: Sender,
|
|
ping_timeout: Option<Timeout>,
|
|
expire_timeout: Option<Timeout>,
|
|
}
|
|
|
|
impl Handler for Server {
|
|
fn on_open(&mut self, _: Handshake) -> Result<()> {
|
|
// schedule a timeout to send a ping every 5 seconds
|
|
self.out.timeout(5_000, PING)?;
|
|
// schedule a timeout to close the connection if there is no activity for 30 seconds
|
|
self.out.timeout(30_000, EXPIRE)
|
|
}
|
|
|
|
fn on_message(&mut self, msg: Message) -> Result<()> {
|
|
println!("Server got message '{}'. ", msg);
|
|
self.out.send(msg)
|
|
}
|
|
|
|
fn on_close(&mut self, code: CloseCode, reason: &str) {
|
|
println!("WebSocket closing for ({:?}) {}", code, reason);
|
|
|
|
// NOTE: This code demonstrates cleaning up timeouts
|
|
if let Some(t) = self.ping_timeout.take() {
|
|
self.out.cancel(t).unwrap();
|
|
}
|
|
if let Some(t) = self.expire_timeout.take() {
|
|
self.out.cancel(t).unwrap();
|
|
}
|
|
|
|
println!("Shutting down server after first connection closes.");
|
|
self.out.shutdown().unwrap();
|
|
}
|
|
|
|
fn on_error(&mut self, err: Error) {
|
|
// Shutdown on any error
|
|
println!("Shutting down server for error: {}", err);
|
|
self.out.shutdown().unwrap();
|
|
}
|
|
|
|
fn on_timeout(&mut self, event: Token) -> Result<()> {
|
|
match event {
|
|
// PING timeout has occured, send a ping and reschedule
|
|
PING => {
|
|
self.out.ping(time::precise_time_ns().to_string().into())?;
|
|
self.ping_timeout.take();
|
|
self.out.timeout(5_000, PING)
|
|
}
|
|
// EXPIRE timeout has occured, this means that the connection is inactive, let's close
|
|
EXPIRE => self.out.close(CloseCode::Away),
|
|
// No other timeouts are possible
|
|
_ => Err(Error::new(
|
|
ErrorKind::Internal,
|
|
"Invalid timeout token encountered!",
|
|
)),
|
|
}
|
|
}
|
|
|
|
fn on_new_timeout(&mut self, event: Token, timeout: Timeout) -> Result<()> {
|
|
// Cancel the old timeout and replace.
|
|
if event == EXPIRE {
|
|
if let Some(t) = self.expire_timeout.take() {
|
|
self.out.cancel(t)?
|
|
}
|
|
self.expire_timeout = Some(timeout)
|
|
} else {
|
|
// This ensures there is only one ping timeout at a time
|
|
if let Some(t) = self.ping_timeout.take() {
|
|
self.out.cancel(t)?
|
|
}
|
|
self.ping_timeout = Some(timeout)
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
|
|
fn on_frame(&mut self, frame: Frame) -> Result<Option<Frame>> {
|
|
// If the frame is a pong, print the round-trip time.
|
|
// The pong should contain data from out ping, but it isn't guaranteed to.
|
|
if frame.opcode() == OpCode::Pong {
|
|
if let Ok(pong) = from_utf8(frame.payload())?.parse::<u64>() {
|
|
let now = time::precise_time_ns();
|
|
println!("RTT is {:.3}ms.", (now - pong) as f64 / 1_000_000f64);
|
|
} else {
|
|
println!("Received bad pong.");
|
|
}
|
|
}
|
|
|
|
// Some activity has occured, so reset the expiration
|
|
self.out.timeout(30_000, EXPIRE)?;
|
|
|
|
// Run default frame validation
|
|
DefaultHandler.on_frame(frame)
|
|
}
|
|
}
|
|
|
|
// For accessing the default handler implementation
|
|
struct DefaultHandler;
|
|
|
|
impl Handler for DefaultHandler {}
|