diff --git a/index.bs b/index.bs index 91f93bab..e6245d95 100644 --- a/index.bs +++ b/index.bs @@ -33,7 +33,7 @@ spec: RFC6455; urlPrefix: https://datatracker.ietf.org/doc/html/rfc6455 text: Reading the Client's Opening Handshake; url: section-4.2.1 text: %x1 denotes a text frame; url: section-5.2 text: Send a WebSocket Message; url: section-6.1 - text: A WebSocket Message Has Been Received; url: section-6.2 + text: a WebSocket Message Has Been Received; url: section-6.2 text: Start The WebSocket Closing Handshake; url: section-7.1.2 text: The WebSocket Closing Handshake is Started; url: section-7.1.3 text: The WebSocket Connection is Closed; url: section-7.1.4 @@ -871,56 +871,69 @@ To obtain a set of event names given a |name|: # Transport # {#transport} -Message transport is provided using the WebSocket protocol. -[[!RFC6455]] - -Note: In the terms of the WebSocket protocol, the [=local end=] is the -client and the [=remote end=] is the server / remote host. - Note: The encoding of [=commands=] and [=events=] as messages is similar to JSON-RPC, but this specification does not normatively reference it. [[JSON-RPC]] The normative requirements on [=remote ends=] are instead given as a precise processing model, while no normative requirements are given for [=local ends=]. -A WebSocket listener is a network endpoint that is able -to accept incoming [[!RFC6455|WebSocket]] connections. +A message transport is an abstract interface for passing +messages between the [=local end=] and the [=remote end=]. -A [=WebSocket listener=] has a host, a port, a secure flag, and a -list of WebSocket resources. +Connection steps for a [=message transport=] are the steps taken when the [=local end=] establishes a new [=connection=]. -When a [=WebSocket listener=] |listener| is created, a [=remote end=] -must start to listen for WebSocket connections on the host and port -given by |listener|'s [=listener/host=] and [=listener/port=]. If -|listener|'s [=listener/secure flag=] is set, then connections -established from |listener| must be TLS encrypted. +A connection listener is a mechanism that is able to accept incoming [=connections=]. + +A connection is an abstract WebDriver BiDi connection between the [=local end=] and the [=remote end=]. + +A [=connection=] has the send a connection message steps for sending a message over the connection. -A [=remote end=] has a [=/set=] of [=WebSocket listeners=] active -listeners, which is initially empty. +A [=connection=] has the close the connection steps for closing the connection. -A [=remote end=] has a [=/set=] of WebSocket connections not associated with a -session, which is initially empty. +A [=remote end=] has a [=/set=] of [=connection listeners=] active listeners, +which is initially empty. -A WebSocket connection is a network connection that follows the -requirements of the [[!RFC6455|WebSocket protocol]] +A [=remote end=] has a [=/set=] of connections not associated with a session, +which is initially empty. -A [=BiDi session=] has a [=/set=] of session WebSocket -connections whose elements are [=WebSocket connections=]. This is -initially empty. +A [=BiDi session=] has a [=/set=] of session connections +whose elements are [=connections=]. This is initially empty. A [=BiDi session=] |session| is associated with connection -|connection| if |session|'s [=session WebSocket connections=] contains |connection|. +|connection| if |session|'s [=session connections=] contains |connection|. + +Note: Each [=connection=] is associated with at most one [=BiDi session=]. + +When a message has been received for a [=connection=] |connection| +with type |type| and data |data|, a [=remote end=] +must [=handle an incoming message=] given |connection|, |type| and |data|. + +When the connection is closed for a [=connection=] |connection|, +a [=remote end=] must [=handle a connection closing=] given |connection|. + +## WebSocket Transport ## {#websocket-transport-section} + +The WebSocket transport is a [=message transport=] implementation +using the WebSocket protocol. +[[!RFC6455]]. + +Note: In the terms of the WebSocket protocol, the [=local end=] is the +client and the [=remote end=] is the server / remote host. + +When a [=WebSocket listener=] |listener| is created, a [=remote end=] +must start to listen for WebSocket connections on the host and port +given by |listener|'s [=listener/host=] and [=listener/port=]. If +|listener|'s [=listener/secure flag=] is set, then connections +established from |listener| must be TLS encrypted. -Note: Each [=WebSocket connection=] is associated with at most one [=BiDi -session=]. +The [=connection steps=] for the [=WebSocket transport=] are:
When a client [=establishes a WebSocket connection=] |connection| by connecting to one of the set of [=active listeners=] |listener|, the -implementation must proceed according to the WebSocket [=server-side -requirements=], with the following steps run when deciding whether to +implementation must proceed according to the WebSocket +[=server-side requirements=], with the following steps run when deciding whether to accept the incoming connection: 1. Let |resource name| be the resource name from [=reading the @@ -936,8 +949,7 @@ accept the incoming connection: connection should be accepted, and if it is not stop running these steps and act as if the requested service is not available. - 1. Add the connection to [=WebSocket connections not associated with a - session=]. + 1. Add the connection to [=connections not associated with a session=]. 1. Return. @@ -955,25 +967,45 @@ accept the incoming connection: connection should be accepted, and if it is not stop running these steps and act as if the requested service is not available. -1. Otherwise append |connection| to |session|'s [=session WebSocket - connections=], and proceed with the WebSocket [=server-side requirements=] +1. Otherwise append |connection| to |session|'s [=session connections=], + and proceed with the WebSocket [=server-side requirements=] when a server chooses to accept an incoming connection. Issue: Do we support > 1 connection for a single session?
-When [=a WebSocket message has been received=] for a [=WebSocket -connection=] |connection| with type |type| and data |data|, a [=remote end=] -must [=handle an incoming message=] given |connection|, |type| and |data|. +A WebSocket listener is a network endpoint that is able to accept +incoming [[!RFC6455|WebSocket]] connections. A [=WebSocket listener=] is a +[=connection listener=]. + +A [=WebSocket listener=] has a host, a port, a secure flag, and a +list of WebSocket resources. -When [=the WebSocket closing handshake is started=] or when [=the -WebSocket connection is closed=] for a [=WebSocket connection=] -|connection|, a [=remote end=] must [=handle a connection closing=] -given |connection|. +A WebSocket connection is a network [=connection=] that follows the +requirements of the [[!RFC6455|WebSocket protocol]]. -Note: Both conditions are needed because it is possible for a -WebSocket connection to be closed without a closing handshake. +[=A message has been received=] for a [=WebSocket connection=] when [=a WebSocket Message Has Been Received=]. +[=The connection is closed=] for a [=WebSocket connection=] when [=the WebSocket closing handshake is started=] +or when [=the WebSocket connection is closed=]. + +Note: Both conditions are needed because it is possible for a connection to be +closed without a closing handshake. + +The [=send a connection message=] steps for a [=WebSocket connection=] are [=send a WebSocket Message=]. + +
+ +The [=close the connection=] steps for a [=WebSocket connection=] |connection| are: + + 1. [=Start the WebSocket closing handshake=] with |connection|. + + Note: this will result in the steps in [=handle a connection closing=] + being run for |connection|, which will clean up resources associated with + |connection|. + +
@@ -1031,8 +1063,8 @@ To start listening for a WebSocket connection given a [=implementation-defined=] [=listener/host=], [=listener/port=], [=listener/secure flag=], and an empty [=list of WebSocket resources=]. -1. Let |resource name| be the result of [=construct a WebSocket - resource name=] with |session|. +1. Let |resource name| be the result of [=construct a WebSocket resource name=] + with |session|. 1. Append |resource name| to the [=list of WebSocket resources=] for |listener|. @@ -1045,7 +1077,7 @@ To start listening for a WebSocket connection given a
Note: An [=intermediary node=] handling multiple sessions can use one -or many WebSocket listeners. [[!WEBDRIVER|WebDriver]] defines that +or many listeners. [[!WEBDRIVER|WebDriver]] defines that an [=endpoint node=] supports at most one session at a time, so it's expected to only have a single listener. @@ -1053,7 +1085,7 @@ Note: For an [=endpoint node=] the [=listener/host=] in the above steps will typically be "localhost".
-To handle an incoming message given a [=WebSocket connection=] +To handle an incoming message given a [=connection=] |connection|, type |type| and data |data|: 1. If |type| is not [=%x1 denotes a text frame|text=], [=send an error @@ -1069,9 +1101,8 @@ To handle an incoming message given a [=WebSocket connection=] is used for UTF-8 errors. 1. If there is a [=BiDi Session=] [=associated with connection=] |connection|, - let |session| be that session. Otherwise if |connection| is in [=WebSocket - connections not associated with a session=], let |session| be - null. Otherwise, return. + let |session| be that session. Otherwise if |connection| is in [=connections not associated with a session=], + let |session| be null. Otherwise, return. 1. Let |parsed| be the result of [=parse JSON into Infra values|parsing JSON into Infra values=] given |data|. If this throws an exception, then [=send @@ -1116,9 +1147,8 @@ To handle an incoming message given a [=WebSocket connection=] 1. If |method| is "session.new", let |session| be the entry in the list of [=active sessions=] whose [=session ID=] is equal to the "sessionId" property of |value|, [=set/append=] - |connection| to |session|'s [=session WebSocket connections=], and - remove |connection| from the [=WebSocket connections not associated with - a session=]. + |connection| to |session|'s [=session connections=], and + remove |connection| from the [=connections not associated with a session=]. 1. Let |response| be a new [=/map=] matching the CommandResponse production in the {^local end definition^} with the id @@ -1128,7 +1158,7 @@ To handle an incoming message given a [=WebSocket connection=] 1. Let |serialized| be the result of [=serialize an infra value to JSON bytes=] given |response|. - 1. [=Send a WebSocket message=] comprised of |serialized| over + 1. [=Send a connection message=] comprised of |serialized| over |connection|. 1. Otherwise: @@ -1252,14 +1282,14 @@ To get valid top-level traversables by ids given a [=/list=] of conte 1. Let |serialized| be the result of [=serialize an infra value to JSON bytes=] given |body|. -1. [=list/For each=] |connection| in |session|'s [=session WebSocket connections=]: +1. [=list/For each=] |connection| in |session|'s [=session connections=]: - 1. [=Send a WebSocket message=] comprised of |serialized| over |connection|. + 1. [=Send a connection message=] comprised of |serialized| over |connection|.
-To send an error response given a [=WebSocket connection=] +To send an error response given a [=connection=] |connection|, |command id|, and |error code|: 1. Let |error data| be a new [=/map=] matching the ErrorResponse @@ -1277,25 +1307,23 @@ To send an error response given a [=WebSocket connection=] Note: |command id| can be null, in which case the id field will also be set to null, not omitted from |response|. -1. [=Send a WebSocket message=] comprised of |response| over |connection|. +1. [=Send a connection message=] comprised of |response| over |connection|.
-To handle a connection closing given a [=WebSocket connection=] -|connection|: +To handle a connection closing given a [=connection=] |connection|: 1. If there is a [=BiDi session=] [=associated with connection=] |connection|: 1. Let |session| be the [=BiDi session=] [=associated with connection=] |connection|. - 1. Remove |connection| from |session|'s [=session WebSocket - connections=]. + 1. Remove |connection| from |session|'s [=session connections=]. -1. Otherwise, if [=WebSocket connections not associated with a session=] +1. Otherwise, if [=connections not associated with a session=] [=list/contains=] |connection|, [=list/remove=] |connection| from that set. Note: This does not end any [=/session=]. @@ -1307,16 +1335,11 @@ the listener if it wants.
-To close the WebSocket connections given |session|: - -1. For each |connection| in |session|'s [=session WebSocket - connections=]: +To close the connections given |session|: - 1. [=Start the WebSocket closing handshake=] with |connection|. +1. For each |connection| in |session|'s [=session connections=]: - Note: this will result in the steps in [=handle a connection closing=] - being run for |connection|, which will clean up resources associated with - |connection|. + 1. Run [=close the connection=] steps for the |connection|.
@@ -1338,11 +1361,9 @@ with parameters |session|, |capabilities|, and |flags| is: 1. [=Assert=]: |webSocketUrl| is true. -1. Let |listener| be the result of [=start listening for a WebSocket - connection=] given |session|. +1. Let |listener| be the result of [=start listening for a WebSocket connection=] given |session|. -1. Set |webSocketUrl| to the result of [=construct a WebSocket - URL=] with |listener| and |session|. +1. Set |webSocketUrl| to the result of [=construct a WebSocket URL=] with |listener| and |session|. 1. [=Set a property=] on |capabilities| named "webSocketUrl" to |webSocketUrl|. @@ -1361,7 +1382,8 @@ communicated out-of-band. An implementation that allows this supports BiDi-only sessions. At the time such an implementation is ready to accept requests to start a WebDriver session, it must: -1. [=Start listening for a WebSocket connection=] given null. +1. Let |transport| be a [=WebSocket transport=]. +1. Run [=start listening for a WebSocket connection=] for |transport| given null.
@@ -1643,7 +1665,7 @@ To end the session given |session|: To cleanup the session given |session|: -1. [=Close the WebSocket connections=] with |session|. +1. [=Close the connections=] with |session|. 1. For each |user context| in the [=set of user contexts=]: @@ -2042,7 +2064,7 @@ The [=remote end steps=] given |session| and command parameterscommand parameters return [=error=] with [=error code=] [=unable to close browser=], and then run the following steps [=in parallel=]: - 1. Wait until the [=Send a WebSocket message=] steps have been called with the + 1. Wait until the [=Send a connection message=] steps have been called with the response to this command. 1. [=Cleanup the session=] with |session|. @@ -2683,7 +2705,7 @@ The [=remote end steps=] with |session| and command parameters 1. Return [=success=] with data null, and run the following steps [=in parallel=]. - 1. Wait until the [=Send a WebSocket message=] steps have been called with the + 1. Wait until the [=Send a connection message=] steps have been called with the response to this command. 1. [=Cleanup the session=] with |session|. @@ -2696,7 +2718,7 @@ The [=remote end steps=] with |session| and command parameters Note: For example this might include cleanly shutting down any OS-level processes associated with the browser under automation, removing temporary state, such as user profile data, created by the [=remote end=] while under - automation, or shutting down the [=WebSocket Listener=]. Because of + automation, or shutting down the [=Connection Listener=]. Because of differences between browsers and operating systems it is not possible to specify in detail precise invariants [=local ends=] can depend on here.