WebSocketConfig extended to allow accepting unmasked client frames
This commit is contained in:
parent
a7daafdfc8
commit
0121bf9682
|
@ -0,0 +1,50 @@
|
|||
use std::{net::TcpListener, thread::spawn};
|
||||
use tungstenite::{
|
||||
handshake::server::{Request, Response},
|
||||
protocol::WebSocketConfig,
|
||||
server::accept_hdr_with_config,
|
||||
};
|
||||
|
||||
fn main() {
|
||||
env_logger::init();
|
||||
let server = TcpListener::bind("127.0.0.1:3012").unwrap();
|
||||
for stream in server.incoming() {
|
||||
spawn(move || {
|
||||
let callback = |req: &Request, mut response: Response| {
|
||||
println!("Received a new ws handshake");
|
||||
println!("The request's path is: {}", req.uri().path());
|
||||
println!("The request's headers are:");
|
||||
for (ref header, _value) in req.headers() {
|
||||
println!("* {}", header);
|
||||
}
|
||||
|
||||
// Let's add an additional header to our response to the client.
|
||||
let headers = response.headers_mut();
|
||||
headers.append("MyCustomHeader", ":)".parse().unwrap());
|
||||
headers.append("SOME_TUNGSTENITE_HEADER", "header_value".parse().unwrap());
|
||||
|
||||
Ok(response)
|
||||
};
|
||||
|
||||
let config = Some(WebSocketConfig {
|
||||
max_send_queue: None,
|
||||
max_message_size: None,
|
||||
max_frame_size: None,
|
||||
// This setting allows to accept client frames which are not masked
|
||||
// This is not in compliance with RFC 6455 but might be handy in some
|
||||
// rare cases where it is necessary to integrate with existing/legacy
|
||||
// clients which are sending unmasked frames
|
||||
server_allow_unmasked: Some(true),
|
||||
});
|
||||
|
||||
let mut websocket = accept_hdr_with_config(stream.unwrap(), callback, config).unwrap();
|
||||
|
||||
loop {
|
||||
let msg = websocket.read_message().unwrap();
|
||||
if msg.is_binary() || msg.is_text() {
|
||||
println!("received message {}", msg);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
|
@ -50,6 +50,11 @@ pub struct WebSocketConfig {
|
|||
/// be reasonably big for all normal use-cases but small enough to prevent memory eating
|
||||
/// by a malicious user.
|
||||
pub max_frame_size: Option<usize>,
|
||||
/// If set to true it will allow the websocket server to accept unmasked frames from client.
|
||||
/// Even though this behaviour is not in compliance with RFC 6455 (which requires the server
|
||||
/// to close the connection when unmasked frame from client is received) it might be handy in some cases
|
||||
/// as there are existing applications sending unmasked client frames.
|
||||
pub server_allow_unmasked: Option<bool>,
|
||||
}
|
||||
|
||||
impl Default for WebSocketConfig {
|
||||
|
@ -58,6 +63,7 @@ impl Default for WebSocketConfig {
|
|||
max_send_queue: None,
|
||||
max_message_size: Some(64 << 20),
|
||||
max_frame_size: Some(16 << 20),
|
||||
server_allow_unmasked: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -449,9 +455,22 @@ impl WebSocketContext {
|
|||
} else {
|
||||
// The server MUST close the connection upon receiving a
|
||||
// frame that is not masked. (RFC 6455)
|
||||
return Err(Error::Protocol(
|
||||
"Received an unmasked frame from client".into(),
|
||||
));
|
||||
// The only exception here is if the user explicitly accepts given
|
||||
// stream (by tungstenite::server::accept_with_config or tungstenite::server::accept_hdr_with_config)
|
||||
// with WebSocketConfig.server_allow_unmasked set to Some(true)
|
||||
if let Some(server_allow_unmasked_val) =
|
||||
self.get_config().server_allow_unmasked
|
||||
{
|
||||
if server_allow_unmasked_val == false {
|
||||
return Err(Error::Protocol(
|
||||
"Received an unmasked frame from client".into(),
|
||||
));
|
||||
}
|
||||
} else {
|
||||
return Err(Error::Protocol(
|
||||
"Received an unmasked frame from client".into(),
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
Role::Client => {
|
||||
|
|
Loading…
Reference in New Issue