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
180 lines
5.7 KiB
Rust
180 lines
5.7 KiB
Rust
extern crate clap;
|
|
extern crate env_logger;
|
|
extern crate term;
|
|
/// Run this cli like this:
|
|
/// cargo run --example server
|
|
/// cargo run --example cli -- ws://127.0.0.1:3012
|
|
extern crate ws;
|
|
|
|
use std::io;
|
|
use std::io::prelude::*;
|
|
use std::sync::mpsc::Sender as TSender;
|
|
use std::sync::mpsc::channel;
|
|
use std::thread;
|
|
|
|
use clap::{App, Arg};
|
|
use ws::{connect, CloseCode, Error, ErrorKind, Handler, Handshake, Message, Result, Sender};
|
|
|
|
fn main() {
|
|
// Setup logging
|
|
env_logger::init();
|
|
|
|
// setup command line arguments
|
|
let matches = App::new("WS Command Line Client")
|
|
.version("1.1")
|
|
.author("Jason Housley <housleyjk@gmail.com>")
|
|
.about("Connect to a WebSocket and send messages from the command line.")
|
|
.arg(
|
|
Arg::with_name("URL")
|
|
.help("The URL of the WebSocket server.")
|
|
.required(true)
|
|
.index(1),
|
|
)
|
|
.get_matches();
|
|
|
|
let url = matches.value_of("URL").unwrap().to_string();
|
|
|
|
let (tx, rx) = channel();
|
|
|
|
// Run client thread with channel to give it's WebSocket message sender back to us
|
|
let client = thread::spawn(move || {
|
|
println!("Connecting to {}", url);
|
|
connect(url, |sender| Client {
|
|
ws_out: sender,
|
|
thread_out: tx.clone(),
|
|
}).unwrap();
|
|
});
|
|
|
|
if let Ok(Event::Connect(sender)) = rx.recv() {
|
|
// If we were able to connect, print the instructions
|
|
instructions();
|
|
|
|
// Main loop
|
|
loop {
|
|
// Get user input
|
|
let mut input = String::new();
|
|
io::stdin().read_line(&mut input).unwrap();
|
|
|
|
if let Ok(Event::Disconnect) = rx.try_recv() {
|
|
break;
|
|
}
|
|
|
|
if input.starts_with("/h") {
|
|
// Show help
|
|
instructions()
|
|
} else if input.starts_with("/c") {
|
|
// If the close arguments are good, close the connection
|
|
let args: Vec<&str> = input.split(' ').collect();
|
|
if args.len() == 1 {
|
|
// Simple close
|
|
println!("Closing normally, please wait...");
|
|
sender.close(CloseCode::Normal).unwrap();
|
|
} else if args.len() == 2 {
|
|
// Close with a specific code
|
|
if let Ok(code) = args[1].trim().parse::<u16>() {
|
|
let code = CloseCode::from(code);
|
|
println!("Closing with code: {:?}, please wait...", code);
|
|
sender.close(code).unwrap();
|
|
} else {
|
|
display(&format!("Unable to parse {} as close code.", args[1]));
|
|
// Keep accepting input if the close arguments are invalid
|
|
continue;
|
|
}
|
|
} else {
|
|
// Close with a code and a reason
|
|
if let Ok(code) = args[1].trim().parse::<u16>() {
|
|
let code = CloseCode::from(code);
|
|
let reason = args[2..].join(" ");
|
|
println!(
|
|
"Closing with code: {:?} and reason: {}, please wait...",
|
|
code,
|
|
reason.trim()
|
|
);
|
|
sender
|
|
.close_with_reason(code, reason.trim().to_string())
|
|
.unwrap();
|
|
} else {
|
|
display(&format!("Unable to parse {} as close code.", args[1]));
|
|
// Keep accepting input if the close arguments are invalid
|
|
continue;
|
|
}
|
|
}
|
|
break;
|
|
} else {
|
|
// Send the message
|
|
display(&format!(">>> {}", input.trim()));
|
|
sender.send(input.trim()).unwrap();
|
|
}
|
|
}
|
|
}
|
|
|
|
// Ensure the client has a chance to finish up
|
|
client.join().unwrap();
|
|
}
|
|
|
|
fn display(string: &str) {
|
|
let mut view = term::stdout().unwrap();
|
|
view.carriage_return().unwrap();
|
|
view.delete_line().unwrap();
|
|
println!("{}", string);
|
|
print!("?> ");
|
|
io::stdout().flush().unwrap();
|
|
}
|
|
|
|
fn instructions() {
|
|
println!("Type /close [code] [reason] to close the connection.");
|
|
println!("Type /help to show these instructions.");
|
|
println!("Other input will be sent as messages.\n");
|
|
print!("?> ");
|
|
io::stdout().flush().unwrap();
|
|
}
|
|
|
|
struct Client {
|
|
ws_out: Sender,
|
|
thread_out: TSender<Event>,
|
|
}
|
|
|
|
impl Handler for Client {
|
|
fn on_open(&mut self, _: Handshake) -> Result<()> {
|
|
self.thread_out
|
|
.send(Event::Connect(self.ws_out.clone()))
|
|
.map_err(|err| {
|
|
Error::new(
|
|
ErrorKind::Internal,
|
|
format!("Unable to communicate between threads: {:?}.", err),
|
|
)
|
|
})
|
|
}
|
|
|
|
fn on_message(&mut self, msg: Message) -> Result<()> {
|
|
display(&format!("<<< {}", msg));
|
|
Ok(())
|
|
}
|
|
|
|
fn on_close(&mut self, code: CloseCode, reason: &str) {
|
|
if reason.is_empty() {
|
|
display(&format!(
|
|
"<<< Closing<({:?})>\nHit any key to end session.",
|
|
code
|
|
));
|
|
} else {
|
|
display(&format!(
|
|
"<<< Closing<({:?}) {}>\nHit any key to end session.",
|
|
code, reason
|
|
));
|
|
}
|
|
|
|
if let Err(err) = self.thread_out.send(Event::Disconnect) {
|
|
display(&format!("{:?}", err))
|
|
}
|
|
}
|
|
|
|
fn on_error(&mut self, err: Error) {
|
|
display(&format!("<<< Error<{:?}>", err))
|
|
}
|
|
}
|
|
|
|
enum Event {
|
|
Connect(Sender),
|
|
Disconnect,
|
|
}
|