Copyright © 2007 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C liability, trademark and document use rules apply.
This document defines a mechanism to enable client-side cross-site
requests. It defines a request algorithm for GET
and
non-GET
requests that specifications that want to enable
cross-site requests in the technologies they define can use.
This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current W3C publications and the latest revision of this technical report can be found in the W3C technical reports index at http://www.w3.org/TR/.
This is the 26 November 2007 Working Draft of the "Access Control for Cross-site Requests" document. This draft has been renamed from "Enabling Read Access for Web Resources" to better and more clearly reflect what it defines. It is expected that this document will progress along the W3C Recommendation track. This document is produced by the Web Application Formats (WAF) Working Group. The WAF Working Group is part of the Rich Web Clients Activity in the W3C Interaction Domain.
Please send comments to the WAF Working Group's public mailing list public-appformats@w3.org with [access-control] at the start of the subject line. Archives of this list are available. See also W3C mailing list and archive usage guidelines.
This document was produced by a group operating under the 5 February 2004 W3C Patent Policy. W3C maintains a public list of any patent disclosures made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s) must disclose the information in accordance with section 6 of the W3C Patent Policy.
Publication as a Working Draft does not imply endorsement by the W3C Membership. This is a draft document and may be updated, replaced or obsoleted by other documents at any time. It is inappropriate to cite this document as other than work in progress.
Cross-site requests are possible using the HTML img
and
script
elements for instance. However, it is not possible to
exchange the contents of resources or manipulate resources "cross-domain".
This is to prevent information leakage and to ensure that malicious site
can not delete your calendar data with cross-site requests using the HTTP
DELETE
method.
The policy this document introduces allows a resource to opt-in to
allowing cross-site data retrieval of it and also enables a mechanism
based on the same policy to allow a resource to opt-in to requests using
an HTTP method other than GET
. This policy builds on top of
the existing restrictions already in place. This policy described in this
document can only be used by a technology, such as
XMLHttpRequest
or XBL, when the respective specification of
that technology describes how it applies.
The access control policy is defined in the resource that might be obtained and is expected to be enforced by the client that retrieves and processes the resource. Thus the client is trusted and acts as a policy enforcement point.
If you have a simple text resource residing at
http://example.com/hello
which contains the string "Hello
World!" and you would like the hello-world.invalid
domain to
be able to access it the resource would look as follows (including one
HTTP header that is significant):
Access-Control: allow <hello-world.invalid> Hello World!
The hello-world.invalid
can now access this document using
XMLHttpRequest
for instance with the following code:
new client = new XMLHttpRequest(); client.open("GET", "http://example.com.com/hello") client.onreadystatechange = function() { /* do something */ } client.send()
It gets slightly more complicated if you want your resource to be able
to handle cross-site requests using the HTTP DELETE
and
POST
methods. Your resource first needs to reply to an
authorization request that uses the GET
method and has the
Method-Check
HTTP header
set and then needs to handle the request that uses the POST
or DELETE
method and give an appropriate response. The reply
to the authorization request can have the following HTTP headers
specified for instance:
Access-Control: allow <hello-world.invalid> method DELETE, POST Method-Check-Expires: Sun, 06 Nov 2012 08:49:37 GMT
The Method-Check-Expires
indicates how long the response can be cached so that for subsequent
requests involving the HTTP DELETE
and POST
methods no authorization request has to be made. The response to the
actual request can simply contain this header:
Access-Control: allow <hello-world.invalid>
As opposed to handling such a request, actually making a request like
that is not difficult as the complexity of doing the additional
authorization request is the task of the user agent. Using
XMLHttpRequest
again and assuming the application were
hosted at http://calendar.invalid/app
you could do something
like the following:
function deleteItem(itemId, updateUI) { var client = new XMLHttpRequest() client.open("DELETE", "http://calendar.invalid/app") client.onload = updateUI client.onerror = updateUI client.onabort = updateUI client.send("id=" + itemId) }
XMLHttpRequest
Level 2 includes support for cross-site access requests though it has not yet been
published as a W3C Working Draft.
It is also possible to specify which domains are allowed to access your resource using XML:
<?access-control allow="http://hello-world.invalid https://test.example.net"?> <hello type="world"/>
You can even combine these two techniques:
Access-Control: allow <http://hello-world.invalid> <?access-control allow="https://test.example.net"?> <hello type="world"/>
This specification is applicable to both user agents and other specifications. This specification will only apply in certain contexts and specifications defining such contexts will define when and how this specification applies.
As well as sections marked as non-normative, all diagrams, examples, and notes in this specification are non-normative. Everything else in this specification is normative.
In this specification, The words must, must not, should, should not and may are to be interpreted as described in RFC 2119. [RFC2119]
A conformant specification is one that implements all the requirements listed in this specification that are applicable to specifications. For instance, a specification needs to define what the source for the referrer root URI is.
A conformant user agent is one that implements all the requirements listed in this specification that are applicable to user agents, while also being consistent with the requirements listed in the specifications that use the access control read policy.
User agents may optimize any algorithm given in this specification, so long as the end result is indistinguishable from the result that would be obtained by the specification's algorithms. (The algorithms in this specification are generally written with more concern for clarity than efficiency.)
Terminology is generally defined throughout the specification. However, the few definitions that did not really fit anywhere else are defined here instead.
The term ToASCII
algorithm means that
the ToASCII
algorithm as described in RFC 3490 is applied
with both the AllowUnassigned
and
UseSTD3ASCIIRules
flags set. [RFC3490]
There is a case-insensitive match of strings s1 and s2 if after mapping the ASCII character range A-Z to the range a-z both strings are identical.
U+0009, U+000A, U+000D and U+0020 are space characters.
A space-separated list is a string of which the items are separated by one or more space characters (in any order). The string may also be prefixed or suffixed with zero or more space characters.
To obtain the list of values from a space-separated list user agents must take the string, replace any sequence of space characters with a single U+0020 character, then drop any leading or trailing U+0020 character, then chop the resulting string at each occurrence of a U+0020 character, then drop all U+0020 values, and then return the list of values.
An XML MIME type is text/xml
,
application/xml
or any MIME type ending in +xml
.
Two URIs are same-origin if after performing scheme-based normalization on both URIs as described in section 5.3.3 of RFC 3987 the scheme, ihost and port components are identical. If either URI does not not have an ihost component the URIs must not be considered same-origin. [RFC3987]
The access control mechanism defined in this specification allows for extension of the same-origin policy in contexts where the same-origin policy currently applies.
When making a cross-site access request user agents should ensure to:
GET
,
unless extra steps are taken as outlined for access requests. Otherwise processing instructions would
not be honored or requests with side effects can be made directly.
User agents which implement this specification must also take care to properly normalize Unicode and to properly interpret IDNs to prevent URI spoofing attacks as outlined in the specification. [RFC3490]
Application authors should be aware that content retrieved from another site is not itself trustable. Authors should protect themselves against cross-site scripting attacks by not rendering or executing the retrieved content directly without validating that content.
Authors sharing content with domains that are on shared hosting environments should ensure to not allow access from arbitrary ports on those domains.
example.com
could host some user-sensitive data protected
by HTTP authentication or cookies. It has an agreement with
company.invalid
to share this data and therefore uses the
following HTTP header:
Access-Control: allow <company.invalid:*>
Now company.invalid
happens to be on a shared hosting
environment with evil.example.net
(they share the IP
address). Because of this evil.example.net
can host content
at company.invalid:9999
and access user-sensitive data at
example.com
if the user, by phishing for instance, goes to
company.invalid:9999
. This can be prevented by clearly
specifying the port or omitting it entirely letting it default to the
default port of the URI scheme:
Access-Control: allow <company.invalid:80>
Access-Control: allow <company.invalid>
Authors should ensure that GET
requests
on their application has no side effects. If by some means an evil
application finds out what applications a user is associated with it might
"attack" these applications with GET
requests that can effect
the user's data if the user is already authenticated with any of these
applications by means of cookies or HTTP authentication.
Integrity protection of the access control policy statements may be required. This could be achieved by use of SSL/TLS for example.
EBNF should maybe be converted to ABNF. If someone can provide the editor some guidance on IRC or through e-mail that would be much appreciated.
An access item is either a single *
character (always
matches) or a domain that can contain a wildcard at the start and can
optionally have a scheme and port specified. An access item must match the following EBNF:
access-item ::= (scheme "://")? domain-pattern (":" port-pattern)? | "*" domain-pattern ::= domain | "*." domain port-pattern ::= port | "*"
scheme
and port
are used as defined in RFC
3986. domain
is an internationalized domain name as defined
in RFC 3490. [RFC3986] [RFC3490]
In addition to matching the above EBNF the ToASCII
algorithm must
apply successfully (without errors) to each label
component
of the subdomain
(if any) from the access item.
Since HTTP syntax does not allow Unicode domain
has to be
written within the ASCII range resorting to the punycode syntax when
necessary.
If the scheme
omitted it will match any
scheme
from the referrer root
URI. If port-pattern
is omitted the port
for the access item will be the default port
for the
scheme
of the access item, or the default port
of the scheme
of the referrer root URI if the access item
did not include a scheme
. If port-pattern
is
*
it will match any port
.
When *
is used as part of domain-pattern
it
matches any number of internationalized labels before
domain
. If just domain
is used it will match
itself and any number of internationalized labels before
domain
.
Several examples of conforming access items:
*
*.example.org
https://*.example.org
https://example.org:8443
The following access items would make the user agent deny access to the resource:
https://*.*:80
*://example.org
http://example.org/
http://example.org/example
http://example.org:
The following access items are identical:
http://example.org
http://example.org:80
The following access items would match
http://foo.bar.example.org:80
:
org
*.org
*.org:*
example.org
http://example.org
http://*.bar.example.org:80
Access-Control
HTTP Response HeaderRetrieved resources can have one
or more Access-Control
headers defined. These headers must match the following
EBNF:
Access-Control ::= "Access-Control" ":" 1#rule rule ::= rule-allow | rule-deny rule-allow ::= "allow" (LWS pattern)+ exclude? (LWS "method" LWS #Method)? rule-deny ::= "deny" (LWS pattern)+ exclude? exclude ::= LWS "exclude" (LWS pattern)+ pattern ::= "<" access item ">"
As stated by RFC 2616, multiple Access-Control
headers can be combined.
The syntax of access items when used in the Access-Control
HTTP header is restricted to
internationalized domain names to which the ToASCII algorithm has been
applied as HTTP does not support Unicode.
LWS
and Method
are used as defined by RFC
2616. The pattern
production above must not
include implied LWS
. Implied LWS
is allowed
everywhere else. [RFC2616]
In case resources on a domain are not all in the control of a single
person "deny" rules can be used by authors to deny read access from
external resources to the entire domain. Read access from other domains is
by default disallowed but individual resources on the domain could have
<?access-control?>
processing instructions specified which can allow access from other
domains. Although files can contain processing instructions, HTTP headers
can be set across an entire server making them far more effective. The
"exclude" clause can be used to list exclusions to these "deny" rules.
"allow" rules can be used to allow read access from particular domains as long as those domains don't match any of the patterns listed in "exclude".
For cross-site non-GET
access requests the server to which
the request is made can list which non-GET
methods are
allowed using a comma-separated list after the "method" rule.
Access-Control: allow <*.example.org> exclude <*.public.example.org>
Access-Control: allow <webmaster.public.example.org>
Means that every subdomain of example.org
can access the
resource including webmaster.public.example.org
, but with
the exclusion of all other subdomains of public.example.org
.
Access-Control: allow <example.org>
Means that example.org
and all its subdomains can access
the resource.
Access-Control: allow <example.org> <example.invalid> method POST, PUT
Means that example.org
and example.invalid
can access the resource and perform POST
and PUT
requests.
<?access-control?>
Processing InstructionXML resources may include an <?access-control?>
processing
instruction within the XML Prolog to indicate, if the access control
read policy applies, from which domains their content can be
accessed. [XML]
The processing instruction takes three pseudo-attributes which each take
a space-separated list of access items and one
psuedo-attribute which takes a space-separated
list of HTTP methods. These pseudo-attributes are allow
,
deny
, exclude
, and method
. Either
the allow
or deny
pseudo-attribute must be specified. allow
and deny
must not be specified at the same time. If an attribute
is specified it must at least contain an access item. If the deny
psuedo-attribute is specified the method
attribute must not be specified.
An <?access-control?>
processing instruction that is part of the XML Prolog must be parsed using the same syntax rules as described in
the XML Stylesheet PI specification. <?access-control?>
processing
instructions outside the XML Prolog are ignored. [XMLSSPI]
The above means that the following examples would be non-conforming and would make the user agent deny access to the resource:
<?access-control?>
<?access-control x?>
<?access-control x=""?>
<?access-control allow=""?>
<?access-control allow="http://example.org"
x=""?>
<?access-control allow="allow.example.org"
deny="deny.example.org"?>
Referer-Root
(sic) HTTP Request HeaderThe Referer-Root
(sic) request HTTP
header helps servers knowing where the request originates in case the
Referer
header is not included in the request. It also
indicates that the request is a cross-site access request. The header must match the following EBNF:
Referer-Root ::= "Referer-Root" ":" referrer root URI
Method-Check
HTTP Request HeaderThe Method-Check
request
HTTP header informs the server that the client is making an authorization
request and will make a subsequent request to the same URI using a
different method specified in the Method-Check
HTTP header if that is
allowed by the server per the semantics of authorization requests. The
Method-Check
HTTP header
must match the following EBNF:
Method-Check ::= "Method-Check" ":" Method
The Method
production is defined in RFC 2616. [RFC2616]
Method-Check-Expires
HTTP Response HeaderThe Method-Check-Expires
HTTP response header indicates how long the results of an authorization
request can be cached in an authorization request cache. The Method-Check-Expires
HTTP
header must match the following EBNF:
Method-Check-Expires ::= "Method-Check-Expires" ":" HTTP-date
The HTTP-date
production is defined in RFC 2616. [RFC2616]
The various subsections below describe the various processing models user agents and specifications have to implement.
A cross-site access request
takes the parameters request URI and request method.
If request method is equal to GET
the user agent
must follow the cross-site GET
access
request algorithm. Otherwise the cross-site non-GET
access request algorithm.
These algorithms have shared return values that specifications can use to instruct user agents what to do. The status return flag indicates the status of the cross-site access request. It takes the value "success" when cross-site access to the resource is allowed, "same-origin" if the cross-site request turned into a same-origin request due to redirects, "network" if a network error of some sort occurred, and "abort" if the user aborted the request. The uri return flag is used when the status return flag is "same-origin" to indicate the URI which the specification can use for a subsequent same-origin request.
As this algorithm is used by other specifications, those specifications must handle all values of the status return flag and handle the uri return flag.
The referrer root URI is the
scheme
followed by ://
, followed by the
domain
without any trailing U+002E (.
) (if any),
followed by :
, followed by the port
(even if it
is the default port for the scheme) of the source of the request. If the
resource does not have a host-based authority (data:
URI
scheme for instance) the referrer root URI is "null".
Specifications using cross-site access requests must define the source of the request for the referrer root URI. Due to the way the origin for protocols is retrieved in different ways it is not possible to define this in a generic way.
While following the requirements for cross-site access requests user
agents must ensure that each request has a Referer-Root
HTTP request header
set, with the value set to referrer root
URI. This includes requests as a result of a redirect.
The variables used in the generic set of steps are part of the algorithms that invoke these set of steps.
The generic redirect steps are as follows:
If the new URI scheme is not supported, infinite loop precautions are violated, or something else went wrong terminate the algorithm that invoked this set of steps and return with the status flag set to "network".
Otherwise, let current request URI be the new URI and then follow these set of steps:
Whenever the generic abort steps are applied terminate the algorithm that invoked this set of steps and return with the status flag set to "abort".
Whenever the generic network error steps are applied terminate the algorithm that invoked this set of steps and return with the status flag set to "network".
Remove the cache entry means removing the entry in the authorization request cache which has as key the tuple (origin, current request URI).
GET
Access RequestThe steps below describe what user agents must do for
cross-site GET
access requests. These are
requests using the HTTP GET
method to a non same-origin URI,
the request URI.
Let origin be the referrer root URI.
Let current request URI be the request URI.
The current request URI can be modified when applying the generic redirect steps.
Then make a request to current request URI using the HTTP
method GET
and observe the following request rules:
Apply the generic redirect steps.
Apply the generic abort steps.
Apply the generic network error steps.
Perform an access control check
using GET
as method. If it returns "fail" terminate this
algorithm and return with the status
flag set to "network". Otherwise, if it returns "pass", terminate
this algorithm and return with the status flag set to "success". Do not
actually terminate the request.
GET
Access RequestCross-site non-GET
access requests use an authorization request cache that
consists of a set of entries. Each entry has a key, list of
methods, and an expiry date. Entries must be
removed when the current time exceeds the time specified by the expiry
date field. Besides expiring entries are added and removed per the
algorithms below. They are added and removed in such a way that there can
never be duplicate items in the cache.
The steps below describe what user agents must do for
cross-site non-GET
access requests. These are
requests to a non same origin URI with an HTTP request method other than
GET
that first need to be authorized using either an
authorization request cache entry or an authorization request.
Let origin be the referrer root URI.
Let request method be the request method parameter passed to the cross-site access request algorithm.
Let current request URI be the request URI.
The current request URI can be modified when applying the generic redirect steps.
If there is an entry in the authorization request cache where the key matches the (origin, current request URI) tuple and the request method is in the list of methods proceed to the next step.
Otherwise, remove the cache entry, if any, and then make an authorization request, by following this set of steps:
Set the Method-Check
HTTP request header to request method and then make a
request using the HTTP GET
method to the current
request URI. The Method-Check
HTTP request
header is to persist during redirects. Ensure that the response to
this request is not cached by specifying the appropriate HTTP headers,
such as Cache-Control: no-cache
.
Observe the following request rules while making the request:
Apply the generic redirect steps.
Apply the generic abort steps.
Apply the generic network error steps.
Perform an access control
check using the request method as method . If it
returns "fail" terminate this algorithm and return with the status flag set to "network".
Otherwise, if it returns "pass" and a "method list", add an entry to
the authorization request
cache with as key the tuple (origin,
current request URI), as list of methods the
"method list" return value, and as expiry date the value of the
Method-Check-Expires
HTTP response header, if any. If there is no Method-Check-Expires
HTTP response header the user agent may chose to
nevertheless cache the entry for a short period of time or not store
a cache entry at all. If there is a Method-Check-Expires
HTTP response headers that can be successfully parsed and the
current time exceeds the time specified by the header remove the cache entry.
Make a request to the current request URI using HTTP method
request method and observe the request rules below
while making the request. For this request the Method-Check
header is no longer
set. The Referer-Root
header is still set, obviously.
First remove the cache entry and then apply the generic network error steps.
Apply the generic abort steps.
Apply the generic network error steps.
Perform an access control check using the request method as method. If it returns "fail" remove the cache entry, then terminate this algorithm, and return with the status flag set to "network". Otherwise, if it returns "pass", terminate this algorithm and return with the status flag set to "success". Do not actually terminate the request.
The algorithms in this section are to be read as if they were part of the algorithm that invoked them. The "overall set of steps" and "overall algorithm" are references to the algorithm that invoked algorithms defined in this section.
The deny list check algorithm takes a list of items consisting of match and exclude lists. For each item in the list run the following steps:
If there is no match for any access item from the match list against the referrer root URI process the next list item. If there is no next list item go to the next step in the overall set of steps.
If the exclude list is non-empty and there is a match for any access item from the exclude list against the referrer root URI process the next list item. If there is no next list item go to the next step in the overall set of steps.
Terminate the overall algorithm and return "fail".
The allow list check algorithm takes a list of items consisting of match, exclude, and method lists. For each item in the list run the following steps:
If there is no match for any access item from the match list against the referrer root URI process the next list item. If there is no next list item go to the next step in the overall set of steps.
If the exclude list is non-empty and there is a match for any access item from the exclude list against the referrer root URI process the next list item. If there is no next list item go to the next step in the overall set of steps.
If the request method is not GET
and the
request method is not in the method
list process the next list item. If there is no next list item go to
the next step in the overall set of steps.
HTTP method comparison is case-sensitive.
If the request method is not GET
append the
items from method list to temp method
list.
Set the allow access flag to "true".
If the request method is GET
go to the next
step in the overall set of steps.
Process the next list item. If there is no next list item go to the next step in the overall set of steps.
This step ensures that temp method list gets all the necessary headers.
When a user agents has to make an access control check for a particular resource it must then associate the following with that resource:
An unordered, initially empty, HTTP access control allow list of which each list item contains a match list, an exclude list, and method list.
An unordered, initially empty, HTTP access control deny list of which each list item contains a match list and an exclude list.
An unordered, initially empty, PI access control allow list of which each list item contains a match list, an exclude list, and a method list.
An unordered, initially empty, PI access control deny list of which each list item contains a match list and an exclude list.
An allow access flag which is used in the algorithms to determine at certain points whether access will be granted. The flag has two values: "true" and "false". Its initial value is "false".
The match lists and exclude lists are unordered lists of access items. The match lists are guaranteed to be non-empty and the exclude lists can be empty. The method lists are unordered lists of HTTP methods. They can be empty and are only used in an access control check as the result of an authorization request.
If an HTTP method name was passed as parameter to the access control
check algorithm that will be the request method. If none was
passed request method is GET
. In addition there is
the temp method list that will eventually be used for the authorization request cache entry.
After associating the aforementioned lists and when all HTTP headers have been received the user agent must run the following algorithm (unless stated otherwise):
Parse the Access-Control
headers. If any
value does not conform to the syntax required terminate the algorithm
and return "fail". Otherwise, if parsed successfully, then for each rule
run the following steps:
If rule
is rule-allow
append a new list
item to the HTTP access control allow list
where the match list is constructed of each
access item following "allow"
,
the exclude list of each access item following "exclude"
,
and the method list of each HTTP method
following "method"
. If "exclude"
or
"method"
is not present their respective list will be
empty.
If rule
is rule-deny
append a new list
item to the HTTP access control deny list
where the match list is constructed of each
access item following "deny"
and the exclude list of each access item following "exclude"
.
If "exclude"
is not present the exclude list will be
empty.
Then run the deny list check on the HTTP access control deny list.
Then run the allow list check on the HTTP access control allow list.
If the requested resource has an XML MIME type go to the next step. Otherwise, if the allow access flag is "false" then terminate the algorithm and return "fail". If the allow access flag is "true" then terminate the algorithm, return "pass", and return the temp method list.
Parse the resource as an XML document using a streaming XML parser
following the rules set forth in the XML specification up to but
not including the root element start tag. Then process the
encountered <?access-control?>
processing
instructions (if any). [XML]
If there is either an XML parse error or failure to parse the
processing instructions terminate the overall algorithm and return
"fail". Otherwise, run the following steps for each <?access-control?>
processing
instruction:
If the processing instruction does not meet the following conditions then terminate the overall algorithm and return "fail":
deny
,
allow
, exclude
, and method
.
deny
or allow
pseudo-attribute,
but not both.
method
pseudo-attribute if there is an
allow
pseudo-attribute present.
Let temp match list be the result of parsing the
allow
or deny
pseudo-attribute value,
whichever is present. If any obtained value does not match the access item syntax or if no values was
obtained terminate the overall algorithm and return "fail".
If there is an exclude
pseudo-attribute let temp
exclude list be the result of parsing the
exclude
pseudo-attribute value. If any obtained value
does not match the access item syntax or if
no value was obtained terminate the overall algorithm and return
"fail". If there is no such pseudo-attribute let temp exclude
list be empty.
If there is an allow
pseudo-attribute append a new list
item to the PI access control allow list
where the match list is temp match
list, the exclude list is temp
exclude list, and the method list is
the result of parsing the method
pseudo-attribute or the
empty list if the attribute is not present.
Otherwise, there is a deny
psuedo-attribute. Append a
new list item to the PI access control deny
list where the match list is temp
match list and the exclude list is
temp exclude list.
Then run the deny list check on the PI access control deny list.
Then run the allow list check on the PI access control allow list.
If the allow access flag is "false" then return "fail". Otherwise, if the allow access flag is "true", then return "pass" and return the temp method list.
To determine whether a referrer root URI and an access item match user agents must run the following algorithm:
Let origin be referrer root URI and item be access item.
If item is a single U+002A (*
) there is a
match. Terminate this algorithm.
If origin is "null" there is no match. Terminate this algorithm.
If item does not have a port-pattern
let the
port
of item be the default port
for the scheme
of item or, if item
does not have a scheme
, let it be the default
port
of the scheme
of origin.
If item has a scheme
and it does not case-insensitively match the scheme
from
origin there is no match. Terminate this algorithm.
Remove the scheme
from item (if it has one
specified) and origin including the ://
sequence
following it.
If the port
from item does not match the
port
from origin and is not *
there
is no match. Terminate this algorithm.
Remove the port
from item and
origin including the U+003A (:
) preceding it.
If item item has a single U+002E (.
) as last
character remove that character from item.
Let origin list be origin split on the U+002E
(.
) character (dropping that character in the process) and
item list be item split on the U+002E
(.
) character (dropping that character in the process).
Ensure that the order is preserved.
Reverse the order of origin list and item list.
Now process the first list item of both origin list and item list using the following steps:
Let the item from origin list be origin label and the item from item list be item label.
If item label is a single U+002A (*
)
character move to the next step in the overall set of steps.
Apply the ToASCII
algorithm to
origin label and item label and store the result
in those variables respectively.
If origin label does not case-insensitively match item label there is no match (terminate the overall algorithm).
Otherwise, apply these set of steps to the next list item of both origin list and item list. If the origin list has no next list item there is no match (terminate the overall algorithm.) If the item list has no next list item go to the next step in the overall set of steps.
There is a match. Terminate this algorithm.
The editor would like to thank Arthur Barstow, Benjamin Hawkes-Lewis, Cameron McCormack, David Håsäther, Dean Jackson, Eric Lawrence, Frank Ellerman, Frederick Hirsch, Graham Klyne, Hal Lockhart, Henri Sivonen, Ian Hickson, Jonas Sicking, Lachlan Hunt, Maciej Stachowiak, Marc Silbey, Marcos Caceres, Mark Nottingham, Martin Dürst, Matt Womer, Mohamed Zergaoui, Sharath Udupa, Sunava Dutta, Thomas Roessler, and Zhenbin Xu for their contributions to this specification.
Special thanks to Brad Porter, Matt Oshry and R. Auburn who helped editing earlier versions of this document.