discovery-api/Overview.html
author Rich Tibbett <richt@opera.com>
Mon, 28 Oct 2013 11:31:42 +1100
changeset 484 608edb43c84d
parent 483 140b6c8d4c18
child 492 2f37e8af951a
permissions -rw-r--r--
Fix minor respec link bugs and other minor editorials
richt@194
     1
<!DOCTYPE html>
richt@437
     2
<html lang="en"
richt@437
     3
      dir="ltr"
richt@437
     4
      typeof="bibo:Document"
richt@437
     5
      about=""
richt@437
     6
      property="dcterms:language"
richt@437
     7
      content="en">
richt@437
     8
  <head>
richt@239
     9
    <title>
richt@239
    10
      Network Service Discovery
richt@239
    11
    </title>
richt@437
    12
    <meta http-equiv="Content-Type"
richt@437
    13
          content="text/html; charset=utf-8">
richt@402
    14
    <style>
richt@437
    15
/* Custom ReSpec CSS (by Rich Tibbett) */
richt@180
    16
richt@402
    17
     /* Add better spacing to sections */
richt@402
    18
     section, .section { margin-bottom: 2em; }
richt@180
    19
richt@402
    20
     /* Add addition spacing to <ol> and <ul> for rule definition */
richt@402
    21
     ol.rule li, ul.rule li { padding:0.6em; }
richt@180
    22
richt@402
    23
     pre.widl { border: solid thin; background: #EEEEEE; color: black; padding: 0.5em 1em; position: relative; }
richt@402
    24
     pre.widl :link, pre.widl :visited { color: #000; background: transparent; }
richt@402
    25
     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 }
richt@238
    26
richt@402
    27
     div.example { border: solid thin black; background: #FFFFF0; color: black; padding: 0.5em 1em; position: relative; margin: 1em 0 1em 4.6em; width: auto; }
richt@402
    28
     div.example:before { content: "EXAMPLE"; font: bold small sans-serif; padding: 0.5em; background: white; color: black; position: absolute; top: 0; margin: -1px 0 0 -7.6em; width: 5em; border: thin solid black; border-radius: 0 0 0 0.5em }
richt@180
    29
richt@402
    30
     dl.domintro { color: green; margin: 2em 0 2em 2em; padding: 0.5em 1em; border: none; background: #DDFFDD; }
richt@402
    31
     hr + dl.domintro, div.impl + dl.domintro { margin-top: 2.5em; margin-bottom: 1.5em; }
richt@402
    32
     dl.domintro dt, dl.domintro dt * { color: black; text-decoration: none; }
richt@402
    33
     dl.domintro dd { margin: 0.5em 0 1em 2em; padding: 0; }
richt@402
    34
     dl.domintro dd p { margin: 0.5em 0; }
richt@402
    35
     dl.domintro code {font-size: inherit; font-style: italic; }
richt@402
    36
     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; font-size:0.8em; }
richt@402
    37
richt@402
    38
     table { border-collapse:collapse; border-style:hidden hidden none hidden }
richt@402
    39
     table thead { border-bottom:solid }
richt@402
    40
     table tbody th:first-child { border-left:solid }
richt@402
    41
     table td, table th { border-left:solid; border-right:solid; border-bottom:solid thin; vertical-align:top; padding:0.2em }
richt@437
    42
    </style>
richt@437
    43
    <style>
richt@437
    44
/*****************************************************************
richt@437
    45
    * ReSpec 3 CSS
richt@437
    46
    * Robin Berjon - http://berjon.com/
richt@437
    47
    *****************************************************************/
richt@402
    48
richt@437
    49
    /* --- INLINES --- */
richt@484
    50
    em.rfc2119 { 
richt@180
    51
    text-transform:     lowercase;
richt@180
    52
    font-variant:       small-caps;
richt@180
    53
    font-style:         normal;
richt@180
    54
    color:              #900;
richt@437
    55
    }
richt@180
    56
richt@437
    57
    h1 acronym, h2 acronym, h3 acronym, h4 acronym, h5 acronym, h6 acronym, a acronym,
richt@437
    58
    h1 abbr, h2 abbr, h3 abbr, h4 abbr, h5 abbr, h6 abbr, a abbr {
richt@180
    59
    border: none;
richt@437
    60
    }
richt@180
    61
richt@437
    62
    dfn {
richt@180
    63
    font-weight:    bold;
richt@437
    64
    }
richt@180
    65
richt@437
    66
    a.internalDFN {
richt@180
    67
    color:  inherit;
richt@194
    68
    border-bottom:  1px solid #99c;
richt@180
    69
    text-decoration:    none;
richt@437
    70
    }
richt@180
    71
richt@437
    72
    a.externalDFN {
richt@180
    73
    color:  inherit;
richt@194
    74
    border-bottom:  1px dotted #ccc;
richt@180
    75
    text-decoration:    none;
richt@437
    76
    }
richt@180
    77
richt@437
    78
    a.bibref {
richt@180
    79
    text-decoration:    none;
richt@437
    80
    }
richt@180
    81
richt@437
    82
    cite .bibref {
richt@194
    83
    font-style: normal;
richt@437
    84
    }
richt@194
    85
richt@437
    86
    code {
richt@180
    87
    color:  #ff4500;
richt@437
    88
    }
richt@180
    89
richt@437
    90
    /* --- TOC --- */
richt@437
    91
    .toc a, .tof a {
richt@437
    92
    text-decoration:    none;
richt@437
    93
    }
richt@180
    94
richt@437
    95
    a .secno, a .figno {
richt@437
    96
    color:  #000;
richt@437
    97
    }
richt@180
    98
richt@437
    99
    ul.tof, ol.tof {
richt@437
   100
    list-style: none outside none;
richt@437
   101
    }
richt@180
   102
richt@437
   103
    .caption {
richt@194
   104
    margin-top: 0.5em;
richt@194
   105
    font-style:   italic;
richt@437
   106
    }
richt@180
   107
richt@437
   108
    /* --- TABLE --- */
richt@437
   109
    table.simple {
richt@180
   110
    border-spacing: 0;
richt@180
   111
    border-collapse:    collapse;
richt@180
   112
    border-bottom:  3px solid #005a9c;
richt@437
   113
    }
richt@180
   114
richt@437
   115
    .simple th {
richt@180
   116
    background: #005a9c;
richt@180
   117
    color:  #fff;
richt@180
   118
    padding:    3px 5px;
richt@180
   119
    text-align: left;
richt@437
   120
    }
richt@180
   121
richt@437
   122
    .simple th[scope="row"] {
richt@180
   123
    background: inherit;
richt@180
   124
    color:  inherit;
richt@180
   125
    border-top: 1px solid #ddd;
richt@437
   126
    }
richt@180
   127
richt@437
   128
    .simple td {
richt@180
   129
    padding:    3px 10px;
richt@180
   130
    border-top: 1px solid #ddd;
richt@437
   131
    }
richt@180
   132
richt@437
   133
    .simple tr:nth-child(even) {
richt@180
   134
    background: #f0f6ff;
richt@437
   135
    }
richt@180
   136
richt@437
   137
    /* --- DL --- */
richt@437
   138
    .section dd > p:first-child {
richt@180
   139
    margin-top: 0;
richt@437
   140
    }
richt@180
   141
richt@437
   142
    .section dd > p:last-child {
richt@180
   143
    margin-bottom: 0;
richt@437
   144
    }
richt@180
   145
richt@437
   146
    .section dd {
richt@180
   147
    margin-bottom:  1em;
richt@437
   148
    }
richt@180
   149
richt@437
   150
    .section dl.attrs dd, .section dl.eldef dd {
richt@180
   151
    margin-bottom:  0;
richt@437
   152
    }
richt@437
   153
    </style>
richt@437
   154
    <style>
richt@437
   155
/* --- ISSUES/NOTES --- */
richt@437
   156
    div.issue-title, div.note-title {
richt@194
   157
    padding-right:  1em;
richt@194
   158
    min-width: 7.5em;
richt@194
   159
    color: #b9ab2d;
richt@437
   160
    }
richt@437
   161
    div.issue-title { color: #e05252; }
richt@437
   162
    div.note-title { color: #2b2; }
richt@437
   163
    div.issue-title span, div.note-title span {
richt@194
   164
    text-transform: uppercase;
richt@437
   165
    }
richt@437
   166
    div.note, div.issue {
richt@194
   167
    margin-top: 1em;
richt@194
   168
    margin-bottom: 1em;
richt@437
   169
    }
richt@437
   170
    .note > p:first-child, .issue > p:first-child { margin-top: 0 }
richt@437
   171
    .issue, .note {
richt@194
   172
    padding: .5em;
richt@194
   173
    border-left-width: .5em;
richt@194
   174
    border-left-style: solid;
richt@437
   175
    }
richt@437
   176
    div.issue, div.note {
richt@437
   177
    padding: 1em 1.2em 0.5em;
richt@194
   178
    margin: 1em 0;
richt@194
   179
    position: relative;
richt@194
   180
    clear: both;
richt@437
   181
    }
richt@437
   182
    span.note, span.issue { padding: .1em .5em .15em; }
richt@180
   183
richt@437
   184
    .issue {
richt@194
   185
    border-color: #e05252;
richt@194
   186
    background: #fbe9e9;
richt@437
   187
    }
richt@437
   188
    .note {
richt@194
   189
    border-color: #52e052;
richt@194
   190
    background: #e9fbe9;
richt@437
   191
    }
richt@180
   192
richt@194
   193
richt@437
   194
    </style>
richt@437
   195
    <style>
richt@437
   196
/* HIGHLIGHTS */
richt@437
   197
    code.prettyprint {
richt@194
   198
    color:  inherit;
richt@437
   199
    }
richt@180
   200
richt@437
   201
    /* this from google-code-prettify */
richt@437
   202
    .pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.pun,.opn,.clo{color:#660}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec,.var{color:#606}.fun{color:red}}@media print,projection{.str{color:#060}.kwd{color:#006;font-weight:bold}.com{color:#600;font-style:italic}.typ{color:#404;font-weight:bold}.lit{color:#044}.pun,.opn,.clo{color:#440}.tag{color:#006;font-weight:bold}.atn{color:#404}.atv{color:#060}}ol.linenums{margin-top:0;margin-bottom:0}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee}
richt@437
   203
    </style>
richt@437
   204
    <link rel="stylesheet"
richt@437
   205
          href="https://www.w3.org/StyleSheets/TR/W3C-ED">
richt@484
   206
    <script type="text/javascript"
richt@484
   207
          charset="utf-8"
richt@484
   208
          async=""
richt@484
   209
          data-requirecontext="_"
richt@484
   210
          data-requiremodule="ui/save-html"
richt@484
   211
          src="https://raw.github.com/darobin/respec/gh-pages/js/ui/save-html.js">
richt@484
   212
</script>
richt@437
   213
  </head>
richt@447
   214
  <body class="h-entry"
richt@480
   215
        style=""
richt@447
   216
        role="document"
richt@447
   217
        id="respecDocument">
richt@447
   218
    <div class="head"
richt@447
   219
         role="contentinfo"
richt@447
   220
         id="respecHeader">
richt@437
   221
      <p>
richt@437
   222
        <a href="http://www.w3.org/"><img width="72"
richt@437
   223
             height="48"
richt@437
   224
             src="https://www.w3.org/Icons/w3c_home"
richt@437
   225
             alt="W3C"></a>
richt@437
   226
      </p>
richt@437
   227
      <h1 class="title p-name"
richt@437
   228
          id="title"
richt@437
   229
          property="dcterms:title">
richt@437
   230
        Network Service Discovery
richt@437
   231
      </h1>
richt@437
   232
      <h2 property="dcterms:issued"
richt@437
   233
          datatype="xsd:dateTime"
richt@484
   234
          content="2013-10-27T13:29:43.000Z"
richt@484
   235
          id="w3c-editor-s-draft-28-october-2013">
richt@437
   236
        <abbr title="World Wide Web Consortium">W3C</abbr> Editor's Draft <time class="dt-published"
richt@484
   237
            datetime="2013-10-28">28 October 2013</time>
richt@437
   238
      </h2>
richt@437
   239
      <dl>
richt@437
   240
        <dt>
richt@437
   241
          This version:
richt@437
   242
        </dt>
richt@437
   243
        <dd>
richt@437
   244
          <a class="u-url"
richt@437
   245
              href=
richt@437
   246
              "http://dvcs.w3.org/hg/dap/raw-file/tip/discovery-api/Overview.html">http://dvcs.w3.org/hg/dap/raw-file/tip/discovery-api/Overview.html</a>
richt@437
   247
        </dd>
richt@437
   248
        <dt>
richt@437
   249
          Latest published version:
richt@437
   250
        </dt>
richt@437
   251
        <dd>
richt@437
   252
          <a href="http://www.w3.org/TR/discovery-api/">http://www.w3.org/TR/discovery-api/</a>
richt@437
   253
        </dd>
richt@437
   254
        <dt>
richt@437
   255
          Latest editor's draft:
richt@437
   256
        </dt>
richt@437
   257
        <dd>
richt@437
   258
          <a href=
richt@437
   259
          "http://dvcs.w3.org/hg/dap/raw-file/tip/discovery-api/Overview.html">http://dvcs.w3.org/hg/dap/raw-file/tip/discovery-api/Overview.html</a>
richt@437
   260
        </dd>
richt@437
   261
        <dt>
richt@437
   262
          Editor:
richt@437
   263
        </dt>
richt@437
   264
        <dd class="p-author h-card vcard"
richt@437
   265
            rel="bibo:editor"
richt@437
   266
            inlist="">
richt@437
   267
          <span typeof="foaf:Person"><span property="foaf:name"
richt@437
   268
                class="p-name fn">Rich Tibbett</span>, <a rel="foaf:workplaceHomepage"
richt@437
   269
             class="p-org org h-org h-card"
richt@437
   270
             href="http://opera.com/">Opera Software ASA</a></span>
richt@437
   271
        </dd>
richt@437
   272
      </dl>
richt@402
   273
      <p class="copyright">
richt@437
   274
        <a href="http://www.w3.org/Consortium/Legal/ipr-notice#Copyright">Copyright</a> © 2013 <a href=
richt@437
   275
        "http://www.w3.org/"><abbr title="World Wide Web Consortium">W3C</abbr></a><sup>®</sup> (<a href=
richt@437
   276
        "http://www.csail.mit.edu/"><abbr title="Massachusetts Institute of Technology">MIT</abbr></a>, <a href=
richt@437
   277
        "http://www.ercim.eu/"><abbr title=
richt@437
   278
        "European Research Consortium for Informatics and Mathematics">ERCIM</abbr></a>, <a href=
richt@437
   279
        "http://www.keio.ac.jp/">Keio</a>, <a href="http://ev.buaa.edu.cn/">Beihang</a>), All Rights Reserved.
richt@437
   280
        <abbr title="World Wide Web Consortium">W3C</abbr> <a href=
richt@437
   281
        "http://www.w3.org/Consortium/Legal/ipr-notice#Legal_Disclaimer">liability</a>, <a href=
richt@437
   282
        "http://www.w3.org/Consortium/Legal/ipr-notice#W3C_Trademarks">trademark</a> and <a href=
richt@437
   283
        "http://www.w3.org/Consortium/Legal/copyright-documents">document use</a> rules apply.
richt@379
   284
      </p>
richt@437
   285
      <hr>
richt@437
   286
    </div>
richt@437
   287
    <section id="abstract"
richt@437
   288
             class="introductory"
richt@437
   289
             property="dcterms:abstract"
richt@437
   290
             datatype=""
richt@437
   291
             typeof="bibo:Chapter"
richt@484
   292
             resource="#ref"
richt@484
   293
             rel="bibo:Chapter">
richt@447
   294
      <h2 aria-level="1"
richt@447
   295
          role="heading"
richt@447
   296
          id="h2_abstract">
richt@437
   297
        Abstract
richt@437
   298
      </h2>
richt@180
   299
      <p>
richt@239
   300
        This specification defines a mechanism for an HTML document to discover and subsequently communicate with
richt@239
   301
        <abbr title="Hypertext Transfer Protocol">HTTP</abbr>-based services advertised via common discovery protocols
richt@239
   302
        within the current network.
richt@180
   303
      </p>
richt@437
   304
    </section>
richt@480
   305
    <section id="sotd"
richt@480
   306
             class="introductory"
richt@480
   307
             typeof="bibo:Chapter"
richt@484
   308
             resource="#ref"
richt@484
   309
             rel="bibo:Chapter">
richt@480
   310
      <h2 aria-level="1"
richt@480
   311
          role="heading"
richt@480
   312
          id="h2_sotd">
richt@480
   313
        Status of This Document
richt@480
   314
      </h2>
richt@480
   315
      <p>
richt@480
   316
        <em>This section describes the status of this document at the time of its publication. Other documents may
richt@480
   317
        supersede this document. A list of current <abbr title="World Wide Web Consortium">W3C</abbr> publications and
richt@480
   318
        the latest revision of this technical report can be found in the <a href="http://www.w3.org/TR/"><abbr title=
richt@480
   319
        "World Wide Web Consortium">W3C</abbr> technical reports index</a> at http://www.w3.org/TR/.</em>
richt@480
   320
      </p>
richt@480
   321
      <p>
richt@480
   322
        This document represents the early consensus of the group on the scope and features of the proposed
richt@480
   323
        <abbr title="Application Programming Interface">API</abbr>.
richt@480
   324
      </p>
richt@480
   325
      <p>
richt@480
   326
        This document was published by the <a href="http://www.w3.org/2009/dap/">Device APIs Working Group</a> as an
richt@480
   327
        Editor's Draft. If you wish to make comments regarding this document, please send them to <a href=
richt@480
   328
        "mailto:public-device-apis@w3.org">public-device-apis@w3.org</a> (<a href=
richt@480
   329
        "mailto:public-device-apis-request@w3.org?subject=subscribe">subscribe</a>, <a href=
richt@480
   330
        "http://lists.w3.org/Archives/Public/public-device-apis/">archives</a>). All comments are welcome.
richt@480
   331
      </p>
richt@480
   332
      <p>
richt@480
   333
        Publication as an Editor's Draft does not imply endorsement by the <abbr title=
richt@480
   334
        "World Wide Web Consortium">W3C</abbr> Membership. This is a draft document and may be updated, replaced or
richt@480
   335
        obsoleted by other documents at any time. It is inappropriate to cite this document as other than work in
richt@480
   336
        progress.
richt@480
   337
      </p>
richt@480
   338
      <p>
richt@480
   339
        This document was produced by a group operating under the <a id="sotd_patent"
richt@480
   340
           about=""
richt@480
   341
           rel="w3p:patentRules"
richt@480
   342
           href="http://www.w3.org/Consortium/Patent-Policy-20040205/">5 February 2004 <abbr title=
richt@480
   343
           "World Wide Web Consortium">W3C</abbr> Patent Policy</a>. <abbr title="World Wide Web Consortium">W3C</abbr>
richt@480
   344
           maintains a <a href="http://www.w3.org/2004/01/pp-impl/43696/status"
richt@480
   345
           rel="disclosure">public list of any patent disclosures</a> made in connection with the deliverables of the
richt@480
   346
           group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge
richt@480
   347
           of a patent which the individual believes contains <a href=
richt@480
   348
           "http://www.w3.org/Consortium/Patent-Policy-20040205/#def-essential">Essential Claim(s)</a> must disclose
richt@480
   349
           the information in accordance with <a href=
richt@480
   350
           "http://www.w3.org/Consortium/Patent-Policy-20040205/#sec-Disclosure">section 6 of the <abbr title=
richt@480
   351
           "World Wide Web Consortium">W3C</abbr> Patent Policy</a>.
richt@480
   352
      </p>
richt@480
   353
    </section>
richt@437
   354
    <section id="toc">
richt@447
   355
      <h2 class="introductory"
richt@447
   356
          aria-level="1"
richt@447
   357
          role="heading"
richt@447
   358
          id="h2_toc">
richt@437
   359
        Table of Contents
richt@437
   360
      </h2>
richt@447
   361
      <ul class="toc"
richt@447
   362
          role="directory"
richt@447
   363
          id="respecContents">
richt@437
   364
        <li class="tocline">
richt@437
   365
          <a href="#introduction"
richt@437
   366
              class="tocxref"><span class="secno">1.</span> Introduction</a>
richt@437
   367
        </li>
richt@437
   368
        <li class="tocline">
richt@437
   369
          <a href="#conformance"
richt@437
   370
              class="tocxref"><span class="secno">2.</span> Conformance</a>
richt@437
   371
          <ul class="toc">
richt@437
   372
            <li class="tocline">
richt@437
   373
              <a href="#dependencies"
richt@437
   374
                  class="tocxref"><span class="secno">2.1</span> Dependencies</a>
richt@437
   375
            </li>
richt@437
   376
          </ul>
richt@437
   377
        </li>
richt@437
   378
        <li class="tocline">
richt@437
   379
          <a href="#terminology"
richt@437
   380
              class="tocxref"><span class="secno">3.</span> Terminology</a>
richt@437
   381
        </li>
richt@437
   382
        <li class="tocline">
richt@440
   383
          <a href="#security-and-privacy-considerations"
richt@440
   384
              class="tocxref"><span class="secno">4.</span> Security and privacy considerations</a>
richt@440
   385
          <ul class="toc">
richt@440
   386
            <li class="tocline">
richt@480
   387
              <a href="#security-considerations-for-api-implementations"
richt@480
   388
                  class="tocxref"><span class="secno">4.1</span> Security considerations for <abbr title=
richt@480
   389
                  "Application Programming Interface">API</abbr> implementations</a>
richt@480
   390
            </li>
richt@480
   391
            <li class="tocline">
richt@440
   392
              <a href="#privacy-considerations-for-api-implementations"
richt@480
   393
                  class="tocxref"><span class="secno">4.2</span> Privacy considerations for <abbr title=
richt@440
   394
                  "Application Programming Interface">API</abbr> implementations</a>
richt@440
   395
            </li>
richt@440
   396
            <li class="tocline">
richt@440
   397
              <a href="#additional-api-implementation-considerations"
richt@480
   398
                  class="tocxref"><span class="secno">4.3</span> Additional <abbr title=
richt@440
   399
                  "Application Programming Interface">API</abbr> implementation considerations</a>
richt@440
   400
            </li>
richt@440
   401
          </ul>
richt@440
   402
        </li>
richt@440
   403
        <li class="tocline">
richt@437
   404
          <a href="#requesting-networked-services"
richt@440
   405
              class="tocxref"><span class="secno">5.</span> Requesting networked services</a>
richt@437
   406
          <ul class="toc">
richt@437
   407
            <li class="tocline">
richt@437
   408
              <a href="#methods"
richt@440
   409
                  class="tocxref"><span class="secno">5.1</span> Methods</a>
richt@437
   410
            </li>
richt@437
   411
            <li class="tocline">
richt@437
   412
              <a href="#error-handling"
richt@440
   413
                  class="tocxref"><span class="secno">5.2</span> Error Handling</a>
richt@437
   414
            </li>
richt@437
   415
          </ul>
richt@437
   416
        </li>
richt@437
   417
        <li class="tocline">
richt@437
   418
          <a href="#obtaining-networked-services"
richt@440
   419
              class="tocxref"><span class="secno">6.</span> Obtaining networked services</a>
richt@437
   420
          <ul class="toc">
richt@437
   421
            <li class="tocline">
richt@437
   422
              <a href="#attributes"
richt@440
   423
                  class="tocxref"><span class="secno">6.1</span> Attributes</a>
richt@437
   424
            </li>
richt@437
   425
            <li class="tocline">
richt@437
   426
              <a href="#methods-1"
richt@440
   427
                  class="tocxref"><span class="secno">6.2</span> Methods</a>
richt@437
   428
            </li>
richt@437
   429
            <li class="tocline">
richt@437
   430
              <a href="#events"
richt@440
   431
                  class="tocxref"><span class="secno">6.3</span> Events</a>
richt@437
   432
            </li>
richt@437
   433
          </ul>
richt@437
   434
        </li>
richt@437
   435
        <li class="tocline">
richt@437
   436
          <a href="#communicating-with-a-networked-service"
richt@440
   437
              class="tocxref"><span class="secno">7.</span> Communicating with a networked service</a>
richt@437
   438
          <ul class="toc">
richt@437
   439
            <li class="tocline">
richt@437
   440
              <a href="#attributes-1"
richt@440
   441
                  class="tocxref"><span class="secno">7.1</span> Attributes</a>
richt@437
   442
            </li>
richt@437
   443
            <li class="tocline">
richt@437
   444
              <a href="#states"
richt@440
   445
                  class="tocxref"><span class="secno">7.2</span> States</a>
richt@437
   446
            </li>
richt@437
   447
            <li class="tocline">
richt@437
   448
              <a href="#events-1"
richt@440
   449
                  class="tocxref"><span class="secno">7.3</span> Events</a>
richt@437
   450
            </li>
richt@437
   451
          </ul>
richt@437
   452
        </li>
richt@437
   453
        <li class="tocline">
richt@437
   454
          <a href="#service-discovery"
richt@440
   455
              class="tocxref"><span class="secno">8.</span> Service Discovery</a>
richt@437
   456
          <ul class="toc">
richt@437
   457
            <li class="tocline">
richt@437
   458
              <a href="#zeroconf-mdns-dns-sd"
richt@440
   459
                  class="tocxref"><span class="secno">8.1</span> Zeroconf (<abbr title="Multicast DNS">mDNS</abbr> +
richt@437
   460
                  <abbr title="Domain Name System">DNS</abbr>-<abbr title="Service Discovery">SD</abbr>)</a>
richt@437
   461
            </li>
richt@437
   462
            <li class="tocline">
richt@437
   463
              <a href="#simple-service-discovery-protocol-ssdp"
richt@440
   464
                  class="tocxref"><span class="secno">8.2</span> Simple Service Discovery Protocol (<abbr title=
richt@437
   465
                  "Simple Service Discovery Protocol">SSDP</abbr>)</a>
richt@437
   466
            </li>
richt@437
   467
            <li class="tocline">
richt@437
   468
              <a href="#discovery-and-launch-protocol-dial"
richt@440
   469
                  class="tocxref"><span class="secno">8.3</span> Discovery and Launch Protocol (<abbr title=
richt@437
   470
                  "Discovery and Launch Protocol">DIAL</abbr>)</a>
richt@437
   471
            </li>
richt@437
   472
            <li class="tocline">
richt@437
   473
              <a href="#network-topology-monitoring"
richt@440
   474
                  class="tocxref"><span class="secno">8.4</span> Network Topology Monitoring</a>
richt@437
   475
            </li>
richt@437
   476
          </ul>
richt@437
   477
        </li>
richt@437
   478
        <li class="tocline">
richt@437
   479
          <a href="#events-summary"
richt@440
   480
              class="tocxref"><span class="secno">9.</span> Events Summary</a>
richt@437
   481
        </li>
richt@437
   482
        <li class="tocline">
richt@437
   483
          <a href="#garbage-collection"
richt@440
   484
              class="tocxref"><span class="secno">10.</span> Garbage collection</a>
richt@437
   485
        </li>
richt@437
   486
        <li class="tocline">
richt@437
   487
          <a href="#use-cases-and-requirements"
richt@440
   488
              class="tocxref"><span class="secno">11.</span> Use Cases and Requirements</a>
richt@437
   489
        </li>
richt@437
   490
        <li class="tocline">
richt@437
   491
          <a href="#examples"
richt@437
   492
              class="tocxref"><span class="secno">A.</span> Examples</a>
richt@437
   493
        </li>
richt@437
   494
        <li class="tocline">
richt@437
   495
          <a href="#acknowledgements"
richt@437
   496
              class="tocxref"><span class="secno">B.</span> Acknowledgements</a>
richt@437
   497
        </li>
richt@437
   498
        <li class="tocline">
richt@437
   499
          <a href="#references"
richt@437
   500
              class="tocxref"><span class="secno">C.</span> References</a>
richt@437
   501
          <ul class="toc">
richt@437
   502
            <li class="tocline">
richt@437
   503
              <a href="#normative-references"
richt@437
   504
                  class="tocxref"><span class="secno">C.1</span> Normative references</a>
richt@437
   505
            </li>
richt@453
   506
            <li class="tocline">
richt@453
   507
              <a href="#informative-references"
richt@453
   508
                  class="tocxref"><span class="secno">C.2</span> Informative references</a>
richt@453
   509
            </li>
richt@437
   510
          </ul>
richt@437
   511
        </li>
richt@437
   512
      </ul>
richt@437
   513
    </section>
richt@437
   514
    <section class="informative"
richt@437
   515
             id="introduction">
richt@447
   516
      <h2 aria-level="1"
richt@447
   517
          role="heading"
richt@447
   518
          id="h2_introduction">
richt@437
   519
        <span class="secno">1.</span> Introduction
richt@437
   520
      </h2>
richt@437
   521
      <p>
richt@437
   522
        <em>This section is non-normative.</em>
richt@437
   523
      </p>
richt@437
   524
      <p>
richt@453
   525
        This specification defines the <a href="#navigatornetworkservice"><code>NavigatorNetworkService</code></a>
richt@453
   526
        interface to enable Web pages to connect and communicate with Local-networked Services provided over
richt@453
   527
        <abbr title="Hypertext Transfer Protocol">HTTP</abbr>. This enables access to services and content provided by
richt@453
   528
        home network devices, including the discovery and playback of content available to those devices, both from
richt@453
   529
        services such as traditional broadcast media and internet based services as well as local services. Initial
richt@453
   530
        design goals and requirements provided by the <a href="http://www.w3.org/2011/webtv/"><abbr title=
richt@453
   531
        "World Wide Web Consortium">W3C</abbr> Web &amp; TV interest group</a> are documented in [<cite><a class=
richt@453
   532
        "bibref"
richt@453
   533
           href="#bib-hnreq">hnreq</a></cite>].
richt@239
   534
      </p>
richt@239
   535
      <p>
richt@239
   536
        Using this <abbr title="Application Programming Interface">API</abbr> consists of requesting a well-known
richt@239
   537
        service type, known by developers and advertised by Local-networked Devices. User authorization, where the user
richt@379
   538
        connects the web page to discovered services, is expected before the web page is able to interact with any
richt@379
   539
        Local-networked Services.
richt@239
   540
      </p>
richt@239
   541
      <p>
richt@239
   542
        A web page creates a request to obtain connectivity to services running in the network by specifying a
richt@239
   543
        well-known discovery service type that it wishes to interact with.
richt@239
   544
      </p>
richt@239
   545
      <p>
richt@437
   546
        The user agent, having captured all advertised services on the network from the <a href=
richt@437
   547
        "#dfn-service-discovery-mechanisms"
richt@437
   548
           class="internalDFN">service discovery mechanisms</a> included in this recommendation, attempts to match the
richt@480
   549
           requested service type to a discovered service according to the processing described herein. Only
richt@483
   550
           Local-networked Services that pass a <a href="#dfn-preliminary-cors-check"
richt@483
   551
           class="internalDFN">preliminary CORS check</a> should be made available to web pages by a user agent. A user
richt@480
   552
           agent may provide a way for users to white-list non-CORS enabled Local-networked Services but implementation
richt@480
   553
           of such a feature is left to the discretion of the implementer.
richt@239
   554
      </p>
richt@239
   555
      <p>
richt@437
   556
        If a service connectivity request is successful then the Web page is provided with a promise-based success
richt@437
   557
        callback with the all necessary information to communicate with the authorized Local-networked Service. If the
richt@447
   558
        request fails then the Web page will receive a promise-based error callback containing an error string
richt@447
   559
        describing the cause of Local-networked Service connectivity failure.
richt@239
   560
      </p>
richt@239
   561
      <p>
richt@239
   562
        Once connected to a Local-networked Service the Web page can send requests and receive responses to the
richt@239
   563
        Local-networked Service via the messaging format and appropriate channel inferred from the service type
richt@437
   564
        authorized via the provided <abbr title="Application Programming Interface">API</abbr>. The Web page, once
richt@437
   565
        connected, can also receive service-pushed events, in the messaging format supported by the Local-networked
richt@437
   566
        Device, if such event subscription functionality is provided by the connected Local-networked Service.
richt@402
   567
      </p>
richt@402
   568
      <p>
richt@437
   569
        Services available within the local network can connect and disconnect at different times during the execution
richt@437
   570
        of a web page. The user agent can inform a web page when the state of networked services matching any of the
richt@437
   571
        requested valid service types change. Web pages can use this information to enable in-page experiences for
richt@437
   572
        communicating the state of networked services with the ability to change the particular service or set of
richt@437
   573
        services the page is connected to (by re-invoking the <a href=
richt@437
   574
        "#dom-navigator-getnetworkservices"><code>getNetworkServices()</code></a> method defined herein).
richt@239
   575
      </p>
richt@239
   576
      <div class="example">
richt@191
   577
        <p>
richt@437
   578
          Example of requesting a <abbr title="Domain Name System">DNS</abbr>-<abbr title="Service Discovery">SD</abbr>
richt@437
   579
          advertised service:
richt@191
   580
        </p>
richt@239
   581
        <hr>
richt@437
   582
        <pre class="highlight prettyprint">
richt@437
   583
<span class="kwd">function</span><span class="pln"> showServices</span><span class="pun">(</span><span class=
richt@437
   584
"pln"> services </span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
richt@194
   585
  </span><span class="com">// Show a list of all the services provided to the web page</span><span class="pln">
richt@437
   586
  </span><span class="kwd">for</span><span class="pun">(</span><span class="kwd">var</span><span class=
richt@437
   587
"pln"> i </span><span class="pun">=</span><span class="pln"> </span><span class="lit">0</span><span class=
richt@437
   588
"pun">,</span><span class="pln"> l </span><span class="pun">=</span><span class="pln"> services</span><span class=
richt@437
   589
"pun">.</span><span class="pln">length</span><span class="pun">;</span><span class="pln"> i </span><span class=
richt@437
   590
"pun">&lt;</span><span class="pln"> l</span><span class="pun">;</span><span class="pln"> i</span><span class=
richt@437
   591
"pun">++)</span><span class="pln"> console</span><span class="pun">.</span><span class="pln">log</span><span class=
richt@437
   592
"pun">(</span><span class="pln"> services</span><span class="pun">[</span><span class="pln">i</span><span class=
richt@437
   593
"pun">].</span><span class="pln">name </span><span class="pun">);</span><span class="pln">
richt@194
   594
</span><span class="pun">}</span><span class="pln">
richt@194
   595
richt@437
   596
navigator</span><span class="pun">.</span><span class="pln">getNetworkServices</span><span class=
richt@437
   597
"pun">(</span><span class="str">'zeroconf:_boxee-jsonrpc._tcp'</span><span class="pun">).</span><span class=
richt@437
   598
"kwd">then</span><span class="pun">(</span><span class="pln">showServices</span><span class="pun">);</span>
richt@437
   599
</pre>
richt@180
   600
      </div>
richt@180
   601
      <div class="example">
richt@239
   602
        <p>
richt@239
   603
          Example of requesting a UPnP advertised service, also handling error conditions:
richt@239
   604
        </p>
richt@180
   605
        <hr>
richt@437
   606
        <pre class="highlight prettyprint">
richt@437
   607
<span class="kwd">function</span><span class="pln"> showServices</span><span class="pun">(</span><span class=
richt@437
   608
"pln"> services </span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
richt@194
   609
  </span><span class="com">// Show a list of all the services provided to the web page</span><span class="pln">
richt@437
   610
  </span><span class="kwd">for</span><span class="pun">(</span><span class="kwd">var</span><span class=
richt@437
   611
"pln"> i </span><span class="pun">=</span><span class="pln"> </span><span class="lit">0</span><span class=
richt@437
   612
"pun">,</span><span class="pln"> l </span><span class="pun">=</span><span class="pln"> services</span><span class=
richt@437
   613
"pun">.</span><span class="pln">length</span><span class="pun">;</span><span class="pln"> i </span><span class=
richt@437
   614
"pun">&lt;</span><span class="pln"> l</span><span class="pun">;</span><span class="pln"> i</span><span class=
richt@437
   615
"pun">++)</span><span class="pln"> console</span><span class="pun">.</span><span class="pln">log</span><span class=
richt@437
   616
"pun">(</span><span class="pln"> services</span><span class="pun">[</span><span class="pln">i</span><span class=
richt@437
   617
"pun">].</span><span class="pln">name </span><span class="pun">);</span><span class="pln">
richt@194
   618
</span><span class="pun">}</span><span class="pln">
richt@194
   619
richt@437
   620
</span><span class="kwd">function</span><span class="pln"> error</span><span class="pun">(</span><span class=
richt@437
   621
"pln"> e </span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
richt@437
   622
  console</span><span class="pun">.</span><span class="pln">log</span><span class="pun">(</span><span class=
richt@437
   623
"pln"> </span><span class="str">"Error occurred: "</span><span class="pln"> </span><span class=
richt@447
   624
"pun">+</span><span class="pln"> e</span><span class="pun">.</span><span class="pln">name </span><span class=
richt@437
   625
"pun">);</span><span class="pln">
richt@194
   626
</span><span class="pun">}</span><span class="pln">
richt@194
   627
richt@437
   628
navigator</span><span class="pun">.</span><span class="pln">getNetworkServices</span><span class=
richt@437
   629
"pun">(</span><span class="str">'upnp:urn:schemas-upnp-org:service:ContentDirectory:1'</span><span class=
richt@437
   630
"pun">).</span><span class="kwd">then</span><span class="pun">(</span><span class="pln">showServices</span><span class=
richt@437
   631
"pun">,</span><span class="pln"> error</span><span class="pun">);</span>
richt@437
   632
</pre>
richt@180
   633
      </div>
richt@180
   634
      <div class="example">
richt@239
   635
        <p>
richt@437
   636
          Example of requesting either a <abbr title="Domain Name System">DNS</abbr>-<abbr title=
richt@437
   637
          "Service Discovery">SD</abbr> or UPnP advertised service:
richt@239
   638
        </p>
richt@180
   639
        <hr>
richt@437
   640
        <pre class="highlight prettyprint">
richt@437
   641
<span class="kwd">function</span><span class="pln"> showServices</span><span class="pun">(</span><span class=
richt@437
   642
"pln"> services </span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
richt@437
   643
  </span><span class=
richt@437
   644
"com">// Show a list of all the services provided to the web page (+ service type)</span><span class="pln">
richt@437
   645
  </span><span class="kwd">for</span><span class="pun">(</span><span class="kwd">var</span><span class=
richt@437
   646
"pln"> i </span><span class="pun">=</span><span class="pln"> </span><span class="lit">0</span><span class=
richt@437
   647
"pun">,</span><span class="pln"> l </span><span class="pun">=</span><span class="pln"> services</span><span class=
richt@437
   648
"pun">.</span><span class="pln">length</span><span class="pun">;</span><span class="pln"> i </span><span class=
richt@437
   649
"pun">&lt;</span><span class="pln"> l</span><span class="pun">;</span><span class="pln"> i</span><span class=
richt@437
   650
"pun">++)</span><span class="pln">
richt@437
   651
     console</span><span class="pun">.</span><span class="pln">log</span><span class="pun">(</span><span class=
richt@437
   652
"pln"> services</span><span class="pun">[</span><span class="pln">i</span><span class="pun">].</span><span class=
richt@437
   653
"pln">name </span><span class="pun">+</span><span class="pln"> </span><span class="str">'('</span><span class=
richt@437
   654
"pln"> </span><span class="pun">+</span><span class="pln"> services</span><span class="pun">[</span><span class=
richt@437
   655
"pln">i</span><span class="pun">].</span><span class="pln">type </span><span class="pun">+</span><span class=
richt@437
   656
"pln"> </span><span class="str">')'</span><span class="pln"> </span><span class="pun">);</span><span class="pln">
richt@194
   657
</span><span class="pun">}</span><span class="pln">
richt@194
   658
richt@437
   659
navigator</span><span class="pun">.</span><span class="pln">getNetworkServices</span><span class=
richt@437
   660
"pun">([</span><span class="pln">
richt@194
   661
  </span><span class="str">'zeroconf:_boxee-jsonrpc._tcp'</span><span class="pun">,</span><span class="pln">
richt@194
   662
  </span><span class="str">'upnp:urn:schemas-upnp-org:service:ContentDirectory:1'</span><span class="pln">
richt@437
   663
</span><span class="pun">]).</span><span class="kwd">then</span><span class="pun">(</span><span class=
richt@437
   664
"pln">showServices</span><span class="pun">);</span>
richt@437
   665
</pre>
richt@180
   666
      </div>
richt@239
   667
      <p>
richt@440
   668
        For more detailed examples, including examples of communicating with obtained networked services, see the
richt@440
   669
        <a href="#examples">Examples</a> section.
richt@239
   670
      </p>
richt@239
   671
    </section>
richt@437
   672
    <section id="conformance"
richt@437
   673
             typeof="bibo:Chapter"
richt@484
   674
             resource="#ref"
richt@484
   675
             rel="bibo:Chapter">
richt@447
   676
      <h2 aria-level="1"
richt@447
   677
          role="heading"
richt@447
   678
          id="h2_conformance">
richt@437
   679
        <span class="secno">2.</span> Conformance
richt@437
   680
      </h2>
richt@437
   681
      <p>
richt@437
   682
        As well as sections marked as non-normative, all authoring guidelines, diagrams, examples, and notes in this
richt@437
   683
        specification are non-normative. Everything else in this specification is normative.
richt@437
   684
      </p>
richt@437
   685
      <p>
richt@437
   686
        The key words <em class="rfc2119"
richt@437
   687
           title="MUST">MUST</em>, <em class="rfc2119"
richt@437
   688
           title="MUST NOT">MUST NOT</em>, <em class="rfc2119"
richt@437
   689
           title="REQUIRED">REQUIRED</em>, <em class="rfc2119"
richt@437
   690
           title="SHOULD">SHOULD</em>, <em class="rfc2119"
richt@437
   691
           title="SHOULD NOT">SHOULD NOT</em>, <em class="rfc2119"
richt@437
   692
           title="RECOMMENDED">RECOMMENDED</em>, <em class="rfc2119"
richt@437
   693
           title="MAY">MAY</em>, and <em class="rfc2119"
richt@437
   694
           title="OPTIONAL">OPTIONAL</em> in this specification are to be interpreted as described in [<cite><a class=
richt@437
   695
           "bibref"
richt@437
   696
           href="#bib-RFC2119">RFC2119</a></cite>].
richt@437
   697
      </p>
richt@239
   698
      <p>
richt@239
   699
        Requirements phrased in the imperative as part of algorithms (such as "strip any leading space characters" or
richt@239
   700
        "return false and abort these steps") are to be interpreted with the meaning of the key word ("must", "should",
richt@239
   701
        "may", etc) used in introducing the algorithm.
richt@239
   702
      </p>
richt@239
   703
      <p>
richt@239
   704
        Some conformance requirements are phrased as requirements on attributes, methods or objects. Such requirements
richt@239
   705
        are to be interpreted as requirements on user agents.
richt@239
   706
      </p>
richt@239
   707
      <p>
richt@437
   708
        Conformance requirements phrased as algorithms or specific steps <em class="rfc2119"
richt@437
   709
           title="MAY">MAY</em> be implemented in any manner, so long as the end result is equivalent. (In particular,
richt@437
   710
           the algorithms defined in this specification are intended to be easy to follow, and not intended to be
richt@437
   711
           performant.)
richt@239
   712
      </p>
richt@239
   713
      <p>
richt@239
   714
        The only conformance class defined by this specification is a <dfn id="dfn-user-agent">user agent</dfn>.
richt@239
   715
      </p>
richt@239
   716
      <p>
richt@437
   717
        User agents <em class="rfc2119"
richt@437
   718
           title="MAY">MAY</em> impose implementation-specific limits on otherwise unconstrained inputs, e.g. to
richt@437
   719
           prevent denial of service attacks, to guard against running out of memory, or to work around
richt@437
   720
           platform-specific limitations.
richt@239
   721
      </p>
richt@239
   722
      <p>
richt@239
   723
        When support for a feature is disabled (e.g. as an emergency measure to mitigate a security problem, or to aid
richt@437
   724
        in development, or for performance reasons), user agents <em class="rfc2119"
richt@437
   725
           title="MUST">MUST</em> act as if they had no support for the feature whatsoever, and as if the feature was
richt@437
   726
           not mentioned in this specification. For example, if a particular feature is accessed via an attribute in a
richt@437
   727
           Web IDL interface, the attribute itself would be omitted from the objects that implement that interface -
richt@437
   728
           leaving the attribute on the object but making it return null or throw an exception is insufficient.
richt@239
   729
      </p>
richt@194
   730
      <section id="dependencies">
richt@447
   731
        <h3 aria-level="2"
richt@447
   732
            role="heading"
richt@447
   733
            id="h3_dependencies">
richt@437
   734
          <span class="secno">2.1</span> Dependencies
richt@239
   735
        </h3>This specification relies on several other underlying specifications.
richt@239
   736
        <dl>
richt@239
   737
          <dt>
richt@239
   738
            HTML
richt@239
   739
          </dt>
richt@239
   740
          <dd>
richt@437
   741
            Many fundamental concepts from HTML are used by this specification. [<cite><a class="bibref"
richt@437
   742
               href="#bib-HTML5">HTML5</a></cite>]
richt@239
   743
          </dd>
richt@239
   744
          <dt>
richt@239
   745
            WebIDL
richt@239
   746
          </dt>
richt@239
   747
          <dd>
richt@437
   748
            The IDL blocks in this specification use the semantics of the WebIDL specification. [<cite><a class=
richt@437
   749
            "bibref"
richt@437
   750
               href="#bib-WEBIDL">WEBIDL</a></cite>]
richt@239
   751
          </dd>
richt@239
   752
        </dl>
richt@180
   753
      </section>
richt@194
   754
    </section>
richt@194
   755
    <section id="terminology">
richt@447
   756
      <h2 aria-level="1"
richt@447
   757
          role="heading"
richt@447
   758
          id="h2_terminology">
richt@437
   759
        <span class="secno">3.</span> Terminology
richt@239
   760
      </h2>
richt@180
   761
      <p>
richt@239
   762
        The construction "a <code>Foo</code> object", where <code>Foo</code> is actually an interface, is sometimes
richt@239
   763
        used instead of the more accurate "an object implementing the interface <code>Foo</code>".
richt@180
   764
      </p>
richt@180
   765
      <p>
richt@437
   766
        The term DOM is used to refer to the <abbr title="Application Programming Interface">API</abbr> set made
richt@437
   767
        available to scripts in Web applications, and does not necessarily imply the existence of an actual
richt@437
   768
        <code>Document</code> object or of any other <code>Node</code> objects as defined in the DOM Core
richt@437
   769
        specifications. [<cite><a class="bibref"
richt@437
   770
           href="#bib-DOM4">DOM4</a></cite>]
richt@180
   771
      </p>
richt@180
   772
      <p>
richt@239
   773
        An IDL attribute is said to be <em>getting</em> when its value is being retrieved (e.g. by author script), and
richt@239
   774
        is said to be <em>setting</em> when a new value is assigned to it.
richt@180
   775
      </p>
richt@180
   776
      <p>
richt@333
   777
        A <dfn id="dfn-valid-service-type">valid service type</dfn> is any of the following:
richt@379
   778
      </p>
richt@379
   779
      <ul>
richt@379
   780
        <li>a string that begins with <code>upnp:</code> or <code>zeroconf:</code> followed by one or more characters
richt@379
   781
        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,
richt@379
   782
        U+005E to U+007E.
richt@379
   783
        </li>
richt@379
   784
        <li>a string that begins with <code>dial:</code> followed by an integer version.
richt@379
   785
        </li>
richt@379
   786
      </ul>
richt@333
   787
      <p>
richt@437
   788
        A <a href="#dfn-valid-service-type"
richt@437
   789
           class="internalDFN">valid service type</a> provided in the <code>type</code> attribute of the <a href=
richt@437
   790
           "#dom-navigator-getnetworkservices"><code>getNetworkServices()</code></a> method will be matched against the
richt@437
   791
           services currently contained in the <a href="#dfn-list-of-available-service-records"
richt@437
   792
           class="internalDFN">list of available service records</a> according to the algorithms defined in this
richt@437
   793
           specification.
richt@180
   794
      </p>
richt@180
   795
      <p>
richt@437
   796
        A <dfn id="dfn-user-agent-generated-callback-url">user-agent generated callback url</dfn> is a Local-network
richt@480
   797
        accessible URL endpoint that a <a href="#dfn-user-agent"
richt@437
   798
           class="internalDFN">user agent</a> generates and maintains for receiving <abbr title=
richt@437
   799
           "Hypertext Transfer Protocol">HTTP</abbr> NOTIFY requests from UPnP Event sources. It is only required when
richt@437
   800
           the user agent implements UPnP Service Discovery as defined in this specification.
richt@230
   801
      </p>
richt@389
   802
      <p>
richt@389
   803
        In this specification we use the following terms to describe the processes required for Local-networked
richt@389
   804
        Services management:
richt@389
   805
      </p>
richt@389
   806
      <ul>
richt@437
   807
        <li>A <dfn id="dfn-new-service">new service</dfn> is a Local-networked Service that has not previously been
richt@437
   808
        discovered or registered in the <a href="#dfn-list-of-available-service-records"
richt@437
   809
              class="internalDFN">list of available service records</a>.
richt@389
   810
        </li>
richt@437
   811
        <li>An <dfn id="dfn-existing-service">existing service</dfn> is a Local-networked Service that has previously
richt@437
   812
        been discovered and is registered in the <a href="#dfn-list-of-available-service-records"
richt@437
   813
              class="internalDFN">list of available service records</a>.
richt@389
   814
        </li>
richt@437
   815
        <li>A <dfn id="dfn-current-service">current service</dfn> is a Local-networked Service, represented by a
richt@437
   816
        <a href="#networkservice"><code>NetworkService</code></a> object, that is currently being shared with a web
richt@437
   817
        page via a <a href="#networkservices"><code>NetworkServices</code></a> object registered in the <a href=
richt@437
   818
        "#dfn-list-of-active-service-managers"
richt@437
   819
              class="internalDFN">list of active service managers</a>.
richt@389
   820
        </li>
richt@389
   821
      </ul>
richt@480
   822
      <p>
richt@480
   823
        A <dfn id="dfn-network-services-whitelist">network services whitelist</dfn> is a list of zero or more <a href=
richt@480
   824
        "#dfn-valid-service-type"
richt@480
   825
           class="internalDFN">valid service type</a> tokens that, when matched to a service type discovered in the
richt@480
   826
           local network, enables that service to be shared with a web page even if that Local-networked Service does
richt@480
   827
           not itself allow Cross-Origin Resource Sharing [<cite><a class="bibref"
richt@480
   828
           href="#bib-CORS">CORS</a></cite>]. A <a href="#dfn-user-agent"
richt@480
   829
           class="internalDFN">user agent</a> <em class="rfc2119"
richt@480
   830
           title="MUST">MUST</em> simulate CORS support for all service interaction in this case. Implementation of
richt@480
   831
           this feature is at implementer's discretion. When a <a href="#dfn-user-agent"
richt@480
   832
           class="internalDFN">user agent</a> does not implement a <a href="#dfn-network-services-whitelist"
richt@480
   833
           class="internalDFN">network services whitelist</a> then it is to treat this as always being an empty list.
richt@480
   834
      </p>
richt@194
   835
    </section>
richt@440
   836
    <section id="security-and-privacy-considerations">
richt@447
   837
      <h2 aria-level="1"
richt@447
   838
          role="heading"
richt@447
   839
          id="h2_security-and-privacy-considerations">
richt@440
   840
        <span class="secno">4.</span> Security and privacy considerations
richt@440
   841
      </h2>
richt@440
   842
      <p>
richt@440
   843
        The <abbr title="Application Programming Interface">API</abbr> defined in this specification can be used to
richt@440
   844
        find and connect to devices and services within a user's current network. This discloses information related to
richt@440
   845
        a user's network: devices available on their network and the publicly-accessible services ("networked
richt@440
   846
        services") currently running and available on those devices. The distribution of this information could
richt@440
   847
        potentially compromise the user's privacy. A conforming implementation of this specification <em class=
richt@440
   848
        "rfc2119"
richt@440
   849
           title="MUST">MUST</em> provide a mechanism that protects the user's privacy. This mechanism <em class=
richt@440
   850
           "rfc2119"
richt@440
   851
           title="MUST">MUST</em> ensure that no networked service information is retrievable without the user's
richt@440
   852
           express permission.
richt@440
   853
      </p>
richt@480
   854
      <section id="security-considerations-for-api-implementations">
richt@480
   855
        <h3 aria-level="2"
richt@480
   856
            role="heading"
richt@480
   857
            id="h3_security-considerations-for-api-implementations">
richt@480
   858
          <span class="secno">4.1</span> Security considerations for <abbr title=
richt@480
   859
          "Application Programming Interface">API</abbr> implementations
richt@480
   860
        </h3>
richt@480
   861
        <p>
richt@480
   862
          A <a href="#dfn-user-agent"
richt@480
   863
             class="internalDFN">user agent</a> <em class="rfc2119"
richt@483
   864
             title="SHOULD">SHOULD</em> only allow web pages to connect with Local-networked Services that have passed
richt@483
   865
             a <a href="#dfn-preliminary-cors-check"
richt@483
   866
             class="internalDFN">preliminary CORS check</a> indicating they support Cross-Origin Resource Sharing
richt@480
   867
             [<cite><a class="bibref"
richt@483
   868
             href="#bib-CORS">CORS</a></cite>]. In this way, a <a href="#dfn-user-agent"
richt@480
   869
             class="internalDFN">user agent</a> <em class="rfc2119"
richt@483
   870
             title="SHOULD NOT">SHOULD NOT</em> allow web pages to access other arbitrary networked services on the
richt@483
   871
             current local network.
richt@480
   872
        </p>
richt@480
   873
        <p>
richt@480
   874
          A <a href="#dfn-user-agent"
richt@480
   875
             class="internalDFN">user agent</a> <em class="rfc2119"
richt@480
   876
             title="MAY">MAY</em> provide a way for users to enable access to non-CORS enabled Local-networked Services
richt@480
   877
             from web pages (i.e. operate a <a href="#dfn-network-services-whitelist"
richt@480
   878
             class="internalDFN">network services whitelist</a>). Implementation of such a <a href=
richt@480
   879
             "#dfn-network-services-whitelist"
richt@480
   880
             class="internalDFN">network services whitelist</a>, if any, is left to an implementer's discretion. Such a
richt@480
   881
             whitelist may be configurable by each user at runtime or may be managed by the implementation itself on
richt@480
   882
             behalf of its users. In the case that a <a href="#dfn-user-agent"
richt@480
   883
             class="internalDFN">user agent</a> provides a <a href="#dfn-network-services-whitelist"
richt@480
   884
             class="internalDFN">network services whitelist</a>, it <em class="rfc2119"
richt@480
   885
             title="MUST">MUST</em> act as if all URLs for the Local-networked Service corresponding to any previously
richt@480
   886
             whitelisted service type had Cross-Origin Resource Sharing [<cite><a class="bibref"
richt@480
   887
             href="#bib-CORS">CORS</a></cite>] enabled indefinitely.
richt@480
   888
        </p>
richt@480
   889
      </section>
richt@440
   890
      <section id="privacy-considerations-for-api-implementations">
richt@447
   891
        <h3 aria-level="2"
richt@447
   892
            role="heading"
richt@447
   893
            id="h3_privacy-considerations-for-api-implementations">
richt@480
   894
          <span class="secno">4.2</span> Privacy considerations for <abbr title=
richt@440
   895
          "Application Programming Interface">API</abbr> implementations
richt@440
   896
        </h3>
richt@440
   897
        <p>
richt@440
   898
          A <a href="#dfn-user-agent"
richt@440
   899
             class="internalDFN">user agent</a> <em class="rfc2119"
richt@440
   900
             title="MUST NOT">MUST NOT</em> provide networked service information to web sites without the express
richt@440
   901
             permission of the user. A user agent <em class="rfc2119"
richt@440
   902
             title="MUST">MUST</em> acquire permission through a user interface, unless they have prearranged trust
richt@440
   903
             relationships with users, as described below. The user interface <em class="rfc2119"
richt@480
   904
             title="MUST">MUST</em> include the document base URL. Those permissions that are acquired through the user
richt@480
   905
             interface and that are preserved beyond the current browsing session (i.e. beyond the time when the
richt@480
   906
             browsing context is navigated to another URL) <em class="rfc2119"
richt@440
   907
             title="MUST">MUST</em> be revocable and a user agent <em class="rfc2119"
richt@440
   908
             title="MUST">MUST</em> respect revoked permissions.
richt@440
   909
        </p>
richt@440
   910
        <p>
richt@440
   911
          Obtaining the user's express permission to access one <abbr title=
richt@440
   912
          "Application Programming Interface">API</abbr> method does not imply the user has granted permission for the
richt@440
   913
          same web site to access any other methods that may be provided by this <abbr title=
richt@440
   914
          "Application Programming Interface">API</abbr>, or to access the same method with a different set of
richt@440
   915
          arguments, as part of the same permission context. If a user has expressed permission for an implementation
richt@440
   916
          to, e.g. find a set of existing networked services, the implementation <em class="rfc2119"
richt@440
   917
             title="MUST">MUST</em> seek the user's express permission if and when any subsequent functions are called
richt@440
   918
             on this <abbr title="Application Programming Interface">API</abbr>.
richt@440
   919
        </p>
richt@440
   920
        <p>
richt@440
   921
          A user agent <em class="rfc2119"
richt@440
   922
             title="MAY">MAY</em> have prearranged trust relationships that do not require such user interfaces. For
richt@440
   923
             example, while a web browser will present a user interface when a web site performs a networked service
richt@440
   924
             lookup, a different runtime may have a prearranged, delegated security relationship with the user and, as
richt@440
   925
             such, a suitable alternative security and privacy mechanism with which to authorise the retrieval of
richt@440
   926
             networked service information.
richt@440
   927
        </p>
richt@440
   928
      </section>
richt@440
   929
      <section class="informative"
richt@440
   930
               id="additional-api-implementation-considerations">
richt@447
   931
        <h3 aria-level="2"
richt@447
   932
            role="heading"
richt@447
   933
            id="h3_additional-api-implementation-considerations">
richt@480
   934
          <span class="secno">4.3</span> Additional <abbr title="Application Programming Interface">API</abbr>
richt@440
   935
          implementation considerations
richt@440
   936
        </h3>
richt@440
   937
        <p>
richt@440
   938
          <em>This section is non-normative.</em>
richt@440
   939
        </p>
richt@440
   940
        <p>
richt@480
   941
          Further to the requirements listed in the previous section, implementers of the Network Service Discovery
richt@440
   942
          <abbr title="Application Programming Interface">API</abbr> are also advised to consider the following aspects
richt@440
   943
          that can negatively affect the privacy of their users: in certain cases, users can inadvertently grant
richt@440
   944
          permission to the user agent to disclose networked services to Web sites. In other cases, the content hosted
richt@480
   945
          at a certain URL changes in such a way that previously granted networked service permissions no longer apply
richt@480
   946
          as far as the user is concerned. Or the users might simply change their minds.
richt@440
   947
        </p>
richt@440
   948
        <p>
richt@440
   949
          Predicting or preventing these situations is inherently difficult. Mitigation and in-depth defensive measures
richt@440
   950
          are an implementation responsibility and not prescribed by this specification. However, in designing these
richt@440
   951
          measures, implementers are advised to enable user awareness of networked service sharing, and to provide easy
richt@440
   952
          access to interfaces that enable revocation of permissions that web applications have for accessing networked
richt@440
   953
          services via this <abbr title="Application Programming Interface">API</abbr>.
richt@440
   954
        </p>
richt@440
   955
      </section>
richt@440
   956
    </section>
richt@194
   957
    <section id="requesting-networked-services">
richt@447
   958
      <h2 aria-level="1"
richt@447
   959
          role="heading"
richt@447
   960
          id="h2_requesting-networked-services">
richt@440
   961
        <span class="secno">5.</span> Requesting networked services
richt@239
   962
      </h2>
richt@437
   963
      <pre class="widl">
richt@437
   964
[Supplemental, NoInterfaceObject]
richt@180
   965
interface <dfn id="navigatornetworkservice">NavigatorNetworkService</dfn> {
richt@437
   966
  <a class="externalDFN"
richt@437
   967
     href="http://dom.spec.whatwg.org/#promise">Promise</a> <a href=
richt@437
   968
     "#dom-navigator-getnetworkservices">getNetworkServices</a>( in any type );
richt@180
   969
};
richt@447
   970
richt@437
   971
<a class="externalDFN"
richt@437
   972
     href=
richt@437
   973
     "http://www.whatwg.org/specs/web-apps/current-work/complete/timers.html#navigator">Navigator</a> implements <a href=
richt@437
   974
     "#navigatornetworkservice">NavigatorNetworkService</a>;
richt@180
   975
</pre>
richt@239
   976
      <section id="methods">
richt@447
   977
        <h3 aria-level="2"
richt@447
   978
            role="heading"
richt@447
   979
            id="h3_methods">
richt@440
   980
          <span class="secno">5.1</span> Methods
richt@239
   981
        </h3>
richt@239
   982
        <dl class="domintro">
richt@239
   983
          <dt>
richt@437
   984
            <var title="">promise</var> = <var title="">window</var> . <code title="dom-navigator"><a href=
richt@437
   985
            "http://www.whatwg.org/specs/web-apps/current-work/complete/timers.html#navigator">navigator</a></code> .
richt@437
   986
            <code title="dom-navigator-getNetworkServices"><a href=
richt@437
   987
            "#dom-navigator-getnetworkservices">getNetworkServices</a></code> ( <var title="">type</var> )
richt@239
   988
          </dt>
richt@239
   989
          <dd>
richt@239
   990
            <p>
richt@437
   991
              Immediately returns a new <a href="http://dom.spec.whatwg.org/#promise"
richt@437
   992
                 class="externalDFN">Promise</a> object and then the user is prompted to select discovered network
richt@437
   993
                 services that have advertised support for the requested service type(s).
richt@239
   994
            </p>
richt@239
   995
            <p>
richt@437
   996
              The <var title="">type</var> argument contains one or more <a href="#dfn-valid-service-type"
richt@437
   997
                 class="internalDFN">valid service type</a> tokens that the web page would like to interact with.
richt@239
   998
            </p>
richt@239
   999
            <p>
richt@437
  1000
              If the user accepts, the <var title="">promise</var> object is <a class="externalDFN"
richt@437
  1001
                 href="http://dom.spec.whatwg.org/#concept-resolver-resolve">resolved</a>, with a <a href=
richt@437
  1002
                 "#networkservices"><code>NetworkServices</code></a> object as its argument.
richt@239
  1003
            </p>
richt@239
  1004
            <p>
richt@437
  1005
              If the user declines, or an error occurs, the <var title="">promise</var> object is <a class=
richt@437
  1006
              "externalDFN"
richt@437
  1007
                 href="http://dom.spec.whatwg.org/#concept-resolver-reject">rejected</a>.
richt@239
  1008
            </p>
richt@239
  1009
          </dd>
richt@239
  1010
        </dl>
richt@239
  1011
        <div>
richt@180
  1012
          <p>
richt@437
  1013
            When the <dfn id="dom-navigator-getnetworkservices"
richt@437
  1014
               title="dom-navigator-getnetworkservices"><code>getNetworkServices(type)</code></dfn> method is called,
richt@437
  1015
               the <a href="#dfn-user-agent"
richt@437
  1016
               class="internalDFN">user agent</a> <em class="rfc2119"
richt@437
  1017
               title="MUST">MUST</em> run the following steps:
richt@180
  1018
          </p>
richt@180
  1019
          <ol class="rule">
richt@437
  1020
            <li>Let <var>Network Service Promise</var> be a new <a href="http://dom.spec.whatwg.org/#promise"
richt@437
  1021
                  class="externalDFN"><code>Promise</code></a> object.
richt@437
  1022
            </li>
richt@437
  1023
            <li>Let <var>Network Service Promise's Resolver</var> be the default <a href=
richt@437
  1024
            "http://dom.spec.whatwg.org/#concept-resolver"
richt@437
  1025
                  class="externalDFN">resolver</a> of <var>Network Service Promise</var>.
richt@437
  1026
            </li>
richt@437
  1027
            <li>Return <var>Network Service Promise</var>, and run the remaining steps asynchronously.
richt@437
  1028
            </li>
richt@239
  1029
            <li>Let <var>requested control types</var> be initially set to an empty array.
richt@239
  1030
            </li>
richt@437
  1031
            <li>If <var>type</var> is an array consisting of one or more <a href="#dfn-valid-service-type"
richt@484
  1032
                  class="internalDFN">valid service type</a> tokens, then let <var>requested control types</var> be the
richt@437
  1033
                  value of <var>type</var>, removing any non-<a href="#dfn-valid-service-type"
richt@437
  1034
                  class="internalDFN">valid service type</a> tokens from the resulting array.
richt@239
  1035
            </li>
richt@437
  1036
            <li>If <var>type</var> is a string consisting of one <a href="#dfn-valid-service-type"
richt@437
  1037
                  class="internalDFN">valid service type</a> token, then let <var>requested control types</var> be an
richt@437
  1038
                  array containing one item with a value of <var>type</var>.
richt@239
  1039
            </li>
richt@437
  1040
            <li>If <var>requested control types</var> is an array that contains at least one or more <a title=
richt@437
  1041
            "valid service type"
richt@437
  1042
                  href="#dfn-valid-service-type"
richt@437
  1043
                  class="internalDFN">valid service type</a> tokens then continue to the step labeled <em>process</em>
richt@437
  1044
                  below. Otherwise, reject <var>Network Service Promise</var> by running the <a href=
richt@437
  1045
                  "http://dom.spec.whatwg.org/#concept-resolver-reject"
richt@437
  1046
                  class="externalDFN">resolver reject algorithm</a> against the <var>Network Service Promise's
richt@447
  1047
                  Resolver</var>, passing in a newly constructed <a href="http://dom.spec.whatwg.org/#domerror"
richt@447
  1048
                  class="externalDFN"><code>DOMError</code></a> object whose <code>name</code> attribute has the string
richt@447
  1049
                  value "UnknownTypePrefixError" (<a href=
richt@447
  1050
                  "#dom-domerror-extensions-unknown_type_prefix"><code>UNKNOWN_TYPE_PREFIX_ERR</code></a>) and whose
richt@447
  1051
                  <code>message</code> attribute has a helpful implementation-dependent message that explains this
richt@447
  1052
                  error, abort any remaining steps and return.
richt@239
  1053
            </li>
richt@180
  1054
            <li>
richt@239
  1055
              <em>Process</em>: Let <var>services found</var> be an empty array.
richt@180
  1056
            </li>
richt@437
  1057
            <li>For each <var>available service</var> in the <a href="#dfn-list-of-available-service-records"
richt@437
  1058
                  class="internalDFN">list of available service records</a> run the following steps:
richt@239
  1059
              <ol class="rule">
richt@239
  1060
                <li>For each <var>requested control type</var> in <var>requested control types</var>: If <var>available
richt@239
  1061
                service</var>'s <code>type</code> attribute equals the <var>requested control type</var> then let <var>
richt@483
  1062
                  matched service</var> equal the value of <var>available service</var>. Otherwise, abort the remaining
richt@483
  1063
                  sub-steps and continue above at the next <var>available service</var>.
richt@239
  1064
                </li>
richt@483
  1065
                <li>If <var>matched service</var> is not empty then run the following steps:
richt@239
  1066
                  <ol class="rule">
richt@483
  1067
                    <li>Let <var>CORS check result</var> be the result of running the <a href=
richt@483
  1068
                    "#dfn-preliminary-cors-check"
richt@483
  1069
                          class="internalDFN">preliminary CORS check</a> algorithm, passing in <var>matched
richt@483
  1070
                          services</var>'s <code>url</code> attribute as the <var>control endpoint URL</var> argument
richt@483
  1071
                          and the <a href=
richt@483
  1072
                          "http://www.whatwg.org/specs/web-apps/current-work/complete/browsers.html#entry-script"
richt@483
  1073
                          class="externalDFN">entry script</a>'s <a href=
richt@483
  1074
                          "http://www.whatwg.org/specs/web-apps/current-work/complete/origin-0.html#origin"
richt@483
  1075
                          class="externalDFN">origin</a> as the <var>request origin</var> argument.
richt@483
  1076
                    </li>
richt@483
  1077
                    <li>If <var>CORS check result</var> is not <code>pass</code> and <var>matched service</var>'s
richt@483
  1078
                    <code>type</code> attribute is also not present in the <a href="#dfn-network-services-whitelist"
richt@483
  1079
                          class="internalDFN">network services whitelist</a> then abort the remaining sub-steps and
richt@483
  1080
                          continue above at the next <var>available service</var>.
richt@483
  1081
                    </li>
richt@437
  1082
                    <li>Let <var>new service object</var> be a new <a href=
richt@437
  1083
                    "#networkservice"><code>NetworkService</code></a> object, mapping the parameters of <var>matched
richt@239
  1084
                    service</var> to this new object where possible.
richt@239
  1085
                    </li>
richt@239
  1086
                    <li>Append <var>new service object</var> to the <var>services found</var> array.
richt@239
  1087
                    </li>
richt@239
  1088
                  </ol>
richt@239
  1089
                </li>
richt@239
  1090
              </ol>
richt@180
  1091
            </li>
richt@239
  1092
            <li>Optionally, e.g. based on a previously-established user preference, for security reasons, or due to
richt@437
  1093
            platform limitations, the <a href="#dfn-user-agent"
richt@437
  1094
                  class="internalDFN">user agent</a> <em class="rfc2119"
richt@437
  1095
                  title="MAY">MAY</em> reject <var>Network Service Promise</var> by running the <a href=
richt@437
  1096
                  "http://dom.spec.whatwg.org/#concept-resolver-reject"
richt@437
  1097
                  class="externalDFN">resolver reject algorithm</a> against the <var>Network Service Promise's
richt@447
  1098
                  Resolver</var>, passing in a newly constructed <a href="http://dom.spec.whatwg.org/#domerror"
richt@447
  1099
                  class="externalDFN"><code>DOMError</code></a> object whose <code>name</code> attribute has the string
richt@447
  1100
                  value "PermissionDeniedError" (<a href=
richt@447
  1101
                  "#dom-domerror-extensions-permission_denied"><code>PERMISSION_DENIED_ERR</code></a>) and whose
richt@447
  1102
                  <code>message</code> attribute has a helpful implementation-dependent message that explains this
richt@447
  1103
                  error, abort any remaining steps and return.
richt@180
  1104
            </li>
richt@437
  1105
            <li>The user agent <em class="rfc2119"
richt@437
  1106
                  title="MUST NOT">MUST NOT</em> provide the entry script's origin with a <a href=
richt@437
  1107
                  "#networkservices"><code>NetworkServices</code></a> object without prior permission given by the
richt@437
  1108
                  user.
richt@239
  1109
              <p>
richt@437
  1110
                If <var>services found</var> is not an empty array then the <a href="#dfn-user-agent"
richt@437
  1111
                   class="internalDFN">user agent</a> <em class="rfc2119"
richt@437
  1112
                   title="MAY">MAY</em> choose to prompt the user in a user-agent-specific manner for permission to
richt@437
  1113
                   provide the <a href=
richt@437
  1114
                   "http://www.whatwg.org/specs/web-apps/current-work/complete/browsers.html#entry-script"
richt@437
  1115
                   class="externalDFN">entry script</a>'s <a href=
richt@437
  1116
                   "http://www.whatwg.org/specs/web-apps/current-work/complete/origin-0.html#origin"
richt@437
  1117
                   class="externalDFN">origin</a> with a <a href="#networkservices"><code>NetworkServices</code></a>
richt@437
  1118
                   object representing the <a href="#dfn-user-authorized"
richt@437
  1119
                   class="internalDFN">user-authorized</a> subset of <var>services found</var>.
richt@180
  1120
              </p>
richt@239
  1121
              <p>
richt@437
  1122
                Alternatively, the user agent <em class="rfc2119"
richt@437
  1123
                   title="MAY">MAY</em> wish to skip this user opt-in step and choose to fulfill <var>Network Service
richt@437
  1124
                   Promise</var> immediately based on a previously-established user preference, for security reasons,
richt@437
  1125
                   or due to platform limitations. In such an implementation, if <var>Network Service Promise</var> is
richt@437
  1126
                   to be fulfilled as a result of a previously-established user preference then the <a href=
richt@437
  1127
                   "#dfn-user-agent"
richt@437
  1128
                   class="internalDFN">user agent</a> <em class="rfc2119"
richt@437
  1129
                   title="MUST">MUST</em> continue at the next step of this algorithm.
richt@379
  1130
              </p>
richt@379
  1131
              <p>
richt@437
  1132
                If permission has been granted by the user to access one or more networked services then the <a href=
richt@437
  1133
                "#dfn-user-agent"
richt@437
  1134
                   class="internalDFN">user agent</a> <em class="rfc2119"
richt@437
  1135
                   title="SHOULD">SHOULD</em> include an "ongoing local-network communication" indicator.
richt@379
  1136
              </p>
richt@379
  1137
              <p>
richt@437
  1138
                If permission has been denied by the user, <a href="#dfn-user-agent"
richt@437
  1139
                   class="internalDFN">user agent</a> or platform, then the <a href="#dfn-user-agent"
richt@437
  1140
                   class="internalDFN">user agent</a> <em class="rfc2119"
richt@437
  1141
                   title="MUST">MUST</em> reject <var>Network Service Promise</var> by running the <a href=
richt@437
  1142
                   "http://dom.spec.whatwg.org/#concept-resolver-reject"
richt@437
  1143
                   class="externalDFN">resolver reject algorithm</a> against the <var>Network Service Promise's
richt@447
  1144
                   Resolver</var>, passing in a newly constructed <a href="http://dom.spec.whatwg.org/#domerror"
richt@447
  1145
                   class="externalDFN"><code>DOMError</code></a> object whose <code>name</code> attribute has the
richt@447
  1146
                   string value "PermissionDeniedError" (<a href=
richt@447
  1147
                   "#dom-domerror-extensions-permission_denied"><code>PERMISSION_DENIED_ERR</code></a>) and whose
richt@447
  1148
                   <code>message</code> attribute has a helpful implementation-dependent message that explains this
richt@447
  1149
                   error, abort any remaining steps and return.
richt@239
  1150
              </p>
richt@180
  1151
              <p>
richt@379
  1152
                If the user never responds or no previously-established user preference has been met, this algorithm
richt@379
  1153
                stalls on this step.
richt@180
  1154
              </p>
richt@180
  1155
            </li>
richt@254
  1156
            <li>Let <var>services</var> be an empty array.
richt@180
  1157
            </li>
richt@379
  1158
            <li>If <var>services found</var> is not an empty array then set <var>services</var> to be an array of one
richt@379
  1159
            or more <a href="#networkservice"><code>NetworkService</code></a> objects for which the user granted
richt@437
  1160
            permission above - known as the current objects <dfn id="dfn-user-authorized">user-authorized</dfn>
richt@437
  1161
            services.
richt@379
  1162
            </li>
richt@254
  1163
            <li>For each Object <var>service</var> in <var>services</var>, if any, run the following sub-steps:
richt@239
  1164
              <ol class="rule">
richt@239
  1165
                <li>If <var>service</var>'s <code>type</code> parameter begins with the DOMString "<code>upnp:</code>"
richt@437
  1166
                and the <var>service</var>'s <code>eventsUrl</code> parameter is not empty then <a href=
richt@437
  1167
                "#dfn-setup-a-upnp-events-subscription"
richt@437
  1168
                      class="internalDFN">setup a UPnP Events Subscription</a> for <var>service</var>.
richt@239
  1169
                </li>
richt@239
  1170
              </ol>
richt@180
  1171
            </li>
richt@239
  1172
            <li>Let <var>services manager</var> be a new <a href="#networkservices"><code>NetworkServices</code></a>
richt@239
  1173
            object.
richt@180
  1174
            </li>
richt@379
  1175
            <li>Store <var>requested control types</var> against <var>services manager</var> as an internal variable.
richt@180
  1176
            </li>
richt@437
  1177
            <li>Set <var>services manager</var>'s <a href=
richt@437
  1178
            "#dom-networkservices-servicesavailable"><code>servicesAvailable</code></a> attribute to the number of
richt@437
  1179
            items currently found in the <a href="#dfn-list-of-available-service-records"
richt@437
  1180
                  class="internalDFN">list of available service records</a> whose <code>type</code> property matches
richt@437
  1181
                  any of the tokens requested in <var>requested control types</var>.
richt@379
  1182
            </li>
richt@379
  1183
            <li>Add <var>services</var>, if any, to the <var>services manager</var> object as its collection of
richt@484
  1184
              <a href="#dfn-indexed-properties"
richt@437
  1185
                  class="internalDFN">indexed properties</a>. If <var>services</var> is an empty array then the
richt@437
  1186
                  <var>services manager</var> does not have any <var>indexed properties</var>.
richt@180
  1187
            </li>
richt@250
  1188
            <li>Set <var>services manager</var>'s <a href="#dom-networkservices-length"><code>length</code></a>
richt@250
  1189
            attribute to the number of items in <var>services</var>.
richt@250
  1190
            </li>
richt@437
  1191
            <li>Add <var>services manager</var> to the <a href="#dfn-list-of-active-service-managers"
richt@437
  1192
                  class="internalDFN">list of active service managers</a>.
richt@250
  1193
            </li>
richt@437
  1194
            <li>The <a href="#dfn-user-agent"
richt@437
  1195
                  class="internalDFN">user agent</a> <em class="rfc2119"
richt@437
  1196
                  title="MUST">MUST</em> fulfill <var>Network Service Promise</var> by running the <a href=
richt@437
  1197
                  "http://dom.spec.whatwg.org/#concept-resolver-fulfill"
richt@437
  1198
                  class="externalDFN">resolver fulfill algorithm</a> against the <var>Network Service Promise's
richt@437
  1199
                  Resolver</var>, passing in <var>services manager</var> as its argument.
richt@180
  1200
            </li>
richt@180
  1201
          </ol>
richt@180
  1202
          <p>
richt@437
  1203
            The <a href="http://www.whatwg.org/specs/web-apps/current-work/complete/webappapis.html#task-source"
richt@437
  1204
               class="externalDFN">task source</a> for these <a href=
richt@437
  1205
               "http://www.whatwg.org/specs/web-apps/current-work/complete/webappapis.html#concept-task"
richt@437
  1206
               class="externalDFN">tasks</a> is the <a href=
richt@437
  1207
               "http://www.whatwg.org/specs/web-apps/current-work/complete/webappapis.html#user-interaction-task-source"
richt@437
  1208
               class="externalDFN">user interaction task source</a>.
richt@180
  1209
          </p>
richt@180
  1210
          <p>
richt@483
  1211
            The <dfn id="dfn-preliminary-cors-check">preliminary CORS check</dfn> algorithm determines whether a
richt@483
  1212
            Local-networked Service supports Cross-Origin Resource Sharing [<cite><a class="bibref"
richt@483
  1213
               href="#bib-CORS">CORS</a></cite>] as part of a call to the <a href=
richt@483
  1214
               "#dom-navigator-getnetworkservices"><code>getNetworkServices()</code></a> method, prior to that service
richt@483
  1215
               being proposed for sharing to users and prior to active sharing with web pages. This algorithm takes two
richt@483
  1216
               arguments, <var>control endpoint URL</var> and <var>request origin</var>, and consists of running the
richt@483
  1217
               following steps:
richt@483
  1218
          </p>
richt@483
  1219
          <ol class="rule">
richt@483
  1220
            <li>Let <var>CORS available check</var> be the result of applying the <a href=
richt@483
  1221
            "http://www.w3.org/TR/cors/#make-a-request-steps"
richt@483
  1222
                  class="externalDFN">make a request steps</a> [<cite><a class="bibref"
richt@483
  1223
                 href="#bib-CORS">CORS</a></cite>], setting the <a href="http://www.w3.org/TR/cors/#request-method"
richt@483
  1224
                  class="externalDFN">request method</a> to <code>OPTIONS</code>, the <a href=
richt@483
  1225
                  "http://www.w3.org/TR/cors/#request-url"
richt@483
  1226
                  class="externalDFN">request URL</a> to <var>control endpoint URL</var>, the <a href=
richt@483
  1227
                  "http://www.w3.org/TR/cors/#source-origin"
richt@483
  1228
                  class="externalDFN">source origin</a> to <var>request origin</var>, setting the <a href=
richt@483
  1229
                  "http://www.w3.org/TR/cors/#omit-credentials-flag"
richt@483
  1230
                  class="externalDFN">omit credentials flag</a> to <code>true</code> and including an <a href=
richt@483
  1231
                  "http://www.w3.org/TR/cors/#http-access-control-request-method"
richt@483
  1232
                  class="externalDFN"><code>Access-Control-Request-Method</code></a> header with a value of
richt@483
  1233
                  <code>GET</code>.
richt@483
  1234
            </li>
richt@483
  1235
            <li>If <var>CORS available check</var> is cancelled by the user, or it results in a network error, or its
richt@483
  1236
            response does not have an <abbr title="Hypertext Transfer Protocol">HTTP</abbr> status code of
richt@483
  1237
            <code>200</code> then abort any remaining steps and return <code>fail</code>.
richt@483
  1238
            </li>
richt@483
  1239
            <li>Return the result of running the <a href="http://www.w3.org/TR/cors/#resource-sharing-check"
richt@483
  1240
                  class="externalDFN">resource sharing check</a> [<cite><a class="bibref"
richt@483
  1241
                 href="#bib-CORS">CORS</a></cite>] against the successful <abbr title=
richt@483
  1242
                 "Hypertext Transfer Protocol">HTTP</abbr> response of the <var>CORS available check</var>.
richt@483
  1243
              <div class="note">
richt@483
  1244
                <div class="note-title"
richt@483
  1245
                     aria-level="3"
richt@483
  1246
                     role="heading"
richt@483
  1247
                     id="h_note_1">
richt@483
  1248
                  <span>Note</span>
richt@483
  1249
                </div>
richt@483
  1250
                <p class="">
richt@483
  1251
                  This returned result will always be either <code>pass</code> or <code>fail</code>.
richt@483
  1252
                </p>
richt@483
  1253
              </div>
richt@483
  1254
            </li>
richt@483
  1255
          </ol>
richt@483
  1256
          <p>
richt@441
  1257
            There is no implied persistence to networked service sharing provided to a web page. It <em class="rfc2119"
richt@483
  1258
               title="MUST NOT">MUST NOT</em> be possible to access a networked service previously granted to a web
richt@483
  1259
               page without user authorization in all of the following cases:
richt@239
  1260
          </p>
richt@239
  1261
          <ul>
richt@239
  1262
            <li>If the current script is reloaded at any point in the same or different window.
richt@239
  1263
            </li>
richt@437
  1264
            <li>if the current script reinvokes the <a href=
richt@437
  1265
            "#dom-navigator-getnetworkservices"><code>getNetworkServices()</code></a> method at any point in its
richt@239
  1266
            execution.
richt@239
  1267
            </li>
richt@239
  1268
            <li>If the user navigates forward or back in their history to reload the current page.
richt@239
  1269
            </li>
richt@239
  1270
            <li>If a script is running in a different origin.
richt@239
  1271
            </li>
richt@239
  1272
          </ul>
richt@239
  1273
        </div>
richt@180
  1274
      </section>
richt@194
  1275
      <section id="error-handling">
richt@447
  1276
        <h3 aria-level="2"
richt@447
  1277
            role="heading"
richt@447
  1278
            id="h3_error-handling">
richt@440
  1279
          <span class="secno">5.2</span> Error Handling
richt@239
  1280
        </h3>
richt@239
  1281
        <dl class="domintro">
richt@239
  1282
          <dt>
richt@447
  1283
            <var title="">error</var> . <code title="dom-NavigatorNetworkServiceError-name"><a href=
richt@447
  1284
            "#dom-domerror-extensions-name">name</a></code>
richt@239
  1285
          </dt>
richt@239
  1286
          <dd>
richt@239
  1287
            <p>
richt@447
  1288
              Returns the current error's error name. At the current time, this will be "PermissionDeniedError" or
richt@447
  1289
              "UnknownTypePrefixError", for which the corresponding error constants <a href=
richt@447
  1290
              "#dom-domerror-extensions-permission_denied"><code>PERMISSION_DENIED_ERR</code></a> and <a href=
richt@447
  1291
              "#dom-domerror-extensions-unknown_type_prefix"><code>UNKNOWN_TYPE_PREFIX_ERR</code></a> are defined.
richt@239
  1292
            </p>
richt@239
  1293
          </dd>
richt@239
  1294
        </dl>
richt@239
  1295
        <p>
richt@447
  1296
          The <dfn id="dom-domerror-extensions-name"
richt@447
  1297
             title="dom-domerror-extensions-name"><code>name</code></dfn> attribute of a <a href=
richt@447
  1298
             "http://dom.spec.whatwg.org/#domerror"
richt@447
  1299
             class="externalDFN"><code>DOMError</code></a> object returned from this <abbr title=
richt@447
  1300
             "Application Programming Interface">API</abbr> <em class="ct"><em class="rfc2119"
richt@447
  1301
              title="MUST">MUST</em></em> return the name for the error, which will be one of the following:
richt@239
  1302
        </p>
richt@239
  1303
        <dl>
richt@239
  1304
          <dt>
richt@447
  1305
            <dfn id="dom-domerror-extensions-permission_denied"
richt@447
  1306
                title="dom-domerror-extensions-permission_denied"><code>PERMISSION_DENIED_ERR</code></dfn> (DOMString
richt@447
  1307
                value "PermissionDeniedError")
richt@239
  1308
          </dt>
richt@239
  1309
          <dd>
richt@239
  1310
            The user or user agent denied the page permission to access any services.
richt@239
  1311
          </dd>
richt@239
  1312
          <dt>
richt@447
  1313
            <dfn id="dom-domerror-extensions-unknown_type_prefix"
richt@447
  1314
                title="dom-domerror-extensions-unknown_type_prefix"><code>UNKNOWN_TYPE_PREFIX_ERR</code></dfn>
richt@447
  1315
                (DOMString value "UnknownTypePrefixError")
richt@239
  1316
          </dt>
richt@239
  1317
          <dd>
richt@437
  1318
            No <a href="#dfn-valid-service-type"
richt@437
  1319
                class="internalDFN">valid service type</a> tokens were provided in the method invocation.
richt@239
  1320
          </dd>
richt@239
  1321
        </dl>
richt@180
  1322
      </section>
richt@239
  1323
    </section>
richt@239
  1324
    <section id="obtaining-networked-services">
richt@447
  1325
      <h2 aria-level="1"
richt@447
  1326
          role="heading"
richt@447
  1327
          id="h2_obtaining-networked-services">
richt@440
  1328
        <span class="secno">6.</span> Obtaining networked services
richt@239
  1329
      </h2>
richt@180
  1330
      <p>
richt@379
  1331
        The <a href="#networkservices"><code>NetworkServices</code></a> interface represents a collection of zero or
richt@484
  1332
        more <a href="#dfn-indexed-properties"
richt@484
  1333
           class="internalDFN">indexed properties</a> that are each a <a href="#dfn-user-authorized"
richt@437
  1334
           class="internalDFN">user-authorized</a> <a href="#networkservice"><code>NetworkService</code></a> object.
richt@254
  1335
      </p>
richt@254
  1336
      <p>
richt@437
  1337
        A <a href="#networkservices"><code>NetworkServices</code></a> object is the <a href=
richt@437
  1338
        "http://dom.spec.whatwg.org/#concept-promise-result"
richt@437
  1339
           class="externalDFN">promise result</a> from a call to <a href=
richt@437
  1340
           "#dom-navigator-getnetworkservices"><code>getNetworkServices()</code></a>.
richt@180
  1341
      </p>
richt@437
  1342
      <pre class="widl">
richt@437
  1343
[NoInterfaceObject]
richt@180
  1344
interface <dfn id="networkservices">NetworkServices</dfn> {
richt@180
  1345
  readonly attribute unsigned long    <a href="#dom-networkservices-length">length</a>;
richt@180
  1346
  getter <a href="#networkservice">NetworkService</a> (unsigned long index);
richt@437
  1347
  <a href="#networkservice">NetworkService</a>? <a href=
richt@437
  1348
"#dom-networkservices-getservicebyid">getServiceById</a>(DOMString id);
richt@180
  1349
richt@180
  1350
  readonly attribute unsigned long    <a href="#dom-networkservices-servicesavailable">servicesAvailable</a>;
richt@180
  1351
richt@180
  1352
  // event handler attributes
richt@437
  1353
           attribute <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/webappapis.html#eventhandler"
richt@448
  1354
     class="externalDFN">EventHandler</a>     <a href="#dom-networkservices-onservicefound">onservicefound</a>;
richt@437
  1355
           attribute <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/webappapis.html#eventhandler"
richt@448
  1356
     class="externalDFN">EventHandler</a>     <a href="#dom-networkservices-onservicelost">onservicelost</a>;
richt@180
  1357
richt@180
  1358
};
richt@180
  1359
richt@437
  1360
<a href="#networkservices">NetworkServices</a> implements <a href=
richt@437
  1361
"http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#interface-eventtarget"
richt@437
  1362
     class="externalDFN">EventTarget</a>;
richt@180
  1363
</pre>
richt@194
  1364
      <section id="attributes">
richt@447
  1365
        <h3 aria-level="2"
richt@447
  1366
            role="heading"
richt@447
  1367
            id="h3_attributes">
richt@440
  1368
          <span class="secno">6.1</span> Attributes
richt@239
  1369
        </h3>
richt@180
  1370
        <dl class="domintro">
richt@180
  1371
          <dt>
richt@239
  1372
            <code title="dom-networkservices-length"><a href="#dom-networkservices-length">length</a></code>
richt@180
  1373
          </dt>
richt@180
  1374
          <dd>
richt@180
  1375
            <p>
richt@484
  1376
              Returns the current number of <a href="#dfn-indexed-properties"
richt@437
  1377
                 class="internalDFN">indexed properties</a> in the current object's collection.
richt@180
  1378
            </p>
richt@180
  1379
          </dd>
richt@180
  1380
          <dt>
richt@437
  1381
            <code title="dom-networkservices-servicesavailable"><a href=
richt@437
  1382
            "#dom-networkservices-servicesavailable">servicesAvailable</a></code>
richt@180
  1383
          </dt>
richt@180
  1384
          <dd>
richt@180
  1385
            <p>
richt@437
  1386
              Returns the current number of items matching one of the app-requested <a href="#dfn-valid-service-type"
richt@437
  1387
                 class="internalDFN">valid service type</a> tokens in the <a href=
richt@437
  1388
                 "#dfn-list-of-available-service-records"
richt@437
  1389
                 class="internalDFN">list of available service records</a>.
richt@180
  1390
            </p>
richt@180
  1391
          </dd>
richt@180
  1392
        </dl>
richt@180
  1393
        <div>
richt@239
  1394
          <p>
richt@437
  1395
            The <dfn id="dom-networkservices-length"><code>length</code></dfn> attribute <em class="rfc2119"
richt@437
  1396
               title="MUST">MUST</em> return the number of <a href="#networkservice"><code>NetworkService</code></a>
richt@437
  1397
               objects represented by the collection.
richt@239
  1398
          </p>
richt@239
  1399
          <p>
richt@437
  1400
            The <dfn id="dom-networkservices-servicesavailable"><code>servicesAvailable</code></dfn> attribute
richt@437
  1401
            <em class="rfc2119"
richt@437
  1402
               title="MUST">MUST</em> return the number of services in the <a href=
richt@437
  1403
               "#dfn-list-of-available-service-records"
richt@437
  1404
               class="internalDFN">list of available service records</a> whose <code>type</code> attribute matches any
richt@437
  1405
               of the <a href="#dfn-valid-service-type"
richt@437
  1406
               class="internalDFN">valid service type</a> tokens that were initially used to create the current <a href=
richt@437
  1407
               "#networkservices"><code>NetworkServices</code></a> object.
richt@239
  1408
          </p>
richt@180
  1409
        </div>
richt@180
  1410
      </section>
richt@194
  1411
      <section id="methods-1">
richt@447
  1412
        <h3 aria-level="2"
richt@447
  1413
            role="heading"
richt@447
  1414
            id="h3_methods-1">
richt@440
  1415
          <span class="secno">6.2</span> Methods
richt@239
  1416
        </h3>
richt@180
  1417
        <dl class="domintro">
richt@239
  1418
          <dt>
richt@437
  1419
            <code title="networkservices-getter"><a href="#networkservices">services</a></code> [ <var title=
richt@437
  1420
            "">index</var> ]
richt@239
  1421
          </dt>
richt@239
  1422
          <dd>
richt@239
  1423
            <p>
richt@239
  1424
              Returns the specified <a href="#networkservice"><code>NetworkService</code></a> object.
richt@239
  1425
            </p>
richt@239
  1426
          </dd>
richt@239
  1427
          <dt>
richt@437
  1428
            <code title="networkservices-getter"><a href="#networkservices">services</a></code> . <code title=
richt@437
  1429
            "dom-networkservices-getservicebyid"><a href=
richt@437
  1430
            "#dom-networkservices-getservicebyid">getServiceById</a></code> ( <var title="">id</var> )
richt@239
  1431
          </dt>
richt@239
  1432
          <dd>
richt@239
  1433
            <p>
richt@239
  1434
              Returns the <a href="#networkservice"><code>NetworkService</code></a> object with the given identifier,
richt@239
  1435
              or null if no service has that identifier.
richt@239
  1436
            </p>
richt@239
  1437
          </dd>
richt@239
  1438
        </dl>
richt@239
  1439
        <p>
richt@379
  1440
          A <a href="#networkservices"><code>NetworkServices</code></a> object represents the current collection of
richt@437
  1441
          zero or more <a href="#networkservice"><code>NetworkService</code></a> objects - its <a href=
richt@484
  1442
          "#dfn-indexed-properties"
richt@484
  1443
             class="internalDFN">indexed properties</a>. The <a href="#dfn-indexed-properties"
richt@437
  1444
             class="internalDFN">indexed properties</a> of a <a href=
richt@437
  1445
             "#networkservices"><code>NetworkServices</code></a> object are <span>immutable</span> meaning that <a href=
richt@484
  1446
             "#dfn-indexed-properties"
richt@484
  1447
             class="internalDFN">indexed properties</a> cannot be added and <a href="#dfn-indexed-properties"
richt@437
  1448
             class="internalDFN">indexed properties</a> cannot be removed for the lifetime of a <a href=
richt@437
  1449
             "#networkservices"><code>NetworkServices</code></a> object.
richt@239
  1450
        </p>
richt@239
  1451
        <p>
richt@437
  1452
          The <a href=
richt@437
  1453
          "http://www.whatwg.org/specs/web-apps/current-work/multipage/infrastructure.html#supported-property-indices"
richt@437
  1454
             class="externalDFN">supported property indices</a> of <a href=
richt@437
  1455
             "#networkservices"><code>NetworkServices</code></a> objects at any instant are the numbers from zero to
richt@250
  1456
             the number of the <a href="#networkservice"><code>NetworkService</code></a> objects in the collection
richt@250
  1457
             minus one.
richt@239
  1458
        </p>
richt@437
  1459
        <div class="note">
richt@437
  1460
          <div class="note-title"
richt@447
  1461
               aria-level="3"
richt@437
  1462
               role="heading"
richt@483
  1463
               id="h_note_2">
richt@437
  1464
            <span>Note</span>
richt@437
  1465
          </div>
richt@437
  1466
          <p class="">
richt@437
  1467
            Each service in a <a href="#networkservices"><code>NetworkServices</code></a> object thus has an index; the
richt@437
  1468
            first has the index 0, and each subsequent service is numbered one higher than the previous one.
richt@437
  1469
          </p>
richt@437
  1470
        </div>
richt@239
  1471
        <p>
richt@437
  1472
          To <a href=
richt@437
  1473
          "http://www.whatwg.org/specs/web-apps/current-work/multipage/infrastructure.html#determine-the-value-of-an-indexed-property"
richt@437
  1474
             class="externalDFN">determine the value of an indexed property</a> for a given index <var>index</var> in a
richt@437
  1475
             <a href="#networkservices"><code>NetworkServices</code></a> object the user agent <em class="rfc2119"
richt@437
  1476
             title="MUST">MUST</em> return the <a href="#networkservice"><code>NetworkService</code></a> object that
richt@437
  1477
             represents the <var>index</var>th item in the collection.
richt@239
  1478
        </p>
richt@239
  1479
        <p>
richt@437
  1480
          The <dfn id="dom-networkservices-getservicebyid"><code>getServiceById(id)</code></dfn> method <em class=
richt@437
  1481
          "ct"><em class="rfc2119"
richt@437
  1482
              title="MUST">MUST</em></em> return the first <a href="#networkservice"><code>NetworkService</code></a>
richt@437
  1483
              object in the collection whose <a href="#dom-networkservice-id"><code>id</code></a> attribute is equal to
richt@437
  1484
              the value of the <var>id</var> argument provided. When no <a href=
richt@437
  1485
              "#networkservice"><code>NetworkService</code></a> objects match the given argument, the method <em class=
richt@437
  1486
              "rfc2119"
richt@437
  1487
             title="MUST">MUST</em> return null.
richt@239
  1488
        </p>
richt@180
  1489
      </section>
richt@194
  1490
      <section id="events">
richt@447
  1491
        <h3 aria-level="2"
richt@447
  1492
            role="heading"
richt@447
  1493
            id="h3_events">
richt@440
  1494
          <span class="secno">6.3</span> Events
richt@239
  1495
        </h3>
richt@239
  1496
        <p>
richt@437
  1497
          The following are the event handlers (and their corresponding event handler event types) that <em class=
richt@437
  1498
          "ct"><em class="rfc2119"
richt@437
  1499
              title="MUST">MUST</em></em> be supported, as IDL attributes, by all objects implementing the <a href=
richt@437
  1500
              "#networkservices"><code>NetworkServices</code></a> interface:
richt@239
  1501
        </p>
richt@243
  1502
        <table border="1">
richt@239
  1503
          <thead>
richt@239
  1504
            <tr>
richt@239
  1505
              <th>
richt@239
  1506
                <span title="event handlers">Event handler</span>
richt@239
  1507
              </th>
richt@239
  1508
              <th>
richt@239
  1509
                <span>Event handler event type</span>
richt@239
  1510
              </th>
richt@239
  1511
            </tr>
richt@239
  1512
          </thead>
richt@239
  1513
          <tbody>
richt@239
  1514
            <tr>
richt@239
  1515
              <td>
richt@448
  1516
                <dfn id="dom-networkservices-onservicefound"
richt@448
  1517
                    title="dom-NetworkServices-onservicefound"><code>onservicefound</code></dfn>
richt@239
  1518
              </td>
richt@239
  1519
              <td>
richt@448
  1520
                <a href="#event-servicefound"><code>servicefound</code></a>
richt@239
  1521
              </td>
richt@239
  1522
            </tr>
richt@239
  1523
            <tr>
richt@239
  1524
              <td>
richt@448
  1525
                <dfn id="dom-networkservices-onservicelost"
richt@448
  1526
                    title="dom-NetworkServices-onservicelost"><code>onservicelost</code></dfn>
richt@239
  1527
              </td>
richt@239
  1528
              <td>
richt@448
  1529
                <a href="#event-servicelost"><code>servicelost</code></a>
richt@239
  1530
              </td>
richt@239
  1531
            </tr>
richt@239
  1532
          </tbody>
richt@239
  1533
        </table>
richt@180
  1534
      </section>
richt@194
  1535
    </section>
richt@194
  1536
    <section id="communicating-with-a-networked-service">
richt@447
  1537
      <h2 aria-level="1"
richt@447
  1538
          role="heading"
richt@447
  1539
          id="h2_communicating-with-a-networked-service">
richt@440
  1540
        <span class="secno">7.</span> Communicating with a networked service
richt@239
  1541
      </h2>
richt@239
  1542
      <p>
richt@239
  1543
        The <a href="#networkservice"><code>NetworkService</code></a> interface is used to provide a set of connection
richt@437
  1544
        information for an <abbr title="Hypertext Transfer Protocol">HTTP</abbr> service endpoint and if available,
richt@437
  1545
        service events, running on a networked device.
richt@239
  1546
      </p>
richt@437
  1547
      <pre class="widl">
richt@437
  1548
[NoInterfaceObject]
richt@180
  1549
interface <dfn id="networkservice">NetworkService</dfn> {
richt@180
  1550
  readonly attribute DOMString        <a href="#dom-networkservice-id">id</a>;
richt@180
  1551
  readonly attribute DOMString        <a href="#dom-networkservice-name">name</a>;
richt@180
  1552
  readonly attribute DOMString        <a href="#dom-networkservice-type">type</a>;
richt@180
  1553
  readonly attribute DOMString        <a href="#dom-networkservice-url">url</a>;
richt@180
  1554
  readonly attribute DOMString        <a href="#dom-networkservice-config">config</a>;
richt@180
  1555
richt@191
  1556
  readonly attribute boolean          <a href="#dom-networkservice-online">online</a>;
richt@180
  1557
richt@180
  1558
  // event handler attributes
richt@437
  1559
           attribute <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/webappapis.html#eventhandler"
richt@448
  1560
     class="externalDFN">EventHandler</a>     <a href="#dom-networkservice-onavailable">onavailable</a>;
richt@437
  1561
           attribute <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/webappapis.html#eventhandler"
richt@448
  1562
     class="externalDFN">EventHandler</a>     <a href="#dom-networkservice-onunavailable">onunavailable</a>;
richt@191
  1563
richt@437
  1564
           attribute <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/webappapis.html#eventhandler"
richt@437
  1565
     class="externalDFN">EventHandler</a>     <a href="#dom-networkservice-onnotify">onnotify</a>;
richt@180
  1566
};
richt@180
  1567
richt@437
  1568
<a href="#networkservice">NetworkService</a> implements <a href=
richt@437
  1569
"http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#interface-eventtarget"
richt@437
  1570
     class="externalDFN">EventTarget</a>;
richt@180
  1571
</pre>
richt@239
  1572
      <section id="attributes-1">
richt@447
  1573
        <h3 aria-level="2"
richt@447
  1574
            role="heading"
richt@447
  1575
            id="h3_attributes-1">
richt@440
  1576
          <span class="secno">7.1</span> Attributes
richt@239
  1577
        </h3>
richt@239
  1578
        <dl class="domintro">
richt@239
  1579
          <dt>
richt@437
  1580
            <var title="">service</var> . <code title="dom-networkservice-id"><a href=
richt@437
  1581
            "#dom-networkservice-id">id</a></code>
richt@239
  1582
          </dt>
richt@239
  1583
          <dd>
richt@239
  1584
            <p>
richt@239
  1585
              A unique identifier for the given user-selected service instance.
richt@239
  1586
            </p>
richt@239
  1587
          </dd>
richt@239
  1588
          <dt>
richt@437
  1589
            <var title="">service</var> . <code title="dom-networkservice-name"><a href=
richt@437
  1590
            "#dom-networkservice-name">name</a></code>
richt@239
  1591
          </dt>
richt@239
  1592
          <dd>
richt@239
  1593
            <p>
richt@239
  1594
              The name of the user-selected service.
richt@239
  1595
            </p>
richt@239
  1596
          </dd>
richt@239
  1597
          <dt>
richt@437
  1598
            <var title="">service</var> . <code title="dom-networkservice-type"><a href=
richt@437
  1599
            "#dom-networkservice-type">type</a></code>
richt@239
  1600
          </dt>
richt@239
  1601
          <dd>
richt@239
  1602
            <p>
richt@437
  1603
              The <a href="#dfn-valid-service-type"
richt@437
  1604
                 class="internalDFN">valid service type</a> token value of the user-selected service.
richt@239
  1605
            </p>
richt@239
  1606
          </dd>
richt@239
  1607
          <dt>
richt@437
  1608
            <var title="">service</var> . <code title="dom-networkservice-url"><a href=
richt@437
  1609
            "#dom-networkservice-url">url</a></code>
richt@239
  1610
          </dt>
richt@239
  1611
          <dd>
richt@239
  1612
            <p>
richt@480
  1613
              The control URL endpoint (including any required port information) of the user-selected control service.
richt@239
  1614
            </p>
richt@239
  1615
          </dd>
richt@239
  1616
          <dt>
richt@437
  1617
            <var title="">service</var> . <code title="dom-networkservice-config"><a href=
richt@437
  1618
            "#dom-networkservice-config">config</a></code>
richt@239
  1619
          </dt>
richt@239
  1620
          <dd>
richt@239
  1621
            <p>
richt@239
  1622
              The configuration information associated with the service depending on the requested service type.
richt@239
  1623
            </p>
richt@239
  1624
          </dd>
richt@239
  1625
        </dl>
richt@239
  1626
        <p>
richt@239
  1627
          The <dfn id="dom-networkservice-id"><code>id</code></dfn> attribute is a unique identifier for the service.
richt@437
  1628
          The same service provided at different times or on different objects <em class="rfc2119"
richt@437
  1629
             title="MUST">MUST</em> have the same <a href="#dom-networkservice-id"><code>id</code></a> value.
richt@239
  1630
        </p>
richt@239
  1631
        <p>
richt@239
  1632
          The <dfn id="dom-networkservice-name"><code>name</code></dfn> attribute represents a human-readable title for
richt@239
  1633
          the service.
richt@239
  1634
        </p>
richt@239
  1635
        <p>
richt@437
  1636
          The <dfn id="dom-networkservice-type"><code>type</code></dfn> attribute reflects the value of the <a href=
richt@437
  1637
          "#dfn-valid-service-type"
richt@437
  1638
             class="internalDFN">valid service type</a> of the service.
richt@239
  1639
        </p>
richt@239
  1640
        <p>
richt@437
  1641
          The <dfn id="dom-networkservice-url"><code>url</code></dfn> attribute is an <a href=
richt@453
  1642
          "http://url.spec.whatwg.org/#concept-absolute-url"
richt@480
  1643
             class="externalDFN">absolute URL</a> pointing to the root <abbr title=
richt@480
  1644
             "Hypertext Transfer Protocol">HTTP</abbr> endpoint for the service. Web pages can subsequently use this
richt@480
  1645
             value for implicit cross-document messaging via various existing mechanisms (e.g. Web Sockets, Server-Sent
richt@480
  1646
             Events, Web Messaging, XMLHttpRequest).
richt@239
  1647
        </p>
richt@239
  1648
        <p>
richt@239
  1649
          The <dfn id="dom-networkservice-config"><code>config</code></dfn> attribute provides the raw configuration
richt@239
  1650
          information extracted from the given network service.
richt@239
  1651
        </p>
richt@239
  1652
      </section>
richt@239
  1653
      <section id="states">
richt@447
  1654
        <h3 aria-level="2"
richt@447
  1655
            role="heading"
richt@447
  1656
            id="h3_states">
richt@440
  1657
          <span class="secno">7.2</span> States
richt@239
  1658
        </h3>
richt@239
  1659
        <dl class="domintro">
richt@239
  1660
          <dt>
richt@437
  1661
            <var title="">service</var> . <code title="dom-networkservice-online"><a href=
richt@437
  1662
            "#dom-networkservice-online">online</a></code>
richt@239
  1663
          </dt>
richt@239
  1664
          <dd>
richt@239
  1665
            <p>
richt@239
  1666
              Returns <code>true</code> if the service is reporting that it is accessible on the local network or
richt@390
  1667
              <code>false</code> if the service is no longer accessible (temporarily or permanently) on the local
richt@390
  1668
              network.
richt@239
  1669
            </p>
richt@239
  1670
          </dd>
richt@239
  1671
        </dl>
richt@239
  1672
        <p>
richt@239
  1673
          The <dfn id="dom-networkservice-online"><code>online</code></dfn> attribute indicates whether the service is
richt@390
  1674
          either <var>online</var>, and therefore accessible on the local network, in which case this attribute will
richt@390
  1675
          return <code>true</code> or, <var>offline</var>, and therefore not accessible on the local network, either
richt@437
  1676
          temporarily or permanently, in which case this attribute will return <code>false</code>. This attribute
richt@437
  1677
          <em class="rfc2119"
richt@437
  1678
             title="MUST">MUST</em> default to <code>true</code>.
richt@239
  1679
        </p>
richt@239
  1680
      </section>
richt@239
  1681
      <section id="events-1">
richt@447
  1682
        <h3 aria-level="2"
richt@447
  1683
            role="heading"
richt@447
  1684
            id="h3_events-1">
richt@440
  1685
          <span class="secno">7.3</span> Events
richt@239
  1686
        </h3>
richt@239
  1687
        <p>
richt@437
  1688
          The following are the event handlers (and their corresponding event handler event types) that <em class=
richt@437
  1689
          "ct"><em class="rfc2119"
richt@437
  1690
              title="MUST">MUST</em></em> be supported, as IDL attributes, by all objects implementing the <a href=
richt@437
  1691
              "#networkservice"><code>NetworkService</code></a> interface:
richt@239
  1692
        </p>
richt@243
  1693
        <table border="1">
richt@239
  1694
          <thead>
richt@239
  1695
            <tr>
richt@239
  1696
              <th>
richt@239
  1697
                <span title="event handlers">Event handler</span>
richt@239
  1698
              </th>
richt@239
  1699
              <th>
richt@239
  1700
                <span>Event handler event type</span>
richt@239
  1701
              </th>
richt@239
  1702
            </tr>
richt@239
  1703
          </thead>
richt@239
  1704
          <tbody>
richt@239
  1705
            <tr>
richt@239
  1706
              <td>
richt@437
  1707
                <dfn id="dom-networkservice-onnotify"
richt@437
  1708
                    title="dom-NetworkService-onnotify"><code>onnotify</code></dfn>
richt@239
  1709
              </td>
richt@239
  1710
              <td>
richt@239
  1711
                <a href="#event-notify"><code>notify</code></a>
richt@239
  1712
              </td>
richt@239
  1713
            </tr>
richt@239
  1714
            <tr>
richt@239
  1715
              <td>
richt@448
  1716
                <dfn id="dom-networkservice-onavailable"
richt@448
  1717
                    title="dom-NetworkService-onavailable"><code>onavailable</code></dfn>
richt@239
  1718
              </td>
richt@239
  1719
              <td>
richt@448
  1720
                <a href="#event-available"><code>available</code></a>
richt@239
  1721
              </td>
richt@239
  1722
            </tr>
richt@239
  1723
            <tr>
richt@239
  1724
              <td>
richt@448
  1725
                <dfn id="dom-networkservice-onunavailable"
richt@448
  1726
                    title="dom-NetworkService-onunavailable"><code>onunavailable</code></dfn>
richt@239
  1727
              </td>
richt@239
  1728
              <td>
richt@448
  1729
                <a href="#event-unavailable"><code>unavailable</code></a>
richt@239
  1730
              </td>
richt@239
  1731
            </tr>
richt@239
  1732
          </tbody>
richt@239
  1733
        </table>
richt@239
  1734
      </section>
richt@239
  1735
    </section>
richt@239
  1736
    <section id="service-discovery">
richt@447
  1737
      <h2 aria-level="1"
richt@447
  1738
          role="heading"
richt@447
  1739
          id="h2_service-discovery">
richt@440
  1740
        <span class="secno">8.</span> Service Discovery
richt@239
  1741
      </h2>
richt@239
  1742
      <p>
richt@437
  1743
        A <a href="#dfn-user-agent"
richt@437
  1744
           class="internalDFN">user agent</a> conforming to this specification <em class="rfc2119"
richt@437
  1745
           title="MAY">MAY</em> implement <abbr title="Simple Service Discovery Protocol">SSDP</abbr> [<cite><a class=
richt@437
  1746
           "bibref"
richt@437
  1747
           href="#bib-UPNP-DEVICEARCH11">UPNP-DEVICEARCH11</a></cite>], Zeroconf [<cite><a class="bibref"
richt@437
  1748
           href="#bib-DNS-SD">DNS-SD</a></cite>] + [<cite><a class="bibref"
richt@437
  1749
           href="#bib-MDNS">MDNS</a></cite>] and/or <abbr title="Discovery and Launch Protocol">DIAL</abbr> [<a href=
richt@437
  1750
           "https://sites.google.com/a/dial-multiscreen.org/dial/dial-protocol-specification"><abbr title=
richt@437
  1751
           "Discovery and Launch Protocol">DIAL</abbr></a>] <dfn id="dfn-service-discovery-mechanisms">service
richt@437
  1752
           discovery mechanisms</dfn> - the requirements detailed in this section of the specification - to enable Web
richt@437
  1753
           pages to request and connect with <abbr title="Hypertext Transfer Protocol">HTTP</abbr> services running on
richt@437
  1754
           networked devices, discovered via any of these mechanisms, through this <abbr title=
richt@437
  1755
           "Application Programming Interface">API</abbr>. When a <a href="#dfn-user-agent"
richt@437
  1756
           class="internalDFN">user agent</a> implements any of these <a href="#dfn-service-discovery-mechanisms"
richt@437
  1757
           class="internalDFN">service discovery mechanisms</a>, then it <em class="rfc2119"
richt@437
  1758
           title="MUST">MUST</em> conform to the corresponding algorithms provided in this section of the
richt@437
  1759
           specification.
richt@239
  1760
      </p>
richt@239
  1761
      <p>
richt@437
  1762
        This section presents how the results of these <a href="#dfn-service-discovery-mechanisms"
richt@437
  1763
           class="internalDFN">service discovery mechanisms</a> will be matched to requested service types, how the
richt@437
  1764
           user agent stores available and active services and how their properties are applied to any resulting
richt@437
  1765
           <a href="#networkservice"><code>NetworkService</code></a> objects.
richt@239
  1766
      </p>
richt@239
  1767
      <p>
richt@437
  1768
        It is expected that user agents will perform these <a href="#dfn-service-discovery-mechanisms"
richt@437
  1769
           class="internalDFN">service discovery mechanisms</a> asynchronously and periodically update the <a href=
richt@437
  1770
           "#dfn-list-of-available-service-records"
richt@437
  1771
           class="internalDFN">list of available service records</a> as required. The timing of any <a href=
richt@437
  1772
           "#dfn-service-discovery-mechanisms"
richt@437
  1773
           class="internalDFN">service discovery mechanisms</a> is an implementation detail left to the discretion of
richt@437
  1774
           the implementer (e.g. by continuously monitoring the network as a background process or on invocation of
richt@437
  1775
           this <abbr title="Application Programming Interface">API</abbr> from a Web page).
richt@239
  1776
      </p>
richt@239
  1777
      <p>
richt@437
  1778
        The <dfn id="dfn-list-of-available-service-records">list of available service records</dfn> is a single dynamic
richt@437
  1779
        internal lookup table within user agents that is used to track all the services that have been discovered and
richt@440
  1780
        are available in the current network at the current time. At any point during the running of any of the
richt@437
  1781
        <a href="#dfn-service-discovery-mechanisms"
richt@437
  1782
           class="internalDFN">service discovery mechanisms</a> then existing entries within this table can be updated,
richt@437
  1783
           entries can be added and entries can be removed as the status of networked services changes according to the
richt@437
  1784
           rules defined in this specification.
richt@239
  1785
      </p>
richt@239
  1786
      <p>
richt@437
  1787
        The <dfn id="dfn-list-of-active-service-managers">list of active service managers</dfn> is an internal list
richt@437
  1788
        within user agents that is used to track all <a href="#networkservices"><code>NetworkServices</code></a>
richt@437
  1789
        objects currently being shared with any web pages at the current time within the user agent. Each <a href=
richt@437
  1790
        "#networkservices"><code>NetworkServices</code></a> object in the <a href=
richt@437
  1791
        "#dfn-list-of-active-service-managers"
richt@437
  1792
           class="internalDFN">list of active service managers</a> represents a collection of zero or more <a href=
richt@437
  1793
           "#networkservice"><code>NetworkService</code></a> objects - known as its <dfn id=
richt@484
  1794
           "dfn-indexed-properties">indexed properties</dfn>. <a href="#networkservice"><code>NetworkService</code></a>
richt@484
  1795
           objects are attached as the <a href="#dfn-indexed-properties"
richt@437
  1796
           class="internalDFN">indexed properties</a> of a <a href="#networkservices"><code>NetworkServices</code></a>
richt@437
  1797
           object as part of the <a href="#dom-navigator-getnetworkservices"><code>getNetworkServices()</code></a>
richt@437
  1798
           algorithm.
richt@239
  1799
      </p>
richt@239
  1800
      <p>
richt@437
  1801
        The rule for <dfn id="dfn-adding-an-available-service">adding an available service</dfn> is the process of
richt@437
  1802
        adding a <a href="#dfn-new-service"
richt@437
  1803
           class="internalDFN">new service</a> or updating an <a href="#dfn-existing-service"
richt@437
  1804
           class="internalDFN">existing service</a> that is generally available on the user's current network in the
richt@437
  1805
           <a href="#dfn-list-of-available-service-records"
richt@437
  1806
           class="internalDFN">list of available service records</a>. This rule takes one argument, <var>network
richt@437
  1807
           service record</var>, and consists of running the following steps:
richt@239
  1808
      </p>
richt@239
  1809
      <ol class="rule">
richt@437
  1810
        <li>For each <var>existing service record</var> in the current <a href="#dfn-list-of-available-service-records"
richt@437
  1811
              class="internalDFN">list of available service records</a>, run the following sub-steps:
richt@239
  1812
          <ol class="rule">
richt@239
  1813
            <li>If the <var>existing service record</var>'s <code>id</code> property does not equal <var>network
richt@239
  1814
            service record</var>'s <code>id</code> property then abort any remaining sub-steps and continue at the next
richt@239
  1815
            available <var>existing service record</var>.
richt@239
  1816
            </li>
richt@437
  1817
            <li>Replace the value of <var>existing service record</var> in the current <a href=
richt@437
  1818
            "#dfn-list-of-available-service-records"
richt@437
  1819
                  class="internalDFN">list of available service records</a> with the value of <var>network service
richt@437
  1820
                  record</var>, aborting any remaining steps in this algorithm and return.
richt@239
  1821
            </li>
richt@239
  1822
          </ol>
richt@239
  1823
        </li>
richt@437
  1824
        <li>Add <var>network service record</var> to the <a href="#dfn-list-of-available-service-records"
richt@437
  1825
              class="internalDFN">list of available service records</a> as a new item.
richt@239
  1826
        </li>
richt@437
  1827
        <li>For each <var>service manager</var> in the <a href="#dfn-list-of-active-service-managers"
richt@437
  1828
              class="internalDFN">list of active service managers</a> run the following steps:
richt@239
  1829
          <ol class="rule">
richt@250
  1830
            <li>For each <var>active service</var> in <var>service manager</var> run the following steps:
richt@250
  1831
              <ol class="rule">
richt@379
  1832
                <li>If the <var>network service record</var>'s <code>id</code> property equals the <var>active
richt@392
  1833
                service</var>'s <code>id</code> attribute and <var>active service</var>'s <code>online</code> attribute
richt@437
  1834
                is currently set to <code>false</code> then set <var>active service</var>'s <a href=
richt@437
  1835
                "#dom-networkservice-online"><code>online</code></a> attribute to <code>true</code> and then <a href=
richt@437
  1836
                "http://www.whatwg.org/specs/web-apps/current-work/complete/webappapis.html#queue-a-task"
richt@437
  1837
                      class="externalDFN">queue a task</a> to dispatch a newly created event with the name <a href=
richt@448
  1838
                      "#event-available"><code>available</code></a> that uses the <a href=
richt@437
  1839
                      "http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#event"
richt@437
  1840
                      class="externalDFN"><code>Event</code></a> interface, which does not bubble, is not cancellable,
richt@250
  1841
                      and has no default action, at the current <var>active service</var> object.
richt@250
  1842
                </li>
richt@250
  1843
              </ol>
richt@239
  1844
            </li>
richt@379
  1845
            <li>Let <var>'service type in current service manager' flag</var> be <code>false</code>.
richt@379
  1846
            </li>
richt@379
  1847
            <li>For each <var>requested control type</var> of the <var>requested control types</var> in <var>service
richt@379
  1848
            manager</var> run the following steps:
richt@379
  1849
              <ol class="rule">
richt@379
  1850
                <li>If <var>network service record</var>'s <code>type</code> property does not equal <var>requested
richt@379
  1851
                control type</var> then abort any remaining sub-steps and continue at the next available <var>requested
richt@379
  1852
                control type</var>.
richt@379
  1853
                </li>
richt@379
  1854
                <li>Set the <var>'service type in current service manager' flag</var> to <code>true</code>, abort any
richt@379
  1855
                remaining sub-steps and continue.
richt@379
  1856
                </li>
richt@379
  1857
              </ol>
richt@379
  1858
            </li>
richt@379
  1859
            <li>If the <var>'service type in current service manager' flag</var> is set to <code>true</code> then
richt@437
  1860
            increment <var>service manager</var>'s <a href=
richt@437
  1861
            "#dom-networkservices-servicesavailable"><code>servicesAvailable</code></a> attribute by <code>1</code> and
richt@437
  1862
            then <a href="http://www.whatwg.org/specs/web-apps/current-work/complete/webappapis.html#queue-a-task"
richt@437
  1863
                  class="externalDFN">queue a task</a> to dispatch a newly created event with the name <a href=
richt@448
  1864
                  "#event-servicefound"><code>servicefound</code></a> that uses the <a href=
richt@437
  1865
                  "http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#event"
richt@437
  1866
                  class="externalDFN"><code>Event</code></a> interface, which does not bubble, is not cancellable, and
richt@250
  1867
                  has no default action, at the current <var>service manager</var> object.
richt@239
  1868
            </li>
richt@239
  1869
          </ol>
richt@239
  1870
        </li>
richt@239
  1871
      </ol>
richt@239
  1872
      <p>
richt@437
  1873
        The rule for <dfn id="dfn-removing-an-available-service">removing an available service</dfn> is the general
richt@437
  1874
        process of removing an <a href="#dfn-existing-service"
richt@437
  1875
           class="internalDFN">existing service</a> from the <a href="#dfn-list-of-available-service-records"
richt@437
  1876
           class="internalDFN">list of available service records</a> that has left the user's current network or has
richt@437
  1877
           otherwise expired. This rule takes one argument, <var>service identifier</var>, and consists of running the
richt@437
  1878
           following steps:
richt@239
  1879
      </p>
richt@239
  1880
      <ol class="rule">
richt@437
  1881
        <li>For each <var>existing service record</var> in the current <a href="#dfn-list-of-available-service-records"
richt@437
  1882
              class="internalDFN">list of available service records</a>, run the following sub-steps:
richt@239
  1883
          <ol class="rule">
richt@239
  1884
            <li>If the <var>existing service record</var>'s <code>id</code> property does not match <var>service
richt@239
  1885
            identifier</var> then skip any remaining sub-steps for the current <var>existing service record</var> and
richt@239
  1886
            continue at the next available <var>existing service record</var>.
richt@239
  1887
            </li>
richt@379
  1888
            <li>Let <var>'service type in use' flag</var> be <code>false</code>.
richt@239
  1889
            </li>
richt@437
  1890
            <li>For each <var>service manager</var> in the <a href="#dfn-list-of-active-service-managers"
richt@437
  1891
                  class="internalDFN">list of active service managers</a> run the following steps:
richt@239
  1892
              <ol class="rule">
richt@379
  1893
                <li>Let <var>'service type in current service manager' flag</var> be <code>false</code>.
richt@239
  1894
                </li>
richt@250
  1895
                <li>For each <var>active service</var> in <var>service manager</var> run the following steps:
richt@250
  1896
                  <ol class="rule">
richt@250
  1897
                    <li>If <var>existing service record</var>'s <code>id</code> property equals the <var>active
richt@437
  1898
                    service</var>'s <code>id</code> attribute and <var>active service</var>'s <a href=
richt@437
  1899
                    "#dom-networkservice-online"><code>online</code></a> attribute is currently set to
richt@250
  1900
                    <code>true</code> then set <var>active service</var>'s <a href="#dom-networkservice-online"><code>
richt@437
  1901
                      online</code></a> attribute to <code>false</code> and then <a href=
richt@437
  1902
                      "http://www.whatwg.org/specs/web-apps/current-work/complete/webappapis.html#queue-a-task"
richt@437
  1903
                          class="externalDFN">queue a task</a> to dispatch a newly created event with the name <a href=
richt@448
  1904
                          "#event-unavailable"><code>unavailable</code></a> that uses the <a href=
richt@437
  1905
                          "http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#event"
richt@437
  1906
                          class="externalDFN"><code>Event</code></a> interface, which does not bubble, is not
richt@250
  1907
                          cancellable, and has no default action, at the current <var>active service</var>.
richt@250
  1908
                    </li>
richt@250
  1909
                  </ol>
richt@239
  1910
                </li>
richt@379
  1911
                <li>For each <var>requested control type</var> of the <var>requested control types</var> in
richt@379
  1912
                <var>service manager</var> run the following steps:
richt@379
  1913
                  <ol class="rule">
richt@379
  1914
                    <li>If <var>existing service record</var>'s <code>type</code> property does not equal
richt@379
  1915
                    <var>requested control type</var> then abort any remaining sub-steps and continue at the next
richt@379
  1916
                    available <var>requested control type</var>.
richt@379
  1917
                    </li>
richt@379
  1918
                    <li>Set the <var>'service type in current service manager' flag</var> to <code>true</code> and the
richt@379
  1919
                    <var>'service type in use' flag</var> to <code>true</code>, abort any remaining sub-steps and
richt@379
  1920
                    continue.
richt@379
  1921
                    </li>
richt@379
  1922
                  </ol>
richt@379
  1923
                </li>
richt@379
  1924
                <li>If the <var>'service type in current service manager' flag</var> is set to <code>true</code> then
richt@437
  1925
                decrement <var>service manager</var>'s <a href=
richt@437
  1926
                "#dom-networkservices-servicesavailable"><code>servicesAvailable</code></a> attribute by <code>1</code>
richt@437
  1927
                and then <a href=
richt@437
  1928
                "http://www.whatwg.org/specs/web-apps/current-work/complete/webappapis.html#queue-a-task"
richt@437
  1929
                      class="externalDFN">queue a task</a> to dispatch a newly created event with the name <a href=
richt@448
  1930
                      "#event-servicelost"><code>servicelost</code></a> that uses the <a href=
richt@437
  1931
                      "http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#event"
richt@437
  1932
                      class="externalDFN"><code>Event</code></a> interface, which does not bubble, is not cancellable,
richt@250
  1933
                      and has no default action, at the current <var>service manager</var> object.
richt@239
  1934
                </li>
richt@239
  1935
              </ol>
richt@239
  1936
            </li>
richt@379
  1937
            <li>If the <var>'service type in use' flag</var> is <code>false</code> and the <var>existing service
richt@379
  1938
            record</var>'s <code>type</code> property begins with the DOMString "<code>upnp:</code>" and <var>existing
richt@437
  1939
            service record</var>'s <code>eventsURL</code> property is set then run the rule to <a href=
richt@437
  1940
            "#dfn-terminate-an-existing-upnp-events-subscription"
richt@437
  1941
                  class="internalDFN">terminate an existing UPnP Events Subscription</a>, if one is currently active
richt@437
  1942
                  (as a result of having previously called <a href="#dfn-setup-a-upnp-events-subscription"
richt@437
  1943
                  class="internalDFN">setup a UPnP Events Subscription</a> against the current <var>existing service
richt@437
  1944
                  record</var>).
richt@379
  1945
            </li>
richt@437
  1946
            <li>Remove <var>existing service record</var> from the current <a href=
richt@437
  1947
            "#dfn-list-of-available-service-records"
richt@437
  1948
                  class="internalDFN">list of available service records</a>.
richt@239
  1949
            </li>
richt@239
  1950
          </ol>
richt@239
  1951
        </li>
richt@239
  1952
      </ol>
richt@239
  1953
      <p>
richt@437
  1954
        User agents <em class="rfc2119"
richt@437
  1955
           title="SHOULD">SHOULD</em> expire a service record from the <a href="#dfn-list-of-available-service-records"
richt@437
  1956
           class="internalDFN">list of available service records</a> when its <code>expiryTimestamp</code> attribute
richt@437
  1957
           exceeds the current UTC timestamp. When this condition is met the <a href="#dfn-user-agent"
richt@437
  1958
           class="internalDFN">user agent</a> <em class="rfc2119"
richt@437
  1959
           title="SHOULD">SHOULD</em> run the rule for <a href="#dfn-removing-an-available-service"
richt@437
  1960
           class="internalDFN">removing an available service</a>, passing in the expired service record's
richt@437
  1961
           <code>id</code> attribute as the only argument.
richt@239
  1962
      </p>
richt@239
  1963
      <section id="zeroconf-mdns-dns-sd">
richt@447
  1964
        <h3 aria-level="2"
richt@447
  1965
            role="heading"
richt@447
  1966
            id="h3_zeroconf-mdns-dns-sd">
richt@440
  1967
          <span class="secno">8.1</span> Zeroconf (<abbr title="Multicast DNS">mDNS</abbr> + <abbr title=
richt@437
  1968
          "Domain Name System">DNS</abbr>-<abbr title="Service Discovery">SD</abbr>)
richt@239
  1969
        </h3>
richt@239
  1970
        <p>
richt@437
  1971
          For each <abbr title="Domain Name System">DNS</abbr> response received from a user-agent-initiated Multicast
richt@437
  1972
          <abbr title="Domain Name System">DNS</abbr> Browse for <abbr title="DNS Pointer Record">PTR</abbr> records
richt@437
  1973
          with the name <code>_services._dns-sd._udp</code> on the resolved recommended automatic browsing domain
richt@437
  1974
          [<cite><a class="bibref"
richt@437
  1975
             href="#bib-MDNS">MDNS</a></cite>], the <a href="#dfn-user-agent"
richt@437
  1976
             class="internalDFN">user agent</a> <em class="rfc2119"
richt@437
  1977
             title="MUST">MUST</em> run the following steps:
richt@239
  1978
        </p>
richt@239
  1979
        <ol class="rule">
richt@437
  1980
          <li>Let <var>service <abbr title="Multicast DNS">mDNS</abbr> responses</var> be an array of <abbr title=
richt@437
  1981
          "DNS Pointer Record">PTR</abbr> records received by issuing a Multicast <abbr title=
richt@437
  1982
          "Domain Name System">DNS</abbr> Browse for <abbr title="DNS Pointer Record">PTR</abbr> records with the name
richt@437
  1983
          of the current discovered service type.
richt@239
  1984
          </li>
richt@437
  1985
          <li>For each Object <var>service <abbr title="Multicast DNS">mDNS</abbr> response</var> in <var>service
richt@437
  1986
          <abbr title="Multicast DNS">mDNS</abbr> responses</var>, run the following steps:
richt@239
  1987
            <ol>
richt@239
  1988
              <li>Let <var>network service record</var> be an Object consisting of the following empty properties:
richt@239
  1989
              <code>id</code>, <code>name</code>, <code>type</code>, <code>url</code>, <code>config</code>,
richt@239
  1990
              <code>expiryTimestamp</code>.
richt@239
  1991
              </li>
richt@437
  1992
              <li>Set <var>network service record</var>'s <code>id</code> property to the value of the full
richt@437
  1993
                <abbr title="DNS Pointer Record">PTR</abbr> Service Instance Name [<cite><a class="bibref"
richt@437
  1994
                   href="#bib-MDNS">MDNS</a></cite>].
richt@239
  1995
              </li>
richt@437
  1996
              <li>Set <var>network service record</var>'s <code>name</code> property to the value of the <abbr title=
richt@437
  1997
              "DNS Pointer Record">PTR</abbr> Service Instance Name's <var>Instance</var> component [<cite><a class=
richt@437
  1998
              "bibref"
richt@437
  1999
                   href="#bib-MDNS">MDNS</a></cite>].
richt@239
  2000
              </li>
richt@239
  2001
              <li>Set <var>network service record</var>'s <code>type</code> property to the concatenation of the string
richt@437
  2002
              <code>zeroconf:</code> followed be the value of the <abbr title="DNS Pointer Record">PTR</abbr> Service
richt@437
  2003
              Instance Name's <var>Service</var> component [<cite><a class="bibref"
richt@437
  2004
                   href="#bib-MDNS">MDNS</a></cite>].
richt@239
  2005
              </li>
richt@480
  2006
              <li>Set <var>network service record</var>'s <code>url</code> property to the resolvable Service URL
richt@480
  2007
              obtained from performing an <abbr title="Domain Name System">DNS</abbr>-<abbr title=
richt@480
  2008
              "Service Discovery">SD</abbr> Lookup [<cite><a class="bibref"
richt@437
  2009
                   href="#bib-DNS-SD">DNS-SD</a></cite>] of the current service from the <abbr title=
richt@437
  2010
                   "DNS Pointer Record">PTR</abbr> record provided [<cite><a class="bibref"
richt@437
  2011
                   href="#bib-MDNS">MDNS</a></cite>].
richt@239
  2012
              </li>
richt@239
  2013
              <li>Set <var>network service record</var>'s <code>config</code> property to the string value of the
richt@437
  2014
              contents of the first <abbr title="Domain Name System">DNS</abbr>-<abbr title=
richt@437
  2015
              "Service Discovery">SD</abbr> TXT record associated with the <var>service <abbr title=
richt@437
  2016
              "Multicast DNS">mDNS</abbr> response</var> as defined in [<cite><a class="bibref"
richt@437
  2017
                   href="#bib-DNS-SD">DNS-SD</a></cite>].
richt@239
  2018
              </li>
richt@239
  2019
              <li>Set <var>network service record</var>'s <code>expiryTimestamp</code> property to the value of the
richt@239
  2020
              current date, in UTC timestamp format, plus a value of <code>120</code> seconds.
richt@239
  2021
              </li>
richt@483
  2022
              <li>Run the general rule for <a href="#dfn-adding-an-available-service"
richt@437
  2023
                    class="internalDFN">adding an available service</a>, passing in the current <var>network service
richt@483
  2024
                    record</var> as the only argument.
richt@239
  2025
              </li>
richt@239
  2026
            </ol>
richt@239
  2027
          </li>
richt@239
  2028
        </ol>
richt@239
  2029
      </section>
richt@239
  2030
      <section id="simple-service-discovery-protocol-ssdp">
richt@447
  2031
        <h3 aria-level="2"
richt@447
  2032
            role="heading"
richt@447
  2033
            id="h3_simple-service-discovery-protocol-ssdp">
richt@440
  2034
          <span class="secno">8.2</span> Simple Service Discovery Protocol (<abbr title=
richt@437
  2035
          "Simple Service Discovery Protocol">SSDP</abbr>)
richt@239
  2036
        </h3>
richt@239
  2037
        <p>
richt@437
  2038
          A user agent that implements UPnP service discovery <em class="rfc2119"
richt@437
  2039
             title="MUST">MUST</em> issue a <dfn id="dfn-search-request-for-upnp-root-devices">search request for UPnP
richt@437
  2040
             root devices</dfn> against the user's current local network according to the full normative text and
richt@437
  2041
             timing provided in 'Section 1.3.2: Search request with M-SEARCH' detailed in [<cite><a class="bibref"
richt@437
  2042
             href="#bib-UPNP-DEVICEARCH11">UPNP-DEVICEARCH11</a></cite>].
richt@239
  2043
        </p>
richt@239
  2044
        <p>
richt@437
  2045
          The user agent <em class="rfc2119"
richt@437
  2046
             title="MUST">MUST</em> issue all <a title="search request for UPnP root devices"
richt@437
  2047
             href="#dfn-search-request-for-upnp-root-devices"
richt@437
  2048
             class="internalDFN">search requests for UPnP root devices</a> with a <abbr title=
richt@437
  2049
             "Hypertext Transfer Protocol">HTTP</abbr> request line equal to <code>M-SEARCH * <abbr title=
richt@437
  2050
             "Hypertext Transfer Protocol">HTTP</abbr>/1.1</code>, with a HOST header equal to the reserved multicast
richt@437
  2051
             address and port of <code>239.255.255.250:1900</code> and a MAN header equal to
richt@437
  2052
             <code>ssdp:discover</code>. The <a href="#dfn-user-agent"
richt@437
  2053
             class="internalDFN">user agent</a> must also send an ST header with this <abbr title=
richt@437
  2054
             "Hypertext Transfer Protocol">HTTP</abbr> request equal to the String value of <code>ssdp:all</code> or
richt@437
  2055
             <code>upnp:rootdevice</code> or a single <a href="#dfn-valid-service-type"
richt@437
  2056
             class="internalDFN">valid service type</a> token beginning with the String value <code>upnp:</code>. If a
richt@437
  2057
             single <a href="#dfn-valid-service-type"
richt@437
  2058
             class="internalDFN">valid service type</a> token beginning with the String value <code>upnp:</code> is to
richt@437
  2059
             be used, the user agent <em class="rfc2119"
richt@437
  2060
             title="MUST">MUST</em> strip the leading String <code>upnp:</code> before using this value in this
richt@437
  2061
             <abbr title="Hypertext Transfer Protocol">HTTP</abbr> request. The user-agent <em class="rfc2119"
richt@437
  2062
             title="MUST">MUST</em> also send an MX header equal to a <dfn id=
richt@437
  2063
             "dfn-maximum-upnp-advertisement-response-wait-time">maximum UPnP advertisement response wait time</dfn>
richt@437
  2064
             value between <code>1</code> and <code>5</code> seconds with this <abbr title=
richt@437
  2065
             "Hypertext Transfer Protocol">HTTP</abbr> request.
richt@239
  2066
        </p>
richt@239
  2067
        <p>
richt@437
  2068
          The user agent <em class="rfc2119"
richt@437
  2069
             title="MUST">MUST</em> listen for any incoming responses to any <a href=
richt@437
  2070
             "#dfn-search-request-for-upnp-root-devices"
richt@437
  2071
             class="internalDFN">search request for UPnP root devices</a>.
richt@239
  2072
        </p>
richt@239
  2073
        <p>
richt@437
  2074
          For each <dfn id="dfn-http-response"><abbr title="Hypertext Transfer Protocol">HTTP</abbr> Response</dfn>
richt@437
  2075
          following an initial <a href="#dfn-search-request-for-upnp-root-devices"
richt@437
  2076
             class="internalDFN">search request for UPnP root devices</a> sent on a <a href=
richt@437
  2077
             "#dfn-standard-upnp-address-and-port"
richt@437
  2078
             class="internalDFN">standard UPnP address and port</a> the user agent <em class="rfc2119"
richt@437
  2079
             title="MUST">MUST</em> run the following steps:
richt@239
  2080
        </p>
richt@239
  2081
        <ol class="rule">
richt@437
  2082
          <li>If the <a href="#dfn-http-response"
richt@437
  2083
                class="internalDFN"><abbr title="Hypertext Transfer Protocol">HTTP</abbr> Response</a> is not a
richt@437
  2084
                <abbr title="Hypertext Transfer Protocol">HTTP</abbr> 200 OK response then this response is invalid and
richt@437
  2085
                the user agent <em class="rfc2119"
richt@437
  2086
                title="MUST">MUST</em> discard this response, abort any remaining steps and return. The user agent
richt@437
  2087
                <em class="rfc2119"
richt@437
  2088
                title="MAY">MAY</em> issue a new <a href="#dfn-search-request-for-upnp-root-devices"
richt@437
  2089
                class="internalDFN">search request for UPnP root devices</a> as a result of this error occurring.
richt@239
  2090
          </li>
richt@437
  2091
          <li>If the <a href="#dfn-maximum-upnp-advertisement-response-wait-time"
richt@437
  2092
                class="internalDFN">maximum UPnP advertisement response wait time</a> has been exceeded since the
richt@437
  2093
                initial <a href="#dfn-search-request-for-upnp-root-devices"
richt@437
  2094
                class="internalDFN">search request for UPnP root devices</a> was sent then the <a href=
richt@437
  2095
                "#dfn-http-response"
richt@437
  2096
                class="internalDFN"><abbr title="Hypertext Transfer Protocol">HTTP</abbr> Response</a> is invalid and
richt@437
  2097
                the user agent <em class="rfc2119"
richt@437
  2098
                title="MUST">MUST</em> discard this response, abort any remaining steps and return. The user agent
richt@437
  2099
                <em class="rfc2119"
richt@437
  2100
                title="MAY">MAY</em> stop listening for responses from the current <a href=
richt@437
  2101
                "#dfn-search-request-for-upnp-root-devices"
richt@437
  2102
                class="internalDFN">search request for UPnP root devices</a> as a result of this error occurring.
richt@437
  2103
                Equally, the user agent <em class="rfc2119"
richt@437
  2104
                title="MAY">MAY</em> issue a new <a href="#dfn-search-request-for-upnp-root-devices"
richt@437
  2105
                class="internalDFN">search request for UPnP root devices</a> as a result of this error occurring.
richt@239
  2106
          </li>
richt@437
  2107
          <li>Let <var>ssdp device</var> be an Object with a property for each <abbr title=
richt@437
  2108
          "Hypertext Transfer Protocol">HTTP</abbr> header received in the <a href="#dfn-http-response"
richt@437
  2109
                class="internalDFN"><abbr title="Hypertext Transfer Protocol">HTTP</abbr> Response</a>, with each key
richt@437
  2110
                being the name of a <abbr title="Hypertext Transfer Protocol">HTTP</abbr> response header and each
richt@437
  2111
                value being that <abbr title="Hypertext Transfer Protocol">HTTP</abbr> response header's value.
richt@239
  2112
          </li>
richt@239
  2113
          <li>If <var>ssdp device</var> does not contain at least one <var>CACHE-CONTROL</var> entry, at least one
richt@379
  2114
          <var>USN</var> entry, at least one <var>ST</var> entry and at least one <var>LOCATION</var> entry then the
richt@437
  2115
          <a href="#dfn-http-response"
richt@437
  2116
                class="internalDFN"><abbr title="Hypertext Transfer Protocol">HTTP</abbr> Response</a> is invalid and
richt@437
  2117
                the <a href="#dfn-user-agent"
richt@437
  2118
                class="internalDFN">user agent</a> <em class="rfc2119"
richt@437
  2119
                title="MUST">MUST</em> discard this response, abort any remaining steps and return.
richt@239
  2120
          </li>
richt@437
  2121
          <li>The user agent <em class="rfc2119"
richt@437
  2122
                title="MUST">MUST</em> run the rule for <a href="#dfn-obtaining-a-upnp-device-description-file"
richt@437
  2123
                class="internalDFN">obtaining a UPnP Device Description File</a> passing in the first occurrence of
richt@480
  2124
                <var>LOCATION</var> from <var>ssdp device</var> as the <var>device descriptor URL</var> argument and
richt@480
  2125
                the first occurrence of <var>USN</var> from <var>ssdp device</var> as the <var>device identifier</var>
richt@480
  2126
                argument and the first occurrence of <var>CACHE-CONTROL</var> from <var>ssdp device</var> (minus the
richt@480
  2127
                leading string of <code>max-age=</code>) as the <var>device expiry</var> argument.
richt@239
  2128
          </li>
richt@239
  2129
        </ol>
richt@239
  2130
        <p>
richt@437
  2131
          The user agent <em class="rfc2119"
richt@437
  2132
             title="MUST">MUST</em> listen for incoming requests on the <dfn id=
richt@437
  2133
             "dfn-standard-upnp-address-and-port">standard UPnP address and port</dfn> on all current local network
richt@437
  2134
             interface addresses with the port <code>1900</code>.
richt@250
  2135
        </p>
richt@250
  2136
        <p>
richt@437
  2137
          For each <dfn id="dfn-http-request"><abbr title="Hypertext Transfer Protocol">HTTP</abbr> Request</dfn>
richt@437
  2138
          received on a <a href="#dfn-standard-upnp-address-and-port"
richt@437
  2139
             class="internalDFN">standard UPnP address and port</a> the user agent <em class="rfc2119"
richt@437
  2140
             title="MUST">MUST</em> run the following steps:
richt@239
  2141
        </p>
richt@239
  2142
        <ol class="rule">
richt@437
  2143
          <li>If the <a href="#dfn-http-request"
richt@437
  2144
                class="internalDFN"><abbr title="Hypertext Transfer Protocol">HTTP</abbr> Request</a> is not a
richt@437
  2145
                <abbr title="Hypertext Transfer Protocol">HTTP</abbr> NOTIFY request then it is not a valid UPnP
richt@437
  2146
                Request and the user agent <em class="rfc2119"
richt@437
  2147
                title="MUST">MUST</em> discard this request, abort any remaining steps and return.
richt@239
  2148
          </li>
richt@437
  2149
          <li>Let <var>ssdp device</var> be an Object with a property for each <abbr title=
richt@437
  2150
          "Hypertext Transfer Protocol">HTTP</abbr> header received in the <a href="#dfn-http-request"
richt@437
  2151
                class="internalDFN"><abbr title="Hypertext Transfer Protocol">HTTP</abbr> Request</a>, with each key
richt@437
  2152
                being the name of a <abbr title="Hypertext Transfer Protocol">HTTP</abbr> header and each value being
richt@437
  2153
                that <abbr title="Hypertext Transfer Protocol">HTTP</abbr> header's value.
richt@239
  2154
          </li>
richt@437
  2155
          <li>If <var>ssdp device</var>'s <var>NTS</var> entry is equal to <code>ssdp:alive</code> and the <a href=
richt@437
  2156
          "#dfn-http-request"
richt@437
  2157
                class="internalDFN"><abbr title="Hypertext Transfer Protocol">HTTP</abbr> Request</a> does not contain
richt@437
  2158
                at least one <var>CACHE-CONTROL</var> entry, at least one <var>USN</var> entry, at least one
richt@437
  2159
                <var>NT</var> entry, at least one <var>NTS</var> entry and at least one <var>LOCATION</var> entry, then
richt@437
  2160
                the <a href="#dfn-user-agent"
richt@437
  2161
                class="internalDFN">user agent</a> <em class="rfc2119"
richt@437
  2162
                title="MUST">MUST</em> discard this request, abort any remaining steps and return.
richt@239
  2163
          </li>
richt@250
  2164
          <li>If <var>ssdp device</var>'s <var>NTS</var> entry is equal to <code>ssdp:alive</code> then the user agent
richt@437
  2165
          <em class="rfc2119"
richt@437
  2166
                title="MUST">MUST</em> run the rule for <a href="#dfn-obtaining-a-upnp-device-description-file"
richt@437
  2167
                class="internalDFN">obtaining a UPnP Device Description File</a> passing in the first occurrence of
richt@480
  2168
                <var>LOCATION</var> from <var>ssdp device</var> as the <var>device descriptor URL</var> argument and
richt@480
  2169
                the first occurrence of <var>USN</var> from <var>ssdp device</var> as the <var>device identifier</var>
richt@480
  2170
                argument and the first occurrence of <var>CACHE-CONTROL</var> from <var>ssdp device</var> (minus the
richt@480
  2171
                leading string of <code>max-age=</code>) as the <var>device expiry</var>.<br>
richt@239
  2172
            <br>
richt@239
  2173
            Otherwise, if <var>ssdp device</var>'s <var>NTS</var> entry is equal to <code>ssdp:byebye</code> then the
richt@437
  2174
            user agent <em class="rfc2119"
richt@437
  2175
                title="MUST">MUST</em> run the rule for <a href=
richt@437
  2176
                "#dfn-removing-all-services-from-a-registered-upnp-device"
richt@437
  2177
                class="internalDFN">removing all services from a registered UPnP Device</a> passing in the first
richt@437
  2178
                occurrence of <var>USN</var> from <var>ssdp device</var> as the <var>device identifier</var> argument.
richt@239
  2179
          </li>
richt@239
  2180
        </ol>
richt@239
  2181
        <p>
richt@437
  2182
          The rule for <dfn id="dfn-obtaining-a-upnp-device-description-file">obtaining a UPnP Device Description
richt@437
  2183
          File</dfn> is the process of obtaining the contents of a standard UPnP Device Description [<cite><a class=
richt@437
  2184
          "bibref"
richt@480
  2185
             href="#bib-UPNP-DEVICEARCH11">UPNP-DEVICEARCH11</a></cite>] from a URL-based resource. This rule takes
richt@480
  2186
             three arguments - <var>device descriptor URL</var>, <var>device identifier</var> and <var>device
richt@480
  2187
             expiry</var> - and when called the user agent <em class="rfc2119"
richt@437
  2188
             title="MUST">MUST</em> run the following steps:
richt@239
  2189
        </p>
richt@239
  2190
        <ol class="rule">
richt@480
  2191
          <li>Let <var>device descriptor file</var> contain the contents of the file located at the URL provided in
richt@480
  2192
          <var>device descriptor URL</var> obtained according to the rules defined in 'Section 2.11: Retrieving a
richt@480
  2193
          description using <abbr title="Hypertext Transfer Protocol">HTTP</abbr>' in [<cite><a class="bibref"
richt@437
  2194
               href="#bib-UPNP-DEVICEARCH11">UPNP-DEVICEARCH11</a></cite>].
richt@239
  2195
          </li>
richt@480
  2196
          <li>If the value provided in <var>device descriptor URL</var> cannot be resolved as a reachable URL on the
richt@480
  2197
          current network or the <var>device descriptor file</var> remains empty then it is invalid and the <a href=
richt@480
  2198
          "#dfn-user-agent"
richt@437
  2199
                class="internalDFN">user agent</a> <em class="rfc2119"
richt@437
  2200
                title="MUST">MUST</em> abort any remaining steps and return.
richt@239
  2201
          </li>
richt@437
  2202
          <li>Run the rule for <a href="#dfn-processing-a-upnp-device-description-file"
richt@437
  2203
                class="internalDFN">processing a UPnP Device Description File</a>, passing in the current <var>device
richt@437
  2204
                descriptor file</var>, <var>device identifier</var> and <var>device expiry</var> arguments.
richt@239
  2205
          </li>
richt@239
  2206
        </ol>
richt@239
  2207
        <p>
richt@437
  2208
          The rule for <dfn id="dfn-processing-a-upnp-device-description-file">processing a UPnP Device Description
richt@437
  2209
          File</dfn> is the process of parsing the contents of a standard UPnP Device Description [<cite><a class=
richt@437
  2210
          "bibref"
richt@437
  2211
             href="#bib-UPNP-DEVICEARCH11">UPNP-DEVICEARCH11</a></cite>] and registering the UPnP services contained
richt@437
  2212
             therein within the <a href="#dfn-list-of-available-service-records"
richt@437
  2213
             class="internalDFN">list of available service records</a>.
richt@239
  2214
        </p>
richt@239
  2215
        <p>
richt@437
  2216
          The rule for <a href="#dfn-processing-a-upnp-device-description-file"
richt@437
  2217
             class="internalDFN">processing a UPnP Device Description File</a> takes three arguments - <var>device
richt@437
  2218
             descriptor file</var>, <var>device identifier</var> and <var>device expiry</var> - and when called the
richt@437
  2219
             user agent <em class="rfc2119"
richt@437
  2220
             title="MUST">MUST</em> run the following steps:
richt@239
  2221
        </p>
richt@239
  2222
        <ol class="rule">
richt@239
  2223
          <li>Let <var>advertised services</var> be a list of all advertised services obtained from the <var>device
richt@239
  2224
          descriptor file</var> containing the value of the first occurrence of the <code>&lt;serviceList&gt;</code>
richt@437
  2225
          element as it is defined in 'Section 2.3: Device Description' in [<cite><a class="bibref"
richt@437
  2226
               href="#bib-UPNP-DEVICEARCH11">UPNP-DEVICEARCH11</a></cite>].
richt@239
  2227
          </li>
richt@239
  2228
          <li>For each <code>&lt;service&gt;</code> element - known as an <var>advertised service</var> - in
richt@239
  2229
          <var>advertised services</var> run the following steps:
richt@239
  2230
            <ol class="rule">
richt@239
  2231
              <li>Let <var>network service record</var> be a new Object consisting of the following empty properties:
richt@239
  2232
              <code>id</code>, <code>deviceId</code>, <code>name</code>, <code>type</code>, <code>url</code>,
richt@239
  2233
              <code>eventsUrl</code>, <code>config</code>, <code>expiryTimestamp</code>.
richt@239
  2234
              </li>
richt@239
  2235
              <li>Set <var>network service record</var>'s <code>id</code> property to the concatenated string value of
richt@250
  2236
              the first occurrence of the <code>&lt;UDN&gt;</code> element in the <var>device descriptor file</var>
richt@250
  2237
              with the <var>advertised service</var>'s <code>&lt;serviceId&gt;</code> sub-element.
richt@239
  2238
              </li>
richt@239
  2239
              <li>Set <var>network service record</var>'s <code>deviceId</code> property to the value of <var>device
richt@239
  2240
              identifier</var>.
richt@239
  2241
              </li>
richt@239
  2242
              <li>Set <var>network service record</var>'s <code>name</code> property to the string value of the first
richt@239
  2243
              occurrence of the <var>advertised service</var>'s <code>&lt;serviceId&gt;</code> sub-element.
richt@239
  2244
              </li>
richt@239
  2245
              <li>Set <var>network service record</var>'s <code>type</code> property to the concatenation of the string
richt@239
  2246
              <code>upnp:</code> followed by the string value of the first occurrence of the <var>advertised
richt@239
  2247
              service</var>'s <code>&lt;serviceType&gt;</code> sub-element.
richt@239
  2248
              </li>
richt@239
  2249
              <li>Set <var>network service record</var>'s <code>url</code> property to the string value of the first