Skip to main content

shift_proxy/routes/
mod.rs

1//! Route handlers for the SHIFT proxy.
2
3pub mod anthropic;
4pub mod google;
5pub mod health;
6pub mod openai;
7pub mod passthrough;
8
9use crate::ProxyState;
10use axum::extract::DefaultBodyLimit;
11use axum::routing::{any, get, post};
12use axum::Router;
13
14/// Maximum request body size: 200 MB.
15/// AI payloads with base64 images can be large (50MB+). This limit prevents
16/// unbounded memory consumption from malicious clients while accommodating
17/// legitimate multi-image payloads.
18const MAX_BODY_SIZE: usize = 200 * 1024 * 1024;
19
20/// Build the complete proxy router with all routes.
21pub fn build_router(state: ProxyState) -> Router {
22    Router::new()
23        // Health and stats
24        .route("/health", get(health::health_handler))
25        .route("/stats", get(health::stats_handler))
26        // Provider-specific routes (with optimization)
27        .route("/v1/messages", post(anthropic::anthropic_handler))
28        .route("/v1/chat/completions", post(openai::openai_handler))
29        // Google routes (passthrough only)
30        .route("/v1beta/models/{*path}", post(google::google_handler))
31        .route("/v1/models/{*path}", post(google::google_handler))
32        // Catch-all passthrough for all HTTP methods (not just POST).
33        // Some provider APIs use GET (list models), PUT, DELETE, etc.
34        .fallback(any(passthrough::passthrough_handler))
35        // Explicit body size limit — prevents OOM from malicious payloads.
36        .layer(DefaultBodyLimit::max(MAX_BODY_SIZE))
37        .with_state(state)
38}