用Rust写一个批量HTTP REST请求工具
2022 Nov 08
See all posts
把一个日常用的小工具用Rust重写一下,以前都是快速写个Python
脚本自己跑,但是现在要给同事用,同事的电脑是Mac
M1,不想装Python,Python程序打出来的包太大了,放弃。
用Go
或Rust
是不错的选择,生成的可执行文件小,还可以很方便跨平台打包。本着哪壶不开提哪壶的原则,选用Rust
吧。
功能很简单,批量发http
rest请求,主要涉及到从配置文件读取cookie信息以及各种配置如限速,从业务文件读取业务参数,然后分批发HTTP
REST请求。
核心代码如下:
async fn do_bat_del(config: &BasicConfig) -> bool {
const UID_FILE_NAME: &str = "uid_list.txt";
let lines = read_lines_to_list(UID_FILE_NAME).unwrap_or_else(|err| {
error!("Failed to read file: {:?}, {}", UID_FILE_NAME, err);
Vec::new()
});
match req::req_proc::get_client(&config.cookie_str) {
Ok(client) => {
let mut i: u32 = 0;
let semaphore = Semaphore::new(1);
for line in lines {
match line.parse::<u64>() {
Ok(uid) => {
let permit = semaphore.acquire().await.unwrap();
req::req_proc::delete(&client, &config.host_url, uid)
.await
.map(|v| info!("{}, success for uid: {:?}, {}", i + 1, uid, v))
.unwrap_or_else(|err| error!("{}, fail for uid: {:?}, {}", i + 1, uid, err));
drop(permit);
}
Err(err) => {
error!("{}, illegal uid: {:?}, {}", i + 1, line, err)
}
}
i += 1;
if i % config.max_ops == 0 {
info!("Start sleep {} seconds", config.sleep_secs_after_max_ops);
tokio::time::sleep(time::Duration::from_secs(config.sleep_secs_after_max_ops)).await;
};
}
}
Err(err) => {
error!("Failed to initialize HttpClient, {}", err);
}
};
true
}
use std::{collections::HashMap, time::Duration};
use super::ReqError;
pub fn get_client(cookie: &str) -> Result<reqwest::Client, ReqError> {
let mut headers = http::HeaderMap::new();
let cookie_head_value = http::header::HeaderValue::from_str(cookie);
match cookie_head_value {
Ok(cookie) => {
headers.insert(http::header::COOKIE, cookie);
let client = reqwest::Client::builder()
.timeout(Duration::from_secs(10))
.cookie_store(true)
.default_headers(headers)
.build();
Ok(client?)
}
Err(_) => Err(ReqError::CookieFmt()),
}
}
pub async fn delete(
client: &reqwest::Client,
host_url: &str,
user_id: u64,
) -> Result<serde_json::value::Value, ReqError> {
let url = host_url.to_owned() + "/xxx/delete.vpage";
let mut params = HashMap::new();
params.insert("userId", user_id.to_string());
let request_builder = client.post(url).form(¶ms);
let resp = request_builder.send().await?;
let text_value = &resp.text().await?;
let json_value = serde_json::from_str(&text_value);
match json_value {
Result::Ok(val) => Ok(val),
Result::Err(err) => {
// error!("Fail to parse json:{}, {}",&text_value, err);
// error!("Please update a valid cookie");
Err(ReqError::SerdeJson(err))
}
}
}
#[cfg(test)]
mod test {}
跨平台编译
M1 Apple Mac:
docker run --rm \
--volume "${PWD}":/root/src \
--workdir /root/src \
joseluisq/rust-linux-darwin-builder:1.65.0 \
sh -c "cargo build --release --target aarch64-apple-darwin"
Intel Mac
docker run --rm \
--volume "${PWD}":/root/src \
--workdir /root/src \
joseluisq/rust-linux-darwin-builder:1.65.0 \
sh -c "cargo build --release --target x86_64-apple-darwin"
Windows
docker run --rm -it -v "${PWD}":/io -w /io messense/cargo-xwin \
sh -c "cargo xwin build --release --target x86_64-pc-windows-msvc"
感想
rust语法庞大,一个补丁加一个补丁。槽点之一:类型推断其实开发人员自己就可以解决,显式指定多好,非得编译器辛辛苦苦做类型推断,真没必要;
抱怨归抱怨,它编译出来的可执行文件小(依赖了庞大的tokio后大小6M左右),运行时占用内存小,生态日益庞大,编译以后的心智负担轻是真的;
用docker做交叉编译实在是太好了,我一直没有Mac
M1的电脑都可以编译出一个短小精悍的程序给它的用户用,用docker不污染宿主机环境,而用docker
-v -w更是不污染docker环境,正所谓:"万花丛中过,片叶不沾身"
2023-03-25新增Delphi
版
- 要论体积,
Delphi
做出来的exe也非常小,为了比较,特意用Delphi7实现了一遍(见下图),在不用Aspack
/WinUpack
压缩的情况下,编译出来执行程序可以只有625k,零dll依赖,可以在win98及其所有的后续的windows操作系统上运行;
- 10几年不写
Delphi
了,发现它的无参函数调用起来是不写()的,有意思;
- 现在写富界面跨平台程序主流是web,用Electron或Rust +
tauri套个壳,后者我更喜欢,有空可以实践一把。
用Rust写一个批量HTTP REST请求工具
2022 Nov 08 See all posts把一个日常用的小工具用Rust重写一下,以前都是快速写个
Python
脚本自己跑,但是现在要给同事用,同事的电脑是Mac M1,不想装Python,Python程序打出来的包太大了,放弃。用
Go
或Rust
是不错的选择,生成的可执行文件小,还可以很方便跨平台打包。本着哪壶不开提哪壶的原则,选用Rust
吧。功能很简单,批量发http rest请求,主要涉及到从配置文件读取cookie信息以及各种配置如限速,从业务文件读取业务参数,然后分批发HTTP REST请求。
核心代码如下:
跨平台编译
M1 Apple Mac:
Intel Mac
Windows
感想
rust语法庞大,一个补丁加一个补丁。槽点之一:类型推断其实开发人员自己就可以解决,显式指定多好,非得编译器辛辛苦苦做类型推断,真没必要;
抱怨归抱怨,它编译出来的可执行文件小(依赖了庞大的tokio后大小6M左右),运行时占用内存小,生态日益庞大,编译以后的心智负担轻是真的;
用docker做交叉编译实在是太好了,我一直没有Mac M1的电脑都可以编译出一个短小精悍的程序给它的用户用,用docker不污染宿主机环境,而用docker -v -w更是不污染docker环境,正所谓:"万花丛中过,片叶不沾身"
2023-03-25新增
Delphi
版Delphi
做出来的exe也非常小,为了比较,特意用Delphi7实现了一遍(见下图),在不用Aspack
/WinUpack
压缩的情况下,编译出来执行程序可以只有625k,零dll依赖,可以在win98及其所有的后续的windows操作系统上运行;Delphi
了,发现它的无参函数调用起来是不写()的,有意思;