@@ -316,6 +316,7 @@ fn ensure_compiled_snapshot(state: &Arc<RwLock<AppState>>) -> Arc<CompiledRouter
316316 let mut st = state. write ( ) ;
317317 if st. compiled . is_none ( ) {
318318 st. compiled = Some ( Arc :: new ( st. snapshot_routers ( ) ) ) ;
319+ st. rebuild_snapshot ( ) ;
319320 }
320321 Arc :: clone ( st. compiled . as_ref ( ) . expect ( "just populated" ) )
321322}
@@ -472,20 +473,6 @@ pub async fn run_rsgi(
472473 let Some ( ( method, path, query_string, is_head, snapshot) ) = prelim else {
473474 return Ok ( Python :: with_gil ( |py| py. None ( ) ) ) ;
474475 } ;
475- type CfgClones = (
476- Option < Py < PyAny > > ,
477- Option < Py < PyAny > > ,
478- Arc < Vec < Py < PyAny > > > ,
479- Arc < Vec < Py < PyAny > > > ,
480- ) ;
481- let ( cors_cfg, security_cfg, req_mw, res_mw) : CfgClones = Python :: with_gil ( |_py| {
482- (
483- snapshot. cors . clone ( ) ,
484- snapshot. security_headers . clone ( ) ,
485- snapshot. request_middleware . clone ( ) ,
486- snapshot. response_middleware . clone ( ) ,
487- )
488- } ) ;
489476 if ( method == "GET" || method == "HEAD" ) && path == "/openapi.json" && snapshot. include_openapi
490477 {
491478 let _ = Python :: with_gil ( |py| {
@@ -539,7 +526,7 @@ pub async fn run_rsgi(
539526 }
540527 }
541528 }
542- for mw in req_mw . iter ( ) {
529+ for mw in snapshot . request_middleware . iter ( ) {
543530 let out: Py < PyAny > = match Python :: with_gil ( |py| {
544531 let f = mw. bind ( py) ;
545532 f. call1 ( ( scope. bind ( py) , protocol. bind ( py) ) )
@@ -556,10 +543,12 @@ pub async fn run_rsgi(
556543 return match Python :: with_gil ( |py| -> PyResult < ( ) > {
557544 let mut mapped = map_handler_return ( py, & out) ?;
558545
559- if !res_mw. is_empty ( ) && !matches ! ( mapped, HandlerMap :: AlreadySent ) {
546+ if !snapshot. response_middleware . is_empty ( )
547+ && !matches ! ( mapped, HandlerMap :: AlreadySent )
548+ {
560549 let response_module = py. import ( "oxyroute.response" ) ?;
561550 let response_class = response_module. getattr ( "Response" ) ?;
562- for res_m in res_mw . iter ( ) {
551+ for res_m in snapshot . response_middleware . iter ( ) {
563552 let kwargs = pyo3:: types:: PyDict :: new ( py) ;
564553 match & mapped {
565554 HandlerMap :: Simple {
@@ -605,16 +594,16 @@ pub async fn run_rsgi(
605594 }
606595 }
607596
608- let mapped = if security_cfg . is_some ( ) || cors_cfg . is_some ( ) {
597+ let mapped = if snapshot . security_headers . is_some ( ) || snapshot . cors . is_some ( ) {
609598 let scope_bound = scope. bind ( py) . clone ( ) ;
610599 let mapped = merge_config_response_headers (
611600 py,
612- & security_cfg ,
601+ & snapshot . security_headers ,
613602 scope_bound. clone ( ) ,
614603 mapped,
615604 true ,
616605 ) ?;
617- merge_config_response_headers ( py, & cors_cfg , scope_bound, mapped, false ) ?
606+ merge_config_response_headers ( py, & snapshot . cors , scope_bound, mapped, false ) ?
618607 } else {
619608 mapped
620609 } ;
@@ -1240,10 +1229,10 @@ pub async fn run_rsgi(
12401229 match Python :: with_gil ( |py| -> PyResult < ( ) > {
12411230 let mut mapped = map_handler_return ( py, & handler_out) ?;
12421231
1243- if !res_mw . is_empty ( ) && !matches ! ( mapped, HandlerMap :: AlreadySent ) {
1232+ if !snapshot . response_middleware . is_empty ( ) && !matches ! ( mapped, HandlerMap :: AlreadySent ) {
12441233 let response_module = py. import ( "oxyroute.response" ) ?;
12451234 let response_class = response_module. getattr ( "Response" ) ?;
1246- for res_m in res_mw . iter ( ) {
1235+ for res_m in snapshot . response_middleware . iter ( ) {
12471236 let kwargs = pyo3:: types:: PyDict :: new ( py) ;
12481237 match & mapped {
12491238 HandlerMap :: Simple {
@@ -1287,16 +1276,16 @@ pub async fn run_rsgi(
12871276 }
12881277 }
12891278
1290- let mapped = if security_cfg . is_some ( ) || cors_cfg . is_some ( ) {
1279+ let mapped = if snapshot . security_headers . is_some ( ) || snapshot . cors . is_some ( ) {
12911280 let scope_bound = scope. bind ( py) . clone ( ) ;
12921281 let mapped = merge_config_response_headers (
12931282 py,
1294- & security_cfg ,
1283+ & snapshot . security_headers ,
12951284 scope_bound. clone ( ) ,
12961285 mapped,
12971286 true ,
12981287 ) ?;
1299- merge_config_response_headers ( py, & cors_cfg , scope_bound, mapped, false ) ?
1288+ merge_config_response_headers ( py, & snapshot . cors , scope_bound, mapped, false ) ?
13001289 } else {
13011290 mapped
13021291 } ;
@@ -1769,7 +1758,6 @@ async fn run_rsgi_websocket(
17691758 Some ( c) => c,
17701759 None => ensure_compiled_snapshot ( & state) ,
17711760 } ;
1772- let ws_routes = Arc :: clone ( & snapshot. websocket_routes ) ;
17731761 let route_match = match_ws_route_compiled ( & compiled, & path) ;
17741762 let Some ( ( route_idx, params) ) = route_match else {
17751763 // No route → polite close. ``close`` is sync on RSGIWebsocketProtocol.
@@ -1781,7 +1769,8 @@ async fn run_rsgi_websocket(
17811769 return Ok ( Python :: with_gil ( |py| py. None ( ) ) ) ;
17821770 } ;
17831771 let ( handler, is_async) = Python :: with_gil ( |_py| -> PyResult < ( Py < PyAny > , bool ) > {
1784- let e = ws_routes
1772+ let e = snapshot
1773+ . websocket_routes
17851774 . get ( route_idx)
17861775 . ok_or_else ( || pyo3:: exceptions:: PyRuntimeError :: new_err ( "ws route index" ) ) ?;
17871776 Ok ( ( e. handler . clone ( ) , e. is_async ) )
0 commit comments