Repository: websockets-rs/rust-websocket (language: rust)

Issue:
Avoid server panic on UnsupportedWebsocketVersion
```
cargo run --example async-server
    Finished dev [unoptimized + debuginfo] target(s) in 0.0 secs
     Running `target/debug/examples/async-server`
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: UnsupportedWebsocketVersion', /checkout/src/libcore/result.rs:906:4
note: Run with `RUST_BACKTRACE=1` for a backtrace.
```

```
wscat -p "8" -c "localhost:2794"
```

This is I guess not necessarily related to the WebsocketVersion but maybe more to how to handle errors in general which occur here:
```
server.incoming()
        // we don't wanna save the stream if it drops
.map_err(|InvalidConnection { error, .. }| error)
```

Is there any guidance on how to avoid that the server crashes when one client tries to establish a connection in such a way ? Basically close the client connection and continue to serve new clients.


Discussion / hints:

Fix patch:
diff --git a/examples/async-server.rs b/examples/async-server.rs
index 5b79ea714b..5794712ae5 100644
--- a/examples/async-server.rs
+++ b/examples/async-server.rs
@@ -8,7 +8,7 @@ use websocket::async::Server;
 use websocket::message::{Message, OwnedMessage};
 use websocket::server::InvalidConnection;
 
-use futures::{Future, Sink, Stream};
+use futures::{future, Future, Sink, Stream};
 use tokio::runtime::TaskExecutor;
 
 fn main() {
@@ -23,8 +23,18 @@ fn main() {
 	// a stream of incoming connections
 	let f = server
 		.incoming()
-		// we don't wanna save the stream if it drops
-		.map_err(|InvalidConnection { error, .. }| error)
+		.then(future::ok) // wrap good and bad events into future::ok
+		.filter(|event| {
+			match event {
+				Ok(_) => true, // a good connection
+				Err(InvalidConnection { ref error, .. }) => {
+					println!("Bad client: {}", error);
+					false // we want to save the stream if a client cannot make a valid handshake
+				}
+			}
+		})
+		.and_then(|event| event) // unwrap good connections
+		.map_err(|_| ()) // and silently ignore errors (in `.filter`)
 		.for_each(move |(upgrade, addr)| {
 			println!("Got a connection from: {}", addr);
 			// check if it has the protocol we want


Test patch: