···
use crate::{CachedRecord, Repo, error::ServerError};
3
+
use serde::Serialize;
use tokio_util::sync::CancellationToken;
6
-
use poem::{Route, Server, listener::TcpListener};
7
+
use poem::{Endpoint, Route, Server, endpoint::make_sync, listener::TcpListener};
ApiResponse, Object, OpenApi, OpenApiService, param::Query, payload::Json, types::Example,
···
// those are a little bit important
195
+
#[derive(Debug, Clone, Serialize)]
196
+
#[serde(rename_all = "camelCase")]
197
+
struct AppViewService {
200
+
service_endpoint: String,
202
+
#[derive(Debug, Clone, Serialize)]
203
+
struct AppViewDoc {
205
+
service: [AppViewService; 1],
207
+
/// Serve a did document for did:web for this to be an xrpc appview
209
+
/// No slingshot endpoints currently require auth, so it's not necessary to do
210
+
/// service proxying, however clients may wish to:
212
+
/// - PDS proxying offers a level of client IP anonymity from slingshot
213
+
/// - slingshot *may* implement more generous per-user rate-limits for proxied requests in the future
214
+
fn get_did_doc(host: String) -> impl Endpoint {
215
+
let doc = poem::web::Json(AppViewDoc {
216
+
id: format!("did:web:{host}"),
217
+
service: [AppViewService {
218
+
id: "#slingshot".to_string(),
219
+
r#type: "SlingshotRecordProxy".to_string(),
220
+
service_endpoint: format!("https://{host}"),
223
+
make_sync(move |_| doc.clone())
cache: HybridCache<String, CachedRecord>,
229
+
host: Option<String>,
_shutdown: CancellationToken,
) -> Result<(), ServerError> {
let repo = Arc::new(repo);
···
.server("http://localhost:3000")
205
-
let app = Route::new()
238
+
let mut app = Route::new()
.nest("/", api_service.scalar())
.nest("/openapi.json", api_service.spec_endpoint())
.nest("/xrpc/", api_service);
243
+
if let Some(host) = host {
244
+
app = app.at("/.well-known/did.json", get_did_doc(host));
Server::new(TcpListener::bind("127.0.0.1:3000"))