- From: Rich Tibbett <richt@opera.com>
- Date: Tue, 05 Feb 2013 15:36:15 +0100
- To: public-device-apis@w3.org
Hi all, Cathy.Chan@nokia.com wrote: > As promised at the DAP call last week, here is a collection of > comments and > questions on Network Service Discovery APIs that have not been addressed > or resolved. I've grouped them into three categories - technical > comments, > feature requests, and questions and clarifications. Hopefully this > helps in > focusing future discussions one way or another. Thanks for consolidating these comments and questions! Let me start by going through each of the items below and let's pick up the discussion here. > > I tried to distill some of the issues where I can, but left most of > them in > the way > that they were initially brought up. Hence the length of this message. If you wish to reply to anything below, please do so in-line, removing the rest of the message that is not relevant to your specific feedback. > > If I inadvertently left out anything, please kindly add to the list. > Thanks. > > ------------------- > > Comments and questions on Network Service Discovery APIs (4 Oct, 2012 > draft > [0]) > > A. Technical comments on the current draft > 1. Explicit user permission is required for every device upon each > getNetworkServices() call. Should that be changed? From Greg [1]: > [[The user verification steps are good as a semantic point, I think, > but the > spec seems too insistent that the user be prompted for every discovery > interaction. If they have a TV they are controlling, why not enable > that to > be used by default? I think the thinking from comparing web intents and > registerProtocolHandler will prevail -- the set of APIs that allow > users to > select handlers, services, etc. will be presented to the user in a > uniform > way by UAs, and so the same defaulting policies should apply to all.]] > Rich's response [2]: > [[That's a good point. The spec doesn't yet have wording to this > effect. I > expect we could add it at Step 13 of the getNetworkServices algorithm, > changing it to something like "Optionally, e.g. based on a > previously-established user preference, for security reasons, or due to > platform limitations, the user agent may "... return a pre-defined > successCallback or throw an errorCallback. The wording here would need > some > work ;)]] > Greg's suggestion [3]: > [[4.1 ... When the getNetworkServices(type, successCallback[, > errorCallback]) method is called, the user agent must run the following > steps: > ... > 10. The user agent must prompt the user in a user-agent-specific > manner for > permission ... > > I suggest changing this to something along the lines of "The user > agent must > not provide the entry script's origin [...] without prior permission > given > by the user." or something like that to communicat that the user and > UA can > team up to make defaulting possible -- the point being the UA has a > responsibility to the user not to do things without permission, but > they can > get an understanding of that permission without explicit prompting at > every > invocation.]] I've updated the specification to incorporate this feedback: https://dvcs.w3.org/hg/dap/rev/8b03e17da083#l1.55 > 2. In the introductory text of 7 Service Discovery, in the definition > of "list > of available service records", s/at any given time/at the current > time/ to > match the change made to "list of active service managers". Fixed. > > 3. Unnecessary requirement on UA to issue UPnP search requests with > search > target of "upnp:rootdevice". From Cathy [4], [6]: > In the introductory text of 7.2 Simple Service Discovery Protocol, > [[The user agent must issue all search requests for UPnP root devices > with a > HTTP request line equal to M-SEARCH * HTTP/1.1, with a HOST header > equal to > the reserved multicast address and port of 239.255.255.250:1900, a MAN > header > equal to ssdp:discover, an ST header equal to upnp:rootdevice and a > user-agent > defined MX header equal to a maximum UPnP advertisement response wait > time > value between 1 and 5 seconds.]] > This requires UAs to always issue search requests for "upnp:rootdevice". > However, in cases where the UA invokes a search in response to a call to > getNetworkServices() with a particular UPnP service type, the UA > should be > allowed to issue a search with the requested search target instead of > the much > broader "upnp:rootdevice" one. This would cause only the targeted > services to > respond (as opposed to all services responding and leaving it to the > UA to > filter out those that do not match). Agreed and I've updated the specification accordingly: https://dvcs.w3.org/hg/dap/rev/7639401e21f4 > 4. Simplify algorithm for "adding an available service"? From Cathy [6]: > [[Actually looking at the algorithm again, step 4.2.3 should be > performed when > the new service registration flag is *true*. In the case that the flag > was > false, the service was already in the list of available service records, > meaning it must have already been online (by definition of the list of > available service records). Thus, all the corresponding NetworkService > objects > within each NetworkServices object would also have had the online > attribute > set to true. There would be no need to change their online attributes > and no > need to dispatch the serviceonline events. On the other hand, in the > case that > the new service registration flag is true, and a matching service > record is > found in the service manager, the service must have been previously > discovered, the service record removed from the list of available service > record (because it went offline), and was retained in the service > manager and > marked as offline (per step 1.3.2.3 in 'removing an available > service'). Now > that the service is back online, the matching record in the service > manager > needs to be marked as online and the serviceonline event be > dispatched. (Note > also that the condition that the online attribute was previously false is > unnecessary, as it must always be the case.) I had to read this around 10 times but finally I figured it out ;) I've updated the spec with changes to the algorithms as suggested: https://dvcs.w3.org/hg/dap/rev/bc1d9819cad3 > > Furthermore, since steps 3 and 4 both apply only when the new service > registration flag is true, one can simplify the algorithm by aborting > at the > end of step 2.3 (where an existing service record is found in the > current list > of available service records). In fact, the new service registration > flag is > not even needed at all, simplifying this even more.]] I've incorporated this in to the commit provided above. > > 5. From Cathy [4]: In 7.2, in the steps for processing HTTP Requests, > Step 3 > applies only to ssdp:alive messages (ssdp:byebye messages do not have the > CACHE-CONTROL and LOCATION entries). It should start with "If the > value of the NTS entry of the ssdp device is 'ssdp:alive'". Fixed. https://dvcs.w3.org/hg/dap/rev/07e931de937f > > 6. From Cathy [6]: In 7, in the steps for adding an available service, > step 4 > determines if the network service record is of a type that the service > manager > would be > interested in (and hence whether the servicesAvailable attribute needs > to be > updated and the serviceavailable event be sent). It would be more > accurate to > simply compare the network service record's type attribute with the type > attribute that was used in the getNetworkServices API to create the > particular > service manager object. Consider the case where the web page invokes > getNetworkServices with two types (A and B). At the time of the > invocation, > two service records of type A were found but nothing of type B was > found. The > associated service manager object would therefore have two service > records, > both of type A, but it (or the web page) would certainly still be > interested > in being notified if a new service of type B do become available later > on. > With the current algorithm, when a new service of type B is found by > the UA, > the service manager would not be made aware of it. Excellent catch and fixed (also updated in the rule for 'removing an available service'): https://dvcs.w3.org/hg/dap/rev/f290bbd84426 > 7. From Cathy [6]: In 7, in the steps for removing an available > service, step > 2 attempts to unsubscribe from existing UPnP events subscriptions. > However, > event > subscription is done once per each *authorized* service, i.e. per > NetworkService object instances in service manager objects, and not per > instance of the service record in the list of available service > records. Thus > step 2 should be a sub-step of 3.2.3. I've made a few structural changes to how this algorithm is laid out that hopefully resolves this issue: https://dvcs.w3.org/hg/dap/rev/89d1cef16d35 > 8. Network topology. From Youenn [7]: > [[A device may have more than one ongoing network connection. > If one network connection is dropped amongst several, only the service > records > that are related to the dropped network should probably be removed. > First sentence in section 7.3 may be further precised on that respect.]] Clarified the first sentence in 7.3: https://dvcs.w3.org/hg/dap/rev/631133236bc9 > B. Feature requests > 1. Unpack config information? From Greg [3]: > [[Would it be more convenient to unpack that for the client in a > strucured > way? That is, it sounds like the opaque config string may only be > useful if > the client app already has knowledge of particular devices. Should the > API > provide that identifier (unique device id? > device descriptor doc?) in parsed form? Or are there too many or too much > variation for that to make sense? I believe there is too much variation in the data we can and may receive. Add to that the complexities in converting XML to JSON and we start to dig ourselves a large hole rather quickly heading down this path IMO. > I don't know that a special user opt-in for this info makes sense -- my > question is more about what the client will use it for, and whether > the UA > can do a better job of presenting it, or if it'll be hard to use, should > just not present it at all.]] We should probably drop the .config attribute for privacy purposes. It doesn't actually add anything to the communication aspects of the API. All of that happens through the .url attribute on NetworkService objects. It's something we need to discuss further so I've left the spec unchanged for now. > 2. Expiration time of mDNS service record should either come from the > service > or be left up to implementation, and not mandated by the spec (currently > 120ms). From Cathy [4]. > Also from Youenn [7]: > [[120 seconds seems a pretty small value. > Depending on the message types, the recommended TTL value is either 120 > seconds or 75 minutes as per the mdns spec. > Would 75 minutes be more appropriate in that case? That's quite a big difference from 120 seconds. > More generally, a browser may have a precise knowledge of the TTL and may > prefer using a value different from the one in the spec. > Would it make sense to accommodate the rules accordingly?]] > Rich indicated that the Zeroconf section will be reviewed and revised > [5]. I'd be more comfortable mandating a short timeout, like the 120 seconds mentioned in the mDNS specification, to maintain a fresh services table and consistency across implementations (not to mention, simplicity). We *could* leave this up to implementations and I could therefore downgrade this to a SHOULD requirement, but I'm tempted to leave it as it is for in the interest of maintaining a healthy active services table. I'm open to rewrite proposals here. > 3. Use UPnP friendly name as NetworkService.name? From Cathy [8]: > [[The NetworkService.name attribute is supposed to be a > "human-readable title > for the service". Currently, for UPnP, it's defined to be the serviceId, > which doesn't fit the intended purpose at all. I would suggest using the > device's friendlyName in this attribute if it's intended to be a > user-facing > property.]] > JCD is concerned about fingerprinting [9]. Cathy thinks as long as the > information is provided after user consent, it should be ok [10]. The UPnP Friendly Name is only provided at the device-level, not at the individual services level. As such it doesn't seem it would make sense to use that for service naming (10 different services from the same device would each have the same names which is misleading IMO). It would be great if there were something equivalent to 'friendly name' in the service description file (obtainable via the Service's SCPDURL element). Alas, there is no such thing. > 4. Allow device type search (and more generally, other UPnP search > strings)? >> From Naoyuki Sato [11], [13] and Cathy [14]: > It is typically more common for UPnP controller applications to search > for > device types than service types, as controllers tend to expose a > device list > for the user to select from. The abstraction introduced by this specification is at the service-level. At no point would a user agent know what device types to search for since that is not a parameter that can be provided via the getNetworkServices() method. I have updated the specification so implementations can search for 'ssdp:all', 'upnp:rootdevice' or a valid service type token in their UPnP Search. I don't know how we could know to search for a specific device type in this specification. That would be a severe limitation on user choice in selecting services that match those requested by the page and favors the big players to promote and exclude existing and new devices from being discovered via this API. The specification is deliberately device-neutral and service orientated. > 5. Allow cross-domain access to additional UPnP device resources in > addition > to control URL? From Naoyuki Sato [11], [13]: > The access white-list should be expanded to include additional UPnP > resources > such as device description page, service description page, which > allows the > web app to examine the actions and other details supported by a > service, and > device icons, which allow the web app to show the device icon to > improve user > experience. That could be a good addition. We could add .icon to the NetworkService interface for example. However, that would be a UPnP specific attribute. There is no easily addressable icon equivalent in mDNS AFAIK. If it only works half the time it's probably not worth adding. > > C. Questions and clarifications > 1. Questions about multi-type query. From Youenn [7]: > [[What is the benefit of having one single query with a set of types? > Wouldn't it be simpler for application developers to make several > requests for > different types? > Like requesting access to a local media storage service and then, if > needed, > requesting access to a print service. > Wouldn't it be simpler as well for users to grant access for one > service type > at a time? Well, that's still possible with what we have specified today. You could request one service type per call to getNetworkServices and you would have the experience you're after above. Allowing multiple types in a single request allow us to do cool things with the UA prompt. For example, we will be showing devices in the UA prompt. If one device happens to support two requested service types, then the user need only select that device once. It also means we can take both upnp: and a zeroconf: types in a single call to getNetworkServices and display a combined UA prompt with the devices that match either/or of those requested types. Whether those devices are UPnP or Zeroconf based is irrelevant in that scenario. > > Also, one NetworkServices for each service type may be more convenient. > For instance, onserviceavailable handlers would directly be linked to > a single > service type.]] Again, you could enforce this in your app by calling getNetworkServices once for each service type you want. The fact is that a zeroconf and upnp service may be indistiguishable from a user's perspective if they provide similar services. The plumbing of interacting with those services may differ but that's a job for the application logic to abstract away from the user. Allowing authorization to happen in a single call and relying on the application to talk different dialects to each service is acceptable and a better user experience than having to request each service individually. > > 2. Questions about available services. From Youenn [7]: > [[What is the goal behind servicesAvailable? > What functionality does it bring to web applications? > Wouldn't the current NetworkServices events and authorized services > length be > sufficient in most cases? > Or just as a boolean value stating that there are some changes in the > services > of interest? > It seems that serviceAvailable is counting services of potentially > different > types, which may not be all that useful.]] It will notify you if the number of services available of a type equal to any of the original requested service types changes in the network. It's intended as a flag that will allow your web application to respond to perceived changes in the current network, if it so wishes to do so (instead of, for example, polling getNetworkServices every X seconds with a knock-on bad user experience). If you're already requesting these services in the original call to getNetworkServices then you've already presumably implemented the application logic to handle these services. When servicesAvailable changes, you may like to re-issue a call to getNetworkServices, since there's a likelihood that more services may be added to the current set of services being provided to your web page. > > 3. Questions about service monitoring. From Youenn [7]: > [[Service monitoring > Monitoring of services availability looks like a useful feature. > Probably a user has three options that should be clearly stated: > - A user is granting permission to 1+ service(s) and grants permission to > monitor services > - A user is granting permission to monitor services > - A user is denying permission to any service and to monitoring > As per step 9 in section 4.1, it is not explicit whether the second > option is > valid. > Two choices are currently described: granting permission to 1+ > services or > denying permission (probably to all services?). The spec says the following: "The NetworkServices interface represents a collection of zero or more indexed properties that are each a user-authorized NetworkService object." If the user provides zero services, then you have the second option above. I'm not sure how the dialog would handle that case but it's certainly made possible by the specification as it is written now. > > Also, what about a user that wants to grant access to one specific > service > while denying access to monitoring information? > Maybe this behavior does not make any sense in practice? We'd need a use case where this does make sense. Do you have one? > But the spec could probably be updated to enable that behavior at a small > cost. > Something like not mandating to add the generated NetworkServices in > the list > of active service managers. > Or making the serviceavailable/serviceunavailable events sending > optional?]] Such a change would need to be based on a common use case. > > 4. Relationship with Web Intent based discovery. From Youenn [7]: > [[Service monitoring is a potentially nice feature in the network > discovery > API specification. > This monitoring does not seem to be available with the "Web Intents > Addendum - > Local Services" approach. > For instance, dynamically adding a print button, or changing its > color, when a > local printer is showing up may be convenient in terms of user > experience. > This seems to be feasible with this API, while this may not be the > case with > the web intents approach. > Is that ok as is? > Is monitoring out of scope (or a potential requirement) for the "Web > Intents > Addendum - Local Services" approach? > Should service monitoring be a separate feature that can be used by both > approaches? This should be addressed in that line of work I think (Web Intents). Anything we need to do here related to the NSD spec? If we end up deciding on sharing a mechanism for that then we could come back to this in the NSD spec work? > > More generally, the question of the relationship between the two > approaches > will probably show up in the future (what is the difference, what is the > scope, which approach should I use...). > It may be good to have some answers publicly available (if it is not > already > the case?).]] Essentially, the Web Intents Addendum Local Services was about specifying a new UPnP and Zeroconf Service Type specifically for handling Web Intents. You would not be able to use it to connect with e.g. any of the UPnP services specified on upnp.org unless that device was patched with the Web Intents UPnP service also. The NSD spec is about communicating with any UPnP Service Type - existing or new (including but not limited to those provided on upnp.org), without requiring any hardware or software changes to existing or new UPnP-based devices. The same priniciple applies to Zeroconf-based devices and services via this API. Perhaps others have observed additional differences between the two approaches. They do not share all that much in common IMO other than the discovery protocols being used at their root. > > 5. Questions on whitelist removal. From Youenn [8]: > [[To disable access to a particular service, a user can decide to remove > access to all services (reloading the app or recalling the function > using the > web app UI). > Some browser implementations may want to propose authorization removal > globally or on a per service basis. Whitelisting in the specification is really a small extension to CORS. Actually its something that's been dubbed 'reverse CORS' where the user grants cross-origin permission via service opt-in themselves (instead of that permission coming implicitly from the service itself). If your request makes sense in the scope of CORS then it may make sense here too. > Is it the purpose of the "ongoing local-network communication" indicator? > In that case, if a user disables access to a particular service, how > would the > application be notified of such change? A 'serviceoffline' event is fired on the affected NetworkService object and its online attribute would simultaneously be set to false. > Is it expected that the application will be notified from error messages > coming from the protocol level? No. We have deliberately obfuscated errors for both privacy and simplicity. The web page only really needs to know if access was granted or not. The cause of any error is not something that needs to bubble up to the web application - unless there are any use cases in which that is essential and warrant us having a further look at this. > What happens if there is an ongoing XHR exchange?]] HTTP provides all the handling for this case. We have the 4XX range and timeouts available if the service is knocked offline during an ongoing XHR exchange. > > 6. No access to previous services. From Youenn [7]: > [[The four bullets at the end of section 4.1 describe when access to > any of > the whitelist URL is authorized or not. > After reading the different points, everything is not crystal clear to > me. > Here are some questions that came to my mind: > > What is the exact meaning of the first bullet (same script related in > same or > different window)? It means if you reload the page or open a new page that includes the same script you don't automatically get access to the same NetworkServices that you may have been granted in the previous page. A call to getNetworkServices is stateless (it does not persist across sessions or domains). > What potential security issue is it addressing? Persistence of NetworkService sharing is addressed by the user agent. For example, if the user clicks a 'Remember my sharing preferences for this domain' button, we could automatically invoke the successCallback of the getNetworkServices call with the previous NetworkServices object. What this bullet-point says is that this does not happen automatically and cannot be set by the script itself. > Does it mean that if the same script is loaded in two different windows, > the authorizations for the script in the first window are cancelled > (whitelist > becomes empty) when the script in the second window is loaded? No. The second script and its corresponding permissions act independently of the first script. > If that is the case, similarly to the previous point 5 on whitelist > removal, > while it is easy for application developers to understand that > authorizations > are removed when getNetworkServices is called again, > it may be less obvious for developers to handle bullet 1. Developers should be aware that a call to getNetworkServices is stateless, much like Geolocation or getUserMedia calls. > > As of the second bullet, does it mean that all granted URLs are > removed from > the whitelist when getNetworkServices is called again? If you re-invoke getNetworkServices then you will get a new opt-in dialog. That opt-in dialog would include the current list of services shared with the current page pre-highlighted in the list of all devices currently available on the network and matching the requested service types in the getNetworkServices call. This dialog would require the user to remove one of these highlighted services for the situation you describe here to occur. That's a perfectly reasonable use case IMO but it means the other services that were pre-highlighted and re-shared with the page would remain unaffected (in reality all previously shared services actually all get removed and then re-added immediately according to the getNetworkServices algorithm). > If so, would it make sense to exactly precise when the previous > whitelist is > emptied? > Section 4.1 defines the different steps of the getNetworkServices call > and one > could envision doing this at step 1, 12 or 18 for instance. Yes, this is a good idea. I've updated the spec accordingly (now Step 12 in the getNetworkServices algorithm defined in Section 4.1): https://dvcs.w3.org/hg/dap/rev/a311e7fe116c > If a web application has access to a content provider and also wants > to access > a particular printer, the app will call again getNetworkServices. > It would be nice if the access to the content provider is not cut > during the > 10 seconds the user takes to answer to the getNetworkServices call. I believe the commit above addresses this, considering the removal and addition of whitelisted items to the URL whitelist is done instantaneously after the user has already clicked 'OK' on their authorization dialog. Before the user clicks 'OK' the old URL whitelist would still be in effect. > > The third bullet (going through the history) probably leads to empty the > current whitelist. > On the other hand, the fourth bullet (a script running in a different > origin) > does not probably lead to empty the current whitelist. > This fourth bullet may different in nature to the other items and, if > that is > the case, may be separated from the list.]] The fourth bullet does not empty the current whitelist for the current origin. Only when the user navigates away from the original page will the URL whitelist for that origin be affected. I'm not sure why we would want to separate this from this list. More discussion may be helpful. > > 7. Active service managers. From Youenn [7]: > [[The list of active service managers contains the NetworkServices > objects > being shared with all web pages. > Each NetworkServices object in that list will issue serviceavailable > events > whenever needed. > NetworkServices objects not in this list will not generate those events. Yes. > > What happens to a NetworkServices object delivered by a > getNetworkServices > call that is made obsolete by a new getNetworkServices call? The old NetworkServices object is still present in the 'list of active service managers'. At no point does this object get removed from the list in the specification. Therefore, any event changes will also be applied to old NetworkServices objects whether they are still active or not. > Is it still in that list of active service managers? Yes. > When reading section 9, it seems to be the case. > But what is the point in processing online/offline events for services > that > the application can no longer get access to? A NetworkServices object provided to a web page is immutable. Because it cannot be changed and cannot be revoked by the user agent once provided to a script that NetworkServices object will exist until the user navigates away from the current page. If the page is still using this object then we still treat it as an active object in the page and fire all necessary events on that object as usual. > Would it make sense to apply section 4.1 rules on NetworkServices object > removal from the list of active service managers? Unfortunately, we cannot remove active JavaScript objects once they have been shared with the current web page. This can only happen once the user navigates away from that page or reloads that page (and hence the state of the JS in the page is lost and the NetworkServices object can no longer exist until re-supplied by the user agent). > Also, if a user is revoking access authorizations, he may also want to > revoke > the implicit monitoring authorization.]] The NetworkServices object does not have special behaviour applied to it if or when it is superseeded by a second call to getNetworkServices and a second NetworkServices object has been returned. Both of these objects are still NetworkServices objects and therefore act in a consistent way. --- Anyone still reading this far? ;) - Rich > > [0] http://www.w3.org/TR/2012/WD-discovery-api-20121004/ - Latest WD > [1] > http://lists.w3.org/Archives/Public/public-device-apis/2012Sep/0132.html > - from Greg > [2] > http://lists.w3.org/Archives/Public/public-device-apis/2012Sep/0138.html > - Rich's response to [1] > [3] > http://lists.w3.org/Archives/Public/public-device-apis/2012Sep/0141.html > - Greg's follow-up on [2] > [4] > http://lists.w3.org/Archives/Public/public-device-apis/2012Oct/0005.html > - from Cathy > [5] > http://lists.w3.org/Archives/Public/public-device-apis/2012Oct/0012.html > - Rich's response to [4] > [6] > http://lists.w3.org/Archives/Public/public-device-apis/2012Oct/0020.html > - Cathy's follow-up on [5] > [7] > http://lists.w3.org/Archives/Public/public-device-apis/2012Oct/0034.html > - from Youenn > [8] > http://lists.w3.org/Archives/Public/public-device-apis/2012Nov/0092.html > - Cathy's follow-up on previous comments by JCD > [9] > http://lists.w3.org/Archives/Public/public-device-apis/2012Nov/0095.html > - JCD's follow-up on [8] > [10] > http://lists.w3.org/Archives/Public/public-device-apis/2012Nov/0098.html > - Cathy's follow-up on [9] > [11] > http://lists.w3.org/Archives/Public/public-device-apis/2012Nov/0101.html > - from Naoyuki Sato > [12] > http://lists.w3.org/Archives/Public/public-device-apis/2013Jan/0011.html > - JCD's follow-up on [11] > [13] > http://lists.w3.org/Archives/Public/public-device-apis/2013Jan/0014.html > - Naoyuki Sato's follow-up on [12] > [14] > http://lists.w3.org/Archives/Public/public-device-apis/2013Jan/0019.html > - Cathy's follow-up on [13]
Received on Tuesday, 5 February 2013 14:36:27 UTC