shift_proxy/routes/
mod.rs1pub mod anthropic;
4pub mod google;
5pub mod health;
6pub mod openai;
7pub mod passthrough;
8
9use crate::ProxyState;
10use axum::body::Bytes;
11use axum::extract::DefaultBodyLimit;
12use axum::extract::State;
13use axum::http::{HeaderMap, Uri};
14use axum::response::Response;
15use axum::routing::{any, get, post};
16use axum::Router;
17
18const MAX_BODY_SIZE: usize = 200 * 1024 * 1024;
23
24async fn messages_fallback_handler(
31 state: State<ProxyState>,
32 uri: Uri,
33 headers: HeaderMap,
34 body: Bytes,
35) -> Response {
36 let query = uri.query().map(|q| format!("?{}", q)).unwrap_or_default();
37 let rewritten: Uri = format!("/v1/messages{}", query)
38 .parse()
39 .expect("/v1/messages is a valid URI");
40
41 anthropic::anthropic_handler(state, rewritten, headers, body).await
42}
43
44async fn responses_fallback_handler(
50 state: State<ProxyState>,
51 uri: Uri,
52 headers: HeaderMap,
53 body: Bytes,
54) -> Response {
55 let query = uri.query().map(|q| format!("?{}", q)).unwrap_or_default();
56 let rewritten: Uri = format!("/v1/responses{}", query)
57 .parse()
58 .expect("/v1/responses is a valid URI");
59
60 openai::openai_handler(state, rewritten, headers, body).await
61}
62
63pub fn build_router(state: ProxyState) -> Router {
65 Router::new()
66 .route("/health", get(health::health_handler))
68 .route("/stats", get(health::stats_handler))
69 .route("/v1/messages", post(anthropic::anthropic_handler))
71 .route("/v1/chat/completions", post(openai::openai_handler))
72 .route("/v1/responses", post(openai::openai_handler))
73 .route("/messages", post(messages_fallback_handler))
75 .route("/responses", post(responses_fallback_handler))
76 .route("/v1beta/models/{*path}", post(google::google_handler))
78 .route("/v1/models/{*path}", post(google::google_handler))
79 .fallback(any(passthrough::passthrough_handler))
82 .layer(DefaultBodyLimit::max(MAX_BODY_SIZE))
84 .with_state(state)
85}