mirror of
https://github.com/DefectingCat/rua-list
synced 2025-07-16 01:01:32 +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/
|
target/
|
||||||
.git/
|
.git/
|
||||||
|
config.json
|
||||||
|
logs/
|
||||||
|
.DS_Store
|
4
.gitignore
vendored
4
.gitignore
vendored
@ -1,3 +1,5 @@
|
|||||||
/target
|
/target
|
||||||
config.json
|
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-appender = "0.2.2"
|
||||||
tracing-error = "0.2.0"
|
tracing-error = "0.2.0"
|
||||||
color-eyre = "0.6.2"
|
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
|
// 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 log::{debug, error, info};
|
||||||
use std::{net::SocketAddr, process::exit, sync::Arc};
|
use std::{net::SocketAddr, process::exit};
|
||||||
use tokio::{
|
use tokio::{
|
||||||
io::{AsyncBufReadExt, AsyncReadExt, AsyncWriteExt, BufReader},
|
io::{AsyncBufReadExt, AsyncReadExt, AsyncWriteExt, BufReader},
|
||||||
net::{TcpListener, TcpStream},
|
net::{TcpListener, TcpStream},
|
||||||
sync::{mpsc, oneshot, Mutex},
|
sync::{mpsc, oneshot},
|
||||||
};
|
};
|
||||||
|
|
||||||
type Responder = oneshot::Sender<String>;
|
type Responder = oneshot::Sender<String>;
|
||||||
@ -31,22 +32,21 @@ pub async fn headers_parser(port: usize) {
|
|||||||
let (tx, mut rx) = mpsc::channel::<Frame>(128);
|
let (tx, mut rx) = mpsc::channel::<Frame>(128);
|
||||||
|
|
||||||
tokio::spawn(async move {
|
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 {
|
while let Some(frame) = rx.recv().await {
|
||||||
let connector = connector.clone();
|
let mut connector = match TcpStream::connect("127.0.0.1:3001").await {
|
||||||
let mut connector = connector.lock().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();
|
let (reader, mut writer) = connector.split();
|
||||||
// Forward all request without illegal headers
|
// Forward all request without illegal headers
|
||||||
if let Err(err) = writer.write_all(frame.request.as_bytes()).await {
|
if let Err(err) = writer.write_all(frame.request.as_bytes()).await {
|
||||||
error!("Can not write to server {}", err);
|
error!("Can not write to server {}", err);
|
||||||
return;
|
break;
|
||||||
}
|
}
|
||||||
let mut reader = BufReader::new(reader);
|
let mut reader = BufReader::new(reader);
|
||||||
let mut res_header = String::new();
|
let mut res_header = String::new();
|
||||||
@ -88,7 +88,13 @@ pub async fn headers_parser(port: usize) {
|
|||||||
|
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
let mut buf = BufReader::new(&mut stream);
|
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 header: Vec<_> = header.split("\r\n").collect();
|
||||||
let first_line = header.first().unwrap();
|
let first_line = header.first().unwrap();
|
||||||
let header = &header[1..header.len() - 2];
|
let header = &header[1..header.len() - 2];
|
||||||
@ -97,7 +103,7 @@ pub async fn headers_parser(port: usize) {
|
|||||||
// Remove all illegal headers
|
// Remove all illegal headers
|
||||||
let header: Vec<_> = header
|
let header: Vec<_> = header
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|head| head.contains(':'))
|
.filter(|head| head.contains(':') && !head.contains(';'))
|
||||||
.map(|head| head.to_string())
|
.map(|head| head.to_string())
|
||||||
.map(|h| {
|
.map(|h| {
|
||||||
if h.to_lowercase().starts_with("content-length") {
|
if h.to_lowercase().starts_with("content-length") {
|
||||||
@ -107,6 +113,7 @@ pub async fn headers_parser(port: usize) {
|
|||||||
h
|
h
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
debug!("{:?}", &header);
|
||||||
let headers = format!("{first_line}\r\n{}\r\n\r\n", header.join("\r\n"));
|
let headers = format!("{first_line}\r\n{}\r\n\r\n", header.join("\r\n"));
|
||||||
// If has content-length, read request body
|
// If has content-length, read request body
|
||||||
let request = if content_len > 0 {
|
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();
|
let mut target = String::new();
|
||||||
loop {
|
loop {
|
||||||
let count = buf.read_line(&mut target).await.unwrap();
|
let count = buf.read_line(&mut target).await?;
|
||||||
if count < 3 {
|
if count < 3 {
|
||||||
break;
|
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))),
|
.layer(TimeoutLayer::new(Duration::from_secs(10))),
|
||||||
);
|
);
|
||||||
|
|
||||||
// Parse illegal headers
|
let addr: SocketAddr = match format!("0.0.0.0:{:?}", port + 1).parse() {
|
||||||
tokio::spawn(async move {
|
|
||||||
headers_parser(port).await;
|
|
||||||
});
|
|
||||||
|
|
||||||
let addr: SocketAddr = match format!("127.0.0.1:{:?}", port + 1).parse() {
|
|
||||||
Ok(addr) => addr,
|
Ok(addr) => addr,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
error!("Failed to parse address {}", err);
|
error!("Failed to parse address {}", err);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
match Server::bind(&addr)
|
// info!("Server listening on {}", &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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,4 +99,36 @@ async fn shutdown_signal() {
|
|||||||
pub async fn fallback(uri: http::Uri) -> impl response::IntoResponse {
|
pub async fn fallback(uri: http::Uri) -> impl response::IntoResponse {
|
||||||
info!("Route {} not found", uri);
|
info!("Route {} not found", uri);
|
||||||
(http::StatusCode::NOT_FOUND, "Not found")
|
(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