Skip to content

Commit

Permalink
up
Browse files Browse the repository at this point in the history
  • Loading branch information
ibigbug committed Dec 25, 2023
1 parent 914d7ef commit 04fd225
Show file tree
Hide file tree
Showing 18 changed files with 234 additions and 110 deletions.
219 changes: 175 additions & 44 deletions Cargo.lock

Large diffs are not rendered by default.

11 changes: 6 additions & 5 deletions clash_lib/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ regex = "1"
byteorder = "1.5"
state = "0.6"
lru_time_cache = "0.11"
hyper = { version = "0.14", features = ["http1","http2","client", "server", "tcp"] }
http = { version = "0.2.11" }
hyper = { version = "0.14.28", features = ["http1","http2","client", "server", "tcp"] }
http = { version = "1.0" }
httparse = "1.8.0"
h2 = "0.4.0"
prost = "0.12"
Expand Down Expand Up @@ -57,8 +57,8 @@ md-5 = "0.10.5"
chacha20poly1305 = "0.10"
aes-gcm = "0.10"
filetime = "0.2"
axum = { version = "0.6.20", features = ["ws"] }
tower-http = { version = "0.4.0", features = ["fs", "trace", "cors"] }
axum = { version = "0.7", features = ["ws"] }
tower-http = { version = "0.5.0", features = ["fs", "trace", "cors"] }
chrono = { version = "0.4.26", features = ["serde"] }

tun = { git = "https://github.com/Watfaq/rust-tun.git", rev = "8f7568190f1200d3e272ca534baf8d1578147e18", features = ["async"] }
Expand All @@ -68,6 +68,7 @@ boringtun = { version = "0.6.0" }

serde = { version = "1.0", features=["derive"] }
serde_yaml = "0.9"
serde_json = "1.0"
erased-serde = "0.3.30"

hickory-client = "0.24"
Expand All @@ -84,7 +85,7 @@ dhcproto = "0.11"
rand = "0.8"

socket2 = { version = "0.5", features = ["all"] }
tokio-tungstenite = "0.20.0"
tokio-tungstenite = "0.21.0"

tracing = "0.1"
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
Expand Down
15 changes: 5 additions & 10 deletions clash_lib/src/app/api/handlers/connection.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
use std::sync::Arc;

use axum::{
extract::{ws::Message, FromRequest, Path, Query, State, WebSocketUpgrade},
body::Body,
extract::{ws::Message, FromRequest, Path, Query, Request, State, WebSocketUpgrade},
response::IntoResponse,
routing::{delete, get},
Json, Router,
};
use http::{HeaderMap, Request};
use hyper::{body::HttpBody, Body};
use http::HeaderMap;
use serde::Deserialize;
use tracing::{debug, warn};

Expand Down Expand Up @@ -63,13 +63,8 @@ async fn get_connections(

loop {
let snapshot = mgr.snapshot().await;
let j = Json(snapshot)
.into_response()
.data()
.await
.unwrap()
.unwrap();
let body = String::from_utf8(j.to_vec()).unwrap();
let j = serde_json::to_vec(&snapshot).unwrap();
let body = String::from_utf8(j).unwrap();

if let Err(e) = socket.send(Message::Text(body)).await {
// likely client gone
Expand Down
6 changes: 2 additions & 4 deletions clash_lib/src/app/api/handlers/log.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,8 @@ use std::{net::SocketAddr, sync::Arc};
use axum::{
extract::{ws::Message, ConnectInfo, State, WebSocketUpgrade},
response::IntoResponse,
Json,
};

use hyper::body::HttpBody;
use tracing::warn;

use crate::app::api::AppState;
Expand All @@ -22,10 +20,10 @@ pub async fn handle(
.on_upgrade(move |mut socket| async move {
let mut rx = state.log_source_tx.subscribe();
while let Ok(evt) = rx.recv().await {
let res = Json(evt).into_response().data().await.unwrap().unwrap();
let res = serde_json::to_vec(&evt).unwrap();

if let Err(e) = socket
.send(Message::Text(String::from_utf8(res.to_vec()).unwrap()))
.send(Message::Text(String::from_utf8(res).unwrap()))
.await
{
warn!("ws send error: {}", e);
Expand Down
12 changes: 6 additions & 6 deletions clash_lib/src/app/api/handlers/provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,11 @@ async fn get_providers(State(state): State<ProviderState>) -> impl IntoResponse
axum::response::Json(res)
}

async fn find_proxy_provider_by_name<B>(
async fn find_proxy_provider_by_name(
State(state): State<ProviderState>,
Path(name): Path<String>,
mut req: Request<B>,
next: Next<B>,
mut req: Request<axum::body::Body>,
next: Next,
) -> Response {
let outbound_manager = state.outbound_manager.clone();
if let Some(provider) = outbound_manager.get_proxy_provider(&name) {
Expand Down Expand Up @@ -123,11 +123,11 @@ async fn provider_healthcheck(
(StatusCode::ACCEPTED, "provider healthcheck")
}

async fn find_provider_proxy_by_name<B>(
async fn find_provider_proxy_by_name(
Extension(provider): Extension<ThreadSafeProxyProvider>,
Path(params): Path<HashMap<String, String>>,
mut req: Request<B>,
next: Next<B>,
mut req: Request<axum::body::Body>,
next: Next,
) -> Response {
let proxy = provider.read().await.proxies().await;
let proxy = proxy
Expand Down
6 changes: 3 additions & 3 deletions clash_lib/src/app/api/handlers/proxy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,11 @@ async fn get_proxies(State(state): State<ProxyState>) -> impl IntoResponse {
axum::response::Json(res)
}

async fn find_proxy_by_name<B>(
async fn find_proxy_by_name(
State(state): State<ProxyState>,
Path(name): Path<String>,
mut req: Request<B>,
next: Next<B>,
mut req: Request<axum::body::Body>,
next: Next,
) -> Response {
let outbound_manager = state.outbound_manager.clone();
if let Some(proxy) = outbound_manager.get_outbound(&name) {
Expand Down
7 changes: 3 additions & 4 deletions clash_lib/src/app/api/handlers/traffic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,8 @@ use std::{net::SocketAddr, sync::Arc};
use axum::{
extract::{ws::Message, ConnectInfo, State, WebSocketUpgrade},
response::IntoResponse,
Json,
};
use hyper::body::HttpBody;

use serde::Serialize;
use tracing::warn;

Expand All @@ -29,10 +28,10 @@ pub async fn handle(
loop {
let (up, down) = mgr.now();
let res = TrafficResponse { up, down };
let j = Json(res).into_response().data().await.unwrap().unwrap();
let j = serde_json::to_vec(&res).unwrap();

if let Err(e) = socket
.send(Message::Text(String::from_utf8(j.to_vec()).unwrap()))
.send(Message::Text(String::from_utf8(j).unwrap()))
.await
{
warn!("ws send error: {}", e);
Expand Down
3 changes: 2 additions & 1 deletion clash_lib/src/app/api/middlewares/auth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use axum::extract::Query;
use axum::http::Request;
use axum::{body::Body, response::Response};
use futures::future::BoxFuture;

use serde::Deserialize;
use tower::{Layer, Service};

Expand Down Expand Up @@ -73,7 +74,7 @@ where

let unauthorised = Response::builder()
.status(http::StatusCode::UNAUTHORIZED)
.body(axum::body::boxed("unauthorized".to_string()))
.body("unauthorized".to_string().into())
.unwrap();

if self.is_websocket(&req) {
Expand Down
19 changes: 8 additions & 11 deletions clash_lib/src/app/api/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use std::path::PathBuf;
use std::{net::SocketAddr, sync::Arc};
use std::sync::Arc;

use axum::{response::Redirect, routing::get, Router};

Expand Down Expand Up @@ -48,15 +48,13 @@ pub fn get_api_runner(
statistics_manager: statistics_manager.clone(),
});

let addr = bind_addr.parse().unwrap();

let cors = CorsLayer::new()
.allow_methods([Method::GET, Method::POST, Method::PUT, Method::PATCH])
.allow_headers([header::AUTHORIZATION, header::CONTENT_TYPE])
.allow_origin(Any);

let runner = async move {
info!("Starting API server at {}", addr);
info!("Starting API server at {}", bind_addr);
let mut app = Router::new()
.route("/", get(handlers::hello::handle))
.route("/logs", get(handlers::log::handle))
Expand Down Expand Up @@ -97,13 +95,12 @@ pub fn get_api_runner(
.nest_service("/ui/", ServeDir::new(PathBuf::from(cwd).join(external_ui)));
}

axum::Server::bind(&addr)
.serve(app.into_make_service_with_connect_info::<SocketAddr>())
.await
.map_err(|x| {
error!("API server error: {}", x);
crate::Error::Operation(format!("API server error: {}", x))
})
let listener = tokio::net::TcpListener::bind(&bind_addr).await.unwrap();

axum::serve(listener, app).await.map_err(|x| {
error!("API server error: {}", x);
crate::Error::Operation(format!("API server error: {}", x))
})
};
Some(Box::pin(runner))
} else {
Expand Down
2 changes: 1 addition & 1 deletion clash_lib/src/app/outbound/manager.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use anyhow::Result;
use erased_serde::Serialize;
use http::Uri;
use hyper::Uri;
use std::collections::HashMap;
use std::path::PathBuf;
use std::sync::Arc;
Expand Down
2 changes: 1 addition & 1 deletion clash_lib/src/app/remote_content_manager/http_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use std::{
};

use futures::Future;
use http::Uri;
use hyper::Uri;

use tower::Service;

Expand Down
6 changes: 3 additions & 3 deletions clash_lib/src/app/remote_content_manager/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use boring::ssl::{SslConnector, SslMethod};
use chrono::{DateTime, Utc};

use futures::{stream::FuturesUnordered, StreamExt};
use http::{Request, Version};
use hyper::Request;
use hyper_boring::HttpsConnector;
use serde::Serialize;
use tokio::sync::RwLock;
Expand Down Expand Up @@ -179,7 +179,7 @@ impl ProxyManager {

let req = Request::get(url)
.header("Connection", "Close")
.version(Version::HTTP_11)
.version(hyper::Version::HTTP_11)
.body(hyper::Body::empty())
.unwrap();

Expand Down Expand Up @@ -209,7 +209,7 @@ impl ProxyManager {

let req2 = Request::get(url)
.header("Connection", "Close")
.version(Version::HTTP_11)
.version(hyper::Version::HTTP_11)
.body(hyper::Body::empty())
.unwrap();
let resp2 = TimedFuture::new(client.request(req2), None);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ mod tests {
use std::str;
use std::sync::Arc;

use http::Uri;
use hyper::Uri;

use crate::app::dns::{Resolver, ThreadSafeDNSResolver};

Expand Down
2 changes: 1 addition & 1 deletion clash_lib/src/app/router/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use std::path::PathBuf;
use std::sync::Arc;
use std::time::Duration;

use http::Uri;
use hyper::Uri;
use tracing::{error, info};

use super::dns::ThreadSafeDNSResolver;
Expand Down
7 changes: 5 additions & 2 deletions clash_lib/src/common/http.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,11 @@ use std::{

use boring::ssl::{SslConnector, SslMethod};
use futures::Future;
use http::Uri;
use hyper::client::connect::{Connected, Connection};

use hyper::{
client::connect::{Connected, Connection},
Uri,
};
use hyper_boring::HttpsConnector;
use tower::Service;

Expand Down
2 changes: 1 addition & 1 deletion clash_lib/src/common/mmdb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ impl MMDB {
path: P,
http_client: &HttpClient,
) -> anyhow::Result<()> {
let uri = url.parse::<http::Uri>()?;
let uri = url.parse::<hyper::Uri>()?;
let mut out = std::fs::File::create(&path)?;

let mut res = http_client.get(uri).await?;
Expand Down
10 changes: 5 additions & 5 deletions clash_lib/src/proxy/http/inbound/auth.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
use base64::Engine;
use http::{Request, Response};
use hyper::Body;

use hyper::{Body, Request, Response};
use tracing::warn;

use crate::common::auth::ThreadSafeAuthenticator;

fn parse_basic_proxy_authorization(req: &Request<Body>) -> Option<&str> {
req.headers()
.get(http::header::PROXY_AUTHORIZATION)
.get(hyper::header::PROXY_AUTHORIZATION)
.map(|v| v.to_str().unwrap_or_default())
.map(|v| {
if v.starts_with("Basic ") {
Expand Down Expand Up @@ -36,8 +36,8 @@ pub fn authenticate_req(
authenticator: ThreadSafeAuthenticator,
) -> Option<Response<Body>> {
let auth_resp = Response::builder()
.status(http::StatusCode::PROXY_AUTHENTICATION_REQUIRED)
.header(http::header::PROXY_AUTHENTICATE, "Basic")
.status(hyper::StatusCode::PROXY_AUTHENTICATION_REQUIRED)
.header(hyper::header::PROXY_AUTHENTICATE, "Basic")
.body("Proxy Auth Required".into())
.unwrap();
let cred = parse_basic_proxy_authorization(req);
Expand Down
13 changes: 6 additions & 7 deletions clash_lib/src/proxy/http/inbound/proxy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@ use std::{
};

use futures::{future::BoxFuture, TryFutureExt};
use http::{uri::Scheme, Method, Request, Response, Uri};

use hyper::{server::conn::Http, Body, Client};
use hyper::{server::conn::Http, Body, Client, Method, Request, Response, Uri};

use tower::Service;
use tracing::{instrument, warn};
Expand All @@ -23,9 +22,9 @@ use super::{auth::authenticate_req, connector::Connector};
pub fn maybe_socks_addr(r: &Uri) -> Option<SocksAddr> {
let port = r
.port_u16()
.unwrap_or(match r.scheme().unwrap_or(&Scheme::HTTP) {
s if s == &Scheme::HTTP => 80 as _,
s if s == &Scheme::HTTPS => 443 as _,
.unwrap_or(match r.scheme().map(|s| s.as_str()).unwrap_or_default() {
"http" => 80 as _,
"https" => 443 as _,
_ => return None,
});

Expand Down Expand Up @@ -79,7 +78,7 @@ async fn proxy(
Ok(Response::new(Body::empty()))
} else {
Ok(Response::builder()
.status(http::StatusCode::BAD_REQUEST)
.status(hyper::StatusCode::BAD_REQUEST)
.body(format!("invalid request uri: {}", req.uri().to_string()).into())
.unwrap())
}
Expand All @@ -93,7 +92,7 @@ async fn proxy(
Err(e) => {
warn!("http proxy error: {}", e);
Ok(Response::builder()
.status(http::StatusCode::BAD_GATEWAY)
.status(hyper::StatusCode::BAD_GATEWAY)
.body(Body::empty())
.unwrap())
}
Expand Down

0 comments on commit 04fd225

Please sign in to comment.