Skip to content

Commit 55a4b36

Browse files
committed
webui: optimize http server speed with http2
1 parent 7c1a232 commit 55a4b36

File tree

1 file changed

+72
-21
lines changed

1 file changed

+72
-21
lines changed

plugin/smartdns-ui/src/http_server.rs

Lines changed: 72 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,10 @@ use bytes::Bytes;
3131
use http_body_util::Full;
3232
use hyper::body;
3333
use hyper::header::HeaderValue;
34-
use hyper::server::conn::http1;
3534
use hyper::StatusCode;
3635
use hyper::{service::service_fn, Request, Response};
3736
use hyper_util::rt::TokioIo;
37+
use hyper_util::server::conn::auto;
3838
use std::convert::Infallible;
3939
use std::error::Error;
4040
use std::fs::Metadata;
@@ -91,9 +91,15 @@ impl HttpServerConfig {
9191
let mut map = std::collections::HashMap::new();
9292
map.insert("http_ip".to_string(), self.http_ip.clone());
9393
map.insert("username".to_string(), self.username.clone());
94-
map.insert("token_expired_time".to_string(), self.token_expired_time.to_string());
94+
map.insert(
95+
"token_expired_time".to_string(),
96+
self.token_expired_time.to_string(),
97+
);
9598
map.insert("enable_cors".to_string(), self.enable_cors.to_string());
96-
map.insert("enable_terminal".to_string(), self.enable_terminal.to_string());
99+
map.insert(
100+
"enable_terminal".to_string(),
101+
self.enable_terminal.to_string(),
102+
);
97103
map
98104
}
99105

@@ -121,7 +127,8 @@ impl HttpServerConfig {
121127
}
122128
}
123129

124-
if let Some(enable_terminal) = data_server.get_server_config("smartdns-ui.enable-terminal") {
130+
if let Some(enable_terminal) = data_server.get_server_config("smartdns-ui.enable-terminal")
131+
{
125132
if enable_terminal.eq_ignore_ascii_case("yes")
126133
|| enable_terminal.eq_ignore_ascii_case("true")
127134
{
@@ -224,6 +231,19 @@ impl Drop for HttpServerControl {
224231
}
225232
}
226233

234+
#[derive(Clone)]
235+
pub struct TokioExecutor;
236+
237+
impl<F> hyper::rt::Executor<F> for TokioExecutor
238+
where
239+
F: std::future::Future + Send + 'static,
240+
F::Output: Send + 'static,
241+
{
242+
fn execute(&self, fut: F) {
243+
tokio::task::spawn(fut);
244+
}
245+
}
246+
227247
pub struct HttpServer {
228248
conf: Mutex<HttpServerConfig>,
229249
notify_tx: Option<mpsc::Sender<()>>,
@@ -247,23 +267,43 @@ impl HttpServer {
247267
login_attempts: Mutex::new((0, Instant::now())),
248268
plugin: Mutex::new(None),
249269
mime_map: std::collections::HashMap::from([
270+
/* text */
250271
("htm", "text/html"),
251272
("html", "text/html"),
252273
("js", "text/javascript"),
253274
("css", "text/css"),
254-
("json", "application/json"),
275+
("txt", "text/plain"),
276+
("conf", "text/plain"),
277+
("xml", "text/xml"),
278+
("csv", "text/csv"),
279+
("md", "text/markdown"),
280+
/* image */
255281
("png", "image/png"),
256282
("gif", "image/gif"),
257283
("jpeg", "image/jpeg"),
258284
("svg", "image/svg+xml"),
259-
("tar", "application/x-tar"),
260-
("zip", "application/zip"),
261-
("txt", "text/plain"),
262-
("conf", "text/plain"),
263-
("ico", "application/octet-stream"),
264-
("xml", "text/xml"),
285+
("ico", "image/x-icon"),
286+
("bmp", "image/bmp"),
287+
("avif", "image/avif"),
288+
/* video */
265289
("mpeg", "video/mpeg"),
290+
("mp4", "video/mp4"),
291+
("webm", "video/webm"),
292+
/* audio */
266293
("mp3", "audio/mpeg"),
294+
("ogg", "audio/ogg"),
295+
("wav", "audio/wav"),
296+
/* font */
297+
("woff", "font/woff"),
298+
("woff2", "font/woff2"),
299+
("ttf", "font/ttf"),
300+
("otf", "font/otf"),
301+
/* application */
302+
("wasm", "application/wasm"),
303+
("pdf", "application/pdf"),
304+
("json", "application/json"),
305+
("tar", "application/x-tar"),
306+
("zip", "application/zip"),
267307
]),
268308
};
269309

@@ -648,6 +688,8 @@ impl HttpServer {
648688
let header = response.headers_mut();
649689
header.insert("Content-Length", bytes_len.to_string().parse().unwrap());
650690
header.insert("Content-Type", this.get_mime_type(&path).parse().unwrap());
691+
header.insert("Connection", "keep-alive".parse().unwrap());
692+
header.insert("Keep-Alive", "timeout=60, max=1000".parse().unwrap());
651693

652694
if file_meta.as_ref().is_some() {
653695
let etag = fn_get_etag(&file_meta.as_ref().unwrap());
@@ -663,7 +705,7 @@ impl HttpServer {
663705
Ok(response)
664706
}
665707
Err(_) => {
666-
let bytes = Bytes::from("Not Found");
708+
let bytes = Bytes::from("Page Not Found");
667709
let mut response = Response::new(Full::new(bytes));
668710
*response.status_mut() = StatusCode::NOT_FOUND;
669711
Ok(response)
@@ -677,9 +719,8 @@ impl HttpServer {
677719
let handle_func = move |req| HttpServer::server_handle_http_request(this.clone(), req);
678720

679721
tokio::task::spawn(async move {
680-
let conn = http1::Builder::new()
681-
.serve_connection(io, service_fn(handle_func))
682-
.with_upgrades()
722+
let conn = auto::Builder::new(TokioExecutor)
723+
.serve_connection_with_upgrades(io, service_fn(handle_func))
683724
.await;
684725
if let Err(err) = conn {
685726
dns_log!(LogLevel::DEBUG, "Error serving connection: {:?}", err);
@@ -698,9 +739,8 @@ impl HttpServer {
698739
let handle_func = move |req| HttpServer::server_handle_http_request(this.clone(), req);
699740

700741
tokio::task::spawn(async move {
701-
let conn = http1::Builder::new()
702-
.serve_connection(io, service_fn(handle_func))
703-
.with_upgrades()
742+
let conn = auto::Builder::new(TokioExecutor)
743+
.serve_connection_with_upgrades(io, service_fn(handle_func))
704744
.await;
705745
if let Err(err) = conn {
706746
dns_log!(LogLevel::DEBUG, "Error serving connection: {:?}", err);
@@ -772,9 +812,11 @@ impl HttpServer {
772812
))?
773813
.unwrap();
774814

775-
let config = rustls::ServerConfig::builder()
815+
let mut config = rustls::ServerConfig::builder()
776816
.with_no_client_auth()
777817
.with_single_cert(cert_chain, key_der)?;
818+
819+
config.alpn_protocols = vec![b"h2".to_vec(), b"http/1.1".to_vec()];
778820
acceptor = Some(TlsAcceptor::from(Arc::new(config)));
779821
}
780822
} else {
@@ -806,10 +848,19 @@ impl HttpServer {
806848
let sock_ref = socket2::SockRef::from(&stream);
807849

808850
let mut ka = socket2::TcpKeepalive::new();
809-
ka = ka.with_time(Duration::from_secs(30));
810-
ka = ka.with_interval(Duration::from_secs(10));
851+
ka = ka.with_time(Duration::from_secs(60));
852+
ka = ka.with_interval(Duration::from_secs(30));
811853
sock_ref.set_tcp_keepalive(&ka)?;
812854
sock_ref.set_nonblocking(true)?;
855+
sock_ref.tcp_nodelay()?;
856+
857+
if let Err(_) = sock_ref.set_recv_buffer_size(262144) {
858+
dns_log!(LogLevel::DEBUG, "Failed to set recv buffer size");
859+
}
860+
861+
if let Err(_) = sock_ref.set_send_buffer_size(262144) {
862+
dns_log!(LogLevel::DEBUG, "Failed to set send buffer size");
863+
}
813864
cfg_if::cfg_if! {
814865
if #[cfg(feature = "https")]
815866
{

0 commit comments

Comments
 (0)