reqrio/lib.rs
1//!### reqrio is an HTTP request library designed for fast, simple, and convenient HTTP request usage.
2//!
3//! * Features: Low copy, high concurrency, low overhead
4//!
5//! * Supports TLS fingerprinting, which can be configured via hexadecimal, Ja3, or Ja4 TLS handshake settings (**subscription only**).
6//!
7//! * Ensures **request header order** (see [Request Header Order Table](#request-header-order-table)), consistent with browsers.
8//!
9//! * Uses **BoringSSL** to implement TLS, consistent with browsers like Chrome and Edge.
10//!
11//! **Note:** std and cls cannot exist simultaneously, while sync and async can exist simultaneously.
12//!
13//! ### Request Header Order Table
14//!
15//! | No. | HTTP/2.0 | HTTP/1.1 |
16//! |:----|:----------------------------|:--------------------------|
17//! | 1 | cache-control | Host |
18//! | 2 | sec-ch-ua | Connection |
19//! | 3 | sec-ch-ua-mobile | Content-Length |
20//! | 4 | sec-ch-ua-full-version | Authorization |
21//! | 5 | sec-ch-ua-arch | Content-Type |
22//! | 6 | sec-ch-ua-platform | Cache-Control |
23//! | 7 | sec-ch-ua-platform-version | sec-ch-ua |
24//! | 8 | sec-ch-ua-model | sec-ch-ua-mobile |
25//! | 9 | sec-ch-ua-bitness | sec-ch-ua-platform |
26//! | 10 | sec-ch-ua-full-version-list | Upgrade-Insecure-Requests |
27//! | 11 | upgrade-insecure-requests | User-Agent |
28//! | 12 | user-agent | Accept |
29//! | 13 | accept | Sec-Fetch-Site |
30//! | 14 | origin | Sec-Fetch-Mode |
31//! | 15 | sec-fetch-site | Sec-Fetch-User |
32//! | 16 | sec-fetch-mode | Sec-Fetch-Dest |
33//! | 17 | sec-fetch-user | Sec-Fetch-Storage-Access |
34//! | 18 | sec-fetch-dest | Referer |
35//! | 19 | sec-fetch-storage-access | Accept-Encoding |
36//! | 20 | referer | Accept-Language |
37//! | 21 | accept-encoding | Cookie |
38//! | 22 | accept-language | Origin |
39//! | 23 | cookie | |
40//! | 24 | priority | |
41//! | | //unknown | |
42//! | 25 | content-encoding | |
43//! | 26 | content-type | |
44//! | 27 | authorization | |
45//! | 28 | content-type | |
46//!
47//! * Rust HTTP Example
48//!
49//! ```rust
50//! use reqrio::{Fingerprint, ScReq, ALPN};
51//!
52//! fn ff() {
53//! let req = ScReq::new()
54//! //The default is to use http/1.1
55//! .with_alpn(ALPN::Http20)
56//! .with_url("https://www.baidu.com").unwrap();
57//! let headers = json::object! {
58//! "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
59//! "Accept-Encoding": "gzip, deflate, br, zstd",
60//! "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6",
61//! "Cache-Control": "no-cache",
62//! "Connection": "keep-alive",
63//! "Cookie": "__guid=15015764.1071255116101212729.1764940193317.2156; env_webp=1; _S=pvc5q7leemba50e4kn4qis4b95; QiHooGUID=4C8051464B2D97668E3B21198B9CA207.1766289287750; count=1; so-like-red=2; webp=1; so_huid=114r0SZFiQcJKtA38GZgwZg%2Fdit1cjUGuRcsIL2jTn4%2FE%3D; __huid=114r0SZFiQcJKtA38GZgwZg%2Fdit1cjUGuRcsIL2jTn4%2FE%3D; gtHuid=1",
64//! "Host": "m.so.com",
65//! "Pragma": "no-cache",
66//! "Sec-Fetch-Dest": "document",
67//! "Sec-Fetch-Mode": "navigate",
68//! "Sec-Fetch-Site": "none",
69//! "Sec-Fetch-User": "?1",
70//! "Upgrade-Insecure-Requests": 1,
71//! "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/143.0.0.0 Safari/537.36 Edg/143.0.0.0",
72//! "sec-ch-ua": r#""Microsoft Edge";v="143", "Chromium";v="143", "Not A(Brand";v="24""#,
73//! "sec-ch-ua-mobile": "?0",
74//! "sec-ch-ua-platform": r#""Windows""#
75//! };
76//! //By default, there are no request headers; you need to configure them yourself.
77//! req.set_headers_json(header);
78//! let res = req.get().unwrap();
79//! //Get response headers
80//! let header = res.header();
81//! //Get the response body; the body here has already been decoded.
82//! let body = res.decode_body().unwrap();
83//! //Try decoding to JSON
84//! let json = res.json().unwrap();
85//! }
86//! ```
87//!
88//! * Rust WebSocket Example
89//! ```rust
90//! use reqrio::*;
91//!
92//! fn ff() {
93//! let mut ws = WebSocket::sync_build()
94//! .with_url("wss://poe.game.qq.com/").unwrap()
95//! .with_uri("wss://poe.game.qq.com/api/trade2/live/poe2/%E7%93%A6%E5%B0%94%E7%9A%84%E5%AE%BF%E5%91%BD/32Y6Wjkc5").unwrap()
96//! .with_origin("https://poe.game.qq.com").unwrap()
97//! .with_cookie("pac_uid=0_NattYaCs7NNmH; omgid=0_NattYaCs7NNmH; _qimei_uuid42=19c1f11150d1000f92fe16d850a9c40cf94ef1d39f; _qimei_fingerprint=f3dc39297e432b1f08da57e9904a8f52; _qimei_q36=; _qimei_h38=a549811f92fe16d850a9c40c02000006b19c1f; _qpsvr_localtk=0.2296543129537577; RK=WPZCq/wl3I; ptcz=c338dead622f05f0d8467ac10589e7e45326b81d67ff476b9643f933cfdc644a; eas_sid=M1b7q677w9D5R5P2L8x5g4p313; eas_entry=https%3A%2F%2Fgraph.qq.com%2F; POESESSID=939e23af876572a0b2852b2e183e20cc").unwrap()
98//! .with_user_agent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/143.0.0.0 Safari/537.36 Edg/143.0.0.0").unwrap()
99//! .build().unwrap();
100//! loop {
101//! let res = ws.read_frame().unwrap();
102//! match res.frame_type().op_code() {
103//! WsOpcode::CONTINUATION => {}
104//! WsOpcode::TEXT => println!("{}", res.payload().as_bytes().len()),
105//! WsOpcode::BINARY => {}
106//! WsOpcode::CLOSE => {}
107//! WsOpcode::PING => {
108//! println!("PING");
109//! let pong = WsFrame::new_pong(true, res.payload().as_bytes());
110//! ws.write_frame(pong).unwrap();
111//! }
112//! WsOpcode::PONG => {}
113//! }
114//! }
115//! }
116//! ```
117
118use crate::error::HlsResult;
119#[cfg(feature = "aync")]
120pub use acq::AcReq;
121pub use body::BodyType;
122pub use buffer::Buffer;
123pub use error::HlsError;
124pub use ext::{ReqExt, ReqGenExt};
125pub use fingerprint::Fingerprint;
126pub use packet::{
127 Application, Body, ContentType, Cookie, Font, FrameFlag, FrameType, H2Frame, Header, HeaderKey,
128 HeaderValue, HttpStatus, Method, Response, Text, WsFrame, WsOpcode,
129};
130pub use reqrio_json as json;
131pub use reqtls::*;
132pub use scq::ScReq;
133pub use stream::{ProxyStream, WebSocket, WebSocketBuilder, Proxy};
134#[cfg(feature = "aync")]
135pub use stream::TlsStream;
136pub use stream::TlsConfig;
137pub use timeout::Timeout;
138#[cfg(feature = "tokio")]
139pub use tokio;
140pub use url::{Addr, Protocol, Uri, Url, Param};
141
142pub type ReqCallback = Box<dyn FnMut(&[u8]) -> HlsResult<()>>;
143pub const HTTP_GAP: &[u8; 4] = b"\r\n\r\n";
144pub const CHUNK_END: [u8; 5] = [48, 13, 10, 13, 10];
145
146#[cfg(feature = "aync")]
147mod acq;
148mod buffer;
149pub mod hpack;
150mod error;
151#[cfg(feature = "export")]
152mod export;
153mod ext;
154mod file;
155mod packet;
156mod scq;
157mod stream;
158mod timeout;
159mod url;
160mod body;
161mod fingerprint;