Files
locutus-server/src/websocket/mod.rs

107 lines
2.3 KiB
Rust

mod handler;
use serde::{Deserialize, Serialize};
use crate::error::Error;
use crate::http;
pub use handler::*;
pub struct WebSocketStream {
stream: http::HttpStream,
compression: bool,
}
pub struct FrameHeader {
fin: bool,
rsv1: bool,
rsv2: bool,
rsv3: bool,
opcode: u8,
mask: bool,
payload_len: u8,
ex_payload_len: Option<u64>,
masking_key: Option<u32>,
}
pub enum Message {
PingMessage(PingMessage),
PongMessage(PongMessage),
CloseMessage(CloseMessage),
TextMessage(TextMessage),
}
pub struct PingMessage {
data: String,
}
pub struct PongMessage {
data: String,
}
pub struct CloseMessage {
code: Option<u16>,
reason: Option<String>,
}
pub struct TextMessage {
data: String,
}
#[derive(Serialize, Deserialize)]
pub struct RequestEnvelope {
endpoint: String,
request_nr: u64,
data: serde_json::Value,
}
#[derive(Serialize, Deserialize)]
pub struct ResponseEnvelope {
to_request_nr: u64,
status: String,
message: Option<String>,
data: serde_json::Value,
}
impl FrameHeader {
pub fn from(socket: &mut http::Stream) -> Result<Self, Error> {
let mut data = [0u8; 2];
socket.read_exact(&mut data)?;
let mut header = FrameHeader {
fin: data[0] & 0x80 != 0,
rsv1: data[0] & 0x40 != 0,
rsv2: data[0] & 0x20 != 0,
rsv3: data[0] & 0x10 != 0,
opcode: data[0] & 0x0F,
mask: data[1] & 0x80 != 0,
payload_len: data[1] & 0x7F,
ex_payload_len: None,
masking_key: None,
};
if header.payload_len == 126 {
let mut data = [0u8; 2];
socket.read_exact(&mut data)?;
header.ex_payload_len = Some(u16::from_be_bytes(data) as u64);
} else if header.payload_len == 127 {
let mut data = [0u8; 8];
socket.read_exact(&mut data)?;
header.ex_payload_len = Some(u64::from_be_bytes(data));
}
if header.mask {
let mut data = [0u8; 4];
socket.read_exact(&mut data)?;
header.masking_key = Some(u32::from_be_bytes(data));
}
Ok(header)
}
pub fn payload_len(&self) -> u64 {
match self.ex_payload_len {
Some(val) => val,
None => self.payload_len as u64,
}
}
}