discovery-api/Overview.src.html
author Rich Tibbett <richt@opera.com>
Tue, 02 Oct 2012 14:51:33 +0200
changeset 238 65e14f8dc95d
parent 232 32487cf058c5
child 239 7e34654692fc
permissions -rw-r--r--
Editorial changes to Service Discovery spec
     1 <!DOCTYPE html>
     2 <html>
     3   <head>
     4     <title>Networked Service Discovery and Messaging</title>
     5     <meta http-equiv='Content-Type' content='text/html;charset=utf-8'/>
     6     <script type="text/javascript" class='remove'>
     7       var respecConfig = {
     8           specStatus:   "ED",
     9           //publishDate:  "2012-08-22",
    10           shortName:    "discovery-api",
    11           edDraftURI:   "http://dvcs.w3.org/hg/dap/raw-file/tip/discovery-api/Overview.html",
    12           previousMaturity: "WD",
    13           previousPublishDate: "2012-08-07",
    14           editors: [
    15             {
    16               name:       "Rich Tibbett",
    17               //url:        "http://richt.me/",
    18               company:    "Opera Software ASA",
    19               companyURL: "http://opera.com/"
    20             },
    21             {
    22               name:       "Clarke Stevens",
    23               //url:      "",
    24               company:    "CableLabs",
    25               companyURL: "http://cablelabs.com/"
    26             }
    27           ],
    28           noIDLIn:      true,
    29           wg:           "Device APIs and Policy Working Group",
    30           wgURI:        "http://www.w3.org/2009/dap/",
    31           wgPublicList: "public-device-apis",
    32           wgPatentURI:  "http://www.w3.org/2004/01/pp-impl/43696/status"
    33       };
    34     </script>
    35 
    36     <script src='http://www.w3.org/Tools/respec/respec-w3c-common' type="text/javascript" class='remove' async></script>
    37     <style type="text/css">
    38       /* Custom CSS optimizations (Richard Tibbett) */
    39 
    40       /* Add better spacing to sections */
    41       section, .section { margin-bottom: 2em; }
    42 
    43       /* Reduce note & issue render size */
    44       .note, .issue { font-size:0.8em; }
    45 
    46       /* Add addition spacing to <ol> and <ul> for rule definition */
    47       ol.rule li, ul.rule li { padding:0.6em; }
    48 
    49       pre.widl { border: solid thin; background: #EEEEEE; color: black; padding: 0.5em 1em; position: relative; }
    50       pre.widl :link, pre.widl :visited { color: #000; background: transparent; }
    51       pre.widl:before { content: "IDL"; font: bold small sans-serif; padding: 0.5em; background: white; position: absolute; top: 0; margin: -1px 0 0 -4em; width: 1.5em; border: thin solid; border-radius: 0 0 0 0.5em }
    52 
    53       div.example { border: solid thin red; background: #F7DFE5; color: black; padding: 0.5em 1em; position: relative; margin: 1em 0 1em 4.6em; width: auto; }
    54       div.example:before { content: "EXAMPLE"; font: bold small sans-serif; padding: 0.5em; background: red; color: white; position: absolute; top: 0; margin: -1px 0 0 -7.6em; width: 5em; border: thin solid red; border-radius: 0 0 0 0.5em }
    55 
    56       dl.domintro { color: green; margin: 2em 0 2em 2em; padding: 0.5em 1em; border: none; background: #DDFFDD; }
    57       hr + dl.domintro, div.impl + dl.domintro { margin-top: 2.5em; margin-bottom: 1.5em; }
    58       dl.domintro dt, dl.domintro dt * { color: black; text-decoration: none; }
    59       dl.domintro dd { margin: 0.5em 0 1em 2em; padding: 0; }
    60       dl.domintro dd p { margin: 0.5em 0; }
    61       dl.domintro code {font-size: inherit; font-style: italic; }
    62       dl.domintro:before { display: table; margin: -1em -0.5em 0.5em auto; width: auto; content: 'This box is non-normative. Implementation requirements are given below this box.'; color: red; border: solid 2px; background: white; padding: 0 0.25em; }
    63 
    64       table { border-collapse:collapse; border-style:hidden hidden none hidden }
    65       table thead { border-bottom:solid }
    66       table tbody th:first-child { border-left:solid }
    67       table td, table th { border-left:solid; border-right:solid; border-bottom:solid thin; vertical-align:top; padding:0.2em }
    68     </style>
    69   </head>
    70 
    71   <body>
    72     <section id='abstract'>
    73       <p>
    74         This specification defines a mechanism for an HTML document to discover and subsequently communicate with <abbr title="Hypertext Transfer Protocol">HTTP</abbr>-based services
    75         advertised via common discovery protocols within a user's network.
    76       </p>
    77     </section>
    78 
    79     <section id='sotd'>
    80       <p>
    81         This document represents the early consensus of the group on the scope and features of the proposed
    82         API.
    83       </p>
    84     </section>
    85 
    86     <section class="informative">
    87       <h3>Introduction</h3>
    88 
    89       <p>To enable Web pages to connect and communicate with Local-networked Services provided over HTTP, this specification introduces the
    90       <a href="#navigatornetworkservice"><code>NavigatorNetworkService</code></a> interface.</p>
    91 
    92       <p>
    93          Using this <abbr title="Application Programming Interface">API</abbr> consists of requesting a well-known service type, known by developers and advertised by Local-networked Devices. User authorization, where the user connects the web page to one or more discovered services,
    94          is expected before the web page is able to interact with any Local-networked Services.
    95       </p>
    96 
    97       <p>
    98          A web page creates a request to obtain connectivity to services running in the network by specifying a well-known discovery service type that it wishes to interact with.
    99       </p>
   100 
   101       <p>
   102          The user agent, having captured all advertised services on the network from the Service Discovery mechanisms included in this recommendation, attempts to match
   103       the requested service type to a discovered service according to the processing described herein.
   104       </p>
   105 
   106       <p>
   107           If a service connectivity request is successful then the Web page is provided with the necessary information to communicate with the authorized Local-networked Service.
   108           If the request fails then the Web page will receive an error callback containing an error code describing the cause of Local-networked Service connectivity failure.
   109       </p>
   110 
   111       <p>
   112          Once connected to a Local-networked Service the Web page can send requests and receive responses to the Local-networked Service via the messaging format and appropriate channel inferred from the service type
   113          authorized via the provided API.
   114          The Web page, once connected, can also receive service-pushed events, in the messaging format supported by the Local-networked Device, if such event subscription functionality is provided by the
   115          connected Local-networked Service.
   116       </p>
   117 
   118       <div class="example">
   119        <p>Example of requesting a DNS-SD advertised service:</p>
   120        <hr />
   121        <pre class="highlight">function showServices( services ) {
   122   // Show a list of all the services provided to the web page
   123   for(var i = 0, l = services.length; i < l; i++) console.log( services[i].name );
   124 }
   125 
   126 navigator.getNetworkServices('zeroconf:_boxee-jsonrpc._tcp', showServices);</pre>
   127       </div>
   128 
   129       <div class="example">
   130         <p>Example of requesting a UPnP advertised service, also handling error conditions:</p>
   131         <hr />
   132         <pre class="highlight">function showServices( services ) {
   133   // Show a list of all the services provided to the web page
   134   for(var i = 0, l = services.length; i < l; i++) console.log( services[i].name );
   135 }
   136 
   137 function error( e ) {
   138   console.log( "Error occurred: " + e.code );
   139 }
   140 
   141 navigator.getNetworkServices('upnp:urn:schemas-upnp-org:service:ContentDirectory:1', showServices, error);</pre>
   142       </div>
   143 
   144       <div class="example">
   145         <p>Example of requesting either a DNS-SD or UPnP advertised service:</p>
   146         <hr />
   147         <pre class="highlight">function showServices( services ) {
   148   // Show a list of all the services provided to the web page (+ service type)
   149   for(var i = 0, l = services.length; i < l; i++)
   150      console.log( services[i].name + '(' + services[i].type + ')' );
   151 }
   152 
   153 navigator.getNetworkServices([
   154   'zeroconf:_boxee-jsonrpc._tcp',
   155   'upnp:urn:schemas-upnp-org:service:ContentDirectory:1'
   156 ], showServices);</pre>
   157       </div>
   158 
   159       <p>For more detailed examples see the <a href="#examples">Examples</a> section.
   160     </section>
   161 
   162     <section
   163      id='conformance'>
   164 
   165      <p>Requirements phrased in the imperative as part of algorithms (such as "strip any leading space characters" or "return false and abort these steps") are to be interpreted with the
   166      meaning of the key word ("must", "should", "may", etc) used in introducing the algorithm.</p>
   167 
   168      <p>
   169       Some conformance requirements are phrased as requirements on attributes, methods or objects. Such requirements are to be interpreted as requirements on user agents.
   170      </p>
   171 
   172      <p>
   173       Conformance requirements phrased as algorithms or specific steps <em class="ct">MAY</em> be implemented in any manner, so long as the end result is equivalent. (In particular, the algorithms defined in
   174       this specification are intended to be easy to follow, and not intended to be performant.)
   175      </p>
   176 
   177      <p>
   178       The only conformance class defined by this specification is a <dfn>user agent</dfn>.
   179      </p>
   180 
   181      <p>
   182       User agents <em class="ct">MAY</em> impose implementation-specific limits on otherwise unconstrained inputs, e.g. to prevent denial of service attacks, to guard against running out of memory, or to work
   183       around platform-specific limitations.
   184      </p>
   185 
   186      <p>
   187       When support for a feature is disabled (e.g. as an emergency measure to mitigate a security problem, or to aid in development, or for performance reasons), user agents <em class="ct">MUST</em> act as if
   188       they had no support for the feature whatsoever, and as if the feature was not mentioned in this specification. For example, if a particular feature is accessed via an attribute in a Web
   189       IDL interface, the attribute itself would be omitted from the objects that implement that interface - leaving the attribute on the object but making it return null or throw an exception
   190       is insufficient.
   191      </p>
   192 
   193       <section>
   194          <h3>Dependencies</h3>
   195 
   196          This specification relies on several other underlying specifications.
   197 
   198          <dl>
   199             <dt>HTML</dt>
   200             <dd>Many fundamental concepts from HTML are used by this specification. [[!HTML5]]</dd>
   201             <dt>WebIDL</dt>
   202             <dd>The IDL blocks in this specification use the semantics of the WebIDL specification. [[!WEBIDL]]</dd>
   203          </dl>
   204       </section>
   205     </section>
   206 
   207     <section>
   208       <h3>Terminology</h3>
   209 
   210       <p>
   211          The construction "a <code>Foo</code> object", where <code>Foo</code> is actually an interface, is sometimes used instead of the more accurate "an object implementing the interface <code>Foo</code>".
   212       </p>
   213 
   214       <p>
   215          The term DOM is used to refer to the API set made available to scripts in Web applications, and does not necessarily imply the existence of an actual <code>Document</code> object or of any
   216          other <code>Node</code> objects as defined in the DOM Core specifications. [[!DOM4]]
   217       </p>
   218 
   219       <p>
   220          An IDL attribute is said to be <em>getting</em> when its value is being retrieved (e.g. by author script), and is said to be <em>setting</em> when a new value is assigned to it.
   221       </p>
   222 
   223       <p>
   224         A <dfn>valid service type</dfn> is a string that begins with <code>upnp:</code> or <code>zeroconf:</code> followed by one or more characters in the ranges U+0021, U+0023 to U+0027, U+002A to U+002B, U+002D to U+002E, U+0030 to U+0039, U+0041 to U+005A, U+005E to U+007E.
   225       </p>
   226       <p></p>
   227 
   228       <p>
   229         A <a>valid service type</a> provided in the <code>type</code> attribute of the <a href="#dom-navigator-getnetworkservices"><code>getNetworkServices()</code></a> method will be matched against the services currently contained in the <a>list of available service records</a> according to the algorithms defined in this specification.
   230       </p>
   231 
   232       <p>
   233         A <dfn>user-agent generated callback url</dfn> is a Local-network accessible URL endpoint that a <a>user agent</a> generates and maintains for receiving HTTP NOTIFY requests from UPnP Event sources. It is only required when the user agent implements UPnP Service Discovery as defined in
   234         this specification.
   235       </p>
   236 
   237     </section>
   238 
   239     <section>
   240      <h2>Requesting networked services</h2>
   241 
   242 
   243 <pre class="widl">[Supplemental, NoInterfaceObject]
   244 interface <dfn id="navigatornetworkservice">NavigatorNetworkService</dfn> {
   245   // Obtain a Local-networked Service
   246   void <a href="#dom-navigator-getnetworkservices">getNetworkServices</a>( in any type,
   247                            in <a href="#navigatornetworkservicesuccesscallback">NavigatorNetworkServiceSuccessCallback</a> successCallback,
   248                            in optional <a href="#navigatornetworkserviceerrorcallback">NavigatorNetworkServiceErrorCallback</a> errorCallback );
   249 };
   250 <a class="externalDFN" href="http://www.whatwg.org/specs/web-apps/current-work/complete/timers.html#navigator">Navigator</a> implements <a href="#navigatornetworkservice">NavigatorNetworkService</a>;
   251 
   252 [Callback=FunctionOnly, NoInterfaceObject]
   253 interface <dfn id="navigatornetworkservicesuccesscallback">NavigatorNetworkServiceSuccessCallback</dfn> {
   254   void handleEvent( in <a href="#networkservices">NetworkServices</a> services );
   255 };
   256 
   257 [NoInterfaceObject]
   258 interface <dfn id="navigatornetworkserviceerror">NavigatorNetworkServiceError</dfn> {
   259   const unsigned short <a href="#dom-navigatornetworkserviceerror-permission_denied">PERMISSION_DENIED_ERR</a> = 1;
   260   const unsigned short <a href="#dom-navigatornetworkserviceerror-unknown_type_prefix">UNKNOWN_TYPE_PREFIX_ERR</a> = 2;
   261   readonly attribute unsigned short <a href="#dom-navigatornetworkserviceerror-code">code</a>;
   262 };
   263 
   264 [Callback=FunctionOnly, NoInterfaceObject]
   265 interface <dfn id="navigatornetworkserviceerrorcallback">NavigatorNetworkServiceErrorCallback</dfn> {
   266   void handleEvent( in <a href="#navigatornetworkserviceerror">NavigatorNetworkServiceError</a> error );
   267 };
   268 </pre>
   269 
   270   <section>
   271    <h2>Methods</h2>
   272 
   273       <dl class="domintro">
   274         <dt>
   275           <var title="">window</var>
   276            .
   277           <code title="dom-navigator">
   278             <a href="http://www.whatwg.org/specs/web-apps/current-work/complete/timers.html#navigator">navigator</a>
   279           </code>
   280            .
   281           <code title="dom-navigator-getNetworkServices">
   282             <a href="#dom-navigator-getnetworkservices">getNetworkServices</a>
   283           </code>
   284           (
   285           <var title="">type</var>
   286           ,
   287           <var title="">successCallback</var>
   288            [,
   289           <var title="">errorCallback</var>
   290            ] )
   291         </dt>
   292         <dd>
   293           <p>Prompts the user to select one or more discovered network services that have advertised support for the requested service type.</p>
   294           <p>
   295             The
   296             <var title="">type</var>
   297              argument contains one or more <a>valid service type</a> tokens that the web page would like to interact with.
   298           </p>
   299           <p>
   300             If the user accepts, the
   301             <var title="">successCallback</var>
   302              is
   303           invoked, with one or more
   304             <code>
   305               <a href="#networkservice"><code>NetworkService</code></a>
   306             </code>
   307              objects as
   308           its argument.
   309           </p>
   310           <p>
   311             If the user declines, the
   312             <var title="">errorCallback</var>
   313              (if
   314           any) is invoked.
   315           </p>
   316         </dd>
   317       </dl>
   318 
   319        <div>
   320           <p>
   321             When the <dfn id="dom-navigator-getnetworkservices" title="dom-navigator-getnetworkservices"><code>getNetworkServices(type, successCallback[, errorCallback])</code></dfn> method is called, the <a>user agent</a> <em class="ct">MUST</em> run the following steps:
   322           </p>
   323 
   324           <ol class="rule">
   325 
   326             <li>
   327               Let <var>requested control types</var> be initially set to an empty array.
   328             </li>
   329 
   330             <li>
   331                If <var>type</var> is an array consisting of one or more <a>valid service type</a> tokens, then let <var>requested control types</var> by the value of <var>type</var>, removing any non-<a>valid service type</a> tokens from the resulting array.
   332             </li>
   333 
   334             <li>
   335                If <var>type</var> is a string consisting of one <a>valid service type</a> token, then let <var>requested control types</var> be an array containing one item with a value of <var>type</var>.
   336             </li>
   337 
   338             <li>
   339                If <var>requested control types</var> is an array that contains at least one or more <a title="valid service type">valid service type</a> tokens then continue to the step labeled <em>process</em> below. Otherwise, the <a>user agent</a> <em class="ct">MUST</em> <a href="http://www.whatwg.org/specs/web-apps/current-work/complete/webappapis.html#queue-a-task" class="externalDFN">queue a task</a> to invoke <var>errorCallback</var>, if it is provided and is an object of type <code>Function</code>, with a new <a href="#navigatornetworkserviceerror"><code>NavigatorNetworkServiceError</code></a> object whose
   340                  <a href="#dom-navigatornetworkserviceerror-code"><code>code</code></a> attribute has the numeric value 2
   341                   (<a href="#dom-navigatornetworkserviceerror-unknown_type_prefix"><code>UNKNOWN_TYPE_PREFIX_ERR</code></a>) as its argument,
   342                    abort any remaining steps and return.
   343             </li>
   344 
   345             <li>
   346                <em>Process</em>: Let <var>services found</var> be an empty array.
   347             </li>
   348 
   349             <li>
   350                For each <var>available service</var> in the <a>list of available service records</a> run the following steps:
   351                <ol class="rule">
   352                   <li>
   353                     For each <var>requested control type</var> in <var>requested control types</var>: If <var>available service</var>'s <code>type</code> attribute equals the <var>requested control type</var> then let <var>matched service</var> equal the value of <var>available service</var> and continue at the step labeled <var>attach</var> below.
   354                   </li>
   355                   <li>
   356                      Continue at the next <var>available service</var>.
   357                   </li>
   358                   <li>
   359                      <em>Attach</em>: If <var>matched service</var> is not empty then run the following steps:
   360 
   361                      <ol class="rule">
   362                         <li>
   363                            Let <var>new service object</var> be a new <a href="#networkservice"><code>NetworkService</code></a> object, mapping the parameters of
   364                      <var>matched service</var> to this new object where possible.
   365                         </li>
   366                         <li>
   367                            Append <var>new service object</var> to the <var>services found</var> array.
   368                         </li>
   369                      </ol>
   370                   </li>
   371                </ol>
   372             </li>
   373 
   374             <li>
   375                If <var>services found</var> is an empty array, then the <a>user agent</a> <em class="ct">MUST</em> <a href="http://www.whatwg.org/specs/web-apps/current-work/complete/webappapis.html#queue-a-task" class="externalDFN">queue a task</a> to invoke <var>errorCallback</var>, if it is provided and is an object of type <code>Function</code>, with a new <a href="#navigatornetworkserviceerror"><code>NavigatorNetworkServiceError</code></a> object whose
   376                  <a href="#dom-navigatornetworkserviceerror-code"><code>code</code></a> attribute has the numeric value 1
   377                  (<a href="#dom-navigatornetworkserviceerror-permission_denied"><code>PERMISSION_DENIED_ERR</code></a>) as its argument, abort any remaining steps and return.
   378             </li>
   379 
   380             <li>
   381                Return, and run the remaining steps asynchronously.
   382             </li>
   383 
   384             <li>
   385                Optionally, e.g. based on a previously-established user preference, for security reasons, or due to platform limitations, the <a>user agent</a> <em class="ct">MAY</em> <a href="http://www.whatwg.org/specs/web-apps/current-work/complete/webappapis.html#queue-a-task" class="externalDFN">queue a task</a> to invoke <var>errorCallback</var>, if it is provided and is an object of type <code>Function</code>, with a new <a href="#navigatornetworkserviceerror"><code>NavigatorNetworkServiceError</code></a> object whose
   386                  <a href="#dom-navigatornetworkserviceerror-code"><code>code</code></a> attribute has the numeric value 1
   387                  (<a href="#dom-navigatornetworkserviceerror-permission_denied"><code>PERMISSION_DENIED_ERR</code></a>) as its argument, abort any remaining steps and return.
   388             </li>
   389 
   390             <li>
   391                   The <a>user agent</a> <em class="ct">MUST</em> prompt the user in a user-agent-specific manner for permission to provide the
   392                   <a href="http://www.whatwg.org/specs/web-apps/current-work/complete/browsers.html#entry-script" class="externalDFN">entry script</a>'s
   393                   <a href="http://www.whatwg.org/specs/web-apps/current-work/complete/origin-0.html#origin" class="externalDFN">origin</a> with an array of
   394                   <a href="#networkservice"><code>NetworkService</code></a> objects representing the user-authorized subset of <var>services found</var>.
   395 
   396                <p>
   397                   If the user grants permission to access one or more networked services then the <a>user agent</a> SHOULD include an
   398                   "ongoing local-network communication" indicator.
   399                </p>
   400 
   401                <p>If the user denies permission, then the <a>user agent</a> <em class="ct">MUST</em> <a href="http://www.whatwg.org/specs/web-apps/current-work/complete/webappapis.html#queue-a-task" class="externalDFN">queue a task</a> to invoke <var>errorCallback</var>, if it is provided and is an object of type <code>Function</code>, with a new <a href="#navigatornetworkserviceerror"><code>NavigatorNetworkServiceError</code></a> object whose
   402                 <a href="#dom-navigatornetworkserviceerror-code"><code>code</code></a> attribute has the numeric value 1
   403                 (<a href="#dom-navigatornetworkserviceerror-permission_denied"><code>PERMISSION_DENIED_ERR</code></a>) as its argument, abort any remaining steps and return.
   404               </p>
   405 
   406               <p>
   407                 If the user never responds, this algorithm stalls on this step.
   408               </p>
   409 
   410             </li>
   411 
   412             <li>
   413                Let <var>services</var> be the array of one or more <a href="#networkservice"><code>NetworkService</code></a> objects for which the user granted permission.
   414             </li>
   415 
   416             <li>
   417                For each Object <var>service</var> in <var>services</var>, run the following substeps:
   418 
   419                <ol class="rule">
   420                   <li>
   421                      Add the <var>service</var>'s <code>url</code> parameter to the <a>entry script origin's <abbr title="Uniform Resource Locator">URL</abbr> whitelist</a>.
   422                   </li>
   423                   <li>
   424                     If <var>service</var>'s <code>type</code> parameter begins with the DOMString &quot;<code>upnp:</code>&quot; and the <var>service</var>'s <code>eventsUrl</code> parameter is not empty then <a>setup a UPnP Events Subscription</a> for <var>service</var>.
   425                   </li>
   426                </ol>
   427             </li>
   428 
   429             <li>
   430                Let <var>services manager</var> be a new <a href="#networkservices"><code>NetworkServices</code></a> object.
   431             </li>
   432 
   433             <li>
   434                Set <var>services manager</var>'s <a href="#dom-networkservices-servicesavailable"><code>servicesAvailable</code></a> attribute to the number of services currently found in the <a>list of available service records</a> whose <code>type</code> property matches any of the tokens requested in <var>requested control types</var>.
   435             </li>
   436 
   437             <li>
   438               Add the set of <var>services</var> to the <a>list of authorized service records</a> internally against the newly created <var>services manager</var> object.
   439             </li>
   440 
   441             <li>
   442                The <a>user agent</a> <em class="ct">MUST</em> <a href="http://www.whatwg.org/specs/web-apps/current-work/complete/webappapis.html#queue-a-task" class="externalDFN">queue a task</a> to invoke <var>successCallback</var> with
   443                <var>services manager</var> as its argument.
   444             </li>
   445 
   446           </ol>
   447 
   448           <p>
   449             The <a href="http://www.whatwg.org/specs/web-apps/current-work/complete/webappapis.html#task-source" class="externalDFN">task source</a> for these
   450             <a href="http://www.whatwg.org/specs/web-apps/current-work/complete/webappapis.html#concept-task" class="externalDFN">tasks</a> is the
   451             <a href="http://www.whatwg.org/specs/web-apps/current-work/complete/webappapis.html#user-interaction-task-source" class="externalDFN">user interaction task source</a>.
   452           </p>
   453 
   454           <p>
   455             When a <a href="#networkservice"><code>NetworkService</code></a> object is provided to a Web page, the <a>user agent</a> <em class="ct">MUST</em> add the <code>url</code> property
   456              to the <dfn>entry script origin's URL whitelist</dfn>. This list enables the
   457             Web page to override and initiate cross-site resource requests towards these URLs, and any sub-resources of these URLs, within the current
   458             <a href="http://www.whatwg.org/specs/web-apps/current-work/complete/browsers.html#entry-script" class="externalDFN">entry script</a>'s
   459             <a href="http://www.whatwg.org/specs/web-apps/current-work/complete/origin-0.html#origin" class="externalDFN">origin</a> via various existing mechanisms (e.g. Web Sockets, Server-Sent Events,
   460             Web Messaging, XMLHttpRequest).
   461          </p>
   462 
   463          <p>
   464             If the user navigates away from the current browsing context, the <a>user agent</a> <em class="ct">MUST</em> remove all previously whitelisted urls from the <a>entry script origin's URL whitelist</a>.
   465             There is no persistence to network service selections provided to a web page. It is not possible to access a previously white-listed networked service without the necessary user authorization in all of the following cases:
   466             <ul>
   467               <li>If the current script is reloaded at any point in the same or different window.</li>
   468               <li>if the current script reinvokes the <a href="#dom-navigator-getnetworkservices"><code>getNetworkServices()</code></a> method at any point in its execution.</li>
   469               <li>If the user navigates forward or back in their history to reload the current page.</li>
   470               <li>If a script is running in a different origin.</li>
   471             </ul>
   472          </p>
   473 
   474       </div>
   475       </section>
   476 
   477       <section>
   478          <h3>Error Handling</h3>
   479 
   480       <dl class="domintro">
   481         <dt>
   482           <var title="">error</var>
   483            .
   484           <code title="dom-NavigatorNetworkServiceError-code">
   485             <a href="#dom-navigatornetworkserviceerror-code">code</a>
   486           </code>
   487         </dt>
   488         <dd>
   489           <p>
   490             Returns the current error's error code. At the current time, this will be <code>1</code> or <code>2</code>, for which the
   491             corresponding error constants
   492             <a href="#dom-navigatornetworkserviceerror-permission_denied"><code>PERMISSION_DENIED_ERR</code></a> and
   493             <a href="#dom-navigatornetworkserviceerror-unknown_type_prefix"><code>UNKNOWN_TYPE_PREFIX_ERR</code></a> are defined.
   494           </p>
   495         </dd>
   496       </dl>
   497 
   498          <p>
   499             The <dfn id="dom-navigatornetworkserviceerror-code" title="dom-navigatornetworkserviceerror-code"><code>code</code></dfn> attribute of a
   500             <a href="#navigatornetworkserviceerror"><code>NavigatorNetworkServiceError</code></a> object <em class="ct">MUST</em> return the code for the error, which will be one of the following:
   501          </p>
   502 
   503          <dl>
   504             <dt>
   505                <dfn id="dom-navigatornetworkserviceerror-permission_denied" title="dom-navigatornetworkserviceerror-permission_denied"><code>PERMISSION_DENIED_ERR</code></dfn> (numeric value 1)
   506             </dt>
   507             <dd>
   508                The user or user agent denied the page permission to access any services.
   509             </dd>
   510             <dt>
   511                <dfn id="dom-navigatornetworkserviceerror-unknown_type_prefix" title="dom-navigatornetworkserviceerror-unknown_type_prefix"><code>UNKNOWN_TYPE_PREFIX_ERR</code></dfn> (numeric value 2)
   512             </dt>
   513             <dd>
   514                No <a>valid service type</a> tokens were provided in the method invocation.
   515             </dd>
   516          </dl>
   517 
   518       </section>
   519 
   520       </section>
   521       <section>
   522       <h2>Obtaining networked services</h2>
   523 
   524       <p>
   525          The <a href="#networkservices"><code>NetworkServices</code></a> interface is the top-level response object from a call to <a href="#dom-navigator-getnetworkservices"><code>getNetworkServices()</code></a> and provides access to a set of user-authorized <a href="#networkservice"><code>NetworkService</code></a> objects for the given request.
   526       </p>
   527 
   528 <pre class="widl">
   529 [NoInterfaceObject]
   530 interface <dfn id="networkservices">NetworkServices</dfn> {
   531   readonly attribute unsigned long    <a href="#dom-networkservices-length">length</a>;
   532   getter <a href="#networkservice">NetworkService</a> (unsigned long index);
   533   <a href="#networkservice">NetworkService</a>? <a href="#dom-networkservices-getservicebyid">getServiceById</a>(DOMString id);
   534 
   535   readonly attribute unsigned long    <a href="#dom-networkservices-servicesavailable">servicesAvailable</a>;
   536 
   537   // event handler attributes
   538            attribute <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/webappapis.html#eventhandler" class="externalDFN">EventHandler</a>     <a href="#dom-networkservices-onserviceavailable">onserviceavailable</a>;
   539            attribute <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/webappapis.html#eventhandler" class="externalDFN">EventHandler</a>     <a href="#dom-networkservices-onserviceunavailable">onserviceunavailable</a>;
   540 
   541 };
   542 
   543 <a href="#networkservices">NetworkServices</a> implements <a href="http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#interface-eventtarget" class="externalDFN">EventTarget</a>;
   544 </pre>
   545 
   546       <section>
   547       <h2>Attributes</h2>
   548 
   549         <dl class="domintro">
   550           <dt>
   551             <code title="dom-networkservices-length">
   552               <a href="#dom-networkservices-length">length</a>
   553             </code>
   554           </dt>
   555           <dd>
   556             <p>
   557               Returns the current number of services belonging in the respective object's <a>list of authorized service records</a>.
   558             </p>
   559           </dd>
   560           <dt>
   561             <code title="dom-networkservices-servicesavailable">
   562               <a href="#dom-networkservices-servicesavailable">servicesAvailable</a>
   563             </code>
   564           </dt>
   565           <dd>
   566             <p>
   567               Returns the current number of services matching one of the app-requested <a>valid service type</a> tokens in the
   568               <a>list of available service records</a>.
   569             </p>
   570           </dd>
   571         </dl>
   572 
   573         <div>
   574            <p>
   575               The <dfn id="dom-networkservices-length"><code>length</code></dfn> attribute <em class="ct">MUST</em> return the number of services represented in the object's corresponding <a>list of authorized service records</a> at the time of getting.
   576            </p>
   577 
   578            <p>
   579               The <dfn id="dom-networkservices-servicesavailable"><code>servicesAvailable</code></dfn> attribute <em class="ct">MUST</em> return the number of services in the <a>list of available service records</a> whose <code>type</code> attribute matches any of the <a>valid service type</a> tokens that was initially used to create the current <a href="#networkservices"><code>NetworkServices</code></a> object.
   580            </p>
   581 
   582         </div>
   583 
   584       </section>
   585 
   586       <section>
   587       <h2>Methods</h2>
   588         <dl class="domintro">
   589         <dt>
   590           <code title="networkservices-getter">
   591             <a href="#networkservices">services</a>
   592           </code>
   593           [
   594           <var title="">index</var>
   595           ]
   596         </dt>
   597         <dd>
   598           <p>
   599             Returns the specified <a href="#networkservice"><code>NetworkService</code></a> object.
   600           </p>
   601         </dd>
   602         <dt>
   603           <code title="networkservices-getter">
   604             <a href="#networkservices">services</a>
   605           </code>
   606           .
   607           <code title="dom-networkservices-getservicebyid">
   608             <a href="#dom-networkservices-getservicebyid">getServiceById</a>
   609           </code>
   610           (
   611           <var title="">id</var>
   612           )
   613         </dt>
   614         <dd>
   615           <p>
   616             Returns the <a href="#networkservice"><code>NetworkService</code></a> object with the given identifier, or null if no
   617             service has that identifier.
   618           </p>
   619         </dd>
   620       </dl>
   621 
   622       <p>
   623         A <a href="#networkservices"><code>NetworkServices</code></a> object represents the current list of one or more current authorized services - the <a>list of authorized service records</a>. Each item in the <a>list of authorized service records</a> is represented by a <a href="#networkservice"><code>NetworkService</code></a> object. The <a>list of authorized service records</a> is <span>immutable</span> meaning that it cannot be modified for the lifetime of a <a href="#networkservices"><code>NetworkServices</code></a> object.
   624       </p>
   625 
   626       <p class="note">
   627         Each service in a <a href="#networkservices"><code>NetworkServices</code></a> object thus has an index; the first has the index 0, and each subsequent service is numbered one higher than the previous one.
   628       </p>
   629 
   630       <p>
   631         The <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/infrastructure.html#supported-property-indices" class="externalDFN">supported property indices</a> of <a href="#networkservices"><code>NetworkServices</code></a> objects at any instant are the numbers from zero to the number of items in the <a>list of authorized service records</a> represented by the respective object minus one, if any services are represented in the <a>list of authorized service records</a>.
   632       </p>
   633 
   634       <p>
   635         To <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/infrastructure.html#determine-the-value-of-an-indexed-property" class="externalDFN">determine the value of an indexed property</a> for a given index <var>index</var> in a <a href="#networkservices"><code>NetworkServices</code></a> object's <a>list of authorized service records</a>, the user agent <em class="ct">MUST</em> return the <a href="#networkservice"><code>NetworkService</code></a> object that represents the <var>index</var>th service in the <a>list of authorized service records</a>.
   636       </p>
   637 
   638       <p>
   639         The <dfn id="dom-networkservices-getservicebyid"><code>getServiceById(id)</code></dfn> method <em class="ct">MUST</em> return the first <a href="#networkservice"><code>NetworkService</code></a> object in the <a>list of authorized service records</a> represented by the respective object whose <a href="#dom-networkservice-id"><code>id</code></a> attribute is equal to the value of the <var>id</var> argument.
   640         When no services in the <a>list of authorized service records</a> match the given argument, the method <em class="ct">MUST</em> return null.
   641       </p>
   642 
   643       <p>
   644          Services available within the local network can connect and disconnect at different times during the execution of a web page. A <a>user agent</a> can
   645          inform a web page when the state of networked services matching the requested <a>valid service type</a> change. Web pages can use this information to enable in-page experiences for communicating the state of networked services
   646          with the ability to change the particular service or set of services the page is connected to by re-invoking the <a href="#dom-navigator-getnetworkservices"><code>getNetworkServices()</code></a> method.
   647       </p>
   648 
   649       </section>
   650 
   651       <section>
   652       <h2>Events</h2>
   653 
   654       <p>
   655          The following are the event handlers (and their corresponding event handler event types) that <em class="ct">MUST</em> be supported, as IDL attributes, by all objects implementing the <a href="#networkservices"><code>NetworkServices</code></a> interface:
   656        </p>
   657 
   658        <table border="1">
   659         <thead>
   660           <tr>
   661             <th>
   662               <span title="event handlers">Event handler</span>
   663             </th>
   664             <th>
   665               <span>Event handler event type</span>
   666             </th>
   667           </tr>
   668         </thead>
   669         <tbody>
   670           <tr>
   671             <td>
   672               <dfn id="dom-networkservices-onserviceavailable" title="dom-NetworkServices-onserviceavailable">
   673                 <code>onserviceavailable</code>
   674               </dfn>
   675             </td>
   676             <td>
   677               <a href="#event-serviceavailable"><code>serviceavailable</code>
   678             </td>
   679           </tr>
   680           <tr>
   681             <td>
   682               <dfn id="dom-networkservices-onserviceunavailable" title="dom-NetworkServices-onserviceunavailable">
   683                 <code>onserviceunavailable</code>
   684               </dfn>
   685             </td>
   686             <td>
   687               <a href="#event-serviceunavailable"><code>serviceunavailable</code></a>
   688             </td>
   689           </tr>
   690         </tbody>
   691       </table>
   692 
   693       </section>
   694 
   695     </section>
   696     <section>
   697     <h2>Communicating with a networked service</h3>
   698 
   699 <p>
   700    The <a href="#networkservice"><code>NetworkService</code></a> interface is used to provide a set of connection information for an HTTP service endpoint and if available, service events, running on a networked device.
   701 </p>
   702 
   703 <pre class="widl">
   704 [NoInterfaceObject]
   705 interface <dfn id="networkservice">NetworkService</dfn> {
   706   readonly attribute DOMString        <a href="#dom-networkservice-id">id</a>;
   707   readonly attribute DOMString        <a href="#dom-networkservice-name">name</a>;
   708   readonly attribute DOMString        <a href="#dom-networkservice-type">type</a>;
   709   readonly attribute DOMString        <a href="#dom-networkservice-url">url</a>;
   710   readonly attribute DOMString        <a href="#dom-networkservice-config">config</a>;
   711 
   712   readonly attribute boolean          <a href="#dom-networkservice-online">online</a>;
   713 
   714   // event handler attributes
   715            attribute <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/webappapis.html#eventhandler" class="externalDFN">EventHandler</a>     <a href="#dom-networkservice-onserviceonline">onserviceonline</a>;
   716            attribute <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/webappapis.html#eventhandler" class="externalDFN">EventHandler</a>     <a href="#dom-networkservice-onserviceoffline">onserviceoffline</a>;
   717 
   718            attribute <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/webappapis.html#eventhandler" class="externalDFN">EventHandler</a>     <a href="#dom-networkservice-onnotify">onnotify</a>;
   719 };
   720 
   721 <a href="#networkservice">NetworkService</a> implements <a href="http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#interface-eventtarget" class="externalDFN">EventTarget</a>;
   722 </pre>
   723 
   724 <section>
   725   <h2>Attributes</h2>
   726 
   727       <dl class="domintro">
   728         <dt>
   729           <var title="">service</var>
   730            .
   731           <code title="dom-networkservice-id">
   732             <a href="#dom-networkservice-id">id</a>
   733           </code>
   734         </dt>
   735         <dd>
   736           <p>
   737             A unique identifier for the given user-selected service instance.
   738           </p>
   739         </dd>
   740         <dt>
   741           <var title="">service</var>
   742            .
   743           <code title="dom-networkservice-name">
   744             <a href="#dom-networkservice-name">name</a>
   745           </code>
   746         </dt>
   747         <dd>
   748           <p>
   749             The name of the user-selected service.
   750           </p>
   751         </dd>
   752         <dt>
   753           <var title="">service</var>
   754            .
   755           <code title="dom-networkservice-type">
   756             <a href="#dom-networkservice-type">type</a>
   757           </code>
   758         </dt>
   759         <dd>
   760           <p>
   761             The <a>valid service type</a> token value of the user-selected service.
   762           </p>
   763         </dd>
   764         <dt>
   765           <var title="">service</var>
   766            .
   767           <code title="dom-networkservice-url">
   768             <a href="#dom-networkservice-url">url</a>
   769           </code>
   770         </dt>
   771         <dd>
   772           <p>
   773             The control URL endpoint (including any required port information) of the user-selected control service that has been added to the <a>entry script origin's URL whitelist</a>.
   774           </p>
   775         </dd>
   776         <dt>
   777           <var title="">service</var>
   778            .
   779           <code title="dom-networkservice-config">
   780             <a href="#dom-networkservice-config">config</a>
   781           </code>
   782         </dt>
   783         <dd>
   784           <p>
   785             The configuration information associated with the service depending on the requested service type.
   786           </p>
   787         </dd>
   788       </dl>
   789 
   790           <p>
   791             The <dfn id="dom-networkservice-id"><code>id</code></dfn> attribute is a unique identifier for the service. The same service provided at different times or on different objects <em class="ct">MUST</em> have the same <a href="#dom-networkservice-id"><code>id</code></a> value.
   792          </p>
   793 
   794          <p>
   795             The <dfn id="dom-networkservice-name"><code>name</code></dfn> attribute represents a human-readable title for the service.
   796          </p>
   797 
   798          <p>
   799              The <dfn id="dom-networkservice-type"><code>type</code></dfn> attribute reflects the value of the <a>valid service type</a> of the service.
   800           </p>
   801 
   802          <p>
   803             The <dfn id="dom-networkservice-url"><code>url</code></dfn> attribute is an <a href="http://www.w3.org/TR/html5/urls.html#absolute-url" class="externalDFN">absolute URL</a> pointing to the root HTTP
   804             endpoint for the service that has been added to the <a>entry script origin's URL whitelist</a>. Web pages can subsequently use this value for implicit cross-document messaging via various existing mechanisms (e.g. Web Sockets, Server-Sent Events, Web Messaging, XMLHttpRequest).
   805          </p>
   806 
   807          <p>
   808             The <dfn id="dom-networkservice-config"><code>config</code></dfn> attribute provides the raw configuration information extracted from the given network service.
   809          </p>
   810 
   811       </section>
   812 
   813       <section>
   814          <h3>States</h3>
   815 
   816       <dl class="domintro">
   817         <dt>
   818           <var title="">service</var>
   819            .
   820           <code title="dom-networkservice-online">
   821             <a href="#dom-networkservice-online">online</a>
   822           </code>
   823         </dt>
   824         <dd>
   825           <p>
   826             Returns <code>true</code> if the service is reporting that it is accessible on the local network or <code>false</code> if the service is reporting that it is no longer accessible (temporarily or permanently) on the local network.
   827           </p>
   828         </dd>
   829       </dl>
   830 
   831       <p>
   832         The <dfn id="dom-networkservice-online"><code>online</code></dfn> attribute indicates whether the service is reporting itself as being
   833         either <var>online</var>, and therefore accessible on the local network, in which case this attribute will return <code>true</code> or, <var>offline</var>, and therefore not accessible on the local network, either temporarily or permanently, in which case this attribute will return <code>false</code>. This attribute <em class="ct">MUST</em> default to <code>true</code>.
   834       </p>
   835 
   836       </section>
   837 
   838       <section>
   839          <h3>Events</h3>
   840 
   841       <p>
   842          The following are the event handlers (and their corresponding event handler event types) that <em class="ct">MUST</em> be supported, as IDL attributes, by all objects implementing the
   843          <a href="#networkservice"><code>NetworkService</code></a> interface:
   844        </p>
   845 
   846        <table border="1">
   847         <thead>
   848           <tr>
   849             <th>
   850               <span title="event handlers">Event handler</span>
   851             </th>
   852             <th>
   853               <span>Event handler event type</span>
   854             </th>
   855           </tr>
   856         </thead>
   857         <tbody>
   858           <tr>
   859             <td>
   860               <dfn id="dom-networkservice-onnotify" title="dom-NetworkService-onnotify">
   861                 <code>onnotify</code>
   862               </dfn>
   863             </td>
   864             <td>
   865               <a href="#event-notify"><code>notify</code></a>
   866             </td>
   867           </tr>
   868           <tr>
   869             <td>
   870               <dfn id="dom-networkservice-onserviceonline" title="dom-NetworkService-onserviceonline">
   871                 <code>onserviceonline</code>
   872               </dfn>
   873             </td>
   874             <td>
   875               <a href="#event-serviceonline"><code>serviceonline</code></a>
   876             </td>
   877           </tr>
   878           <tr>
   879             <td>
   880               <dfn id="dom-networkservice-onserviceoffline" title="dom-NetworkService-onserviceoffline">
   881                 <code>onserviceoffline</code>
   882               </dfn>
   883             </td>
   884             <td>
   885               <a href="#event-serviceoffline"><code>serviceoffline</code></a>
   886             </td>
   887           </tr>
   888         </tbody>
   889       </table>
   890 
   891       </section>
   892    </section>
   893 
   894       <section>
   895             <h2>Service Discovery</h2>
   896 
   897       <p>
   898          A <a>user agent</a> conforming to this specification <em class="ct">MAY</em> implement <acronym title="Simple Service Discovery Protocol">SSDP</acronym> [[!UPNP-DEVICEARCH11]] and Zeroconf [[!DNS-SD]] + [[!MDNS]] service discovery mechanisms
   899          to enable Web pages to request and connect with HTTP services running on networked devices, discovered via either mechanism, through this API. When a <a>user agent</a> implements either of these service discovery mechanisms, then it <em class="ct">MUST</em> conform to the corresponding algorithms provided in this section of the specification.
   900       </p>
   901       <p>
   902          This section presents how the results of these two service discovery
   903          mechanisms will be matched to requested service types, how the user agent stores available and active services, how their properties are applied to any resulting <a href="#networkservice"><code>NetworkService</code></a> objects.
   904       </p>
   905 
   906       <p>
   907          It is expected that user agents will perform these service discovery mechansisms asynchronously and periodically update the <a>list of networked devices</a> as required. The timing of any
   908          service discovery mechanisms is an implementation detail left to the discretion of the implementer (e.g. once on user agent start-up, every X seconds during user agent execution or on
   909          invocation of this API from a Web page).
   910       </p>
   911 
   912       <p>
   913          The <dfn>list of available service records</dfn> is a single dynamic internal lookup table within user agents that is used to track all the  services that have been discovered and are available in the current network at any given time.
   914          At any point during the running of either of the two service discovery mechanisms then existing entries within this table can be updated, entries can be added and entries can be removed as the status of networked
   915          services changes according to the rules defined in this specification.
   916       </p>
   917 
   918       <p>
   919         The <dfn>list of authorized service records</dfn> is a single dynamic internal lookup table within user agents that is used to track the
   920         current services that are being shared with web pages at any given time from the <a>list of available service records</a>. Each record in the <a>list of authorized service records</a> is associated with a <var>services manager</var> object that is assigned as part of the
   921          <a href="#dom-navigator-getnetworkservices"><code>getNetworkServices()</code></a> algorithm.
   922       </p>
   923 
   924       <p>
   925         The rule for <dfn>adding an available service</dfn> is the process of adding a new service or updating an existing service in the <a>list of available service records</a> that is generally available on the user's current network. This rule takes one argument, <var>network service record</var>, and consists of
   926         running the following steps:
   927       </p>
   928 
   929       <ol class="rule">
   930 
   931         <li>
   932           Let <var>new service registration flag</var> be <code>true</code>.
   933         </li>
   934 
   935         <li>
   936            For each <var>existing service record</var> in the current <a>list of available service records</a>, run the following sub-steps:
   937            <ol class="rule">
   938 
   939              <li>
   940               If the <var>existing service record</var>'s <code>id</code> property does not equal <var>network service record</var>'s <code>id</code>
   941                property then abort any remaining sub-steps and continue at the next available <var>existing service record</var>.
   942              </li>
   943 
   944              <li>
   945               Set <var>new service registration flag</var> to <code>false</code>.
   946              </li>
   947 
   948              <li>
   949                Replace the value of <var>existing service record</var> in the current <a>list of available service records</a> with the value of
   950               <var>network service record</var>.
   951              </li>
   952            </ol>
   953         </li>
   954 
   955         <li>
   956            If <var>new service registration flag</var> is set to <code>true</code> then add <var>network service record</var> to the <a>list of available service records</a> as a new entry.
   957         </li>
   958 
   959         <li>
   960           For each <var>active service</var> in the <a>list of authorized service records</a> run the following steps:
   961 
   962           <ol class="rule">
   963 
   964             <li>
   965                If <var>network service record</var>'s <code>type</code> property does not equal the current <var>active service</var>'s
   966                 <code>type</code> attribute then abort any remaining sub-steps for this <var>active service</var> and continue at the next available <var>active service</var>.
   967             </li>
   968 
   969             <li>
   970                If the <var>new service registration flag</var> is set to <code>true</code> then increment the <a href="#dom-networkservices-servicesavailable"><code>servicesAvailable</code></a> attribute of the <var>services manager</var> associated with
   971                the current <var>active service</var>
   972                 object by <code>1</code> and then <a href="http://www.whatwg.org/specs/web-apps/current-work/complete/webappapis.html#queue-a-task" class="externalDFN">queue a task</a>
   973                  to dispatch a newly created event with the name <a href="#event-serviceavailable"><code>serviceavailable</code></a> that uses the <a href="http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#event" class="externalDFN"><code>Event</code></a> interface,
   974                  which does not bubble, is not cancellable, and has no default action, at the <var>services manager</var> associated with
   975                  the current <var>active service</var> object.
   976             </li>
   977 
   978             <li>
   979                Set <var>active service</var>'s <a href="#dom-networkservice-online"><code>online</code></a> attribute to <code>true</code> and then
   980                <a href="http://www.whatwg.org/specs/web-apps/current-work/complete/webappapis.html#queue-a-task" class="externalDFN">queue a task</a>
   981                 to dispatch a newly created event with the name <a href="#event-serviceonline"><code>serviceonline</code></a> that uses the
   982                 <a href="http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#event" class="externalDFN"><code>Event</code></a> interface, which
   983                  does not bubble, is not cancellable, and has no default action, at the current
   984                 <var>active service</var> object.
   985             </li>
   986 
   987           </ol>
   988 
   989         </li>
   990 
   991       </ol>
   992 
   993 
   994       <p>
   995         The rule for <dfn>removing an available service</dfn> is the general process of removing a service from the
   996         <a>list of available service records</a>
   997          that has left the user's current network or has otherwise expired. This rule takes one argument, <var>service identifier</var>, and consists of running the following steps:</p>
   998 
   999       <ol class="rule">
  1000 
  1001         <li>
  1002            For each <var>existing service record</var> in the current <a>list of available service records</a>, run the following sub-steps:
  1003            <ol class="rule">
  1004 
  1005              <li>
  1006               If the <var>existing service record</var>'s <code>id</code> property does not match <var>service identifier</var> then skip any remaining sub-steps for the current <var>existing service record</var> and continue at the next available <var>existing service record</var>.
  1007              </li>
  1008 
  1009              <li>
  1010                If the <var>existing service record</var>'s <code>type</code> property begins with the DOMString "<code>upnp:</code>" and
  1011                <var>existing service record</var>'s <code>eventsURL</code> property is set then run the rule to
  1012                <a>terminate an existing UPnP Events Subscription</a>, if one is currently active (as a result of having previously called
  1013                <a>setup a UPnP Events Subscription</a> against the current <var>existing service record</var>).
  1014              </li>
  1015 
  1016              <li>
  1017                For each <var>active service</var> in <a>list of authorized service records</a> run the following steps:
  1018 
  1019                <ol class="rule">
  1020 
  1021                  <li>
  1022                     If <var>existing service record</var>'s <code>type</code> property does not equal the current <var>active service</var>'s
  1023                      <code>type</code> attribute then abort any remaining sub-steps for this <var>active service</var> and continue at the next available <var>active service</var>.
  1024                  </li>
  1025 
  1026                  <li>
  1027                     Decrement the <a href="#dom-networkservices-servicesavailable"><code>servicesAvailable</code></a> attribute of the
  1028                     <var>services manager</var> associated with the current <var>active service</var>
  1029                      object by <code>1</code> and then <a href="http://www.whatwg.org/specs/web-apps/current-work/complete/webappapis.html#queue-a-task" class="externalDFN">queue a task</a>
  1030                       to dispatch a newly created event with the name <a href="#event-serviceunavailable"><code>serviceunavailable</code></a> that uses the
  1031                       <a href="http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#event" class="externalDFN"><code>Event</code></a> interface,
  1032                       which does not bubble, is not cancellable, and has no default action, at the <var>services manager</var> associated with
  1033                       the current <var>active service</var> object.
  1034                  </li>
  1035 
  1036                  <li>
  1037                     Set <var>active service</var>'s <a href="#dom-networkservice-online"><code>online</code></a> attribute to <code>false</code> and then
  1038                     <a href="http://www.whatwg.org/specs/web-apps/current-work/complete/webappapis.html#queue-a-task" class="externalDFN">queue a task</a>
  1039                      to dispatch a newly created event with the name <a href="#event-serviceoffline"><code>serviceoffline</code></a> that uses the
  1040                      <a href="http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#event" class="externalDFN"><code>Event</code></a> interface, which
  1041                       does not bubble, is not cancellable, and has no default action, at the current
  1042                      <var>active service</var> object.
  1043                  </li>
  1044 
  1045                </ol>
  1046 
  1047              </li>
  1048 
  1049              <li>
  1050                Remove <var>existing service record</var> from the current <a>list of available service records</a>.
  1051              </li>
  1052 
  1053            </ol>
  1054         </li>
  1055 
  1056       </ol>
  1057 
  1058       <p>
  1059        User agents <em class="ct">SHOULD</em> expire a service record from the <a>list of available service records</a> when its
  1060        <code>expiryTimestamp</code> attribute exceeds the current UTC timestamp. When this condition is met the <a>user agent</a> SHOULD
  1061        run the rule for <a>removing an available service</a>, passing in the expired service record's <code>id</code> attribute as the
  1062        only argument.
  1063       </p>
  1064 
  1065 
  1066       <section>
  1067          <h4>Zeroconf (<abbr title="Multicast DNS">mDNS</abbr> + <abbr title="Domain Name System">DNS</abbr>-<abbr title="Service Discovery">SD</abbr>)</h4>
  1068 
  1069          <p>
  1070             For each DNS response received from a user-agent-initiated Multicast DNS Browse for <abbr title="DNS Pointer Record">PTR</abbr> records with the name <code>_services._dns-sd._udp</code> on the resolved recommended automatic browsing
  1071    domain [[!MDNS]], the <a>user agent</a> <em class="ct">MUST</em> run the following steps:
  1072          </p>
  1073 
  1074          <ol class="rule">
  1075 
  1076             <li>Let <var>service mDNS responses</var> be an array of PTR records received by issuing a Multicast DNS Browse for PTR records with the name of the current discovered service type.</li>
  1077 
  1078             <li>For each Object <var>service mDNS response</var> in <var>service mDNS responses</var>, run the following steps:
  1079                <ol>
  1080 
  1081                   <li>
  1082                      Let <var>network service record</var> be an Object consisting of the following empty properties: <code>id</code>, <code>name</code>, <code>type</code>, <code>url</code>, <code>config</code>, <code>expiryTimestamp</code>.
  1083                   </li>
  1084 
  1085                   <li>
  1086                      Set <var>network service record</var>'s <code>id</code> property to the value of the full PTR Service Instance Name [[!MDNS]].
  1087                   </li>
  1088 
  1089                   <li>
  1090                      Set <var>network service record</var>'s <code>name</code> property to the value of the PTR Service Instance Name's <var>Instance</var> component [[!MDNS]].
  1091                   </li>
  1092 
  1093                   <li>
  1094                      Set <var>network service record</var>'s <code>type</code> property to the concatenation of the string <code>zeroconf:</code> followed be the value of the PTR Service Instance Name's <var>Service</var> component [[!MDNS]].
  1095                   </li>
  1096 
  1097                   <li>
  1098                      Set <var>network service record</var>'s <code>url</code> property to the resolvable Service URL obtained from performing an DNS-SD Lookup [[!DNS-SD]] of the current service from the PTR record provided [[!MDNS]].
  1099                   </li>
  1100 
  1101                   <li>
  1102                      Set <var>network service record</var>'s <code>config</code> property to the string value of the contents of the first DNS-SD TXT record associated with the <var>service mDNS response</var> as defined in [[!DNS-SD]].
  1103                   </li>
  1104 
  1105                   <li>
  1106                      Set <var>network service record</var>'s <code>expiryTimestamp</code> property to the value of the current date, in UTC timestamp format, plus a value of <code>120</code> seconds.
  1107                   </li>
  1108 
  1109                   <li>
  1110                      Run the general rule for <a>adding an available service</a>, passing in the current <var>network service record</var> as the
  1111                      only argument.
  1112                   </li>
  1113 
  1114             </ol>
  1115            </li>
  1116          </ol>
  1117 
  1118       </section>
  1119 
  1120       <section>
  1121          <h5>Simple Service Discovery Protocol (<abbr title="Simple Service Discovery Protocol">SSDP</abbr>)</h5>
  1122 
  1123          <p>
  1124           A user agent that implements UPnP service discovery <em class="ct">MUST</em> issue an <dfn>advertisement for UPnP root devices</dfn> against the user's
  1125           current local network according to the full normative text and timing provided in 'Section 1.3.2: Search request with M-SEARCH' detailed in [[!UPNP-DEVICEARCH11]].
  1126           </p>
  1127 
  1128           <p>
  1129             The user agent <em class="ct">MUST</em> issue all <a title="advertisement for UPnP root devices">advertisements for UPnP root devices</a> with a HTTP request line equal to <code>M-SEARCH * HTTP/1.1</code>, with a HOST header equal to the reserved multicast address and port of <code>239.255.255.250:1900</code>, a MAN header equal to <code>ssdp:discover</code>, an ST header equal to <code>upnp:rootdevice</code> and a user-agent defined MX header equal to a <dfn>maximum UPnP advertisement response wait time</dfn> value between <code>1</code> and <code>5</code> seconds.
  1130          </p>
  1131 
  1132          <p>
  1133           The user agent <em class="ct">MUST</em> listen for incoming requests and process any incoming responses to any <a>advertisement for UPnP root devices</a> on the <dfn>standard UPnP address and port</dfn>, on all current local network interface addresses with the port <code>1900</code>, according to the rules defined in this section.
  1134          </p>
  1135 
  1136          <p>
  1137           For each <dfn>HTTP Response</dfn> following an initial <a>advertisement for UPnP root devices</a> sent on a <a>standard UPnP address
  1138             and port</a> the user agent <em class="ct">MUST</em> run the following steps:
  1139          </p>
  1140 
  1141          <ol class="rule">
  1142           <li>
  1143             If the <a>HTTP Response</a> is not a HTTP 200 OK response then this response is invalid and the user agent <em class="ct">MUST</em> discard this response, abort any remaining steps and return. The user agent <em class="ct">MAY</em> issue a new <a>advertisement for UPnP root devices</a> as a result of this error occurring.
  1144           </li>
  1145 
  1146           <li>
  1147             If the <a>maximum UPnP advertisement response wait time</a> has been exceeded since the initial <a>advertisement for UPnP root devices</a> was sent then the <a>HTTP Response</a> is invalid and the user agent <em class="ct">MUST</em> discard this response, abort any remaining steps and return.
  1148           </li>
  1149 
  1150           <li>
  1151              Let <var>ssdp device</var> be an Object with a property for each HTTP header received in the <a>HTTP Response</a>, with each key being the name of a HTTP response header and each value being that HTTP response header's value.
  1152           </li>
  1153 
  1154           <li>
  1155             If <var>ssdp device</var> does not contain at least one <var>CACHE-CONTROL</var> entry, at least one <var>USN</var> entry, at least one <var>ST</var> entry and at least one <var>LOCATION</var> entry or the value of its <var>ST</var> entry is not <code>upnp:rootdevice</code>, then the <a>HTTP Response</a> is invalid and the <a>user agent</a> <em class="ct">MUST</em> discard this response, abort any remaining steps and return.
  1156           </li>
  1157 
  1158           <li>
  1159             The user agent <em class="ct">MUST</em> run the rule for <a>obtaining a UPnP Device Description File</a> passing in the first occurrence of <var>LOCATION</var> from <var>ssdp device</var> as the <var>device descriptor URL</var> argument and the first occurrence of <var>USN</var> from <var>ssdp device</var> as the <var>device identifier</var> argument and the first occurrence of <var>CACHE-CONTROL</var> from <var>ssdp device</var> as the <var>device expiry</var> argument.
  1160           </li>
  1161 
  1162         </ol>
  1163 
  1164         <p>
  1165           For each <dfn>HTTP Request</dfn> received on a <a>standard UPnP address and port</a> the user agent <em class="ct">MUST</em> run the following steps:
  1166          </p>
  1167 
  1168         <ol class="rule">
  1169 
  1170           <li>
  1171             If the <a>HTTP Request</a> is not a HTTP NOTIFY request then it is not a valid UPnP Request and the user agent <em class="ct">MUST</em> return a HTTP 200 OK response, discard this request, abort any remaining steps and return.
  1172           </li>
  1173 
  1174           <li>
  1175              Let <var>ssdp device</var> be an Object with a property for each HTTP header received in the <a>HTTP Request</a>, with each key being the name of a HTTP header and each value being that HTTP header's value.
  1176           </li>
  1177 
  1178           <li>
  1179             If <var>ssdp device</var> does not contain at least one <var>CACHE-CONTROL</var> entry, at least one <var>USN</var> entry, at least one <var>NT</var> entry, at least one <var>NTS</var> entry and at least one <var>LOCATION</var> entry or the value of its <var>NT</var> entry is not <code>upnp:rootdevice</code>, then the <a>HTTP Request</a> is a malformed UPnP Request and the <a>user agent</a> <em class="ct">MUST</em> return a 400 Bad Request response, discard this request, abort any remaining steps and return.
  1180           </li>
  1181 
  1182           <li>
  1183             If <var>ssdp device</var>'s <var>NTS</var> entry is equal to <code>ssdp:alive</code> or <code>ssdp:update</code> then the user agent <em class="ct">MUST</em> run the rule for <a>obtaining a UPnP Device Description File</a> passing in the first occurrence of <var>LOCATION</var> from <var>ssdp device</var> as the <var>device descriptor URL</var> argument and the first occurrence of <var>USN</var> from <var>ssdp device</var> as the <var>device identifier</var> argument and the first occurrence of <var>CACHE-CONTROL</var> from <var>ssdp device</var> as the <var>device expiry</var>. <br/><br/>Otherwise, if <var>ssdp device</var>'s <var>NTS</var> entry is equal to <code>ssdp:byebye</code> then the user agent <em class="ct">MUST</em> run the rule for <a>removing all services from a registered UPnP Device</a> passing in the first occurrence of <var>USN</var> from <var>ssdp device</var> as the <var>device identifier</var> argument.
  1184           </li>
  1185 
  1186         </ol>
  1187 
  1188       <p>
  1189         The rule for <dfn>obtaining a UPnP Device Description File</dfn> is the process of obtaining the contents of a standard UPnP Device Description [[!UPNP-DEVICEARCH11]] from a URL-based resource. This rule takes three arguments - <var>device descriptor URL</var>, <var>device identifier</var> and <var>device expiry</var> - and when called the user agent <em class="ct">MUST</em> run the following steps:
  1190       </p>
  1191 
  1192       <ol class="rule">
  1193 
  1194           <li>
  1195              Let <var>device descriptor file</var> contain the contents of the file located at the URL provided in <var>device descriptor URL</var> obtained according to the rules
  1196              defined in 'Section 2.11: Retrieving a description using HTTP' in [[!UPNP-DEVICEARCH11]].
  1197           </li>
  1198 
  1199           <li>
  1200             If the value provided in <var>device descriptor URL</var> cannot be resolved as a reachable URL on the current network or the <var>root device descriptor file</var> remains empty then it is invalid and the <a>user agent</a> <em class="ct">MUST</em> abort any remaining steps and return.
  1201           </li>
  1202 
  1203           <li>
  1204             Run the rule for <a>processing a UPnP Device Description File</a>, passing in the current <var>device descriptor file</var>, <var>device identifier</var> and <var>device expiry</var> arguments.
  1205           </li>
  1206 
  1207           <li>
  1208             If the current <var>device descriptor file</var> contains a <code>&lt;deviceList&gt;</code> element then for each <code>&lt;device&gt;</code> element within <code>&lt;deviceList&gt;</code> - herein known as an <var>embedded device descriptor file</var> - the user agent <em class="ct">MUST</em>
  1209             run the rule for <a>processing a UPnP Device Description File</a>, passing in the current <var>embedded device descriptor file</var> as the <var>device descriptor file</var> argument, along with the common <var>device identifier</var> and <var>device expiry</var> arguments.
  1210           </li>
  1211 
  1212       </ol>
  1213 
  1214       <p>
  1215         The rule for <dfn>processing a UPnP Device Description File</dfn> is the process of parsing the contents of a standard UPnP Device Description [[!UPNP-DEVICEARCH11]] and
  1216         registering the UPnP services contained therein within the <a>list of available service records</a>.
  1217       </p>
  1218 
  1219       <p>The rule for <a>processing a UPnP Device Description File</a> takes three arguments - <var>device descriptor file</var>, <var>device identifier</var> and <var>device expiry</var> - and when called the user
  1220          agent <em class="ct">MUST</em> run the following steps:</p>
  1221 
  1222       <ol class="rule">
  1223 
  1224           <li>
  1225              Let <var>advertised services</var> be a list of all advertised services obtained from the <var>device descriptor file</var> containing the value of the first occurrence of the <code>&lt;serviceList&gt;</code> element as it is defined in 'Section 2.3: Device Description' in [[!UPNP-DEVICEARCH11]].
  1226           </li>
  1227 
  1228           <li>
  1229              For each <code>&lt;service&gt;</code> element - known as an <var>advertised service</var> - in <var>advertised services</var> run the following steps:
  1230 
  1231              <ol class="rule">
  1232 
  1233                 <li>
  1234                    Let <var>network service record</var> be a new Object consisting of the following empty properties: <code>id</code>, <code>deviceId</code>, <code>name</code>, <code>type</code>, <code>url</code>, <code>eventsUrl</code>, <code>config</code>, <code>expiryTimestamp</code>.
  1235                 </li>
  1236 
  1237                 <li>
  1238                    Set <var>network service record</var>'s <code>id</code> property to the concatenated string value of <var>device identifier</var> with the <var>advertised service</var>'s <code>&lt;serviceId&gt;</code> sub-element.
  1239                 </li>
  1240 
  1241                 <li>
  1242                    Set <var>network service record</var>'s <code>deviceId</code> property to the value of <var>device identifier</var>.
  1243                 </li>
  1244 
  1245                 <li>
  1246                    Set <var>network service record</var>'s <code>name</code> property to the string value of the first occurrence of the <var>advertised service</var>'s <code>&lt;serviceId&gt;</code> sub-element.
  1247                 </li>
  1248 
  1249                 <li>
  1250                    Set <var>network service record</var>'s <code>type</code> property to the concatenation of the string <code>upnp:</code> followed by the string value of the first occurrence of the <var>advertised service</var>'s <code>&lt;serviceType&gt;</code> sub-element.
  1251                 </li>
  1252 
  1253                 <li>
  1254                    Set <var>network service record</var>'s <code>url</code> property to the string value of the first occurrence of the <var>advertised service</var>'s <code>&lt;controlURL&gt;</code> sub-element.
  1255                 </li>
  1256 
  1257                 <li>
  1258                    Set <var>network service record</var>'s <code>config</code> property to the string value of the contents of the first occurrence of the <code>&lt;device&gt;</code> element in the <var>device descriptor file</var>.
  1259                 </li>
  1260 
  1261                 <li>
  1262                    If <var>advertised service</var>'s <code>&lt;eventSubURL&gt;</code> sub-element is not empty, then set <var>network service record</var>'s <code>eventsUrl</code> property to the string value of the first occurrence of the <var>advertised service</var>'s <code>&lt;eventSubURL&gt;</code> sub-element. Otherwise, do not set <var>network service record</var>'s <code>eventsUrl</code> property.
  1263                 </li>
  1264 
  1265                 <li>
  1266                    Set <var>network service record</var>'s <code>expiryTimestamp</code> property to the value of the current date, in UTC timestamp format, plus the value of <var>device expiry</var>.
  1267                 </li>
  1268 
  1269                 <li>
  1270                   Run the general rule for <a>adding an available service</a>, passing in the current <var>network service record</var> as the only argument.
  1271                 </li>
  1272 
  1273               </ol>
  1274 
  1275           </ol>
  1276 
  1277          <p>
  1278            The rule for <dfn>removing all services from a registered UPnP Device</dfn> is the process of removing all services associated with a
  1279            device from the <a>list of available service records</a> that has left the user's current network or has otherwise timed out or expired.
  1280            This rule takes one argument, <var>device identifier</var>, and consists of running the following steps:
  1281         </p>
  1282 
  1283          <ol class="rule">
  1284 
  1285            <li>
  1286               For each <var>existing service record</var> in the current <a>list of available service records</a>, run the following sub-steps:
  1287               <ol class="rule">
  1288 
  1289                 <li>
  1290                  If the <var>existing service record</var>'s <code>deviceId</code> property does not match <var>device identifier</var> then skip any remaining sub-steps for the current <var>existing service record</var> and continue at the next available <var>existing service record</var>.
  1291                 </li>
  1292 
  1293                 <li>
  1294                   Run the general rule for <a>removing an available service</a> passing in <var>existing service record</var>'s <code>id</code>
  1295                   property as the only argument.
  1296                 </li>
  1297 
  1298               </ol>
  1299            </li>
  1300 
  1301          </ol>
  1302 
  1303          <p>When the <a>user agent</a> is to <dfn>setup a UPnP Events Subscription</dfn>, it is to run the following steps with the current <var>network service record</var> object as defined in 'Section 4.1.2: SUBSCRIBE with NT and CALLBACK' in [[!UPNP-DEVICEARCH11]]:</p>
  1304 
  1305          <ol class="rule">
  1306             <li>
  1307                If <var>network service record</var>'s <code>eventsUrl</code> property is empty then the <a>user agent</a> <em class="ct">MUST</em> abort these steps.
  1308             </li>
  1309 
  1310             <li>
  1311                Let <var>callback URL</var> be the value of creating a new <a>user-agent generated callback url</a>.
  1312             </li>
  1313 
  1314             <li>
  1315                Send a HTTP SUBSCRIBE request with a <em>NT</em> header with a string value of <code>upnp:event</code>, a <em>TIMEOUT</em> header with a user-agent defined timeout value (in the form <code>Second-XX</code> where <code>XX</code> is the user-agent defined timeout value in seconds) and a <em>CALLBACK</em> header
  1316                with a string value of <var>callback URL</var> towards the <var>network service record</var>'s <code>eventsUrl</code> property.
  1317             </li>
  1318 
  1319             <li>
  1320                If a non-200 OK response is received from the HTTP SUBSCRIBE request then the <a>user agent</a> <em class="ct">MUST</em> abort these steps.
  1321             </li>
  1322 
  1323             <li>
  1324                On receiving a valid 200 OK response, run the following steps:
  1325 
  1326                <ol class="rule">
  1327                   <li>
  1328                      Let <var>callback ID</var> equal the string value of the first included <em>SID</em> header, if it exists.
  1329                   </li>
  1330                   <li>
  1331                      Let <var>timeout date</var> equal the sum of the current UTC date value plus the integer value of the first included <em>TIMEOUT</em> header (minus the leading string of <code>Second-</code>), if it exists.
  1332                   </li>
  1333                   <li>
  1334                      Run the following steps aynchronously and continue to the step labeled <em>listen</em> below.
  1335                   </li>
  1336                   <li>
  1337                      <em>Refresh Subscription</em>: Run the following steps at a set interval (X) within the <a>user agent</a>:
  1338 
  1339                      <ol class="rule">
  1340                         <li>
  1341                            Let <var>current date</var> equal the current UTC date.
  1342                         </li>
  1343                         <li>
  1344                            If <var>current date</var> is less than the <var>timeout date</var> then continue to the step labeled <em>refresh subscription</em> above.
  1345                         </li>
  1346                         <li>
  1347                            Send a HTTP SUBSCRIBE request with a <em>SID</em> header with the string value of <var>callback ID</var> and a user-agent defined <em>TIMEOUT</em> header (in the form <code>Second-XX</code> where <code>XX</code> is the user-agent defined timeout value in seconds) towards the <var>network service record</var>'s <code>eventsUrl</code> property.
  1348                         </li>
  1349                         <li>
  1350                            On receiving a valid 200 OK, update <var>callback ID</var> with the string value of the first included <em>SID</em> header, if it exists. All other HTTP
  1351                            responses should cause the <a>user agent</a> to continue from the step labeled <em>refresh subscription</em> above.
  1352                         </li>
  1353                      </ol>
  1354 
  1355                   </li>
  1356 
  1357                   <li>
  1358                      <em>Listen</em>: For each HTTP NOTIFY request received at the <var>callback URL</var> the <a>user agent</a> is to run the following steps:
  1359 
  1360                      <ol class="rule">
  1361                         <li>
  1362                            Let <var>content clone</var> be the result of obtaining the message body of the HTTP NOTIFY request. If <var>content clone</var> is empty, then the <a>user agent</a> <em class="ct">MUST</em> abort these steps.
  1363                         </li>
  1364                         <li>
  1365                           Let <var>notification event</var> be a new simple event that uses the
  1366                           <a href="http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#event" class="externalDFN"><code>Event</code></a>
  1367                            interface with the name <a href="#event-notify"><code>notify</code></a>,
  1368                            which does not bubble, is not cancellable, and has no default action.
  1369                         </li>
  1370                         <li>
  1371                            Let the <code>data</code> attribute of <var>notification event</var> have the DOMString value of <var>content clone</var>.
  1372                         </li>
  1373                         <li>
  1374                            <a href="http://www.whatwg.org/specs/web-apps/current-work/complete/webappapis.html#queue-a-task" class="externalDFN">Queue a task</a> to
  1375                             dispatch <var>notification event</var> at the current <a><code>NetworkService</code></a> object.
  1376                         </li>
  1377                      </ol>
  1378                   </li>
  1379 
  1380                </ol>
  1381 
  1382             </li>
  1383          </ol>
  1384 
  1385          <p>
  1386            A <a>user agent</a> can <dfn>terminate an existing UPnP Events Subscription</dfn> at any time for any <var>active service</var> in the <a>list of authorized service records</a> by sending an HTTP UNSUBSCRIBE request - as defined in 'Section 4.1.4: Canceling a subscription with UNSUBSCRIBE' in [[!UPNP-DEVICEARCH11]] - with a HOST header set to that <var>active service</var>'s <code>eventsUrl</code> property and a SID header set to the <var>callback ID</var> obtained when the initial <a>setup a UPnP Events Subscription</a> action occurred.
  1387          </p>
  1388 
  1389          </section>
  1390 
  1391          <section>
  1392             <h3>Network Topology Monitoring</h3>
  1393 
  1394                   <div>
  1395                      <p>
  1396                         When the <a>user agent</a> detects that the user has dropped from their connected network then, for each <var>existing service record</var> in the <a>list of available service records</a>, the user agent
  1397                         <em class="ct">MUST</em>
  1398                             run the general rule for <a>removing an available service</a> passing in each <var>existing service record</var>'s
  1399                             <code>id</code> property as the only argument for each call.
  1400                     </p>
  1401 
  1402                      <p>
  1403                         When the <a>user agent</a> detects that the user has connected to a new network or reconnected to an existing network, then it
  1404                         <em class="ct">SHOULD</em> restart its discovery
  1405                          mechanisms as defined in the <a href="#service-discovery">Service Discovery</a> section of this specification, maintaining
  1406                          the existing <a>list of authorized service records</a> currently in use.
  1407                      </p>
  1408                   </div>
  1409          </section>
  1410       </section>
  1411 
  1412   <section>
  1413       <h3>Events Summary</h3>
  1414 
  1415       <p>The following events are dispatched on the <a href="#networkservices"><code>NetworkServices</code></a> and/or <a href="#networkservice"><code>NetworkService</code></a> objects:</p>
  1416 
  1417        <table border="1">
  1418         <thead>
  1419           <tr>
  1420             <th>
  1421               <span title="event handlers">Event name</span>
  1422             </th>
  1423             <th>
  1424               <span>Interface</span>
  1425             </th>
  1426             <th>
  1427               <span>Dispatched when...</span>
  1428             </th>
  1429           </tr>
  1430         </thead>
  1431         <tbody>
  1432           <tr>
  1433             <td>
  1434               <dfn id="event-serviceavailable">
  1435                 <code>serviceavailable</code>
  1436               </dfn>
  1437             </td>
  1438             <td>
  1439               <a href="http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#event" class="externalDFN"><code>Event</code></a>
  1440             </td>
  1441             <td>
  1442               When a new service that matches one of the <a>requested type tokens</a> is found in the current network.
  1443             </td>
  1444           </tr>
  1445           <tr>
  1446             <td>
  1447               <dfn id="event-serviceunavailable">
  1448                 <code>serviceunavailable</code>
  1449               </dfn>
  1450             </td>
  1451             <td>
  1452               <a href="http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#event" class="externalDFN"><code>Event</code></a>
  1453             </td>
  1454             <td>
  1455               When an existing service that matches one of the <a>requested type tokens</a> gracefully leaves or expires from the current network.
  1456             </td>
  1457           </tr>
  1458           <tr>
  1459             <td>
  1460               <dfn id="event-serviceonline">
  1461                 <code>serviceonline</code>
  1462               </dfn>
  1463             </td>
  1464             <td>
  1465               <a href="http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#event" class="externalDFN"><code>Event</code></a>
  1466             </td>
  1467             <td>
  1468               When a current service renews its service registration within the current network.
  1469             </td>
  1470           </tr>
  1471           <tr>
  1472             <td>
  1473               <dfn id="event-serviceoffline">
  1474                 <code>serviceoffline</code>
  1475               </dfn>
  1476             </td>
  1477             <td>
  1478               <a href="http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#event" class="externalDFN"><code>Event</code></a>
  1479             </td>
  1480             <td>
  1481               When a current service gracefully leaves or otherwise expires from the current network.
  1482             </td>
  1483           </tr>
  1484           <tr>
  1485             <td>
  1486               <dfn id="event-notify">
  1487                 <code>notify</code>
  1488               </dfn>
  1489             </td>
  1490             <td>
  1491               <a href="http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#event" class="externalDFN"><code>Event</code></a>
  1492             </td>
  1493             <td>
  1494               When a valid UPnP Events Subscription Message is received on a <a>user-agent generated callback url</a> for a current service. This event never fires for Zeroconf-based services.
  1495             </td>
  1496           </tr>
  1497         </tbody>
  1498       </table>
  1499 
  1500   </section>
  1501 
  1502    <section>
  1503       <h3>Garbage collection</h3>
  1504 
  1505       <p>
  1506          Only when the user navigates away from the current browsing context can <a><code>NetworkService</code></a> objects be garbage-collected, its records in the <a>entry script origin's URL whitelist</a> be removed and its corresponding entry in the <a>list of authorized service records</a> be removed according to passing each expired object identifier through the rule for <a>removing an available service</a>.
  1507       </p>
  1508 
  1509    </section>
  1510 
  1511 
  1512     <section>
  1513       <h3>Use Cases and Requirements</h3>
  1514 
  1515       <p>This section covers what the requirements are for this API, as well as illustrates some use cases.</p>
  1516 
  1517       <ul class="rule">
  1518          <li>
  1519             Once a user has given permission, user agents should provide the ability for Web pages to communicate directly with a Local-networked Service.
  1520             <ul class="rule">
  1521                <li>
  1522                   Example: A web-based TV remote control. A Web page wants to control the current user's TV, changing the programming shown or increasing/decreasing/muting the
  1523                   volume of the Local-networked Device. The Web page requests a service type that is known to be implemented by television sets to which it has the
  1524                   application logic to communicate. Local devices providing the request service types are discovered and presented to the user for authorization. The user selects one
  1525                   or more of the discovered television sets to be accessible to the current Web page and then clicks 'Share'. The Web page can now communicate directly with
  1526                   the user-authorized Local-networked services.
  1527                </li>
  1528             </ul>
  1529          </li>
  1530 
  1531          <li>
  1532            Web pages should be able to communicate with Local-networked Services using the messaging channel supported by those Devices.
  1533            <ul class="rule">
  1534             <li>
  1535                Example: A Web page advertises that it is capable of controlling multiple Home Media Servers. The user can select their Home Media Server type from a drop-down list, at which point the
  1536                Web page sends a request to the user agent to connect with the associated service type of the Home Media Server. The Media Server selected implements a Web Socket channel for
  1537                bi-directional service communication and so the Web page opens a web socket to the requested Media Server and can communicate as required via that appropriate channel.
  1538             </li>
  1539            </ul>
  1540          </li>
  1541 
  1542          <li>
  1543            Web pages should be able to communicate with Local-networked Services using the messaging format supported by those Devices.
  1544            <ul class="rule">
  1545             <li>
  1546                Example: A Web page advertises that it is capable of interacting with and controlling multiple types of Home Media Server. The user can select their Home Media Server type from a drop-down list or known Media Servers, at which point the
  1547                Web page sends a request to the user agent to connect with the associated service type (and, optionally, the associated event type) of the Home Media Server. The communiciation protocols supported by Home Media Servers typically vary
  1548                between UPnP, JSON-RPC, Protocol Buffers or other messaging formats depending on the Home Media Server requested. The Web page is able to communicate with the user-selected Home Media
  1549                Server in the messaging format supported by that Device, which, in this example is a simple key/value pair text format.
  1550             </li>
  1551            </ul>
  1552          </li>
  1553 
  1554          <li>
  1555            Web pages should not be able to communicate with Local-networked Services that have not been authorized by the user thereby maintaining the user's privacy.
  1556            <ul class="rule">
  1557             <li>
  1558                Example: A Web page requests access to one type of Local-networked service. The user authorizes access to that particular service. Other services running on that same device, and on other devices
  1559                within the network, should not be accessible to the current Web page.
  1560             </li>
  1561            </ul>
  1562          </li>
  1563 
  1564          <li>
  1565            A user should be able to share one or more Local-networked Services based on a particular service type request from a Web page.
  1566            <ul class="rule">
  1567             <li>
  1568                Example: A Web page is capable of interacting with a specific profile of Local-networked Service. As such, it makes a request to the user agent to access those services, of which multiple matches
  1569                are found. The user is capable of selecting one or more of the discovered services to share with the Web page. The Web page can then implement a drag-and-drop interface for the user to drag specific
  1570                actions on to one or more of the authorized Local-networked Services.
  1571             </li>
  1572            </ul>
  1573          </li>
  1574 
  1575          <li>
  1576            User agents should provide an API exposed to script that exposes the features above. The user is notified by UI anytime interaction with Local-networked Services is requested, giving the user
  1577            full ability to cancel or abort the transaction. The user selects the Local-networked Services to be connected to the current Web page, and can cancel these at any time. No invocations to
  1578            these APIs occur silently without user intervention.
  1579          </li>
  1580       </ul>
  1581     </section>
  1582 
  1583           <section class="informative appendix">
  1584              <h3>Examples</h3>
  1585 
  1586            <div class="example">
  1587             <p>This sample code exposes a button. When clicked, this button is disabled and the user is prompted to offer a network service. The user may also select multiple network services. When the user has authorized a network service to be connected to the web page then the web page issues a simple command to get a list of all the albums stored on the connected media player service.
  1588             <p>The button is re-enabled only when the connected network service disconnects for whatever reason (the service becomes unavailable on the network, the user disconnects from their current network or the user revokes access to the service from the current web page). At this point the user can re-click the button to select a new network service to connect to the web page and the above steps are repeated.</p>
  1589             <p>The provided service type identifier and service interaction used in this example is based on the well-defined service type and messaging format supported by the <a href="http://xbmc.org/about/">XBMC Media Server</a>. </p>
  1590             <hr />
  1591             <pre class="highlight">&lt;input type="button" value="Start" onclick="start()" id="startBtn"/&gt;
  1592 &lt;div id="debugconsole">&lt;/div>
  1593 
  1594 &lt;script>
  1595  var startBtn = document.getElementById('startBtn'),
  1596      debug = document.getElementById('debugconsole');
  1597 
  1598  function start() {
  1599    if(navigator.getNetworkServices) {
  1600       navigator.getNetworkServices('zeroconf:_xbmc-jsonrpc._tcp', gotXBMCService, error);
  1601       startBtn.disabled = true;
  1602    } else {
  1603       debug.innerHTML += "&lt;br&gt;Service Discovery not supported!";
  1604    }
  1605  }
  1606 
  1607  function gotXBMCService(services) {
  1608 
  1609 // Listen for service disconnect messages
  1610 
  1611    services[0].addEventListener('serviceoffline', function ( e ) {
  1612        debug.innerHTML += "&lt;br>" + services[0].name + " disconnected.";
  1613        startBtn.disabled = false;
  1614    }, false);
  1615 
  1616 // Send a service message to get albums list (and process the service response)
  1617 
  1618    var svcXhr = new XMLHttpRequest();
  1619    svcXhr.open("POST", services[0].url + "/getAlbums"); // services[0].url and its subresources have been
  1620                                                         // whitelisted for cross-site XHR use in this
  1621                                                         // current browsing context.
  1622 
  1623    svcXhr.setRequestHeader('Content-Type', 'application/json-rpc');
  1624 
  1625    svcXhr.addEventListener('readystatechange', function ( response ) {
  1626      if( response.readyState != 4 || response.status != 200 )
  1627         return;
  1628      debug.innerHTML += "&lt;br>" + services[0].name + " response received: ";
  1629      debug.textContent += JSON.parse(response.responseText);
  1630    }, false);
  1631 
  1632    var svcMsg = [
  1633      { "jsonrpc": "2.0", "method": "AudioLibrary.GetAlbums", "params": { "genreid": -1,
  1634          "artistid": -1, "start": -1, "end": -1 }, "id": "1" }
  1635    ];
  1636 
  1637    svcXhr.send(JSON.stringify(svcMsg));
  1638    debug.innerHTML += "&lt;br>" + services[0].name + " request sent: ";
  1639    debug.textContent += JSON.stringify(svcMsg);
  1640 
  1641  }
  1642 
  1643  function error( err ) {
  1644    debug.innerHTML += "&lt;br>An error occurred obtaining a local network service.";
  1645    startBtn.disabled = false;
  1646  }
  1647 &lt;/script></pre>
  1648            </div>
  1649 
  1650            <div class="example">
  1651             <p>
  1652              This sample exposes a drop-down list containing a number of common Home-based audio devices. When the user selects an audio device from the list provided, they are prompted to authorize a network service
  1653              based on the service type requested. The user may also select multiple network services matching the selected service type.
  1654              In this example, the user selects their make as being <var>Sony</var> and their model as being <var>Bravia S1000</var> from which the Web page can derive a service type
  1655              (<var>urn:schemas-upnp-org:service:RenderingControl:1</var>).
  1656              <br /><br />Once the user has authorized the device, the web page sends a simple mute command according to the messaging format supported by the device.
  1657             </p>
  1658             <hr />
  1659             <pre class="highlight">&lt;select name="make" id="make"&gt;
  1660   &lt;option selected="selected" disabled="disabled"&gt;Select make&lt;/option&gt;
  1661   &lt;option&gt;Sony&lt;/option&gt;
  1662   &lt;option&gt;Philips&lt;/option&gt;
  1663   &lt;option&gt;Alba&lt;/option&gt;
  1664 &lt;/select&gt;
  1665 &lt;select name="model" id="model"&gt;&lt;/select&gt;
  1666 &lt;div id="debugconsole"&gt;&lt;/div&gt;
  1667 
  1668 &lt;script&gt;
  1669   var debug = document.getElementById('debugconsole');
  1670 
  1671   var models = {
  1672     "Sony": [
  1673       {"name": "Bravia TV S1000", "type": "upnp", "service": "urn:schemas-upnp-org:service:RenderingControl:1" },
  1674       {"name": "Bravia TV S2000", "type": "zeroconf", "service": "_mediarenderer._http._tcp" },
  1675       {"name": "HiFi WD10", "type": "upnp", "service": "urn:schemas-upnp-org:service:RenderingControl:1" }
  1676     ],
  1677     "Philips": [ /* ... */ ],
  1678     "Alba": [ /* ... */ ]
  1679   };
  1680 
  1681   var makeEl = document.getElementById("make"),
  1682       modelEl = document.getElementById("model");
  1683 
  1684   makeEl.addEventListener('change', function() {
  1685     modelEl.innerHTML = ""; // reset
  1686     var defaultOption = document.createElement("option");
  1687     defaultOption.textContent = "Select model";
  1688     defaultOption.setAttribute("disabled", "disabled");
  1689     defaultOption.setAttribute("selected", "selected");
  1690     modelEl.appendChild(defaultOption);
  1691     for(var i = 0, l = models[makeEl.value].length; i < l; i++) {
  1692       var option = document.createElement("option");
  1693       option.textContent = models[makeEl.value][i]["name"];
  1694       option.setAttribute("value", models[makeEl.value][i]["type"] + ":" + models[makeEl.value][i]["service"]);
  1695       modelEl.appendChild(option);
  1696     }
  1697   }, false);
  1698 
  1699   modelEl.addEventListener('change', function() {
  1700     if(navigator.getNetworkServices &&
  1701          modelEl.value == "upnp:urn:schemas-upnp-org:service:RenderingControl:1") {
  1702       navigator.getNetworkServices(modelEl.value, successCallback, errorCallback);
  1703     } else if (modelEl.value == "zeroconf:_mediarenderer._http._tcp") {
  1704       debug.innerHTML += "&lt;br&gt;Service type is not implemented by this application.";
  1705     } else {
  1706       debug.innerHTML += "&lt;br&gt;Service Discovery is not supported!";
  1707     }
  1708   }, false);
  1709 &lt;/script&gt;
  1710 
  1711 &lt;script&gt;
  1712   function successCallback( services ) {
  1713 
  1714   // Listen for service push notification messages
  1715 
  1716     services[0].addEventListener('notify', function ( msg ) {
  1717          debug.innerHTML += "&lt;br>" + services[0].name + " event received: ";
  1718          debug.textContent += msg.data;
  1719     }, false);
  1720 
  1721  // Send a control signal to mute the service audio
  1722 
  1723     var svcXhr = new XMLHttpRequest();
  1724     svcXhr.open("POST", services[0].url); // services[0].url and its
  1725                                           // subresources have been whitelisted for
  1726                                           // cross-site XHR use in this current
  1727                                           // browsing context.
  1728 
  1729     svcXhr.setRequestHeader('SOAPAction', 'urn:schemas-upnp-org:service:RenderingControl:1#SetMute');
  1730     svcXhr.setRequestHeader('Content-Type', 'text/xml; charset="utf-8";');
  1731 
  1732     svcXhr.onreadystatechange = function ( response ) {
  1733       if( response.readyState != 4 || response.status != 200 )
  1734         return;
  1735       debug.innerHTML += "&lt;br&gt;" + services[0].name + " response received: ";
  1736       debug.textContent += response.responseXML;
  1737     }
  1738 
  1739     // Service messaging to mute the provided service
  1740     var svcMsg = '&lt;?xml version="1.0" encoding="utf-8"?&gt;' +
  1741                  '&lt;s:Envelope s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" ' +
  1742                    'xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"&gt;' +
  1743                    '&lt;s:Body&gt;' +
  1744                      '&lt;u:SetMute xmlns:u="urn:schemas-upnp-org:service:RenderingControl:1"&gt;' +
  1745                        '&lt;InstanceID&gt;0&lt;/InstanceID&gt;' +
  1746                        '&lt;Channel&gt;Master&lt;/Channel&gt;' +
  1747                        '&lt;DesiredMute&gt;true&lt;/DesiredMute&gt;' +
  1748                      '&lt;/u:SetMute&gt;' +
  1749                    '&lt;/s:Body&gt;' +
  1750                  '&lt;/s:Envelope&gt;';
  1751 
  1752     svcXhr.send(svcMsg);
  1753     debug.innerHTML += "&lt;br&gt;" + services[0].name + " request sent: ";
  1754     debug.textContent += svcMsg;
  1755   }
  1756 
  1757   function errorCallback( error ) {
  1758     debug.innerHTML += "&lt;br&gt;An error occurred: " + error.code;
  1759   }
  1760 &lt;/script&gt;</pre>
  1761           </div>
  1762 
  1763        </section>
  1764 
  1765     <section>
  1766       <h3>Acknowledgements</h3>
  1767 
  1768       <p>Thanks are expressed by the editor to the following individuals for their feedback on this specification to date (in alphabetical order):
  1769       <br /><br />
  1770       Gar Bergstedt, Lars-Erik Bolstad, Cathy Chan, Hari G Kumar, Bob Lund, Giuseppe Pascale, Marcin Simonides, Clarke Stevens, Christian S&ouml;derstr&ouml;m, Mark Vickers, ...</p>
  1771 
  1772       <p>Thanks are also expressed by the editor to the following organizations and groups for their support in producing this specification to date (in alphabetical order):
  1773       <br /></br />
  1774       CableLabs, Opera Software ASA, W3C Device APIs Working Group, W3C Web and TV Interest Group, ...</p>
  1775     </section>
  1776 </body>
  1777 </html>