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