@@ -5,7 +5,7 @@ use axum::{
55 Request , State ,
66 ws:: { Message , WebSocket , WebSocketUpgrade } ,
77 } ,
8- http:: { HeaderValue , StatusCode , Uri } ,
8+ http:: { HeaderValue , StatusCode , header :: CONTENT_LENGTH } ,
99 middleware:: { self , Next } ,
1010 response:: { IntoResponse , Response } ,
1111 routing:: get,
@@ -17,7 +17,7 @@ use tokio::{
1717 signal,
1818 sync:: { RwLock , broadcast} ,
1919} ;
20- use tracing:: { Level , debug, warn } ;
20+ use tracing:: { Level , debug} ;
2121
2222use std:: net:: { IpAddr , SocketAddr } ;
2323use std:: sync:: Arc ;
@@ -69,12 +69,9 @@ struct AppState {
6969 current_status : Arc < RwLock < Option < PersistentStatus > > > ,
7070}
7171
72- fn inject_live_reload_script (
73- uri : & Uri ,
74- html_content : & str ,
75- socket_addr : SocketAddr ,
76- host : bool ,
77- ) -> String {
72+ fn inject_live_reload_script ( html_content : & str , socket_addr : SocketAddr , host : bool ) -> String {
73+ let mut content = html_content. to_string ( ) ;
74+
7875 let script_content = include_str ! ( concat!( env!( "OUT_DIR" ) , "/js/client.js" ) ) . replace (
7976 "{SERVER_ADDRESS}" ,
8077 & format ! (
@@ -88,19 +85,8 @@ fn inject_live_reload_script(
8885 ) ,
8986 ) ;
9087
91- // Only inject script if content looks like proper HTML
92- if html_content. trim_start ( ) . starts_with ( "<!DOCTYPE" )
93- || html_content. trim_start ( ) . starts_with ( "<html" )
94- {
95- format ! ( "{}<script>{}</script>" , html_content, script_content)
96- } else {
97- warn ! (
98- "{} matched an HTML response, but it does not look like proper HTML, live-reload won't work. Make sure your HTML has a proper <!DOCTYPE> or <html> tag." ,
99- uri
100- ) ;
101- // Not proper HTML, return content unchanged
102- html_content. to_string ( )
103- }
88+ content. push_str ( & format ! ( "\n \n <script>{script_content}</script>" ) ) ;
89+ content
10490}
10591
10692pub async fn start_dev_web_server (
@@ -124,12 +110,7 @@ pub async fn start_dev_web_server(
124110 } ) ;
125111 }
126112
127- async fn handle_404 (
128- uri : Uri ,
129- socket_addr : SocketAddr ,
130- host : bool ,
131- dist_dir : & str ,
132- ) -> impl IntoResponse {
113+ async fn handle_404 ( socket_addr : SocketAddr , host : bool , dist_dir : & str ) -> impl IntoResponse {
133114 let content = match fs:: read_to_string ( format ! ( "{}/404.html" , dist_dir) ) . await {
134115 Ok ( custom_content) => custom_content,
135116 Err ( _) => include_str ! ( "./404.html" ) . to_string ( ) ,
@@ -138,7 +119,7 @@ pub async fn start_dev_web_server(
138119 (
139120 StatusCode :: NOT_FOUND ,
140121 [ ( header:: CONTENT_TYPE , "text/html; charset=utf-8" ) ] ,
141- inject_live_reload_script ( & uri , & content, socket_addr, host) ,
122+ inject_live_reload_script ( & content, socket_addr, host) ,
142123 )
143124 . into_response ( )
144125 }
@@ -162,8 +143,8 @@ pub async fn start_dev_web_server(
162143 debug ! ( "listening on {}" , listener. local_addr( ) . unwrap( ) ) ;
163144
164145 let serve_dir =
165- ServeDir :: new ( dist_dir) . not_found_service ( axum:: routing:: any ( move |uri : Uri | async move {
166- handle_404 ( uri , socket_addr, host, dist_dir) . await
146+ ServeDir :: new ( dist_dir) . not_found_service ( axum:: routing:: any ( move || async move {
147+ handle_404 ( socket_addr, host, dist_dir) . await
167148 } ) ) ;
168149
169150 // TODO: Return a `.well-known/appspecific/com.chrome.devtools.json` for Chrome
@@ -254,16 +235,24 @@ async fn add_dev_client_script(
254235 if res. headers ( ) . get ( axum:: http:: header:: CONTENT_TYPE )
255236 == Some ( & HeaderValue :: from_static ( "text/html" ) )
256237 {
238+ let original_headers = res. headers ( ) . clone ( ) ;
257239 let body = res. into_body ( ) ;
258240 let bytes = to_bytes ( body, usize:: MAX ) . await . unwrap ( ) ;
259241
260242 let body = String :: from_utf8_lossy ( & bytes) . into_owned ( ) ;
261243
262- let body_with_script = inject_live_reload_script ( & uri, & body, socket_addr, host) ;
244+ let body_with_script = inject_live_reload_script ( & body, socket_addr, host) ;
245+ let new_body_length = body_with_script. len ( ) ;
263246
264247 // Copy the headers from the original response
265248 let mut res = Response :: new ( body_with_script. into ( ) ) ;
266- * res. headers_mut ( ) = res. headers ( ) . clone ( ) ;
249+ * res. headers_mut ( ) = original_headers;
250+
251+ // Update Content-Length header to match new body size
252+ res. headers_mut ( ) . insert (
253+ CONTENT_LENGTH ,
254+ HeaderValue :: from_str ( & new_body_length. to_string ( ) ) . unwrap ( ) ,
255+ ) ;
267256
268257 res. extensions_mut ( ) . insert ( uri) ;
269258
0 commit comments