└── README.md /README.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | This specification aims to allow web applications to connect with and 4 | communicate to each other over local-area transport protocols. In particular, 5 | this specification aims to bring the web's client/server application model to 6 | inter-device communication. The web's application architecture enables an 7 | application running on a server to dynamically and incrementally send 8 | application state and logic to an intermittently connected client. This model 9 | enables a powerful multi-homed application architecture. 10 | 11 | In contrast to this power, the web architecture is also constrained. A server 12 | must reside on a TCP-based network and must have an IP address. A client can 13 | only identify a server via a URL it is given. Only clients may initiate 14 | connections to servers; servers cannot identify and initiate connections to 15 | clients. A client/server session must be established over a TCP socket and no 16 | other underlying transport protocol may be used. 17 | 18 | This specification aims to lift the above restrictions and allow the web's 19 | application architecture to work between devices which are proximally located. 20 | With FlyWeb, both web clients and servers may advertise themselves for 21 | local-area consumption over local-area transport protocols such as Bluetooth, 22 | Wi-Fi Direct or over a wired/wireless LAN. Clients may discover and connect to 23 | servers and vice-versa, servers may discover and connect to locally available 24 | web clients. 25 | 26 | In addition, FlyWeb aims to introduce a web API to allow web pages to host a 27 | *server endpoint*. This mechanism is designed as a way to enable cross-device 28 | communication using no additional infrastructure aside from web browsers. 29 | 30 | # Conformance 31 | 32 | TODO 33 | 34 | # Dependencies 35 | 36 | FlyWeb uses [`Promise`][Promise reference] objects as defined in the [ES6 37 | specification][Promise specification]. 38 | 39 | FlyWeb's API for hosting a server endpoint from a webpage uses the classes 40 | defined in the [Fetch Standard] and the [WebSocket specification] to represent 41 | both typical HTTP traffic [to][Fetch API request] and [from][Fetch API response] 42 | the page-hosted server as well as [bidirectional, persistent connections][WebSocket interface]. 43 | 44 | # Terminology 45 | 46 | This web API is structured around a process for establishing a web session 47 | between two computational endpoints where one endpoint serves as a web client 48 | and the other as a web server. 49 | 50 | ### Client endpoint 51 | 52 | A *client endpoint* is a device or program on that device which plays the role 53 | of a web client in a FlyWeb session. This endpoint is able to receive and 54 | execute web applications written using web technologies such as HTML, JavaScript 55 | and CSS. The canonical *client endpoint* is a web browser. 56 | 57 | ### Server endpoint 58 | 59 | A *server endpoint* is a device or program on that device which plays the role 60 | of a web server in a FlyWeb session. This endpoint is able to serve web 61 | applications using the HTTP protocol. 62 | 63 | To establish a FlyWeb session, the *client endpoint* performs a local-area 64 | discovery (at the direction of the user) over supported underlying transports 65 | (e.g. mDNS over Wi-Fi). The discovery reveals the presence of any local-area 66 | *server endpoints* which are presented to the user. The user then selects 67 | a *server endpoint* to connect to, at which point the client performs whatever 68 | transport-specific steps are required to set up a web session with the server. 69 | It then navigates to a page on the server which establishes an application 70 | session between the user on the *client endpoint* and the service exposed by 71 | the *server endpoint*. 72 | 73 | # Security and privacy considerations 74 | 75 | The web API defined in this specification can be used to find and connect to 76 | devices and services near the user. This specification uses two mechanisms 77 | to ensure that services are not inadvertently exposed to potentially 78 | malicious code executing on web pages. 79 | 80 | Firstly, a *server endpoint* advertises its services with explicit metadata 81 | that indicates its willingness to serve as a FlyWeb *server endpoint*. Other 82 | non-FlyWeb services which are advertised using similar mechanisms cannot thus 83 | be mistaken for a FlyWeb service. 84 | 85 | Secondly, an endpoint may force a pairing protocol at the point of session 86 | establishment. This protocol may take various forms including entering a 87 | secret code, scanning a QR code displayed on a screen, or a synchronized 88 | button press. These pairing protocols are similar to Bluetooth device pairing 89 | protocols and are already familiar to users. 90 | 91 | # Advertising a server 92 | 93 | FlyWeb allows web pages to expose a *server endpoint* using a web API: 94 | 95 | ```language-webidl 96 | interface FlyWebPublishingAPI { 97 | Promise publishServer(DOMString name, 98 | FlyWebPublishOptions options); 99 | }; 100 | 101 | dictionary FlyWebPublishOptions { 102 | DOMString? uiUrl = null; // URL to user interface. Can be different server. Makes 103 | // endpoint show up in browser's "local services" UI. 104 | // If relative, resolves against the root of the server. 105 | }; 106 | ``` 107 | 108 | *Do we need something to hide server from discovery?* 109 | 110 | *Rather than have a separate `uiUrl` property, we could make discoverable 111 | servers use a specific category and then indicate the url through a property 112 | in `data`. This might depend on mDNS capabilities since we want it to be 113 | efficient to query for all servers with a user UI.* 114 | 115 | # Methods 116 | 117 | ### navigator.publishServer 118 | 119 | ``` 120 | promise = navigator.publishServer(name, {...options...}); 121 | ``` 122 | 123 | Immediately returns a new `Promise` object. The user agent asynchronously 124 | begins the process of establishing a published service under the given 125 | name. The user agent SHOULD prompt the user before advertising a service 126 | from a web page allowing the user to prevent the page from advertising 127 | services to nearby clients. 128 | 129 | If the user declined the publishing or an error occurs, the `Promise` 130 | is rejected. 131 | 132 | If the publishing is successful, the `Promise` is resolved with a 133 | `FlyWebPublishedServer` object: 134 | 135 | ```language-webidl 136 | interface FlyWebPublishedServer : EventTarget { 137 | readonly attribute DOMString name; 138 | readonly attribute DOMString? uiUrl; 139 | 140 | void close(); 141 | 142 | attribute EventHandler onclose; 143 | attribute EventHandler onfetch; 144 | attribute EventHandler onwebsocket; 145 | }; 146 | ``` 147 | 148 | # Attributes 149 | 150 | ### publishedServer.name 151 | 152 | The display name the server is published under. 153 | 154 | ### publishedServer.uiUrl 155 | 156 | The URL to the published server that clients should connect to. 157 | 158 | # Events 159 | 160 | ### onclose 161 | 162 | Called when the published server is closed, for example because the 163 | `close()` method is called on the `FlyWebPublishedServer` object. 164 | 165 | ### onfetch 166 | 167 | Called when a client of the published server sends an HTTP request. 168 | The event type is 'FlyWebFetchEvent': 169 | 170 | ```language-webidl 171 | interface FlyWebFetchEvent : Event { 172 | [SameObject] readonly attribute Request request; 173 | 174 | [Throws] 175 | void respondWith(Promise r); 176 | }; 177 | ``` 178 | 179 | The `request` attribute holds a DOM [`Request`][Fetch API request] object 180 | describing the details of the HTTP request. 181 | 182 | The `respondWith` method on the event can accept a `Promise` for 183 | resolving a [`Response`][Fetch API response] object to service the HTTP request. 184 | 185 | ### onwebsocket 186 | 187 | Called when a client of the published server establishes a new WebSocket 188 | connection request. The event type is 'FlyWebWebSocketEvent': 189 | 190 | ```language-webidl 191 | interface FlyWebWebSocketEvent : Event { 192 | [SameObject] readonly attribute Request request; 193 | 194 | [Throws] 195 | WebSocket accept(optional DOMString protocol); 196 | 197 | [Throws] 198 | void respondWith(Promise r); 199 | }; 200 | ``` 201 | 202 | The `request` attribute holds a DOM [`Request`][Fetch API Request] object describing the 203 | details of the WebSocket request. 204 | 205 | The `accept` method on the event can be used to accept the WebSocket 206 | request. It immediately returns a [`WebSocket`][WebSocket interface] instance which can be used 207 | to communicate with the client. 208 | 209 | The `respondWith` method on the event can accept a `Promise` for 210 | resolving a [`Response`][Fetch API Response] object to service the WebSocket request. 211 | 212 | 213 | [Fetch Standard]: https://fetch.spec.whatwg.org/ 214 | [Fetch API request]: https://fetch.spec.whatwg.org/#request-class 215 | [Fetch API response]: https://fetch.spec.whatwg.org/#response-class 216 | [WebSocket specification]: https://html.spec.whatwg.org/multipage/comms.html#network 217 | [WebSocket interface]: https://html.spec.whatwg.org/multipage/comms.html#the-websocket-interface 218 | [Promise specification]: http://www.ecma-international.org/ecma-262/6.0/#sec-promise-objects 219 | [Promise reference]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise 220 | --------------------------------------------------------------------------------