@@ -34,6 +34,9 @@ mod gateway_prober;
3434#[ cfg( feature = "_test-util" ) ]
3535pub mod gateway_prober;
3636mod gateway_uri;
37+ pub mod sentinel;
38+ pub use sentinel:: { InvalidHeader , SentinelTag } ;
39+
3740use crate :: error:: { BoxError , Error } ;
3841
3942#[ cfg( any( feature = "connect-bootstrap" , feature = "ws-bootstrap" ) ) ]
@@ -52,7 +55,7 @@ pub async fn listen_tcp(
5255 let addr = SocketAddr :: from ( ( [ 0 , 0 , 0 , 0 ] , port) ) ;
5356 let listener = TcpListener :: bind ( addr) . await ?;
5457 println ! ( "OHTTP relay listening on tcp://{}" , addr) ;
55- ohttp_relay ( listener, RelayConfig :: new_with_default_client ( gateway_origin) ) . await
58+ ohttp_relay ( listener, RelayConfig :: new_with_default_client ( gateway_origin, None ) ) . await
5659}
5760
5861#[ instrument]
@@ -62,7 +65,7 @@ pub async fn listen_socket(
6265) -> Result < tokio:: task:: JoinHandle < Result < ( ) , BoxError > > , BoxError > {
6366 let listener = UnixListener :: bind ( socket_path) ?;
6467 info ! ( "OHTTP relay listening on socket: {}" , socket_path) ;
65- ohttp_relay ( listener, RelayConfig :: new_with_default_client ( gateway_origin) ) . await
68+ ohttp_relay ( listener, RelayConfig :: new_with_default_client ( gateway_origin, None ) ) . await
6669}
6770
6871#[ cfg( feature = "_test-util" ) ]
@@ -73,7 +76,7 @@ pub async fn listen_tcp_on_free_port(
7376 let listener = tokio:: net:: TcpListener :: bind ( "[::]:0" ) . await ?;
7477 let port = listener. local_addr ( ) ?. port ( ) ;
7578 println ! ( "OHTTP relay binding to port {}" , listener. local_addr( ) ?) ;
76- let config = RelayConfig :: new ( default_gateway, root_store) ;
79+ let config = RelayConfig :: new ( default_gateway, root_store, None ) ;
7780 let handle = ohttp_relay ( listener, config) . await ?;
7881 Ok ( ( port, handle) )
7982}
@@ -83,17 +86,25 @@ struct RelayConfig {
8386 default_gateway : GatewayUri ,
8487 client : HttpClient ,
8588 prober : Prober ,
89+ sentinel_tag : Option < SentinelTag > ,
8690}
8791
8892impl RelayConfig {
89- fn new_with_default_client ( default_gateway : GatewayUri ) -> Self {
90- Self :: new ( default_gateway, HttpClient :: default ( ) )
93+ fn new_with_default_client (
94+ default_gateway : GatewayUri ,
95+ sentinel_tag : Option < SentinelTag > ,
96+ ) -> Self {
97+ Self :: new ( default_gateway, HttpClient :: default ( ) , sentinel_tag)
9198 }
9299
93- fn new ( default_gateway : GatewayUri , into_client : impl Into < HttpClient > ) -> Self {
100+ fn new (
101+ default_gateway : GatewayUri ,
102+ into_client : impl Into < HttpClient > ,
103+ sentinel_tag : Option < SentinelTag > ,
104+ ) -> Self {
94105 let client = into_client. into ( ) ;
95106 let prober = Prober :: new_with_client ( client. clone ( ) ) ;
96- RelayConfig { default_gateway, client, prober }
107+ RelayConfig { default_gateway, client, prober, sentinel_tag }
97108 }
98109}
99110
@@ -105,21 +116,24 @@ pub struct Service {
105116impl Service {
106117 fn from_config ( config : Arc < RelayConfig > ) -> Self { Self { config } }
107118
108- pub async fn new ( ) -> Self {
119+ pub async fn new ( sentinel_tag : SentinelTag ) -> Self {
109120 // The default gateway is hardcoded because it is obsolete and required only for backwards
110121 // compatibility.
111122 // The new mechanism for specifying a custom gateway is via RFC 9540 using
112123 // `/.well-known/ohttp-gateway` request paths.
113124 let gateway_origin = GatewayUri :: from_str ( DEFAULT_GATEWAY ) . expect ( "valid gateway uri" ) ;
114- let config = RelayConfig :: new_with_default_client ( gateway_origin) ;
125+ let config = RelayConfig :: new_with_default_client ( gateway_origin, Some ( sentinel_tag ) ) ;
115126 config. prober . assert_opt_in ( & config. default_gateway ) . await ;
116127 Self { config : Arc :: new ( config) }
117128 }
118129
119130 #[ cfg( feature = "_test-util" ) ]
120- pub async fn new_with_roots ( root_store : rustls:: RootCertStore ) -> Self {
131+ pub async fn new_with_roots (
132+ root_store : rustls:: RootCertStore ,
133+ sentinel_tag : SentinelTag ,
134+ ) -> Self {
121135 let gateway_origin = GatewayUri :: from_str ( DEFAULT_GATEWAY ) . expect ( "valid gateway uri" ) ;
122- let config = RelayConfig :: new ( gateway_origin, root_store) ;
136+ let config = RelayConfig :: new ( gateway_origin, root_store, Some ( sentinel_tag ) ) ;
123137 config. prober . assert_opt_in ( & config. default_gateway ) . await ;
124138 Self { config : Arc :: new ( config) }
125139 }
@@ -319,7 +333,8 @@ where
319333 B : hyper:: body:: Body < Data = Bytes > + Send + Debug + ' static ,
320334 B :: Error : Into < BoxError > ,
321335{
322- let fwd_req = into_forward_req ( req, gateway) . await ?;
336+ let fwd_req = into_forward_req ( req, gateway, config. sentinel_tag . as_ref ( ) ) . await ?;
337+
323338 forward_request ( fwd_req, config) . await . map ( |res| {
324339 let ( parts, body) = res. into_parts ( ) ;
325340 let boxed_body = BoxBody :: new ( body) ;
@@ -332,6 +347,7 @@ where
332347async fn into_forward_req < B > (
333348 req : Request < B > ,
334349 gateway_origin : GatewayUri ,
350+ sentinel_tag : Option < & SentinelTag > ,
335351) -> Result < Request < BoxBody < Bytes , hyper:: Error > > , Error >
336352where
337353 B : hyper:: body:: Body < Data = Bytes > + Send + Debug + ' static ,
@@ -359,6 +375,10 @@ where
359375 let bytes =
360376 body. collect ( ) . await . map_err ( |e| Error :: BadRequest ( e. into ( ) . to_string ( ) ) ) ?. to_bytes ( ) ;
361377
378+ if let Some ( tag) = sentinel_tag {
379+ builder = builder. header ( sentinel:: HEADER_NAME , tag. to_header_value ( ) ) ;
380+ }
381+
362382 builder. body ( full ( bytes) ) . map_err ( |e| Error :: InternalServerError ( Box :: new ( e) ) )
363383}
364384
0 commit comments