Re: [discovery] Adding CORS to NSD API - proposal and issues

On Fri, Oct 4, 2013 at 7:18 PM, Rich Tibbett <richt@opera.com> wrote:

> >>
> >> The NSD API spec currently details the network service discovery
> >> processes for three mechanisms: SSDP (UPnP), mDNS+DNS-SD and DIAL and
> >> the method for each of these mechanisms to indicate a networked
> >> service supports CORS could be as follows:
> >>
> >> - For SSDP, a <service> node contained within a UPnP Device Descriptor
> >> File must provide a <corsEnabled> sub-element whose value must be set
> >> to '1', 'yes', 'y' or 'true'. Otherwise, the <service> is said not to
> >> support CORS and is therefore not accessible to web pages (except if
> >> the service type is whitelisted by the user or user agent).
> >>
> >> [...]
> >>
> >>
> >> - For DIAL, the discovery message response must contain a
> >> 'Access-Control-Allow-Origin' HTTP header and the value of this header
> >> must be '*'. Otherwise, the DIAL service is said not to support CORS
> >> and is therefore not accessible to web pages (except if the DIAL
> >> service type is whitelisted by the user or user agent).
> >>
> >
> > since DIAL is based on SSDP, why using two different mechanisms for DIAL
> and
> > "regular" SSDP? In particular, why not using an header in both cases?
> Would
> > make the process lighter, as you don't have to parse xml files. Such
> header
> > could either be the CORS header or an extra header (based on the answer
> to
> > my question further up)
>
> Presumably we want CORS opt-in to be on a service-by-service basis

rather than on a devices level (which would otherwise expose _all_
> services belonging to that device to web pages).
>
UPnP provides a device descriptor that describes multiple network
> services (and, optionally, embedded device descriptors that describe
> yet more network services). DIAL does not advertise services in the
> device descriptor file in the same way. A DIAL discovery message
> always represents exactly one network service, hence the ability for
> us to indicate CORS opt-in at the HTTP level of the discovery
> messaging itself (since that does not apply to a range of network
> services as we get in standard SSDP discovery).
>
>
It has been pointed out before that "device" in UPnP terminology doesn't
mean one physical device. Actually a "device" in UPnP is somewhat closer to
our definition of "service", e.g. a "Media Server" in UPnP is a device, and
includes the following services: "ConnectionManager", "ContentDirectory",
"AVTransport", "ScheduledRecording".

I think a web app will be interested in talking to a "Media Server" and NOT
to a subset of functionalities of a Media Server services (functions).  I
think this goes back to the old discussion about UPnP services VS UPnP
devices: does it make sense to expose single UPnP services rather than UPnP
devices? I don't remember if we concluded on that, maybe we should do it
before we change the spec.

Going back to the original issue, my comment above is not that relevant
anymore if we go for the "alternative" proposal (as I also suggest). It's
still important to define though what to do with UPnP devices: if only some
services support CORS (i.e. the tentative preflight requests on their
control URL is successful) what should the UA do? Should it be exposed to a
web application or not? Should we even allow search for single UPnP
services, or only for devices?


>> ---
> >>
> >> Current Proposal Issues:
> >>
> >> The main problem with this approach is that dissonance has now been
> >> introduced between a.) the indicating of support for CORS during the
> >> discovery process and b.) _actual_ support for CORS in subsequent
> >> service interactions. i.e. If a networked service indicates it
> >> supports CORS during the discovery process and then subsequently fails
> >> to provide 'Access-Control-Allow-Origin: *' in all subsequent HTTP
> >> responses or the networked service doesn't implement the ability to
> >> respond to CORS preflight requests correctly (among other potential
> >> CORS-related pitfalls) then the process of communicating with a
> >> networked service fails and the service is broken for all meaningful
> >> purposes (I can't communicate with a discovered process from a web
> >> page).
> >>
> >> One solution to this issue may be to require networked services to
> >> opt-in to cross-site requests during their discovery processes (as
> >> proposed above) but then for the user agent to 'simulate' CORS support
> >> for that networked service's URL endpoint. This is similar to the way
> >> the API is currently drafted, by adding service URLs to a URL
> >> whitelist that requires the user agent to treat service URLs as if
> >> they supported CORS without the service itself needing to support CORS
> >> directly.
> >>
> >
> > I don't think we should do this, unless there is a use case behind it. We
> > shouldn't do it to workaround a potential bug, especially for something
> that
> > is new!
>
> But it does fulfil the requirement that services opt-in to web sharing
> without then also mandating those network services to also implement
> CORS at the messaging level. Then maybe requiring CORS implementation
> at the messaging level in all network services is overkill considering
> those services have already opted-in to web sharing at the discovery
> level.
>
>
A comment from implementer would be valuable here. I've got the impression
that the effort required to change your services to "opt-in" is the same as
to change your service to support CORS. If so, better to go for a cleaner
solution



> >
> > So this means a service will be exposed to a web app IFF:
> >
> > - the service end point is CORS Enabled
> > - the user as approved sharing that service, correct?
>
> Yes. Of course the tricky bit is finding a way for the service to
> indicate that it is CORS enabled _before_ the user is asked to share
> the service with a web page and before any service messaging has taken
> place which is the main topic of this thread.
>
>
not sure I understand: wouldn't the UA issue this preflight request to make
sure the service is CIRS enabled before exposing it to the user/webapp?


> >
> > BTW could be a good idea to also include a "blacklist" of services that
> > shall never be exposed (like routers)
>
> We could do this and it would have no impact on the current API itself.
>
> Since all network service access is essentially 'keyed' on its
> respective, well-known service type token then we could certainly
> disallow certain service types from ever connecting with web pages.
>
>
Maybe you can try to write something in the spec on this (you could start
with an informative section (SHOULD) and we can discuss if to make it a MUST



> >
> >> ---
> >>
> >> Alternative Proposal Issues:
> >>
> >> The major problem with adopting this alternative approach is that the
> >> root of a networked service endpoint URL is not always configured to
> >> return 200 OK responses (some networked services may provide access
> >> only in sub-directories or non-standard root locations which can
> >> differ per network service type). CORS preflight requests abort if the
> >> HTTP response is not 200 OK, in which case this approach would fail to
> >> capture legitimate CORS-enabled networked services during this
> >> process.
> >>
> >
> > not sure I get this, can you give a concrete example?
>
> If a network service's control URL is resolved during the discovery
> process to be http://192.168.1.2:3333/myservice and we then want to
> tentatively check if CORS is enabled then the user agent would then
> immediately issue a tentative CORS preflight request to that URL (A
> HTTP OPTIONS request to the root service endpoint URL as described in
> [3]). That service MUST respond with a 200 OK from that URL with a
> 'Access-Control-Allow-Origin: *' response header provided for that
> service to be considered CORS-enabled and therefore for that service
> to be accessible to web pages (pending prior user authorization via
> browser chrome before any sharing taking place of course).
>
> My initial concern was whether _all_ service root URLs would be set up
> to respond to that tentative CORS preflight request or whether some
> service endpoints are only configured to work on sub-paths of that
> root URL. e.g. if my service only responds to CORS requests at
> http://192.168.1.2:3333/myservice/mymethod then it would fail the CORS
> preflight check and not be offered up to users to share with web
> pages.

On second thoughts that may be a non-issue since we do not have any
> legacy CORS support in any of the network services we are looking at
> sharing.


yes, this is my thought as well. Anyway the best thing would be to write a
proposal and discuss it with relevant standardization bodies.


> Perhaps the original alternative proposal is better since it
> requires no changes at the discovery protocol level.
>

yes, and the fallback to support for "legacy" devices would be to basically
allow cross-domain requests regardless of the services supporting CORS.

Received on Saturday, 5 October 2013 09:09:03 UTC