mirror of
https://github.com/DefectingCat/rua-list
synced 2025-07-15 16:51:31 +00:00
Compare commits
79 Commits
Author | SHA1 | Date | |
---|---|---|---|
c0a7a1661f | |||
07f40c5edb | |||
19c83b02da | |||
52f00ac563 | |||
c1899bcbdd | |||
baabfadda5 | |||
bdafa0d086 | |||
0de4fe7a67 | |||
1e1c5e6e83 | |||
df5ac42963 | |||
0c2ef39aca | |||
4ad81b4aff | |||
91c4328b7d | |||
05f4f669a9 | |||
af55be9eca | |||
507e392f69 | |||
6d139f30d7 | |||
021e90af62 | |||
336f090a49 | |||
a6b327c97f | |||
18753b6679 | |||
1108d92d78 | |||
4c802ba781 | |||
f2288667d1 | |||
9a648cf408 | |||
66a2efa9e4 | |||
896d439728 | |||
bd60a2b7f9 | |||
a0df34128d | |||
e9033358fa | |||
ed06d0becc | |||
a350bee7a6 | |||
6ceb03d674 | |||
54e53782aa | |||
dd2158ab46 | |||
9863348b8a | |||
6a248c51ad | |||
ae1ca2bf44 | |||
3e2b2b006c | |||
83f47e223d | |||
7ca9b02370 | |||
e4f2216d23 | |||
d48dbcb230 | |||
c66137f842 | |||
e1ebde7e50 | |||
2703d44125 | |||
68fd726068 | |||
2564a2e565 | |||
4520f5cc66 | |||
88dccb53a2 | |||
2db53cd98e | |||
df0f87a034 | |||
c97a46e1c3 | |||
17531118b3 | |||
f536b0e8c1 | |||
dcc5d43604 | |||
18f2766805 | |||
478c99d949 | |||
3d67b404a5 | |||
75ea312c92 | |||
916c539900 | |||
ffaacc7851 | |||
e2bab674e7 | |||
4e2d699a00 | |||
2251fc57ca | |||
65332d953d | |||
b1474f7125 | |||
78a47c3cf6 | |||
4638df0bab | |||
2215402860 | |||
79e204d80d | |||
f1d8deaaf2 | |||
29bb64cf70 | |||
a1c1f0bc1e | |||
a49cabe829 | |||
72657d6312 | |||
54ed3f9320 | |||
13f9c04fc3 | |||
8d07f6dcfc |
@ -1,2 +1,5 @@
|
||||
target/
|
||||
.git/
|
||||
.git/
|
||||
config.json
|
||||
logs/
|
||||
.DS_Store
|
4
.gitignore
vendored
4
.gitignore
vendored
@ -1,3 +1,5 @@
|
||||
/target
|
||||
config.json
|
||||
logs/
|
||||
logs/
|
||||
.DS_Store
|
||||
.cargo
|
86
.gitlab-ci.yml
Normal file
86
.gitlab-ci.yml
Normal file
@ -0,0 +1,86 @@
|
||||
stages:
|
||||
- build
|
||||
|
||||
build:linux-gnu-amd64:
|
||||
stage: build
|
||||
image: rust:latest
|
||||
rules:
|
||||
- if: $CI_COMMIT_TAG
|
||||
script:
|
||||
- mkdir $HOME/.cargo
|
||||
- echo "[source.crates-io]" >> $HOME/.cargo/config
|
||||
- echo "replace-with = 'ustc'" >> $HOME/.cargo/config
|
||||
- echo "" >> $HOME/.cargo/config
|
||||
- echo "[source.ustc]" >> $HOME/.cargo/config
|
||||
- echo "registry = \"sparse+https://mirrors.ustc.edu.cn/crates.io-index/\"" >> $HOME/.cargo/config
|
||||
- mkdir public
|
||||
- cargo build --release
|
||||
- "mv target/release/rua-list target/release/rua-list-x86_64-unknown-linux-gnu-$CI_COMMIT_TAG"
|
||||
- "mv target/release/rua-list-x86_64-unknown-linux-gnu-$CI_COMMIT_TAG public/"
|
||||
artifacts:
|
||||
paths:
|
||||
- "public/rua-list-x86_64-unknown-linux-gnu-$CI_COMMIT_TAG"
|
||||
|
||||
build:linux-musl-amd64:
|
||||
stage: build
|
||||
image: rust:latest
|
||||
rules:
|
||||
- if: $CI_COMMIT_TAG
|
||||
script:
|
||||
- apt update
|
||||
- apt install -y musl-tools
|
||||
- rustup target add x86_64-unknown-linux-musl
|
||||
- cargo build --release --target x86_64-unknown-linux-musl
|
||||
- mkdir public
|
||||
- "mv target/x86_64-unknown-linux-musl/release/rua-list target/x86_64-unknown-linux-musl/release/rua-list-x86_64-unknown-linux-musl-$CI_COMMIT_TAG"
|
||||
- "mv target/x86_64-unknown-linux-musl/release/rua-list-x86_64-unknown-linux-musl-$CI_COMMIT_TAG public/"
|
||||
artifacts:
|
||||
paths:
|
||||
- public/rua-list-x86_64-unknown-linux-musl-$CI_COMMIT_TAG
|
||||
|
||||
build:windows-amd64:
|
||||
stage: build
|
||||
image: rust:latest
|
||||
rules:
|
||||
- if: $CI_COMMIT_TAG
|
||||
script:
|
||||
- apt update
|
||||
- apt install -y g++-mingw-w64-x86-64
|
||||
- rustup target add x86_64-pc-windows-gnu
|
||||
- rustup toolchain install stable-x86_64-pc-windows-gnu
|
||||
- cargo build --release --target x86_64-pc-windows-gnu
|
||||
- mkdir public
|
||||
- "mv target/x86_64-pc-windows-gnu/release/rua-list.exe target/x86_64-pc-windows-gnu/release/rua-list-x86_64-pc-windows-gnu-$CI_COMMIT_TAG.exe"
|
||||
- "mv target/x86_64-pc-windows-gnu/release/rua-list-x86_64-pc-windows-gnu-$CI_COMMIT_TAG.exe public/"
|
||||
artifacts:
|
||||
paths:
|
||||
- public/rua-list-x86_64-pc-windows-gnu-$CI_COMMIT_TAG.exe
|
||||
|
||||
rustdoc:
|
||||
stage: build
|
||||
image: rust
|
||||
rules:
|
||||
- if: $CI_COMMIT_TAG
|
||||
script:
|
||||
- cargo doc
|
||||
artifacts:
|
||||
paths:
|
||||
- target/doc
|
||||
#release_job:
|
||||
# stage: release
|
||||
# image: registry.gitlab.com/gitlab-org/release-cli:latest
|
||||
# rules:
|
||||
# - if: $CI_COMMIT_TAG # Run this job when a tag is created
|
||||
# script:
|
||||
# - echo "running release_job"
|
||||
# release: # See https://docs.gitlab.com/ee/ci/yaml/#release for available properties
|
||||
# tag_name: "$CI_COMMIT_TAG"
|
||||
# description: "$CI_COMMIT_TAG"
|
||||
# assets:
|
||||
# links:
|
||||
# - name: "rua-list-x86_64-unknown-linux-gnu-$CI_COMMIT_TAG"
|
||||
# url: "https://git.rua.plus/${CI_PROJECT_NAMESPACE}/${CI_PROJECT_NAME}/cw/-/jobs/${CI_JOB_ID}/artifacts/file/public/rua-list-x86_64-unknown-linux-gnu-$CI_COMMIT_TAG"
|
||||
# - name: "rua-list-x86_64-unknown-linux-musl-$CI_COMMIT_TAG"
|
||||
# url: "https://git.rua.plus/${CI_PROJECT_NAMESPACE}/${CI_PROJECT_NAME}/cw/-/jobs/${CI_JOB_ID}/artifacts/file/public/rua-list-x86_64-unknown-linux-musl-$CI_COMMIT_TAG"
|
||||
# - name: "ua-list-x86_64-pc-windows-gnu-$CI_COMMIT_TAG.exe"
|
||||
# url: "https://git.rua.plus/${CI_PROJECT_NAMESPACE}/${CI_PROJECT_NAME}/cw/-/jobs/${CI_JOB_ID}/artifacts/file/public/ua-list-x86_64-pc-windows-gnu-$CI_COMMIT_TAG.exe"
|
1346
Cargo.lock
generated
1346
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@ -24,3 +24,6 @@ tracing-subscriber = "0.3.17"
|
||||
tracing-appender = "0.2.2"
|
||||
tracing-error = "0.2.0"
|
||||
color-eyre = "0.6.2"
|
||||
|
||||
[target.'cfg(unix)'.dependencies]
|
||||
openssl = { version = "=0.10.52", features = ["vendored"] }
|
||||
|
29
dockerfiles/Dockerfile.windows
Normal file
29
dockerfiles/Dockerfile.windows
Normal file
@ -0,0 +1,29 @@
|
||||
FROM rust:latest as builder
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Create appuser
|
||||
ENV USER=xfy
|
||||
ENV UID=10001
|
||||
|
||||
RUN adduser \
|
||||
--disabled-password \
|
||||
--gecos "" \
|
||||
--home "/nonexistent" \
|
||||
--shell "/sbin/nologin" \
|
||||
--no-create-home \
|
||||
--uid "${UID}" \
|
||||
"${USER}" \
|
||||
&& mkdir $HOME/.cargo \
|
||||
&& echo "[source.crates-io]" >> $HOME/.cargo/config \
|
||||
&& echo "replace-with = 'ustc'" >> $HOME/.cargo/config \
|
||||
&& echo "" >> $HOME/.cargo/config \
|
||||
&& echo "[source.ustc]" >> $HOME/.cargo/config \
|
||||
&& echo "registry = \"sparse+https://mirrors.ustc.edu.cn/crates.io-index/\"" >> $HOME/.cargo/config \
|
||||
&& apt update \
|
||||
&& apt install -y g++-mingw-w64-x86-64 \
|
||||
&& rustup target add x86_64-unknown-linux-musl \
|
||||
&& rustup target add x86_64-pc-windows-gnu \
|
||||
&& rustup toolchain install stable-x86_64-pc-windows-gnu
|
||||
|
||||
ENTRYPOINT [ "/bin/bash" ]
|
@ -1,2 +1,4 @@
|
||||
// Target address
|
||||
pub static MSG_URL: &str = "https://swdx.kdah.cn:8011";
|
||||
// pub static MSG_URL: &str = "https://swdx.kdah.cn:8011";
|
||||
|
||||
pub static MSG_URL: &str = "http://58.242.187.12:8011";
|
@ -1,9 +1,10 @@
|
||||
use anyhow::Result;
|
||||
use log::{debug, error, info};
|
||||
use std::{net::SocketAddr, process::exit, sync::Arc};
|
||||
use std::{net::SocketAddr, process::exit};
|
||||
use tokio::{
|
||||
io::{AsyncBufReadExt, AsyncReadExt, AsyncWriteExt, BufReader},
|
||||
net::{TcpListener, TcpStream},
|
||||
sync::{mpsc, oneshot, Mutex},
|
||||
sync::{mpsc, oneshot},
|
||||
};
|
||||
|
||||
type Responder = oneshot::Sender<String>;
|
||||
@ -31,22 +32,21 @@ pub async fn headers_parser(port: usize) {
|
||||
let (tx, mut rx) = mpsc::channel::<Frame>(128);
|
||||
|
||||
tokio::spawn(async move {
|
||||
let connector = match TcpStream::connect("127.0.0.1:3001").await {
|
||||
Ok(stream) => stream,
|
||||
Err(err) => {
|
||||
error!("Can not request to server {}", err);
|
||||
return;
|
||||
}
|
||||
};
|
||||
let connector = Arc::new(Mutex::new(connector));
|
||||
while let Some(frame) = rx.recv().await {
|
||||
let connector = connector.clone();
|
||||
let mut connector = connector.lock().await;
|
||||
let mut connector = match TcpStream::connect("127.0.0.1:3001").await {
|
||||
Ok(stream) => stream,
|
||||
Err(err) => {
|
||||
error!("Can not request to server {}", err);
|
||||
break;
|
||||
}
|
||||
};
|
||||
// let connector = connector.clone();
|
||||
// let mut connector = connector.lock().await;
|
||||
let (reader, mut writer) = connector.split();
|
||||
// Forward all request without illegal headers
|
||||
if let Err(err) = writer.write_all(frame.request.as_bytes()).await {
|
||||
error!("Can not write to server {}", err);
|
||||
return;
|
||||
break;
|
||||
}
|
||||
let mut reader = BufReader::new(reader);
|
||||
let mut res_header = String::new();
|
||||
@ -88,7 +88,13 @@ pub async fn headers_parser(port: usize) {
|
||||
|
||||
tokio::spawn(async move {
|
||||
let mut buf = BufReader::new(&mut stream);
|
||||
let header = read_to_end(&mut buf).await;
|
||||
let header = match read_to_end(&mut buf).await {
|
||||
Ok(c) => c,
|
||||
Err(err) => {
|
||||
error!("Failed to read headers {}", err);
|
||||
return;
|
||||
}
|
||||
};
|
||||
let header: Vec<_> = header.split("\r\n").collect();
|
||||
let first_line = header.first().unwrap();
|
||||
let header = &header[1..header.len() - 2];
|
||||
@ -97,7 +103,7 @@ pub async fn headers_parser(port: usize) {
|
||||
// Remove all illegal headers
|
||||
let header: Vec<_> = header
|
||||
.iter()
|
||||
.filter(|head| head.contains(':'))
|
||||
.filter(|head| head.contains(':') && !head.contains(';'))
|
||||
.map(|head| head.to_string())
|
||||
.map(|h| {
|
||||
if h.to_lowercase().starts_with("content-length") {
|
||||
@ -107,6 +113,7 @@ pub async fn headers_parser(port: usize) {
|
||||
h
|
||||
})
|
||||
.collect();
|
||||
debug!("{:?}", &header);
|
||||
let headers = format!("{first_line}\r\n{}\r\n\r\n", header.join("\r\n"));
|
||||
// If has content-length, read request body
|
||||
let request = if content_len > 0 {
|
||||
@ -145,13 +152,13 @@ pub async fn headers_parser(port: usize) {
|
||||
}
|
||||
}
|
||||
|
||||
async fn read_to_end(buf: &mut BufReader<&mut TcpStream>) -> String {
|
||||
async fn read_to_end(buf: &mut BufReader<&mut TcpStream>) -> Result<String> {
|
||||
let mut target = String::new();
|
||||
loop {
|
||||
let count = buf.read_line(&mut target).await.unwrap();
|
||||
let count = buf.read_line(&mut target).await?;
|
||||
if count < 3 {
|
||||
break;
|
||||
}
|
||||
}
|
||||
target
|
||||
Ok(target)
|
||||
}
|
70
src/main.rs
70
src/main.rs
@ -56,32 +56,32 @@ async fn main() -> Result<()> {
|
||||
.layer(TimeoutLayer::new(Duration::from_secs(10))),
|
||||
);
|
||||
|
||||
// Parse illegal headers
|
||||
tokio::spawn(async move {
|
||||
headers_parser(port).await;
|
||||
});
|
||||
|
||||
let addr: SocketAddr = match format!("127.0.0.1:{:?}", port + 1).parse() {
|
||||
let addr: SocketAddr = match format!("0.0.0.0:{:?}", port + 1).parse() {
|
||||
Ok(addr) => addr,
|
||||
Err(err) => {
|
||||
error!("Failed to parse address {}", err);
|
||||
exit(1);
|
||||
}
|
||||
};
|
||||
match Server::bind(&addr)
|
||||
.serve(app.into_make_service())
|
||||
.with_graceful_shutdown(shutdown_signal())
|
||||
.await
|
||||
{
|
||||
Ok(()) => {
|
||||
info!("Server shutdown");
|
||||
}
|
||||
Err(err) => {
|
||||
error!("Can not start server {}", err);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
// info!("Server listening on {}", &addr);
|
||||
|
||||
tokio::spawn(async move {
|
||||
match Server::bind(&addr)
|
||||
.serve(app.into_make_service())
|
||||
.with_graceful_shutdown(shutdown_signal())
|
||||
.await
|
||||
{
|
||||
Ok(()) => {
|
||||
info!("Server shutdown");
|
||||
}
|
||||
Err(err) => {
|
||||
error!("Can not start server {}", err);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
headers_parser(port).await;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -99,4 +99,36 @@ async fn shutdown_signal() {
|
||||
pub async fn fallback(uri: http::Uri) -> impl response::IntoResponse {
|
||||
info!("Route {} not found", uri);
|
||||
(http::StatusCode::NOT_FOUND, "Not found")
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use tokio::{
|
||||
io::{AsyncBufReadExt, AsyncWriteExt, BufReader},
|
||||
net::TcpStream,
|
||||
};
|
||||
|
||||
#[tokio::test]
|
||||
async fn accept_illegal_headers() {
|
||||
illegal_headers().await;
|
||||
}
|
||||
|
||||
async fn illegal_headers() {
|
||||
let mut stream = TcpStream::connect("127.0.0.1:3000").await.unwrap();
|
||||
let (read, mut write) = stream.split();
|
||||
let headers =
|
||||
"GET /sms.aspx HTTP/1.1\r\nHost: localhost:3000\r\nAccept: */*\r\nUser-Agent: curl/7.87.0\r\nthis is illgeal headers\r\n\r\n";
|
||||
println!("{headers}");
|
||||
write.write_all(headers.as_bytes()).await.unwrap();
|
||||
|
||||
let mut buf = BufReader::new(read);
|
||||
let mut res = String::new();
|
||||
loop {
|
||||
let count = buf.read_line(&mut res).await.unwrap();
|
||||
if count < 3 {
|
||||
break;
|
||||
}
|
||||
}
|
||||
println!("{}", res);
|
||||
}
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
use tokio::io::{AsyncBufReadExt, AsyncWriteExt, BufReader};
|
||||
use tokio::net::TcpStream;
|
||||
|
||||
#[tokio::test]
|
||||
async fn accept_illegal_headers() {
|
||||
illegal_headers().await;
|
||||
}
|
||||
|
||||
async fn illegal_headers() {
|
||||
let mut stream = TcpStream::connect("localhost:3000").await.unwrap();
|
||||
let (read, mut write) = stream.split();
|
||||
let headers =
|
||||
"GET /sms.aspx HTTP/1.1\r\nHost: localhost:3000\r\nAccept: */*\r\nUser-Agent: curl/7.87.0\r\nthis is illgeal headers\r\n\r\n";
|
||||
println!("{headers}");
|
||||
write.write_all(headers.as_bytes()).await.unwrap();
|
||||
|
||||
let mut buf = BufReader::new(read);
|
||||
let mut res = String::new();
|
||||
loop {
|
||||
let count = buf.read_line(&mut res).await.unwrap();
|
||||
if count < 3 {
|
||||
break;
|
||||
}
|
||||
}
|
||||
println!("{}", res);
|
||||
}
|
Reference in New Issue
Block a user