···1111let handler =
1212 Xrpc.handler (fun ctx ->
1313 let input = Xrpc.parse_query ctx.req query_of_yojson in
1414- let%lwt input_did = Xrpc.resolve_repo_did ctx input.repo in
1515- let%lwt repo = Repository.load ~ensure_active:true input_did in
1616- let path = input.collection ^ "/" ^ input.rkey in
1717- let uri = "at://" ^ input_did ^ "/" ^ path in
1818- match%lwt Repository.get_record repo path with
1919- | Some {cid; value; _}
2020- when input.cid = None || input.cid = Some (Cid.to_string cid) ->
2121- Dream.json @@ Yojson.Safe.to_string
2222- @@ response_to_yojson {uri; cid= Cid.to_string cid; value}
2323- | _ ->
1414+ try%lwt
1515+ let%lwt input_did = Xrpc.resolve_repo_did ctx input.repo in
1616+ let uri =
1717+ Util.make_at_uri ~repo:input_did ~collection:input.collection
1818+ ~rkey:input.rkey ~fragment:None
1919+ in
2020+ let%lwt repo = Repository.load ~ensure_active:true input_did in
2121+ let path = input.collection ^ "/" ^ input.rkey in
2222+ match%lwt Repository.get_record repo path with
2323+ | Some {cid; value; _}
2424+ when input.cid = None || input.cid = Some (Cid.to_string cid) ->
2525+ Dream.json @@ Yojson.Safe.to_string
2626+ @@ response_to_yojson {uri; cid= Cid.to_string cid; value}
2727+ | _ ->
2828+ Errors.internal_error ~name:"RecordNotFound"
2929+ ~msg:("could not find record " ^ uri)
3030+ ()
3131+ with _ -> (
3232+ let%lwt input_did =
3333+ if String.starts_with ~prefix:"did:" input.repo then
3434+ Lwt.return input.repo
3535+ else
3636+ match%lwt Id_resolver.Handle.resolve input.repo with
3737+ | Ok did ->
3838+ Lwt.return did
3939+ | Error _ ->
4040+ Errors.invalid_request "failed to resolve repo"
4141+ in
4242+ let%lwt pds =
4343+ match%lwt Id_resolver.Did.resolve input_did with
4444+ | Ok doc -> (
4545+ Lwt.return
4646+ @@
4747+ match Id_resolver.Did.Document.get_service doc "#atproto_pds" with
4848+ | Some service ->
4949+ service
5050+ | None ->
5151+ Errors.invalid_request "failed to resolve repo pds" )
5252+ | Error _ ->
5353+ Errors.invalid_request "failed to resolve repo did document"
5454+ in
5555+ if pds = Env.host_endpoint then
2456 Errors.internal_error ~name:"RecordNotFound"
2525- ~msg:("could not find record " ^ uri)
2626- () )
5757+ ~msg:("could not resolve user " ^ input.repo)
5858+ () ;
5959+ let get_uri = Uri.of_string pds in
6060+ let get_uri =
6161+ Uri.with_path get_uri "/xrpc/com.atproto.repo.getRecord"
6262+ in
6363+ let get_uri = Uri.with_query get_uri (Util.copy_query ctx.req) in
6464+ let%lwt res, body =
6565+ Util.http_get get_uri
6666+ ~headers:(Cohttp.Header.of_list [("Accept", "application/json")])
6767+ in
6868+ match res.status with
6969+ | `OK ->
7070+ let%lwt json = Cohttp_lwt.Body.to_string body in
7171+ let%lwt () = Cohttp_lwt.Body.drain_body body in
7272+ Dream.json json
7373+ | _ ->
7474+ let%lwt () = Cohttp_lwt.Body.drain_body body in
7575+ Errors.internal_error ~name:"RecordNotFound"
7676+ ~msg:
7777+ ( "could not find record "
7878+ ^ Util.make_at_uri ~repo:input.repo ~collection:input.collection
7979+ ~rkey:input.rkey ~fragment:None )
8080+ () ) )
+9-1
pegasus/lib/util.ml
···395395 |> String.trim
396396397397let rec http_get ?(max_redirects = 5) ?headers uri =
398398- let%lwt ans = Cohttp_lwt_unix.Client.get ?headers uri in
398398+ let ua = "pegasus (" ^ Env.host_endpoint ^ ")" in
399399+ let headers =
400400+ match headers with
401401+ | Some headers ->
402402+ Http.Header.add_unless_exists headers "User-Agent" ua
403403+ | None ->
404404+ Http.Header.of_list [("User-Agent", ua)]
405405+ in
406406+ let%lwt ans = Cohttp_lwt_unix.Client.get ~headers uri in
399407 follow_redirect ~max_redirects uri ans
400408401409and follow_redirect ~max_redirects request_uri (response, body) =
+5-7
pegasus/lib/xrpc.ml
···328328 Lwt.return res
329329330330let resolve_repo_did ctx repo =
331331- if String.starts_with ~prefix:"did:" repo then Lwt.return repo
332332- else
333333- match%lwt Data_store.get_actor_by_identifier repo ctx.db with
334334- | Some {did; _} ->
335335- Lwt.return did
336336- | None ->
337337- Errors.invalid_request "target repository not found"
331331+ match%lwt Data_store.get_actor_by_identifier repo ctx.db with
332332+ | Some {did; _} ->
333333+ Lwt.return did
334334+ | None ->
335335+ Errors.invalid_request "target repository not found"
338336339337let resolve_repo_did_authed ctx repo =
340338 let%lwt input_did = resolve_repo_did ctx repo in