@@ -20,6 +20,7 @@ use axum::{
20
20
Router ,
21
21
} ;
22
22
use axum_extra:: routing:: RouterExt ;
23
+ use bustdir:: BustDir ;
23
24
use parking_lot:: RwLock ;
24
25
use reqwest:: { header:: HeaderMap , redirect:: Policy , Client } ;
25
26
use serde:: { Deserialize , Serialize } ;
@@ -46,6 +47,7 @@ async fn main() {
46
47
let root_url = valk_utils:: get_var ( "ROOT_URL" ) ;
47
48
let root_url = root_url. trim_end_matches ( '/' ) . to_owned ( ) ;
48
49
let port: u16 = std:: env:: var ( "PORT" ) . map_or ( DEFAULT_PORT , |v| v. parse ( ) . unwrap ( ) ) ;
50
+ let bust_dir = BustDir :: new ( & asset_dir) . expect ( "Failed to build cache busting directory" ) ;
49
51
50
52
let mut default_headers = HeaderMap :: new ( ) ;
51
53
default_headers. insert ( "Accept" , "application/json" . parse ( ) . unwrap ( ) ) ;
@@ -68,6 +70,7 @@ async fn main() {
68
70
let state = AppState {
69
71
svc_response : current_mcstatus,
70
72
root_url : root_url. into ( ) ,
73
+ bust_dir : bust_dir. into ( ) ,
71
74
} ;
72
75
73
76
let serve_dir = ServeDir :: new ( & asset_dir)
@@ -85,18 +88,18 @@ async fn main() {
85
88
. route ( "/api/java/" , get ( no_address) )
86
89
. route ( "/api/bedrock/" , get ( no_address) )
87
90
. route ( "/api/services" , get ( services:: handle_mcstatus) )
88
- . layer ( axum:: middleware:: from_fn ( noindex) )
91
+ . layer (
92
+ ServiceBuilder :: new ( )
93
+ . layer ( axum:: middleware:: from_fn ( noindex) )
94
+ . layer ( axum:: middleware:: from_fn ( cache) ) ,
95
+ )
89
96
. route ( "/" , get ( root) )
90
97
. route_with_tsr ( "/api/" , get ( api_info) )
91
98
. route_with_tsr ( "/ping/:edition/:hostname" , get ( ping_page) )
92
99
. route ( "/internal/ping-frame/:edition/:hostname" , get ( ping_frame) )
93
100
. route ( "/internal/ping-markup/:edition/:hostname" , get ( ping_markup) )
94
101
. fallback_service ( serve_dir)
95
- . layer (
96
- ServiceBuilder :: new ( )
97
- . layer ( axum:: middleware:: from_fn ( csp) )
98
- . layer ( axum:: middleware:: from_fn ( cache) ) ,
99
- )
102
+ . layer ( axum:: middleware:: from_fn ( csp) )
100
103
. with_state ( state) ;
101
104
102
105
let socket_address = SocketAddr :: from ( ( [ 0 , 0 , 0 , 0 ] , port) ) ;
@@ -111,11 +114,13 @@ async fn main() {
111
114
pub struct AppState {
112
115
svc_response : Arc < RwLock < ServicesResponse > > ,
113
116
root_url : Arc < str > ,
117
+ bust_dir : Arc < BustDir > ,
114
118
}
115
119
116
120
static ROBOTS_NAME : HeaderName = HeaderName :: from_static ( "x-robots-tag" ) ;
117
121
static ROBOTS_VALUE : HeaderValue = HeaderValue :: from_static ( "noindex" ) ;
118
- static CACHE_CONTROL_AGE : HeaderValue = HeaderValue :: from_static ( "s-maxage=30" ) ;
122
+ static CACHE_CONTROL_IMMUTABLE : HeaderValue =
123
+ HeaderValue :: from_static ( "immutable, public, max-age=604800" ) ;
119
124
120
125
static CSP_VALUE : HeaderValue = HeaderValue :: from_static (
121
126
"default-src 'self'; \
@@ -145,21 +150,23 @@ async fn csp(req: Request, next: Next) -> Response {
145
150
async fn cache ( req : Request , next : Next ) -> Response {
146
151
let mut resp = next. run ( req) . await ;
147
152
resp. headers_mut ( )
148
- . insert ( CACHE_CONTROL , CACHE_CONTROL_AGE . clone ( ) ) ;
153
+ . insert ( CACHE_CONTROL , CACHE_CONTROL_IMMUTABLE . clone ( ) ) ;
149
154
resp
150
155
}
151
156
152
157
#[ derive( Template ) ]
153
158
#[ template( path = "index.html" ) ]
154
159
pub struct RootTemplate {
155
160
svc_status : ServicesResponse ,
156
- root_url : String ,
161
+ root_url : Arc < str > ,
162
+ bd : Arc < BustDir > ,
157
163
}
158
164
159
165
async fn root ( State ( state) : State < AppState > ) -> RootTemplate {
160
166
RootTemplate {
161
167
svc_status : * state. svc_response . read ( ) ,
162
- root_url : state. root_url . to_string ( ) ,
168
+ root_url : state. root_url ,
169
+ bd : state. bust_dir ,
163
170
}
164
171
}
165
172
@@ -183,7 +190,8 @@ async fn ping_redirect(
183
190
#[ template( path = "ping-page.html" ) ]
184
191
pub struct PingPageTemplate {
185
192
svc_status : ServicesResponse ,
186
- root_url : String ,
193
+ root_url : Arc < str > ,
194
+ bd : Arc < BustDir > ,
187
195
hostname : String ,
188
196
edition : String ,
189
197
}
@@ -203,7 +211,8 @@ async fn ping_page(
203
211
}
204
212
Ok ( PingPageTemplate {
205
213
svc_status : * state. svc_response . read ( ) ,
206
- root_url : state. root_url . to_string ( ) ,
214
+ root_url : state. root_url ,
215
+ bd : state. bust_dir ,
207
216
hostname,
208
217
edition,
209
218
} )
@@ -230,7 +239,8 @@ async fn ping_generic(
230
239
#[ template( path = "ping-frame.html" ) ]
231
240
pub struct PingFrameTemplate {
232
241
ping : MCPingResponse ,
233
- root_url : String ,
242
+ bd : Arc < BustDir > ,
243
+ root_url : Arc < str > ,
234
244
}
235
245
236
246
async fn ping_frame (
@@ -240,15 +250,17 @@ async fn ping_frame(
240
250
let ping = ping_generic ( edition, hostname, & state) . await ?;
241
251
Ok ( PingFrameTemplate {
242
252
ping,
243
- root_url : state. root_url . to_string ( ) ,
253
+ root_url : state. root_url ,
254
+ bd : state. bust_dir ,
244
255
} )
245
256
}
246
257
247
258
#[ derive( Template ) ]
248
259
#[ template( path = "ping-element.html" ) ]
249
260
pub struct PingElementTemplate {
250
261
ping : MCPingResponse ,
251
- root_url : String ,
262
+ bd : Arc < BustDir > ,
263
+ root_url : Arc < str > ,
252
264
}
253
265
254
266
async fn ping_markup (
@@ -258,19 +270,22 @@ async fn ping_markup(
258
270
let ping = ping_generic ( edition, hostname, & state) . await ?;
259
271
Ok ( PingElementTemplate {
260
272
ping,
261
- root_url : state. root_url . to_string ( ) ,
273
+ bd : state. bust_dir ,
274
+ root_url : state. root_url ,
262
275
} )
263
276
}
264
277
265
278
#[ derive( Template ) ]
266
279
#[ template( path = "api.html" ) ]
267
280
pub struct ApiTemplate {
268
- root_url : String ,
281
+ bd : Arc < BustDir > ,
282
+ root_url : Arc < str > ,
269
283
}
270
284
271
285
async fn api_info ( State ( state) : State < AppState > ) -> ApiTemplate {
272
286
ApiTemplate {
273
- root_url : state. root_url . to_string ( ) ,
287
+ root_url : state. root_url ,
288
+ bd : state. bust_dir ,
274
289
}
275
290
}
276
291
@@ -290,7 +305,8 @@ async fn no_address() -> Failure {
290
305
async fn handle_404 ( State ( state) : State < AppState > ) -> ErrorTemplate {
291
306
ErrorTemplate {
292
307
error : "404 not found" . to_owned ( ) ,
293
- root_url : state. root_url . to_string ( ) ,
308
+ bd : state. bust_dir ,
309
+ root_url : state. root_url ,
294
310
}
295
311
}
296
312
@@ -335,13 +351,15 @@ pub struct ErrorSerialization {
335
351
#[ template( path = "error.html" ) ]
336
352
pub struct ErrorTemplate {
337
353
error : String ,
338
- root_url : String ,
354
+ bd : Arc < BustDir > ,
355
+ root_url : Arc < str > ,
339
356
}
340
357
341
358
impl ErrorTemplate {
342
359
fn from_failure ( failure : & Failure , state : & AppState ) -> Self {
343
360
Self {
344
- root_url : state. root_url . to_string ( ) ,
361
+ root_url : state. root_url . clone ( ) ,
362
+ bd : state. bust_dir . clone ( ) ,
345
363
error : failure. to_string ( ) ,
346
364
}
347
365
}
0 commit comments