From 24f8f1afd8153a048256d134ad710c99dc81a30e Mon Sep 17 00:00:00 2001 From: hatoo Date: Wed, 30 Oct 2024 22:08:19 +0900 Subject: [PATCH] move websocket codes to example --- Cargo.toml | 5 +-- examples/websocket.rs | 86 +++++++++++++++++++++++++++++++++++++++++-- src/default_client.rs | 82 ----------------------------------------- 3 files changed, 83 insertions(+), 90 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 7bfd830..1b22a5a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,9 +13,6 @@ keywords = ["http", "proxy", "http-proxy"] # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html -[features] -websocket = ["dep:winnow"] - [dependencies] tokio = { version = "1.39.3", features = [ "macros", @@ -46,7 +43,7 @@ clap = { version = "4.5.16", features = ["derive"] } rcgen = { version = "0.13.1", features = ["x509-parser"] } reqwest = { version = "0.12.7", features = ["native-tls-alpn"] } tracing-subscriber = { version = "0.3.18", features = ["env-filter"] } +winnow = "0.6.20" [[example]] name = "websocket" -required-features = ["websocket"] diff --git a/examples/websocket.rs b/examples/websocket.rs index b5fc289..874d67a 100644 --- a/examples/websocket.rs +++ b/examples/websocket.rs @@ -1,10 +1,7 @@ use std::path::PathBuf; use clap::{Args, Parser}; -use http_mitm_proxy::{ - default_client::{websocket, Upgraded}, - DefaultClient, MitmProxy, -}; +use http_mitm_proxy::{default_client::Upgraded, DefaultClient, MitmProxy}; use moka::sync::Cache; use tokio::io::{AsyncReadExt, AsyncWriteExt}; use tracing_subscriber::EnvFilter; @@ -191,3 +188,84 @@ async fn main() { server.await; } + +pub mod websocket { + /* + https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API/Writing_WebSocket_servers + Frame format: + + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-------+-+-------------+-------------------------------+ + |F|R|R|R| opcode|M| Payload len | Extended payload length | + |I|S|S|S| (4) |A| (7) | (16/64) | + |N|V|V|V| |S| | (if payload len==126/127) | + | |1|2|3| |K| | | + +-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - + + | Extended payload length continued, if payload len == 127 | + + - - - - - - - - - - - - - - - +-------------------------------+ + | |Masking-key, if MASK set to 1 | + +-------------------------------+-------------------------------+ + | Masking-key (continued) | Payload Data | + +-------------------------------- - - - - - - - - - - - - - - - + + : Payload Data continued ... : + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + | Payload Data continued ... | + +---------------------------------------------------------------+ + + */ + + use winnow::{ + binary::{be_u16, be_u64, u8}, + prelude::*, + token::take, + }; + + pub struct Frame { + pub b0: u8, + pub b1: u8, + pub payload_len: usize, + pub masking_key: Option<[u8; 4]>, + pub payload_data: Vec, + } + + pub fn frame(input: &mut &[u8]) -> PResult { + let b0 = u8(input)?; + let b1 = u8(input)?; + + let payload_len = match b1 & 0b0111_1111 { + 126 => { + let len = be_u16(input)?; + len as usize + } + 127 => { + let len = be_u64(input)?; + len as usize + } + len => len as usize, + }; + + let mask = b1 & 0b1000_0000 != 0; + let masking_key = if mask { + Some([u8(input)?, u8(input)?, u8(input)?, u8(input)?]) + } else { + None + }; + + let mut payload_data = take(payload_len).parse_next(input)?.to_vec(); + + if let Some(mask) = masking_key { + for (i, byte) in payload_data.iter_mut().enumerate() { + *byte ^= mask[i % 4]; + } + } + + Ok(Frame { + b0, + b1, + payload_len, + masking_key, + payload_data, + }) + } +} diff --git a/src/default_client.rs b/src/default_client.rs index eff548e..b86010a 100644 --- a/src/default_client.rs +++ b/src/default_client.rs @@ -249,85 +249,3 @@ fn remove_authority(req: &mut Request) { parts.authority = None; *req.uri_mut() = Uri::from_parts(parts).unwrap(); } - -#[cfg(feature = "websocket")] -pub mod websocket { - /* - https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API/Writing_WebSocket_servers - Frame format: - - 0 1 2 3 - 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 - +-+-+-+-+-------+-+-------------+-------------------------------+ - |F|R|R|R| opcode|M| Payload len | Extended payload length | - |I|S|S|S| (4) |A| (7) | (16/64) | - |N|V|V|V| |S| | (if payload len==126/127) | - | |1|2|3| |K| | | - +-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - + - | Extended payload length continued, if payload len == 127 | - + - - - - - - - - - - - - - - - +-------------------------------+ - | |Masking-key, if MASK set to 1 | - +-------------------------------+-------------------------------+ - | Masking-key (continued) | Payload Data | - +-------------------------------- - - - - - - - - - - - - - - - + - : Payload Data continued ... : - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - | Payload Data continued ... | - +---------------------------------------------------------------+ - - */ - - use winnow::{ - binary::{be_u16, be_u64, u8}, - prelude::*, - token::take, - }; - - pub struct Frame { - pub b0: u8, - pub b1: u8, - pub payload_len: usize, - pub masking_key: Option<[u8; 4]>, - pub payload_data: Vec, - } - - pub fn frame(input: &mut &[u8]) -> PResult { - let b0 = u8(input)?; - let b1 = u8(input)?; - - let payload_len = match b1 & 0b0111_1111 { - 126 => { - let len = be_u16(input)?; - len as usize - } - 127 => { - let len = be_u64(input)?; - len as usize - } - len => len as usize, - }; - - let mask = b1 & 0b1000_0000 != 0; - let masking_key = if mask { - Some([u8(input)?, u8(input)?, u8(input)?, u8(input)?]) - } else { - None - }; - - let mut payload_data = take(payload_len).parse_next(input)?.to_vec(); - - if let Some(mask) = masking_key { - for (i, byte) in payload_data.iter_mut().enumerate() { - *byte ^= mask[i % 4]; - } - } - - Ok(Frame { - b0, - b1, - payload_len, - masking_key, - payload_data, - }) - } -}