Skip to content

Commit

Permalink
feat(http-serve): support http cli
Browse files Browse the repository at this point in the history
  • Loading branch information
upupnoah committed Jun 21, 2024
1 parent e1258bc commit a6d7839
Show file tree
Hide file tree
Showing 14 changed files with 1,695 additions and 44 deletions.
1,360 changes: 1,323 additions & 37 deletions Cargo.lock

Large diffs are not rendered by default.

7 changes: 7 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,23 @@ authors = ["Noah <upupqi.cs@gmail.com>"]

[dependencies]
anyhow = "^1.0"
axum = "0.7.5"
base64 = "^0.22.1"
blake3 = "^1.5.1"
clap = { version = "^4.5.4", features = ["derive"] }
csv = "^1.3.0"
ed25519-dalek = { version = "^2.1.1", features = ["rand_core"] }
futures = "0.3.30"
hex = "0.4.3"
rand = "^0.8.5"
reqwest = "0.12.5"
serde = { version = "^1.0", features = ["derive"] }
serde_json = "^1.0"
# serde_toml = "^0.0.1" # replace to toml
serde_yaml = "^0.9"
tokio = { version = "1.38.0", features = ["fs", "macros", "rt-multi-thread"] }
toml = "^0.8.14"
tower-http = { version = "0.5.2", features = ["fs"] }
tracing = "0.1.40"
tracing-subscriber = "0.3.18"
zxcvbn = "^3.0.1"
81 changes: 80 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,85 @@ validated_values:

text-cli:
cargo run --example text_cli -- $(ARGS)
async:
cargo run --example async
async2:
cargo run --example async2
axum:
cargo run --example axum
thread:
cargo run --example thread

run:
@cargo run -- $(ARGS)
@cargo run -- $(ARGS)
# ******** csv ********
# make run ARGS="csv --input "
# make run ARGS="csv --input a.csv"
# make run ARGS="csv --input ./asserts/juventus.csv"
# make run ARGS="csv --input './asserts/juventus.csv'"
# make run ARGS="csv --input ./assets/juventus.csv --output ./assets/juventus.csv"
# make run ARGS="csv --input ./assets/juventus.csv --output ./assets/juventus.json"
# make run ARGS="csv --input ./assets/juventus.csv --format json"
# make run ARGS="csv -h"
# make run ARGS="csv --input ./assets/juventus.csv --format toml"
# make run ARGS="csv --input ./assets/juventus.csv --format yaml --output ./assets/juventus"
# make run ARGS="csv --input ./assets/juventus.csv --format json --output ./assets/juventus"
# make run ARGS="csv --input ./assets/juventus.csv --format yaml"

# ******** genpass ********
# make run ARGS="genpass -h"
# make run ARGS="genpass"
# make run ARGS="genpass -l 20"
# make run ARGS="genpass -l 30"
# make run ARGS="genpass -l 100"
# make run ARGS="genpass -l 3"
# make run ARGS="genpass -l 4^J"
# make run ARGS="genpass -l 116"
# make run ARGS="genpass -l 16"
# make run ARGS="genpass --upper --lower --number 16 --symbool"
# make run ARGS="genpass --upper --lower --symbool --number 16"
# make run ARGS="genpass --upper --lower --symbol --number 16"
# make run ARGS="genpass --upper --lower --symbol -n16"
# make run ARGS="genpass --upper --lower --symbol"
# make run ARGS="genpass --upper --lower --symbol -n 16"
# make run ARGS="genpass --length 100 --upper --lower --symbol --number"
# make run ARGS="genpass --length 10 --upper --lower --symbol --number"
# make run ARGS="genpass --length 16 --upper --lower --symbol --number"
# make run ARGS="genpass -l 32"

# ******** base64 ********
# make run ARGS="base64 encode"
# make run ARGS="base64"
# make run ARGS="base64 decode -i
# make run ARGS="base64 decode -i Cargo.b64"
# make run ARGS="base64 encode -i Cargo.toml"
# make run ARGS="base64 encode -i Cargo.toml" > ./fixtures/b64.txt
# make run ARGS="base64 encode"
# make run ARGS="base64 decode"
# make run ARGS="base64 decode -i ./fixtures/b64.txt"
# make run ARGS="base64 encode -i Cargo.toml --format urlsafe" > ./fixtures/b64.txt
# make run ARGS="base64 decode -i ./fixtures/b64.txt --format urlsafe"

# ******** text ********
# make run ARGS="text sign --format ed25519 --key fixtures/blake3.txt"
# make run ARGS="text generate --format ed25519 -o ./fixtures/ed25519"
# make run ARGS="text generate --format ed25519 -o ./fixtures"
# make run ARGS="text generate --format blake3 -o ./fixtures"
# make run ARGS="text verify -k ./fixtures/blake3.txt"
# make run ARGS="text verify -k ./fixtures/blake3.txt --sig"
# make run ARGS="text verify -h"
# make run ARGS="text verify -k ./fixtures/blake3.txt --sig 'eG6j-ghHZvMgTj0fQRrHrQ17v"
# make run ARGS="text verify -k ./fixtures/blake.txt --sig eG6j-ghHZvMgTj0fQRrHrQ17vdo"
# make run ARGS="text sign --format blake3 --key fixtures/blake3.txt"
# make run ARGS="text verify -k ./fixtures/blake3.txt --sig'eG6j-ghHZvMgTj0fQRrHrQ17vd"
# make run ARGS="text verify -k ./fixtures/blake3.txt --sig 'eG6j-ghHZvMgTj0fQRrHrQ17v"
# make run ARGS="text sign -h"
# make run ARGS="text verify --format ed25519 -k ./fixtures/ed25519.pk"
# make run ARGS="text verify --format ed25519 -k ./fixtures/ed25519.pk --sig yY0cc2vo"
# make run ARGS="text sign --format ed25519 -k ./fixtures/ed25519.pk"
# make run ARGS="text verify --format ed25519 -k ./fixtures/ed25519.sk --sig B6SBry_iU"
# make run ARGS="text sign --format ed25519 -k ./fixtures/ed25519.sk"
# make run ARGS="text verify --format ed25519 -k ./fixtures/ed25519.pk --sig 'yY0cc2vo"

# ******** http ********
# make run ARGS="http serve"
65 changes: 65 additions & 0 deletions examples/async.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// 引入需要的库
use futures::future::join_all;
use tokio::fs::File;
use tokio::io::AsyncWriteExt;

// 定义异步函数来进行数据处理
async fn process_data(data: String) -> String {
// 假设这里有一些复杂的数据处理逻辑
data.to_uppercase()
}

// 异步函数,用于从网站获取数据
async fn fetch_data_from_website(url: &str) -> Result<String, reqwest::Error> {
let response = reqwest::get(url).await?.text().await?;
Ok(response)
}

// 异步函数,用于保存数据到文件
async fn save_to_file(filename: &str, data: &str) -> std::io::Result<()> {
let mut file = File::create(filename).await?;
file.write_all(data.as_bytes()).await?;
Ok(())
}

// 异步主函数,处理所有任务
async fn main_task() -> Result<(), Box<dyn std::error::Error>> {
let urls = [
"https://jsonplaceholder.typicode.com/posts/1",
"https://jsonplaceholder.typicode.com/posts/2",
"https://jsonplaceholder.typicode.com/posts/3",
];

// 创建一个 Vec 来保存所有任务
let mut tasks = vec![];

// 并发地发起网络请求并处理每个响应
for (idx, &url) in urls.iter().enumerate() {
let task = async move {
let data = fetch_data_from_website(url).await?;
let processed_data = process_data(data).await;
let filename = format!("output{}.txt", idx);
save_to_file(&filename, &processed_data).await?;
Ok(())
};
tasks.push(task);
}

// 并发地执行所有任务
let results: Vec<Result<(), Box<dyn std::error::Error>>> = join_all(tasks).await;
for result in results {
if let Err(err) = result {
eprintln!("任务执行出错: {:?}", err);
}
}

Ok(())
}

// 入口函数,调用异步主函数并运行事件循环
#[tokio::main]
async fn main() {
if let Err(err) = main_task().await {
eprintln!("程序执行出错: {:?}", err);
}
}
21 changes: 21 additions & 0 deletions examples/async2.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
use tokio::task;
use tokio::time::{sleep, Duration};

#[tokio::main]
async fn main() {
let tasks = (0..5)
.map(|i| {
task::spawn(async move {
println!("task {}", i);
})
})
.collect::<Vec<_>>();

// 等待所有任务完成
for task in tasks {
task.await.unwrap();
}

// 等待一段时间,以保证所有输出都打印完毕
sleep(Duration::from_secs(1)).await;
}
57 changes: 57 additions & 0 deletions examples/axum.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
use axum::{
http::StatusCode,
routing::{get, post},
Json, Router,
};
use serde::{Deserialize, Serialize};

#[tokio::main]
async fn main() {
// initialize tracing
tracing_subscriber::fmt::init();

// build our application with a route
let app = Router::new()
// `GET /` goes to `root`
.route("/", get(root))
// `POST /users` goes to `create_user`
.route("/users", post(create_user));

// run our app with hyper, listening globally on port 3000
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
axum::serve(listener, app).await.unwrap();
}

// basic handler that responds with a static string
async fn root() -> &'static str {
"Hello, World!"
}

async fn create_user(
// this argument tells axum to parse the request body
// as JSON into a `CreateUser` type
Json(payload): Json<CreateUser>,
) -> (StatusCode, Json<User>) {
// insert your application logic here
let user = User {
id: 1337,
username: payload.username,
};

// this will be converted into a JSON response
// with a status code of `201 Created`
(StatusCode::CREATED, Json(user))
}

// the input to our `create_user` handler
#[derive(Deserialize)]
struct CreateUser {
username: String,
}

// the output to our `create_user` handler
#[derive(Serialize)]
struct User {
id: u64,
username: String,
}
20 changes: 20 additions & 0 deletions examples/thread.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
use std::thread;
use std::time::Duration;

fn main() {
let handles: Vec<_> = (0..5)
.map(|i| {
thread::spawn(move || {
println!("thread {}", i);
})
})
.collect();

// 等待所有线程完成
for handle in handles {
handle.join().unwrap();
}

// 等待一段时间,以保证所有线程的输出都打印出来
thread::sleep(Duration::from_secs(1));
}
4 changes: 4 additions & 0 deletions src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use clap::Parser;
mod base64;
mod csv;
mod genpass;
mod http;
mod text;

// pub use csv_opts::{CsvOpts, OutputFormat};
Expand All @@ -14,6 +15,7 @@ mod text;
pub use self::base64::{Base64Format, Base64Subcommand};
pub use self::csv::{CsvOpts, OutputFormat};
pub use self::genpass::GenPassOpts;
pub use self::http::HttpSubCommand;
pub use self::text::{TextSignFormat, TextSubcommand};

#[derive(Debug, Parser)]
Expand All @@ -33,6 +35,8 @@ pub enum SubCommand {
Base64(Base64Subcommand),
#[command(subcommand, about = "Text sign/verify")]
Text(TextSubcommand),
#[command(subcommand, about = "HTTP server")]
Http(HttpSubCommand),
}

// 会传入文件名
Expand Down
19 changes: 19 additions & 0 deletions src/cli/http.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
use std::path::PathBuf;

use clap::Parser;

use super::verify_path;

#[derive(Debug, Parser)]
pub enum HttpSubCommand {
#[command(about = "Serve a directory over HTTP")]
Serve(HttpServeOpts),
}

#[derive(Debug, Parser)]
pub struct HttpServeOpts {
#[arg(short, long, value_parser = verify_path, default_value = ".")]
pub dir: PathBuf,
#[arg(short, long, default_value_t = 8080)]
pub port: u16,
}
7 changes: 4 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@ mod process;
mod utils;

pub use cli::{
Base64Format, Base64Subcommand, Opts, OutputFormat, SubCommand, TextSignFormat, TextSubcommand,
Base64Format, Base64Subcommand, HttpSubCommand, Opts, OutputFormat, SubCommand, TextSignFormat,
TextSubcommand,
};
pub use process::{
process_csv, process_decode, process_encode, process_genpass, process_text_key_generate,
process_text_sign, process_text_verify,
process_csv, process_decode, process_encode, process_genpass, process_http_serve,
process_text_key_generate, process_text_sign, process_text_verify,
};
pub use utils::{get_content, get_reader};
// pub use cli::*;
14 changes: 11 additions & 3 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@ use base64::{engine::general_purpose::URL_SAFE_NO_PAD, Engine};
use clap::Parser;
use rcli::{
get_content, get_reader, process_csv, process_decode, process_encode, process_genpass,
process_text_key_generate, process_text_sign, process_text_verify, Base64Subcommand, Opts,
SubCommand, TextSubcommand,
process_http_serve, process_text_key_generate, process_text_sign, process_text_verify,
Base64Subcommand, HttpSubCommand, Opts, SubCommand, TextSubcommand,
};

fn main() -> anyhow::Result<()> {
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let opts = Opts::parse();
match opts.cmd {
SubCommand::Csv(opts) => {
Expand Down Expand Up @@ -80,6 +81,13 @@ fn main() -> anyhow::Result<()> {
}
}
},
SubCommand::Http(subcmd) => match subcmd {
HttpSubCommand::Serve(opts) => {
// dir and port, start http server
// println!("{:?}", opts);
process_http_serve(opts.dir, opts.port).await?;
}
},
}
Ok(())
}
2 changes: 2 additions & 0 deletions src/process.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
mod b64;
mod csv_convert;
mod gen_pass;
mod http_serve;
mod text;

pub use b64::{process_decode, process_encode};
pub use csv_convert::process_csv;
pub use gen_pass::process_genpass;
pub use http_serve::process_http_serve;
pub use text::{process_text_key_generate, process_text_sign, process_text_verify};
Loading

0 comments on commit a6d7839

Please sign in to comment.