@@ -42,18 +42,20 @@ impl IntoResponse for ProxyError {
4242 }
4343}
4444
45- /// Forward an incoming request to the given `upstream_base` URL.
45+ /// Forward an incoming request to the given upstream URL, stripping the
46+ /// gateway prefix from the path.
4647///
47- /// Strips the gateway prefix so that `/api/meta/videos/v_1` becomes
48- /// `{upstream_base}/videos/v_1` on the upstream service.
49- pub async fn proxy_to_meta (
50- State ( state) : State < AppState > ,
48+ /// `prefix` is the gateway path prefix (e.g. `/api/meta`) to strip before
49+ /// forwarding to `upstream_base`.
50+ async fn forward (
51+ state : & AppState ,
52+ prefix : & str ,
53+ upstream_base : & str ,
5154 req : Request < Body > ,
5255) -> Result < Response , ProxyError > {
5356 let path = req. uri ( ) . path ( ) ;
5457
55- // Strip the `/api/meta` prefix
56- let upstream_path = path. strip_prefix ( "/api/meta" ) . unwrap_or ( path) ;
58+ let upstream_path = path. strip_prefix ( prefix) . unwrap_or ( path) ;
5759 let upstream_path = if upstream_path. is_empty ( ) {
5860 "/"
5961 } else {
@@ -66,7 +68,7 @@ pub async fn proxy_to_meta(
6668 . map ( |q| format ! ( "?{q}" ) )
6769 . unwrap_or_default ( ) ;
6870
69- let upstream_url = format ! ( "{}{upstream_path}{query}" , state . meta_upstream ) ;
71+ let upstream_url = format ! ( "{upstream_base }{upstream_path}{query}" ) ;
7072
7173 let max_body = state. max_body_size ;
7274 let method = req. method ( ) . clone ( ) ;
@@ -116,6 +118,27 @@ pub async fn proxy_to_meta(
116118 . expect ( "failed to build response" ) )
117119}
118120
121+ /// Proxy handler for the meta service (`/api/meta/*`).
122+ ///
123+ /// Strips the `/api/meta` prefix and forwards to the configured meta upstream.
124+ pub async fn proxy_to_meta (
125+ State ( state) : State < AppState > ,
126+ req : Request < Body > ,
127+ ) -> Result < Response , ProxyError > {
128+ forward ( & state, "/api/meta" , & state. meta_upstream . clone ( ) , req) . await
129+ }
130+
131+ /// Proxy handler for the ingestor service (`/api/ingest/*`).
132+ ///
133+ /// Strips the `/api/ingest` prefix and forwards to the configured ingestor
134+ /// upstream.
135+ pub async fn proxy_to_ingestor (
136+ State ( state) : State < AppState > ,
137+ req : Request < Body > ,
138+ ) -> Result < Response , ProxyError > {
139+ forward ( & state, "/api/ingest" , & state. ingestor_upstream . clone ( ) , req) . await
140+ }
141+
119142#[ cfg( test) ]
120143mod tests {
121144 use std:: sync:: Arc ;
@@ -150,6 +173,7 @@ mod tests {
150173 async fn rejects_oversized_request_body ( ) {
151174 let state = AppState :: builder ( )
152175 . meta_upstream ( "http://127.0.0.1:9999" . to_string ( ) )
176+ . ingestor_upstream ( "http://127.0.0.1:9998" . to_string ( ) )
153177 . http_client ( reqwest:: Client :: new ( ) )
154178 . rate_limiter ( Arc :: new ( RateLimiter :: new ( 100 , 60 ) ) )
155179 . max_body_size ( 16 ) // 16-byte limit
0 commit comments