use axum::http::{HeaderMap, StatusCode, header};
use bytes::Bytes;
use crate::error::ProxyError;
const FORWARDED_REQUEST_HEADERS: &[&str] = &[
"x-api-key",
"authorization",
"anthropic-version",
"anthropic-beta",
"content-type",
];
fn build_request(
client: &reqwest::Client,
base: &str,
headers: &HeaderMap,
body: Bytes,
) -> reqwest::RequestBuilder {
let url = format!("{}/v1/messages", base.trim_end_matches('/'));
let mut req = client.post(url);
for name in FORWARDED_REQUEST_HEADERS {
if let Some(value) = headers.get(*name) {
req = req.header(*name, value.clone());
}
}
req.body(body)
}
fn passthrough_headers(response: &reqwest::Response) -> HeaderMap {
let mut out = HeaderMap::new();
if let Some(content_type) = response.headers().get(header::CONTENT_TYPE) {
out.insert(header::CONTENT_TYPE, content_type.clone());
}
out
}
pub async fn forward_anthropic(
client: &reqwest::Client,
base: &str,
headers: &HeaderMap,
body: Bytes,
) -> Result<(StatusCode, HeaderMap, Bytes), ProxyError> {
let response = build_request(client, base, headers, body).send().await?;
let status = response.status();
let out_headers = passthrough_headers(&response);
let body = response.bytes().await?;
Ok((status, out_headers, body))
}
pub async fn forward_anthropic_streaming(
client: &reqwest::Client,
base: &str,
headers: &HeaderMap,
body: Bytes,
) -> Result<(StatusCode, HeaderMap, reqwest::Response), ProxyError> {
let response = build_request(client, base, headers, body).send().await?;
let status = response.status();
let out_headers = passthrough_headers(&response);
Ok((status, out_headers, response))
}