this repo has no description
1use axum::{ 2 extract::{Path, Query}, 3 http::{HeaderMap, Method, StatusCode}, 4 response::{IntoResponse, Response}, 5 body::Bytes, 6}; 7use reqwest::Client; 8use tracing::{info, error}; 9use std::collections::HashMap; 10 11pub async fn proxy_handler( 12 Path(method): Path<String>, 13 method_verb: Method, 14 headers: HeaderMap, 15 Query(params): Query<HashMap<String, String>>, 16 body: Bytes, 17) -> Response { 18 19 let proxy_header = headers.get("atproto-proxy") 20 .and_then(|h| h.to_str().ok()) 21 .map(|s| s.to_string()); 22 23 let appview_url = match proxy_header { 24 Some(url) => url, 25 None => match std::env::var("APPVIEW_URL") { 26 Ok(url) => url, 27 Err(_) => return (StatusCode::BAD_GATEWAY, "No upstream AppView configured").into_response(), 28 }, 29 }; 30 31 let target_url = format!("{}/xrpc/{}", appview_url, method); 32 33 info!("Proxying {} request to {}", method_verb, target_url); 34 35 let client = Client::new(); 36 37 let mut request_builder = client 38 .request(method_verb, &target_url) 39 .query(&params); 40 41 for (key, value) in headers.iter() { 42 if key != "host" && key != "content-length" { 43 request_builder = request_builder.header(key, value); 44 } 45 } 46 47 request_builder = request_builder.body(body); 48 49 match request_builder.send().await { 50 Ok(resp) => { 51 let status = resp.status(); 52 let headers = resp.headers().clone(); 53 let body = match resp.bytes().await { 54 Ok(b) => b, 55 Err(e) => { 56 error!("Error reading proxy response body: {:?}", e); 57 return (StatusCode::BAD_GATEWAY, "Error reading upstream response").into_response(); 58 } 59 }; 60 61 let mut response_builder = Response::builder().status(status); 62 63 for (key, value) in headers.iter() { 64 response_builder = response_builder.header(key, value); 65 } 66 67 match response_builder.body(axum::body::Body::from(body)) { 68 Ok(r) => r, 69 Err(e) => { 70 error!("Error building proxy response: {:?}", e); 71 (StatusCode::INTERNAL_SERVER_ERROR, "Internal Server Error").into_response() 72 } 73 } 74 }, 75 Err(e) => { 76 error!("Error sending proxy request: {:?}", e); 77 if e.is_timeout() { 78 (StatusCode::GATEWAY_TIMEOUT, "Upstream Timeout").into_response() 79 } else { 80 (StatusCode::BAD_GATEWAY, "Upstream Error").into_response() 81 } 82 } 83 } 84}