Contents
- About
- Status
- XRD Schema Definitions for Redirect and Ref elements
- The Redirect Element
- The Ref Element
About
This page contains the text that will become the revised Section 12: Redirect and Ref Processing in XRI Resolution 2.0 Working Draft 11 Editor’s Draft 06 (EDO6).
Status
2007-10-04: This page now contains the final revisions agreed to on the 2007-10-04 TC telecon. This proposal will now be committed to ED06.
XRD Schema Definitions for Redirect and Ref elements
As Children of xrd:XRD
At the XRD level, the XRD schema will allow a CHOICE of either:
Zero or more Redirect elements.
Zero or more Ref elements.
Allowing an XRD to contain only one of the these two element types eliminates any question about precedence if more than one type were present.
As Children of xrd:XRD/xrd:Service
At the Service level, the XRD schema will allow a CHOICE of either:
Zero or more URI elements.
Zero or more Redirect elements.
Zero or more Ref elements.
Allowing a SEP to contain only one of the these three element types eliminates any question about precedence if more than one type were present. Note that the URI element behaves exactly as it does today, i.e., no changes. The presence of a URI element in a SEP always indicates to a resolver that no Redirect processing or Ref processing is needed.
The Redirect Element
The Redirect element replaces the functionality of the current "service ref" (defined in section 12.2 of ED05).
The primary use case for a Redirect is remote administration of an XRDS document. The Redirect element enables one XRDS administrator to delegate to another XRDS administrator without starting a new CanonicalID verification chain.
The rules for usage of a Redirect element are:
Value
A Redirect element MUST contain an HTTP or HTTPS URI, just like an authority resolution service endpoint URI.
Attributes
The Redirect element accepts the same attributes as the URI element, i.e., the priority and append attributes. It follows the same rules for URI construction as the URI attribute.
Resolution
The HTTP(S) URI in a Redirect element MUST be resolved as specified in section 6 (the Yadis section). This means it may result only one XRD contained in one XRDS.
Processing
Unlike Ref elements, there is no resolution parameter governing processing of a Redirect element. A Redirect at the XRD level is always processed; a Redirect at the Service level is processed automatically if that SEP is selected.
If a Redirect fails to resolve, the resolver MUST try the next highest priority Redirect until it is either successful or it has either tried all Redirect elements in the highest priority SEP. Note: if there are multiple Redirects at the same priority level, a resolver MUST try all of them in random order.
The resolver MUST NOT try any additional SEPs once the Redirect elements in the highest priority SEP have been exhausted.
Special Rule for Processing at the XRD Level
If one or more Redirect elements appear as a child of the XRD element, a resolver:
MUST process the redirect before the resolution query is satisifed, even if sep=false.
MUST process the redirect before service endpoint selection if sep=true.
Synonym Verification
A Redirect MUST NOT start a new CanonicalID verification chain. Instead, if a Redirect resolves successfully, a resolver MUST verify that:
The source XRD and the target XRD contain exactly the same value for the ProviderID element, if present.
The source XRD contains a superset of the synonyms asserted in the source XRD. Note that this means the source XRD MAY contain a synonym that does not appear in the target XRD (this prevents a race condition when a new synonym is added to the source XRD but has not yet been added to the target XRD).
- If a Redirect leads to another Redirect, these rules apply iteratively.
IMPORTANT: If Redirect synonym verification fails, the resolver MUST error out immediately and MUST NOT perform further Redirect processing, even if additional Redirect elements are present.
Status Codes
Redirects have their own class of status code for Redirect processing: x5x, Redirect processing error. These status codes are provided in the XRD inserted for the Redirect (see below). If multiple Redirect elements are present, the HTTP(S) URI from the final Redirect tried by the resolver MUST be the one recorded on the XRD used to record the Redirect failure. The proposed status codes are:
250 REDIRECT_FAILED: All Redirect elements in the selected SEP failed to resolve.
251 REDIRECT_SYNONYM_VERIFICATION_FAILED: Verification of synonyms failed (the synonyms in the source XRD were not a superset of the synonyms in the target XRD).
XRDS Document Nesting
If a Redirect resolves successfully and Redirect synonym verification succeeds, the resolver MUST nest an XRDS document inside the current XRDS document.
The XRDS element MUST have a redirect attribute and the value of this attribute MUST be the fully constructed HTTP(S) URI from the Redirect element processed to produce this XRDS document.
Redirect Example #1: During Authority Resolution
<XRDS xmlns="xri://$xrds" ref="xri://@a*b*c">
<XRD xmlns="xri://$xrd*($v*2.0)" version=”2.0”>
<Query>*a</Query>
<ProviderID>xri://@</ProviderID>
<CanonicalID>xri://@!1</CanonicalID> ;XRDS #1 CID #1
...
<Service>
<Type>xri://$res*auth*($v*2.0)</Type>
<URI>http://a.example.com/</URI>
</Service>
</XRD>
<XRD xmlns="xri://$xrd*($v*2.0)" version=”2.0”>
<Query>*b</Query>
<ProviderID>xri://@!1</ProviderID>
<CanonicalID>xri://@!1!2</CanonicalID> ;XRDS #1 CID #2
...
<Service>
<Type>xri://$res*auth*($v*2.0)</Type>
<Redirect>http://other.example.com</Redirect>
</Service>
</XRD>
<XRDS redirect="http://other.example.com">
<XRD xmlns="xri://$xrd*($v*2.0)" version=”2.0”>
<Query>*b</Query>
<ProviderID>xri://@!1</ProviderID>
<CanonicalID>xri://@!1!2</CanonicalID> ;SAME AS XRDS #1 CID #2
...
<Service>
<Type>xri://$res*auth*($v*2.0)</Type>
<URI>http://b.example.com/</URI>
</Service>
</XRD>
</XRDS>
<XRD xmlns="xri://$xrd*($v*2.0)" version=”2.0”>
<Query>*c</Query>
<ProviderID>xri://@!1!2</ProviderID>
<CanonicalID>xri://@!1!2!3</CanonicalID> ;XRDS #1 CID #3
...
<Service>
...final service endpoints described here...
</Service>
</XRD>
</XRDS>
Redirect Example #2: During Service Endpoint Selection
<XRDS xmlns="xri://$xrds" ref="xri://@a*b*c">
<XRD xmlns="xri://$xrd*($v*2.0)" version=”2.0”>
<Query>*a</Query>
<ProviderID>xri://@</ProviderID>
<CanonicalID>xri://@!1</CanonicalID> ;XRDS #1 CID #1
...
<Service>
<Type>xri://$res*auth*($v*2.0)</Type>
<URI>http://a.example.com/</URI>
</Service>
</XRD>
<XRD xmlns="xri://$xrd*($v*2.0)" version=”2.0”>
<Query>*b</Query>
<ProviderID>xri://@!1</ProviderID>
<CanonicalID>xri://@!1!2</CanonicalID> ;XRDS #1 CID #2
...
<Service>
<Type>xri://$res*auth*($v*2.0)</Type>
<URI>http://b.example.com/</URI>
</Service>
</XRD>
<XRD xmlns="xri://$xrd*($v*2.0)" version=”2.0”>
<Query>*c</Query>
<ProviderID>xri://@!1!2</ProviderID>
<CanonicalID>xri://@!1!2!3</CanonicalID> ;XRDS #1 CID #3
...
<Service>
<Type>http://openid.net/signon/1.0</Type>
<Redirect>http://r.example.com/openid</Redirect>
</Service>
</XRD>
<XRDS redirect="http://r.example.com/openid">
<XRD xmlns="xri://$xrd*($v*2.0)" version=”2.0”>
<ProviderID>xri://@!1!2</ProviderID>
<CanonicalID>xri://@!1!2!3</CanonicalID> ;SAME AS XRDS #1 CID #3
...
<Service>
<Type>http://openid.net/signon/1.0</Type>
<URI>http://openid.example.com/</URI>
</Service>
</XRD>
</XRDS>
</XRDS>
Redirect Example #3: At the XRD Level
<XRDS xmlns="xri://$xrds" ref="xri://@a">
<XRD xmlns="xri://$xrd*($v*2.0)" version=”2.0”>
<Query>*a</Query>
<ProviderID>xri://@</ProviderID>
<CanonicalID>xri://@!1</CanonicalID> ;XRDS #1 CID #1
<Redirect>http://a.example.com/</Redirect>
...
</XRD>
<XRDS redirect="http://a.example.com/">
<XRD xmlns="xri://$xrd*($v*2.0)" version=”2.0”>
<ProviderID>xri://@</ProviderID>
<CanonicalID>xri://@!1</CanonicalID> ;SAME AS XRDS #1 CID #1
...
<Service>
<Type>http://openid.net/signon/1.0</Type>
<URI>http://openid.example.com/</URI>
</Service>
</XRD>
</XRDS>
</XRDS>
Default Redirects
There are two ways to express a default Redirect in service endpoint selection (note that this is only necessary if the XRDS author does not want to trigger automatic Redirect processing by placing a Redirect element at the XRD level).
Optional Default Match
The following Redirect will be selected as a default unless nodefault_t, nodefault_p, and nodefault_m are all set to true.
<XRDS>
<XRD>
<Query>...</Query>
<Service>
<Redirect>=x*y</Redirect>
</Service>
</XRD>
</XRDS>
Forced Default Match
The following Redirect will always be selected, even if nodefault_t, nodefault_p, and nodefault_m are all set to true.
<XRDS>
<XRD>
<Query>...</Query>
<Service>
<Type match="all" select="true" />
<Redirect>=x*y</Redirect>
</Service>
</XRD>
</XRDS>
The Ref Element
The Ref element replaces the functionality of the current "authority ref" (defined in section 12.1 of ED05), as modified by the rules below.
Value
A Ref element MUST contain a valid XRI.
Attributes
The Ref element accepts only the priority attribute.
Resolution
A Ref MUST be resolved according to the same parameters as the original resolution query.
Processing
Processing of Ref elements is controlled by the boolean refs parameter.
Processing Rules when refs=false
No Ref element processing is performed (at either the XRD level or the Service level).
If a resolver is unable to fulfill the resolution request but the current XRD contains at least one Ref element that could be followed, the resolver MUST return the error code specified below.
Processing Rules when refs=true
If the highest priorityRef is resolved successfully but the result does not satisfy the original resolution query, the resolver MUST continue to follow other Ref elements in order of priority until it succeeds or all Ref elements fail. If more than one Ref element has the same priority, the resolver MUST try them all in random order.
- The previous rule applies iteratively down a Ref resolution chain, but a resolver MUST NOT back up beyond the SEP where Ref processing began.
The resolver MUST NOT try any additional SEPs once the Ref elements in the highest priority SEP have been exhausted.
Special Rule for Processing at the XRD Level
If refs=true and one or more Ref elements appear as a child of the XRD element, a resolver:
MUST process the Ref before the resolution query is satisifed, even if sep=false.
MUST process the Ref before service endpoint selection if sep=true.
Synonym Verification
A Ref element always starts a new CanonicalID verification chain for the nested XRDS document (see below). If CanonicalID verification is on, a resolver MUST restart CanonicalID verification with the new community root authority and apply it to all XRDs in the resulting XRDS document.
If a Ref is processed during XRI authority resolution, the CanonicalID for the XRD following the nested XRDS document MUST be a direct child of the CanonicalID of the XRD that was the source of the Ref. See Ref Example #1, below.
- There is no change in CanonicalEquivID verification; it still applies to the final XRD at the very end of the resolution chain.
- If CanonicalID verification fails for any XRD in the Ref chain, it MUST fail all subsequent XRDs in the entire resolution chain, and also for CanonicalEquivID verification at the very end of the chain.
Status Codes
If the resolution output format is an XRDS document, all XRDS documents and all XRDs within those documents successfully resolved during Ref processing MUST be reported in the XRDS document, even if they result in a "dead end". If an error is encountered, it MUST be reported using the Status element of the XRD where the error was encountered.
Since all Ref processing is standard XRI resolution, all standard XRI resolution error codes apply. There is only one condition for which we need a special error code. This will use a new class of status code for Ref processing: x6x, Ref processing error. The new status code is:
260 REF_NOT_FOLLOWED: occurs when a Ref is present and would have been processed to fulfill the resolution query but refs=false.
XRDS Document Nesting
If a Ref resolves successfully, it MUST result in a nested XRDS document representing the Ref chain followed. The XRDS element MUST contain a ref attribute whose value is the XRI contained in the Ref element.
Ref Example #1: During Authority Resolution
Note that this starts a new CanonicalID verification chain inside the Ref but it DOES NOT carry to the final XRD following the Ref, because it is a child of the XRD that is the source of the Ref.
<XRDS xmlns="xri://$xrds" ref="xri://@a*b*c">
<XRD xmlns="xri://$xrd*($v*2.0)" version=”2.0”>
<Query>*a</Query>
<ProviderID>xri://@</ProviderID>
<CanonicalID>xri://@!1</CanonicalID> ;XRDS #1 CID #1
...
<Service>
<Type>xri://$res*auth*($v*2.0)</Type>
<URI>http://a.example.com/</URI>
</Service>
</XRD>
<XRD xmlns="xri://$xrd*($v*2.0)" version=”2.0”>
<Query>*b</Query>
<ProviderID>xri://@!1</ProviderID>
<CanonicalID>xri://@!1!2</CanonicalID> ;XRDS #1 CID #2
...
<Service>
<Type>xri://$res*auth*($v*2.0)</Type>
<Ref>xri://@x*y</Ref>
</Service>
</XRD>
<XRDS ref="xri://@x*y">
<XRD xmlns="xri://$xrd*($v*2.0)" version=”2.0”>
<Query>*x</Query>
<ProviderID>xri://@</ProviderID>
<CanonicalID>xri://@!7</CanonicalID> ;XRDS #2 CID #1
...
<Service>
<Type>xri://$res*auth*($v*2.0)</Type>
<URI>http://x.example.com/</URI>
</Service>
</XRD>
<XRD xmlns="xri://$xrd*($v*2.0)" version=”2.0”>
<Query>*y</Query>
<ProviderID>xri://@!7</ProviderID>
<CanonicalID>xri://@!7!8</CanonicalID> ;XRDS #2 CID #2
...
<Service>
<Type>xri://$res*auth*($v*2.0)</Type>
<URI>http://y.example.com/</URI>
</Service>
</XRD>
</XRDS>
<XRD xmlns="xri://$xrd*($v*2.0)" version=”2.0”>
<Query>*c</Query>
<ProviderID>xri://@!1!2</ProviderID>
<CanonicalID>xri://@!1!2!3</CanonicalID> ;XRDS #1 CID #3 IS CHILD OF XRDS #1 CID #2
...
<Service>
...final service endpoints described here...
</Service>
</XRD>
</XRDS>
Ref Example #2: During Service Endpoint Selection
Note that this starts a new CanonicalID verification chain inside the Ref that carries to the final XRD.
<XRDS xmlns="xri://$xrds" ref="xri://@a*b*c">
<XRD xmlns="xri://$xrd*($v*2.0)" version=”2.0”>
<Query>*a</Query>
<ProviderID>xri://@</ProviderID>
<CanonicalID>xri://@!1</CanonicalID> ;XRDS #1 CID #1
...
<Service>
<Type>xri://$res*auth*($v*2.0)</Type>
<URI>http://a.example.com/</URI>
</Service>
</XRD>
<XRD xmlns="xri://$xrd*($v*2.0)" version=”2.0”>
<Query>*b</Query>
<ProviderID>xri://@!1</ProviderID>
<CanonicalID>xri://@!1!2</CanonicalID> ;XRDS #1 CID #2
...
<Service>
<Type>xri://$res*auth*($v*2.0)</Type>
<URI>http://a.example.com/</URI>
</Service>
</XRD>
<XRD xmlns="xri://$xrd*($v*2.0)" version=”2.0”>
<Query>*c</Query>
<ProviderID>xri://@!1!2</ProviderID>
<CanonicalID>xri://@!1!2!3</CanonicalID> ;XRDS #1 CID #3
...
<Service>
<Type>http://openid.net/signon/1.0</Type>
<Ref>xri://@x*y</Ref>
</Service>
</XRD>
<XRDS ref="xri://@x*y">
<XRD xmlns="xri://$xrd*($v*2.0)" version=”2.0”>
<Query>*x</Query>
<ProviderID>xri://@</ProviderID>
<CanonicalID>xri://@!7</CanonicalID> ;XRDS #2 CID #1
...
<Service>
<Type>xri://$res*auth*($v*2.0)</Type>
<URI>http://x.example.com/</URI>
</Service>
</XRD>
<XRD xmlns="xri://$xrd*($v*2.0)" version=”2.0”>
<Query>*y</Query>
<ProviderID>xri://@!7</ProviderID>
<CanonicalID>xri://@!7!8</CanonicalID> ;XRDS #2 CID #2
...
<Service>
<Type>xri://$res*auth*($v*2.0)</Type>
<URI>http://y.example.com/</URI>
</Service>
<Service>
<Type>http://openid.net/signon/1.0</Type>
<URI>http://openid.example.com/</URI>
</Service>
</XRD>
</XRDS>
</XRDS>
Ref Example #3: At the XRD Level
<XRDS xmlns="xri://$xrds" ref="xri://@a">
<XRD xmlns="xri://$xrd*($v*2.0)" version=”2.0”>
<Query>*a</Query>
<ProviderID>xri://@</ProviderID>
<CanonicalID>xri://@!1</CanonicalID> ;XRDS #1 CID #1
<Ref>xri://@x*y</Ref>
</XRD>
<XRDS ref="xri://@x*y">
<XRD xmlns="xri://$xrd*($v*2.0)" version=”2.0”>
<Query>*x</Query>
<ProviderID>xri://@</ProviderID>
<CanonicalID>xri://@!7</CanonicalID> ;XRDS #2 CID #1
...
<Service>
<Type>xri://$res*auth*($v*2.0)</Type>
<URI>http://x.example.com/</URI>
</Service>
</XRD>
<XRD xmlns="xri://$xrd*($v*2.0)" version=”2.0”>
<Query>*y</Query>
<ProviderID>xri://@!7</ProviderID>
<CanonicalID>xri://@!7!8</CanonicalID> ;XRDS #2 CID #2
...
<Service>
<Type>xri://$res*auth*($v*2.0)</Type>
<URI>http://y.example.com/</URI>
</Service>
<Service>
<Type>http://openid.net/signon/1.0</Type>
<URI>http://openid.example.com/</URI>
</Service>
</XRD>
</XRDS>
</XRDS>
Default Refs
There are two ways to express a default Ref in service endpoint selection (note that this is only necessary if the XRDS author does not want to trigger automatic Ref processing by placing a Ref element at the XRD level).
Optional Default Match
The following Ref will be selected as a default unless nodefault_t, nodefault_p, and nodefault_m are all set to true.
<XRDS>
<XRD>
<Query>...</Query>
<Service>
<Ref>=x*y</Ref>
</Service>
</XRD>
</XRDS>
Forced Default Match
The following Ref will always be selected, even if nodefault_t, nodefault_p, and nodefault_m are all set to true.
<XRDS>
<XRD>
<Query>...</Query>
<Service>
<Type match="all" select="true" />
<Ref>=x*y</Ref>
</Service>
</XRD>
</XRDS>
XRI Wiki