1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
//! Lightweight websocket implement for stream transmission.
//!
//! ## Features
//!
//! - Avoid heap allocation.
//! - Avoid buffering frame payload.
//! - Use vectored-io if available.
//! - Transparent Read/Write over the underlying IO source.
//!
//! ## High-level API
//!
//! - [`role`]
//! - [`endpoint`]
//! - [`stream`]
//!
//! Std:
//!
//! ```no_run
//! use std::io::{Read, Write};
//! use std::net::TcpStream;
//! use lightws::role::Client;
//! use lightws::endpoint::Endpoint;
//! fn run_sync() -> std::io::Result<()> {
//! let mut buf = [0u8; 256];
//! // establish tcp connection
//! let mut tcp = TcpStream::connect("example.com:80")?;
//! // establish ws connection
//! let mut ws = Endpoint::<TcpStream, Client>::connect(tcp, &mut buf, "example.com", "/ws")?;
//! // read some data
//! let n = ws.read(&mut buf)?;
//! // write some data
//! let n = ws.write(&buf)?;
//! Ok(())
//! }
//! ```
//!
//! Tokio:
//!
//! ```no_run
//! use tokio::net::TcpStream;
//! use tokio::io::{AsyncReadExt, AsyncWriteExt};
//! use lightws::role::Client;
//! use lightws::endpoint::Endpoint;
//! async fn run_async() -> std::io::Result<()> {
//! let mut buf = [0u8; 256];
//! // establish tcp connection
//! let mut tcp = TcpStream::connect("example.com:80").await?;
//! // establish ws connection
//! let mut ws = Endpoint::<TcpStream, Client>::connect_async(tcp, &mut buf, "example.com", "/ws").await?;
//! // read some data
//! let n = ws.read(&mut buf).await?;
//! // write some data
//! let n = ws.write(&buf).await?;
//! Ok(())
//! }
//! ```
//!
//! ## Low-level API
//!
//! - [`frame`]
//! - [`handshake`]
//!
//! Frame:
//!
//! ```no_run
//! use lightws::frame::{FrameHead, Fin, OpCode, PayloadLen, Mask};
//! {
//! let mut buf = [0u8; 14];
//! // crate a frame head
//! let head = FrameHead::new(
//! Fin::N, OpCode::Binary,
//! Mask::None, PayloadLen::from_num(256)
//! );
//! // encode to buffer
//! let offset = unsafe {
//! head.encode_unchecked(&mut buf);
//! };
//! // decode from buffer
//! let (head, offset) = FrameHead::decode(&buf).unwrap();
//! }
//! ```
//!
//! Handshake:
//!
//! ```no_run
//! use lightws::handshake::{Request, Response, HttpHeader};
//! {
//! let mut buf = [0u8; 256];
//! // make a client handshake request
//! let request = Request::new(b"/ws", b"example.com", b"sec-key..");
//! let offset = request.encode(&mut buf).unwrap();
//!
//! // parse a server handshake response
//! let mut custom_headers = HttpHeader::new_storage();
//! let mut response = Response::new_storage(&mut custom_headers);
//! let offset = response.decode(&buf).unwrap();
//! }
//! ```