Proxy a raw HTTP request to the first compatible route from `candidates`. Filters candidates by `source_protocol` compatibility (exact match against one of the route's `protocols`), then forwards to the first match.
(
&self,
source_protocol: &str,
method: &str,
path: &str,
headers: Vec<(String, String)>,
body: bytes::Bytes,
candidates: &[ResolvedRoute],
| 59 | /// Filters candidates by `source_protocol` compatibility (exact match against |
| 60 | /// one of the route's `protocols`), then forwards to the first match. |
| 61 | pub async fn proxy_with_candidates( |
| 62 | &self, |
| 63 | source_protocol: &str, |
| 64 | method: &str, |
| 65 | path: &str, |
| 66 | headers: Vec<(String, String)>, |
| 67 | body: bytes::Bytes, |
| 68 | candidates: &[ResolvedRoute], |
| 69 | ) -> Result<ProxyResponse, RouterError> { |
| 70 | let normalized_source = source_protocol.trim().to_ascii_lowercase(); |
| 71 | let route = candidates |
| 72 | .iter() |
| 73 | .find(|r| r.protocols.iter().any(|p| p == &normalized_source)) |
| 74 | .ok_or_else(|| RouterError::NoCompatibleRoute(source_protocol.to_string()))?; |
| 75 | |
| 76 | info!( |
| 77 | protocols = %route.protocols.join(","), |
| 78 | endpoint = %route.endpoint, |
| 79 | method = %method, |
| 80 | path = %path, |
| 81 | "routing proxy inference request" |
| 82 | ); |
| 83 | |
| 84 | if mock::is_mock_route(route) { |
| 85 | info!(endpoint = %route.endpoint, "returning mock response"); |
| 86 | return Ok(mock::mock_response(route, &normalized_source)); |
| 87 | } |
| 88 | |
| 89 | backend::proxy_to_backend( |
| 90 | &self.client, |
| 91 | route, |
| 92 | &normalized_source, |
| 93 | method, |
| 94 | path, |
| 95 | headers, |
| 96 | body, |
| 97 | ) |
| 98 | .await |
| 99 | } |
| 100 | |
| 101 | /// Streaming variant of [`proxy_with_candidates`](Self::proxy_with_candidates). |
| 102 | /// |