Skip to main content

canonical_did

Function canonical_did 

Source
pub fn canonical_did(value: &str) -> String
Expand description

A DID from a URL, spelled the way this project stores it.

Both a path segment and a query value are percent-decoded once before a handler sees them, and a local agent’s DID already contains a percent-encoding of its own: a DID on a bare loopback host is written did:web:localhost%3A3400, so naming one in a URL means encoding the % as well. A client that builds URLs properly does that and this changes nothing; a person with curl and a DID copied out of a log writes the bare colon, and without this gets an empty answer for an agent that is plainly there.

The repair is unambiguous rather than a guess: in did:web a colon separates path segments, a port must be written %3A, and a bare host:3400 in the identifier position is not a DID this server could have minted. Anything that is not a did:web with a numeric last segment comes back untouched, so a did:plc, a handle and a properly encoded DID all pass straight through.

Applied to every DID-valued input rather than only where a bug was noticed: a filter that silently matched nothing is worse than a 404, because a caller reads it as “no such children” rather than as “ask differently”.

It lives here rather than beside either caller because both the query service and the personal data server’s com.atproto.repo.* routes need exactly this repair, and two copies of it would agree until one was edited.

use didbot_identity::canonical_did;
assert_eq!(
    canonical_did("did:web:localhost:3400"),
    "did:web:localhost%3A3400"
);
// Already encoded, a plain hostname, and a `did:plc` all pass through.
assert_eq!(
    canonical_did("did:web:localhost%3A3400"),
    "did:web:localhost%3A3400"
);
assert_eq!(canonical_did("did:web:agents.example"), "did:web:agents.example");
assert_eq!(canonical_did("did:plc:abc123"), "did:plc:abc123");