Skip to content

Commit

Permalink
refactor: adjust test
Browse files Browse the repository at this point in the history
  • Loading branch information
vicanso committed Mar 23, 2024
1 parent 35ba35c commit e563c5c
Show file tree
Hide file tree
Showing 10 changed files with 173 additions and 32 deletions.
67 changes: 45 additions & 22 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ readme = "./README.md"
[dependencies]
async-trait = "0.1.78"
base64 = "0.22.0"
bytes = "1.5.0"
bytes = "1.6.0"
bytesize = "1.3.0"
chrono = "0.4.35"
clap = { version = "4.5.3", features = ["derive"] }
Expand All @@ -33,7 +33,7 @@ num_cpus = "1.16.0"
once_cell = "1.19.0"
path-absolutize = "3.1.1"
pingora = { version = "0.1.0", default-features = false, features = ["lb"] }
regex = "1.10.3"
regex = "1.10.4"
serde = "1.0.197"
serde_json = "1.0.114"
snafu = "0.8.2"
Expand All @@ -44,6 +44,7 @@ url = "2.5.0"

[dev-dependencies]
criterion = { version = "0.5.1", features = ["html_reports"] }
pretty_assertions = "1.4.0"

[profile.release]
codegen-units = 1
Expand Down
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ bloat:
outdated:
cargo outdated

test:
cargo test

release:
cargo build --release
ls -lh target/release
Expand Down
2 changes: 2 additions & 0 deletions SUMMARY.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# Summary

- [介绍](./docs/introduction_zh.md)
- [配置说明](./docs/config_zh.md)
- [日志格式化](./docs/log_zh.md)
2 changes: 1 addition & 1 deletion benches/bench.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,5 +60,5 @@ fn insert_header_name(c: &mut Criterion) {
});
}

criterion_group!(benches, insert_bytes_header, insert_header_name);
criterion_group!(benches, insert_bytes_header, insert_header_name,);
criterion_main!(benches);
47 changes: 47 additions & 0 deletions docs/config_zh.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
---
description: Pingap 配置说明
---

Pingap使用toml来配置相关参数,具体参数说明如下:

## 基本配置

- `error_template`: 参数可选,出错时的html模板,可自定义出错的html模板,在出错时会替换模板中的`{{version}}`为pingap的版本号,`{{content}}`为出错的具体信息。
- `pid_file`: 参数可选,默认为`/tmp/pingap.pid`,此参数配置进程id的记录文件。
- `upgrade_sock`: 参数可选,默认为`/tmp/pingap.sock`,此参数配置程序无中断式更新时的socket路径,用于新的pingap进程与旧进程之间切换时使用。
- `user`: 参数可选,默认为空,用于设置守护进程的执行用户
- `group`: 参数可选,默认为空,与`user`类似
- `threads`: 参数可选,默认为1,用于设置每个服务(如server监控的tcp连接)使用的线程数,如果设置为0,则使用cpu或cgroup限制核数
- `work_stealing`: 参数可选,默认为`true`,是否允许同服务中的不同线程的抢占工作。

## upstreams

- `upstreams.x`: upstream配置,其中`x`为upstream的名称,需要注意名称不要相同,相同名称的配置会被覆盖。
- `addrs`: 该upstream的服务地址列表,格式为`ip:port`的形式,如果要指定权重则可通过此形式指定`ip:port weight`
- `algo`: 参数可选,默认为`round_robin`。upstream各节点的选择方法,支持`hash``round_robin`两种形式。
- `health_check`: 参数可选,默认为`tcp`形式。upstream节点的健康检查方式,支持`tcp``http`方式。`tcp://upstreamname?connection_timeout=3s&success=2&failure=1&check_frequency=10s`表示使用tcp的形式,连接超时为3秒,成功2次则成功或失败1次则失败,检测间隔为10秒。`http://upstreamname/ping?connection_timeout=3s&read_timeout=1s&success=2&failure=1&check_frequency=10s`表示使用http的形式检测,路径为`/ping`,连接超时为3少,读取超时为1秒,成功2次则成功或失败1次则失败,检测间隔为10秒。
- `connection_timeout`: 参数可选,默认为无超时,表示tcp连接建立的超时时间为多少秒。
- `total_connection_timeout` 参数可选,默认为无超时,表示连接建立的超时时间为多少秒,包括tcp与tls。
- `read_timeout`: 参数可选,默认为无超时,表示读取的超时时间。
- `write_timeout`: 参数可选,默认为无超时,表示写的超时时间。
- `idle_timeout`: 参数可选,默认为无,表示空闲连接不关闭。若设置为0秒表示禁用连接池。

## Location

- `locations.x`: locations配置,其中`x`为locations的名称,需要注意名称不要相同,相同名称的配置会被覆盖。
- `upstream`: 该location使用的upstream。
- `host`: 参数可选,默认无。表示该location匹配请求的`host`
- `path`: 参数可选,默认无。表示该location匹配的请求`path`,支持以下几种模式,`~/api`表示正则形式匹配;`=/api`表示全等模式匹配,需要path等于`/api`才算匹配;`/api`则表示前缀匹配,需要path以`/api`开头的请求。
- `proxy_headers`: 设置发送至`upstream`时添加的请求头列表,格式为`name:value`的形式。
- `headers`: 设置响应时添加的响应头列表,格式为`name:value`的形式。
- `rewrite`: 请求替换规则,`^/api/ /`如表示将请求的path前缀的`/api/`表示为`/。

## Server

- `server.x`: server的配置,其中`x`为server的名称,需要注意名称不要相同,相同名称的配置会被覆盖。
- `addr`: 监控的端口地址。
- `tls_cert`: tls证书的cert,base64格式,如果是https的形式才需要添加。
- `tls_key`: tls证书的key,base64格式,如果是https的形式才需要添加。
- `access_log`: 可选,默认为不输出访问日志。请求日志格式化,指定输出访问日志的形式。
- `locations`: location的列表,指定该server使用的所有location。
- `stats_path`: 可选,默认无。指定返回server的stats的路由。
5 changes: 5 additions & 0 deletions docs/log_zh.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
description: Pingap 请求日志格式化
---

Pingap格式化相关参数,具体参数说明如下:
14 changes: 14 additions & 0 deletions src/cache/http_header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,17 @@ pub static HTTP_HEADER_CONTENT_JSON: Lazy<HttpHeader> = Lazy::new(|| {
HeaderValue::from_str("application/json; charset=utf-8").unwrap(),
)
});

#[cfg(test)]
mod tests {
use super::convert_headers;
use pretty_assertions::assert_eq;
#[test]
fn test_convert_headers() {
let headers =
convert_headers(&["Content-Type: application/octet-stream".to_string()]).unwrap();
assert_eq!(1, headers.len());
assert_eq!("content-type", headers[0].0.to_string());
assert_eq!("application/octet-stream", headers[0].1.to_str().unwrap());
}
}
58 changes: 51 additions & 7 deletions src/cache/http_response.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use http::StatusCode;
use pingora::{http::ResponseHeader, proxy::Session};
use std::time::{SystemTime, UNIX_EPOCH};

#[derive(Default)]
#[derive(Default, Debug)]
pub struct HttpResponse {
pub status: StatusCode,
pub body: Bytes,
Expand All @@ -16,7 +16,7 @@ pub struct HttpResponse {
}

impl HttpResponse {
pub async fn send(&self, session: &mut Session) -> pingora::Result<usize> {
fn get_response_header(&self) -> pingora::Result<ResponseHeader> {
let fix_size = 3;
let size = self
.headers
Expand Down Expand Up @@ -58,11 +58,55 @@ impl HttpResponse {
resp.insert_header(name.to_owned(), value)?;
}
}

let buf = self.body.clone();
let size = buf.len();
session.write_response_header(Box::new(resp)).await?;
session.write_response_body(buf).await?;
Ok(resp)
}
pub async fn send(self, session: &mut Session) -> pingora::Result<usize> {
let header = self.get_response_header()?;
let size = self.body.len();
session.write_response_header(Box::new(header)).await?;
session.write_response_body(self.body).await?;
Ok(size)
}
}

#[cfg(test)]
mod tests {
use super::HttpResponse;
use crate::cache::convert_headers;
use bytes::Bytes;
use http::StatusCode;
use pretty_assertions::assert_eq;
use std::time::{SystemTime, UNIX_EPOCH};
#[test]
fn test_http_response() {
let resp = HttpResponse {
status: StatusCode::OK,
body: Bytes::from("Hello world!"),
max_age: Some(3600),
created_at: Some(
SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_secs()
- 10,
),
private: Some(true),
headers: Some(
convert_headers(&[
"Contont-Type: application/json".to_string(),
"Content-Encoding: gzip".to_string(),
])
.unwrap(),
),
};

let mut header = resp.get_response_header().unwrap();
assert_eq!(true, !header.headers.get("Age").unwrap().is_empty());
header.remove_header("Age").unwrap();

assert_eq!(
r###"ResponseHeader { base: Parts { status: 200, version: HTTP/1.1, headers: {"content-length": "12", "cache-control": "private, max-age=3600", "content-encoding": "gzip", "contont-type": "application/json"} }, header_name_map: Some({"content-length": CaseHeaderName(b"Content-Length"), "cache-control": CaseHeaderName(b"Cache-Control"), "content-encoding": CaseHeaderName(b"Content-Encoding"), "contont-type": CaseHeaderName(b"contont-type")}) }"###,
format!("{header:?}")
);
}
}
2 changes: 2 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ mod config;
mod proxy;
mod utils;

pub use cache::HttpResponse;

/// A reverse proxy like nginx.
#[derive(Parser, Debug, Default)]
#[command(author, version, about, long_about = None)]
Expand Down

0 comments on commit e563c5c

Please sign in to comment.