ceres: a small planet in a giant solar system
33
fork

Configure Feed

Select the types of activity you want to include in your feed.

wip on proxy

+46 -13
+1 -2
src/handlers/xrpc/app_bsky_actor.rs
··· 99 99 Ok(Json(profile).into_response()) 100 100 } 101 101 102 - pub fn routes(state: AppState) -> Router { 102 + pub fn routes() -> Router<AppState> { 103 103 Router::<AppState>::new() 104 104 .merge(GetProfileRequest::into_router::<_, AppState, _>( 105 105 get_profile, 106 106 )) 107 - .with_state(state) 108 107 }
+44 -11
src/main.rs
··· 1 1 use axum::{ 2 2 Json, Router, body, 3 - extract::Request, 3 + extract::{Request, State}, 4 4 http::{Method, StatusCode}, 5 + response::{IntoResponse, Response}, 5 6 routing::get, 6 7 }; 8 + use axum::body::Bytes; 7 9 use env_logger::Env; 8 10 use handlers::{well_known::did_document, xrpc::app_bsky_actor}; 9 11 use jacquard::{identity::resolver::ResolverOptions, prelude::JacquardResolver, types::did::Did}; ··· 42 44 service_auth, 43 45 reqwest_client, 44 46 resolver, 47 + forwarded_app_view: env::var("FORWARDED_APP_VIEW").ok(), 45 48 }; 46 49 47 50 let app = Router::new() 48 51 .route("/.well-known/did.json", get(did_document)) 49 - .merge(app_bsky_actor::routes(state.clone())) 52 + .merge(app_bsky_actor::routes()) 50 53 .fallback(log_request) 51 - .layer(CorsLayer::permissive()); 54 + .layer(CorsLayer::permissive()) 55 + .with_state(state); 52 56 53 57 let listener = TcpListener::bind(&bind_addr) 54 58 .await ··· 59 63 Ok(()) 60 64 } 61 65 62 - async fn log_request(req: Request) -> (StatusCode, Json<Value>) { 66 + async fn log_request( 67 + State(state): State<AppState>, 68 + req: Request, 69 + ) -> Response { 63 70 let (parts, body) = req.into_parts(); 64 71 let method = parts.method.clone(); 65 72 let path = parts.uri.path().to_string(); 73 + let query = parts.uri.query().map(|q| format!("?{}", q)).unwrap_or_default(); 66 74 67 - info!("{method} {path}"); 75 + info!("{method} {path}{query}"); 68 76 69 77 if method == Method::GET { 70 78 match parts.uri.query() { 71 79 Some(q) => info!(" query: {q}"), 72 80 None => info!(" query: <none>"), 73 81 } 74 - return (StatusCode::OK, Json(json!({}))); 75 82 } 76 83 77 84 let bytes = match body::to_bytes(body, usize::MAX).await { 78 85 Ok(b) => b, 79 86 Err(e) => { 80 87 info!(" body: <failed to read: {e}>"); 81 - return (StatusCode::OK, Json(json!({}))); 88 + if state.forwarded_app_view.is_none() { 89 + return (StatusCode::OK, Json(json!({}))).into_response(); 90 + } 91 + // If we are proxying, we might want to try anyway or fail. 92 + // Let's just use empty bytes if it failed to read. 93 + Bytes::new() 82 94 } 83 95 }; 84 96 85 - if bytes.is_empty() { 86 - info!(" body: <empty>"); 87 - } else { 97 + if !bytes.is_empty() { 88 98 match serde_json::from_slice::<Value>(&bytes) { 89 99 Ok(value) => { 90 100 let pretty = ··· 95 105 info!(" body: <non-json, {} bytes>", bytes.len()); 96 106 } 97 107 } 108 + } else if method != Method::GET { 109 + info!(" body: <empty>"); 98 110 } 99 111 100 - (StatusCode::OK, Json(json!({}))) 112 + if let Some(ref base_url) = state.forwarded_app_view { 113 + let target_url = format!("{base_url}{path}{query}"); 114 + let proxy_res = state.reqwest_client 115 + .request(method, &target_url) 116 + .body(bytes) 117 + .send() 118 + .await; 119 + 120 + match proxy_res { 121 + Ok(res) => { 122 + let status = res.status(); 123 + let body_bytes = res.bytes().await.unwrap_or_default(); 124 + return (status, body_bytes).into_response(); 125 + } 126 + Err(e) => { 127 + log::error!("Proxy request failed: {e}"); 128 + return (StatusCode::INTERNAL_SERVER_ERROR, "Proxy Error").into_response(); 129 + } 130 + } 131 + } 132 + 133 + (StatusCode::OK, Json(json!({}))).into_response() 101 134 }
+1
src/state.rs
··· 6 6 pub service_auth: ServiceAuthConfig<JacquardResolver>, 7 7 pub reqwest_client: reqwest::Client, 8 8 pub resolver: JacquardResolver, 9 + pub forwarded_app_view: Option<String>, 9 10 } 10 11 11 12 impl ServiceAuth for AppState {