| rfc8887xml2.original.xml | rfc8887.xml | |||
|---|---|---|---|---|
| <?xml version="1.0" encoding="utf-8"?> | <?xml version='1.0' encoding='utf-8'?> | |||
| <!DOCTYPE rfc SYSTEM 'rfc2629.dtd' | <!DOCTYPE rfc SYSTEM "rfc2629-xhtml.ent"> | |||
| [ | ||||
| <!ENTITY rfc2119 PUBLIC '' | <rfc xmlns:xi="http://www.w3.org/2001/XInclude" category="std" | |||
| 'http://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.2119.xml'> | ipr="trust200902" docName="draft-ietf-jmap-websocket-07" obsoletes="" | |||
| <!ENTITY rfc2818 PUBLIC '' | updates="" submissionType="IETF" xml:lang="en" tocInclude="true" | |||
| 'http://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.2818.xml'> | symRefs="true" sortRefs="true" tocDepth="3" version="3" number="8887" | |||
| <!ENTITY rfc5246 PUBLIC '' | consensus="true"> | |||
| 'http://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.5246.xml'> | <!-- xml2rfc v2v3 conversion 2.43.0 --> | |||
| <!ENTITY rfc6455 PUBLIC '' | ||||
| 'http://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.6455.xml'> | ||||
| <!ENTITY rfc6570 PUBLIC '' | ||||
| 'http://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.6570.xml'> | ||||
| <!ENTITY rfc7230 PUBLIC '' | ||||
| 'http://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.7230.xml'> | ||||
| <!ENTITY rfc7235 PUBLIC '' | ||||
| 'http://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.7235.xml'> | ||||
| <!ENTITY rfc7525 PUBLIC '' | ||||
| 'http://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.7525.xml'> | ||||
| <!ENTITY rfc7540 PUBLIC '' | ||||
| 'http://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.7540.xml'> | ||||
| <!ENTITY rfc7692 PUBLIC '' | ||||
| 'http://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.7692.xml'> | ||||
| <!ENTITY rfc8174 PUBLIC '' | ||||
| 'http://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.8174.xml'> | ||||
| <!ENTITY rfc8441 PUBLIC '' | ||||
| 'http://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.8441.xml'> | ||||
| <!ENTITY rfc8446 PUBLIC '' | ||||
| 'http://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.8446.xml'> | ||||
| <!ENTITY rfc8620 PUBLIC '' | ||||
| 'http://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.8620.xml'> | ||||
| <!ENTITY rfc8621 PUBLIC '' | ||||
| 'http://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.8621.xml'> | ||||
| ]> | ||||
| <?xml-stylesheet type='text/xsl' href='rfc2629.xslt' ?> | ||||
| <?rfc toc="yes"?> | ||||
| <?rfc comments="yes"?> | ||||
| <?rfc inline="yes"?> | ||||
| <?rfc symrefs="yes"?> | ||||
| <?rfc sortrefs="yes"?> | ||||
| <?rfc compact="yes"?> | ||||
| <?rfc subcompact="no"?> | ||||
| <?rfc tocdepth="3"?> | ||||
| <?rfc strict="yes"?> | ||||
| <rfc category="std" ipr='trust200902' | ||||
| docName='draft-ietf-jmap-websocket-07'> | ||||
| <front> | <front> | |||
| <title abbrev="JMAP Over WebSocket"> | <title abbrev="JMAP over WebSocket"> | |||
| A JSON Meta Application Protocol (JMAP) Subprotocol for WebSocket | A JSON Meta Application Protocol (JMAP) Subprotocol for WebSocket | |||
| </title> | </title> | |||
| <author initials="K." surname="Murchison" | <seriesInfo name="RFC" value="8887"/> | |||
| fullname="Kenneth Murchison"> | <author initials="K." surname="Murchison" fullname="Kenneth Murchison"> | |||
| <organization abbrev="Fastmail">Fastmail US LLC</organization> | <organization abbrev="Fastmail">Fastmail US LLC</organization> | |||
| <address> | <address> | |||
| <postal> | <postal> | |||
| <street>1429 Walnut Street - Suite 1201</street> | <street>1429 Walnut Street, Suite 1201</street> | |||
| <city>Philadelphia</city> <region>PA</region> | <city>Philadelphia</city> | |||
| <code>19102</code> <country>USA</country> | <region>PA</region> | |||
| <code>19102</code> | ||||
| <country>United States of America</country> | ||||
| </postal> | </postal> | |||
| <email>murch@fastmailteam.com</email> | <email>murch@fastmailteam.com</email> | |||
| <uri>http://www.fastmail.com/</uri> | <uri>http://www.fastmail.com/</uri> | |||
| </address> | </address> | |||
| </author> | </author> | |||
| <date month="August" year="2020"/> | ||||
| <date /> | ||||
| <area>ART</area> | <area>ART</area> | |||
| <workgroup>JMAP</workgroup> | <workgroup>JMAP</workgroup> | |||
| <keyword>jmap</keyword> | <keyword>jmap</keyword> | |||
| <keyword>websocket</keyword> | <keyword>websocket</keyword> | |||
| <abstract> | <abstract> | |||
| <t>This document defines a binding for the JSON Meta Application | <t>This document defines a binding for the JSON Meta Application | |||
| Protocol (JMAP) over a WebSocket transport layer. The WebSocket | Protocol (JMAP) over a WebSocket transport layer. The WebSocket | |||
| binding for JMAP provides higher performance than the current | binding for JMAP provides higher performance than the current | |||
| HTTP binding for JMAP. | HTTP binding for JMAP. | |||
| </t> | </t> | |||
| </abstract> | </abstract> | |||
| <!-- | ||||
| <note title="Open Issues"> | ||||
| <t> | ||||
| <list style="symbols"> | ||||
| <t>Still need to craft some text to discuss/address | ||||
| potential security risks of using WebSocket compression.</t> | ||||
| </list> | ||||
| </t> | ||||
| </note> | ||||
| </front> | ||||
| </front> | ||||
| <middle> | <middle> | |||
| <section title='Introduction'> | <section numbered="true" toc="default"> | |||
| <t><xref target='RFC8620'>JMAP</xref> | <name>Introduction</name> | |||
| over <xref target='RFC7235'>HTTP</xref> requires that every | <t><xref target="RFC8620" format="default">JMAP</xref> | |||
| JMAP API request be authenticated. | over <xref target="RFC7235" format="default">HTTP</xref> requires that | |||
| every JMAP API request be authenticated. | ||||
| Depending on the type of authentication used by | Depending on the type of authentication used by | |||
| the JMAP client and the configuration of the JMAP server, | the JMAP client and the configuration of the JMAP server, | |||
| authentication could be an expensive operation both in time and | authentication could be an expensive operation both in time and | |||
| resources. In such circumstances, reauthenticating for every | resources. In such circumstances, reauthenticating for every | |||
| JMAP API request may harm performance.</t> | JMAP API request may harm performance.</t> | |||
| <t>The <xref target="RFC6455" format="default">WebSocket</xref> | ||||
| <t>The <xref target='RFC6455'>WebSocket</xref> | ||||
| binding for JMAP eliminates this performance | binding for JMAP eliminates this performance | |||
| hit by authenticating just the WebSocket handshake request and | hit by authenticating just the WebSocket handshake request and | |||
| having those credentials remain in effect for the duration of | having those credentials remain in effect for the duration of | |||
| the WebSocket connection. This binding supports JMAP API | the WebSocket connection. This binding supports JMAP API | |||
| requests and responses, with optional support for push | requests and responses, with optional support for push | |||
| notifications.</t> | notifications.</t> | |||
| <t>Furthermore, the WebSocket binding for JMAP can optionally | <t>Furthermore, the WebSocket binding for JMAP can optionally | |||
| <xref target='RFC7692'>compress</xref> both JMAP API requests | <xref target="RFC7692" format="default">compress</xref> both JMAP API | |||
| and responses. | requests and responses. | |||
| Although compression of HTTP responses is ubiquitous, | Although compression of HTTP responses is ubiquitous, | |||
| compression of HTTP requests has very low, if any deployment, | compression of HTTP requests has very low, if any, deployment | |||
| and therefore isn't a viable option for JMAP API requests | and therefore isn't a viable option for JMAP API requests | |||
| over HTTP.</t> | over HTTP.</t> | |||
| </section> | ||||
| <!-- Intro --> | ||||
| </section> <!-- Intro --> | <section numbered="true" toc="default"> | |||
| <name>Conventions Used in This Document</name> | ||||
| <section title='Conventions Used in This Document'> | <t> | |||
| <t>The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL | The key words "<bcp14>MUST</bcp14>", "<bcp14>MUST NOT</bcp14>", | |||
| NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", | "<bcp14>REQUIRED</bcp14>", "<bcp14>SHALL</bcp14>", "<bcp14>SHALL | |||
| "MAY", and "OPTIONAL" in this document are to be interpreted as | NOT</bcp14>", "<bcp14>SHOULD</bcp14>", "<bcp14>SHOULD NOT</bcp14>", | |||
| described in BCP 14 | "<bcp14>RECOMMENDED</bcp14>", "<bcp14>NOT RECOMMENDED</bcp14>", | |||
| <xref target='RFC2119' /> <xref target='RFC8174' /> | "<bcp14>MAY</bcp14>", and "<bcp14>OPTIONAL</bcp14>" in this document are | |||
| when, and only when, they appear in all capitals, as shown | to be interpreted as | |||
| here.</t> | described in BCP 14 <xref target="RFC2119"/> <xref target="RFC8174"/> | |||
| when, and only when, they appear in all capitals, as shown here. | ||||
| <t>The same terminology is used in this document as in the core | </t> | |||
| JMAP specification.</t> | <t>This document uses the terminology defined in the core JMAP | |||
| specification <xref target="RFC8620"/>.</t> | ||||
| </section> <!-- Conventions --> | </section> | |||
| <!-- Conventions --> | ||||
| <section anchor='discovery' | <section anchor="discovery" numbered="true" toc="default"> | |||
| title='Discovering Support for JMAP over WebSocket'> | <name>Discovering Support for JMAP over WebSocket</name> | |||
| <t>The JMAP capabilities object is returned as part of the | <t>The JMAP capabilities object is returned as part of the | |||
| standard JMAP Session object (see Section 2 of | standard JMAP Session object (see | |||
| <xref target='RFC8620' />). | <xref target="RFC8620" sectionFormat="of" section="2"/>). | |||
| Servers supporting this specification MUST add a property named | Servers supporting this specification <bcp14>MUST</bcp14> add a property n | |||
| amed | ||||
| "urn:ietf:params:jmap:websocket" to the capabilities object. | "urn:ietf:params:jmap:websocket" to the capabilities object. | |||
| The value of this property is an object which MUST contain the | The value of this property is an object that <bcp14>MUST</bcp14> contain t he | |||
| following information on server capabilities: | following information on server capabilities: | |||
| <list style='symbols'> | </t> | |||
| <t>url: "String" | <ul spacing="normal"> | |||
| <vspace blankLines="1"/> | <li> | |||
| The wss-URI (see Section 3 of <xref target='RFC6455' />) | <t>url: "String"</t> | |||
| to use for initiating a JMAP over WebSocket handshake | <t>The wss-URI (see <xref target="RFC6455" sectionFormat="of" | |||
| (the "WebSocket URL endpoint" colloquially). | section="3"/>) to use for initiating a JMAP-over-WebSocket | |||
| </t> | handshake (the "WebSocket URL endpoint" colloquially).</t> | |||
| </li> | ||||
| <t>supportsPush: "Boolean" | <li> | |||
| <vspace blankLines="1"/> | <t>supportsPush: "Boolean"</t> | |||
| This is true if the server supports push | <t>This is true if the server supports push notifications over the | |||
| notifications over the WebSocket, as described in | WebSocket, as described in <xref target="push" | |||
| <xref target='push' />. | format="default"/>.</t> | |||
| </t> | </li> | |||
| </list> | </ul> | |||
| <t keepWithNext="true"> Example:</t> | ||||
| <figure> | <artwork name="" type="" align="left" alt=""><![CDATA[ | |||
| <preamble> | ||||
| Example: | ||||
| </preamble> | ||||
| <artwork><![CDATA[ | ||||
| "urn:ietf:params:jmap:websocket": { | "urn:ietf:params:jmap:websocket": { | |||
| "url": "wss://server.example.com/jmap/ws/", | "url": "wss://server.example.com/jmap/ws/", | |||
| "supportsPush": true | "supportsPush": true | |||
| } | } | |||
| ]]></artwork> | ]]></artwork> | |||
| </figure></t> | </section> | |||
| </section> <!-- discovery --> | <!-- discovery --> | |||
| <section anchor='jmap' title='JMAP Subprotocol'> | <section anchor="jmap" numbered="true" toc="default"> | |||
| <name>JMAP Subprotocol</name> | ||||
| <t>The term WebSocket subprotocol refers to an application-level | <t>The term WebSocket subprotocol refers to an application-level | |||
| protocol layered on top of a WebSocket connection. This | protocol layered on top of a WebSocket connection. This | |||
| document specifies the WebSocket JMAP subprotocol for carrying | document specifies the WebSocket JMAP subprotocol for carrying | |||
| JMAP API requests, responses, and optional push notifications | JMAP API requests, responses, and optional push notifications | |||
| through a WebSocket connection. | through a WebSocket connection. | |||
| Binary data is handled per Section 6 | Binary data is handled per <xref target="RFC8620" sectionFormat="of" | |||
| of <xref target='RFC8620' /> via a separate HTTP | section="6"/> (via a separate HTTP connection or stream) | |||
| connection or stream.</t> | or per a future extension to JMAP or this specification.</t> | |||
| <section anchor="authentication" numbered="true" toc="default"> | ||||
| <section anchor='authentication' title='Authentication'> | <name>Authentication</name> | |||
| <t>A JMAP WebSocket connection is authenticated by presenting | <t>A JMAP WebSocket connection is authenticated by presenting | |||
| a user's <xref target='RFC7235'>credentials in the | a user's <xref target="RFC7235" format="default">credentials in the | |||
| HTTP request</xref> that initiates the WebSocket handshake. | HTTP request</xref> that initiates the WebSocket handshake. | |||
| See Section 8.2 of <xref target='RFC8620' /> for | See <xref target="RFC8620" sectionFormat="of" section="8.2"/> for | |||
| recommendations regarding the selection of HTTP authentication | recommendations regarding the selection of HTTP authentication | |||
| schemes.</t> | schemes.</t> | |||
| </section> <!-- authentication --> | </section> | |||
| <!-- authentication --> | ||||
| <section anchor='handshake' title='Handshake'> | <section anchor="handshake" numbered="true" toc="default"> | |||
| <name>Handshake</name> | ||||
| <t>The JMAP WebSocket client and JMAP WebSocket server | <t>The JMAP WebSocket client and JMAP WebSocket server | |||
| negotiate the use of the WebSocket JMAP subprotocol during | negotiate the use of the WebSocket JMAP subprotocol during | |||
| the WebSocket handshake, either via a HTTP/1.1 Upgrade request | the WebSocket handshake, either via an HTTP/1.1 Upgrade request | |||
| (see Section 4 of <xref target='RFC6455' />) | (see <xref target="RFC6455" sectionFormat="of" section="4"/>) | |||
| or a HTTP/2 Extended CONNECT request (see Section 5 of | or an HTTP/2 Extended CONNECT request (see | |||
| <xref target='RFC8441' />). | <xref target="RFC8441" sectionFormat="of" section="5"/>). | |||
| The WebSocket JMAP subprotocol is also intended to run | The WebSocket JMAP subprotocol is also intended to run | |||
| over future bindings of HTTP (e.g. HTTP/3) provided that there | over future bindings of HTTP (e.g., HTTP/3) provided that there | |||
| is a defined mechanism for performing a WebSocket handshake | is a defined mechanism for performing a WebSocket handshake | |||
| over that binding.</t> | over that binding.</t> | |||
| <t>Regardless of the method used for the WebSocket handshake, | <t>Regardless of the method used for the WebSocket handshake, | |||
| the client MUST first perform a TLS handshake on a | the client <bcp14>MUST</bcp14> first perform a TLS handshake on a | |||
| JMAP <xref target='discovery'>WebSocket URL endpoint</xref> | JMAP <xref target="discovery" format="default">WebSocket URL endpoint</x | |||
| ref> | ||||
| having the "wss://" scheme (WebSocket over TLS) in | having the "wss://" scheme (WebSocket over TLS) in | |||
| accordance with the requirements of running the particular | accordance with the requirements of running the particular | |||
| binding of HTTP over TLS (see <xref target='RFC2818' /> | binding of HTTP over TLS (see <xref target="RFC2818" format="default"/> | |||
| and Section 4.1 of <xref target='RFC6455' /> for HTTP/1.1 | and <xref target="RFC6455" sectionFormat="of" section="4.1"/> for HTTP/1 | |||
| and Section 9.2 of <xref target='RFC7540' /> for HTTP/2). | .1 | |||
| and <xref target="RFC7540" sectionFormat="of" section="9.2"/> for HTTP/2 | ||||
| If the TLS handshake fails, the client MUST close the | ). | |||
| connection. | If the TLS handshake fails, the client <bcp14>MUST</bcp14> close the | |||
| connection. Otherwise, the client <bcp14>MUST</bcp14> make an | ||||
| Otherwise, the client MUST make an | <xref target="RFC7235" format="default">authenticated HTTP request</xref | |||
| <xref target='RFC7235'>authenticated</xref> HTTP request | > | |||
| on the encrypted connection, and MUST include the value "jmap" | on the encrypted connection and <bcp14>MUST</bcp14> include the value "j | |||
| map" | ||||
| in the list of protocols for the "Sec-WebSocket-Protocol" | in the list of protocols for the "Sec-WebSocket-Protocol" | |||
| header field.</t> | header field.</t> | |||
| <t>The reply from the server <bcp14>MUST</bcp14> also contain a | ||||
| <t>The reply from the server MUST also contain a | ||||
| corresponding "Sec-WebSocket-Protocol" header field with a | corresponding "Sec-WebSocket-Protocol" header field with a | |||
| value of "jmap" in order | value of "jmap" in order | |||
| for a JMAP subprotocol connection to be established.</t> | for a JMAP subprotocol connection to be established.</t> | |||
| <t>Once the handshake has successfully completed, the | <t>Once the handshake has successfully completed, the | |||
| WebSocket connection is established and can be used for JMAP | WebSocket connection is established and can be used for JMAP | |||
| API requests, responses, and optional push notifications. | API requests, responses, and optional push notifications. | |||
| Other message types MUST NOT be transmitted over this | Other message types <bcp14>MUST NOT</bcp14> be transmitted over this | |||
| connection.</t> | connection.</t> | |||
| <t>The credentials used for authenticating the HTTP request | <t>The credentials used for authenticating the HTTP request | |||
| to initiate the handshake remain in effect for the duration | to initiate the handshake remain in effect for the duration | |||
| of the WebSocket connection. If the authentication | of the WebSocket connection. If the authentication | |||
| credentials for the user expire, the server can either treat | credentials for the user expire, the server can either treat | |||
| subsequent requests as if they are unauthenticated or close | subsequent requests as if they are unauthenticated or close | |||
| the WebSocket connection. | the WebSocket connection. | |||
| In the latter case, the server MAY send a Close frame with a | In the latter case, the server <bcp14>MAY</bcp14> send a Close frame wit | |||
| status code of 1008 (Policy Violation) as defined in Section | h a | |||
| 7.4.1 of <xref target='RFC6455' />.</t> | status code of 1008 (Policy Violation), as defined in | |||
| <xref target="RFC6455" sectionFormat="of" section="7.4.1"/>.</t> | ||||
| </section> <!-- handshake --> | </section> | |||
| <!-- handshake --> | ||||
| <section anchor='messages' title='WebSocket Messages'> | <section anchor="messages" numbered="true" toc="default"> | |||
| <t>Data frame messages in the JMAP subprotocol MUST be | <name>WebSocket Messages</name> | |||
| text frames and contain UTF-8 encoded data. The messages MUST | <t>Data frame messages in the JMAP subprotocol <bcp14>MUST</bcp14> be | |||
| be in the form of a single JMAP Request object (see Section | text frames and contain UTF-8 encoded data. The messages <bcp14>MUST</b | |||
| 3.3 of <xref target='RFC8620' />), | cp14> | |||
| JMAP WebSocketPushEnable object (see <xref target='pushenable' />), | be in the form of a single JMAP Request object (see | |||
| or JMAP WebSocketPushDisable object (see <xref target='pushdisable' />) | <xref target="RFC8620" sectionFormat="of" section="3.3"/>), | |||
| JMAP WebSocketPushEnable object (see <xref target="pushenable" format="d | ||||
| efault"/>), | ||||
| or JMAP WebSocketPushDisable object (see <xref target="pushdisable" form | ||||
| at="default"/>) | ||||
| when sent from | when sent from | |||
| the client to the server, and in the form of a single JMAP | the client to the server, and MUST be in the form of a single JMAP | |||
| Response object, JSON Problem Details object, or JMAP StateChange | Response object, JSON Problem Details object, or JMAP StateChange | |||
| object (see Sections 3.4, 3.6.1, and 7.1 respectively of | object (see Sections <xref target="RFC8620" section="3.4" | |||
| <xref target='RFC8620' />) when sent from the | sectionFormat="bare"/>, <xref target="RFC8620" section="3.6.1" | |||
| server to the client.</t> | sectionFormat="bare"/>, and <xref target="RFC8620" section="7.1" | |||
| sectionFormat="bare"/> of <xref target="RFC8620" format="default"/>, | ||||
| respectively) when sent from the server to the client.</t> | ||||
| <t>Note that fragmented WebSocket messages (split over | <t>Note that fragmented WebSocket messages (split over | |||
| multiple text frames) MUST be coalesced prior to parsing them | multiple text frames) <bcp14>MUST</bcp14> be coalesced prior to parsing them | |||
| as JSON objects.</t> | as JSON objects.</t> | |||
| <section anchor="invalid" numbered="true" toc="default"> | ||||
| <section anchor='invalid' title='Handling Invalid Data'> | <name>Handling Invalid Data</name> | |||
| <t>If a client or server receives a binary frame, the endpoint | <t>If a client or server receives a binary frame, the endpoint | |||
| can either ignore the frame or close the WebSocket connection. | can either ignore the frame or close the WebSocket connection. | |||
| In the latter case, the endpoint MAY send a Close frame with a | In the latter case, the endpoint <bcp14>MAY</bcp14> send a Close frame | |||
| status code of 1003 (Unsupported Data) as defined in Section | with a | |||
| 7.4.1 of <xref target='RFC6455' />.</t> | status code of 1003 (Unsupported Data), as defined in | |||
| <xref target="RFC6455" sectionFormat="of" section="7.4.1"/>.</t> | ||||
| <t>If a client receives a message that is not in the form of | <t>If a client receives a message that is not in the form of | |||
| either a JSON Problem Details object, a JMAP Response | a JSON Problem Details object, a JMAP Response | |||
| object, or a JMAP StateChange object, the client can either | object, or a JMAP StateChange object, the client can either | |||
| ignore the message or close the WebSocket connection. | ignore the message or close the WebSocket connection. | |||
| In the latter case, the endpoint MAY send a Close frame with a | In the latter case, the endpoint <bcp14>MAY</bcp14> send a Close frame | |||
| status code of 1007 (Invalid frame payload data Data) as | with a | |||
| defined in Section 7.4.1 of <xref target='RFC6455' />. | status code of 1007 (Invalid frame payload data), as | |||
| </t> | defined in <xref target="RFC6455" sectionFormat="of" | |||
| section="7.4.1"/>.</t> | ||||
| <t>A server MUST return an appropriate | <t>A server <bcp14>MUST</bcp14> return an appropriate | |||
| <xref target='errors'>JSON Problem Details object</xref> | <xref target="errors" format="default">JSON Problem Details object</xr | |||
| ef> | ||||
| for any request-level errors | for any request-level errors | |||
| (E.g. an invalid JMAP object, an unsupported capability or | (e.g., an invalid JMAP object, an unsupported capability or | |||
| method call, or exceeding a server request limit).</t> | method call, or exceeding a server request limit).</t> | |||
| </section> | ||||
| <!-- invalid --> | ||||
| </section> <!-- invalid --> | <section anchor="requests" numbered="true" toc="default"> | |||
| <name>JMAP Requests</name> | ||||
| <section anchor='requests' title='JMAP Requests'> | ||||
| <t>The specification extends the Request object with two | <t>The specification extends the Request object with two | |||
| additional arguments when used over a WebSocket: | additional arguments when used over a WebSocket: | |||
| </t> | ||||
| <list style='symbols'> | <ul spacing="normal"> | |||
| <t>@type: "String" | <li> | |||
| <vspace blankLines="1"/> | <t>@type: "String"</t> | |||
| This MUST be the string "Request".</t> | <t>This <bcp14>MUST</bcp14> be the string "Request".</t> | |||
| </li> | ||||
| <t>id: "String" (optional) | <li> | |||
| <vspace blankLines="1"/> | <t>id: "String" (optional)</t> | |||
| A client-specified identifier for the request | <t>A client-specified identifier for the request to be echoed | |||
| to be echoed back in the response to this request.</t> | back in the response to this request.</t> | |||
| </list></t> | </li> | |||
| </ul> | ||||
| <t>JMAP over WebSocket allows the server to process requests | <t>JMAP over WebSocket allows the server to process requests | |||
| out of order. The client-specified identifier is used as a | out of order. The client-specified identifier is used as a | |||
| mechanism for the client to correlate requests and | mechanism for the client to correlate requests and | |||
| responses.</t> | responses.</t> | |||
| <t>Additionally, the "maxConcurrentRequests" limit in the | <t>Additionally, the "maxConcurrentRequests" limit in the | |||
| "capabilities" object (see Section 2 of | "capabilities" object (see <xref target="RFC8620" sectionFormat="of" | |||
| <xref target='RFC8620' />) also applies to requests made on | section="2"/>) also applies to requests made on | |||
| the WebSocket connection. When using the WebSocket JMAP | the WebSocket connection. When using the WebSocket JMAP | |||
| subprotocol over a binding of HTTP that allows multiplexing | subprotocol over a binding of HTTP that allows multiplexing | |||
| of requests (e.g. HTTP/2), this limit applies to the the sum | of requests (e.g., HTTP/2), this limit applies to the sum | |||
| of requests made on both the JMAP API endpoint and the | of requests made on both the JMAP API endpoint and the | |||
| WebSocket connection.</t> | WebSocket connection.</t> | |||
| </section> <!-- requests --> | </section> | |||
| <!-- requests --> | ||||
| <section anchor='responses' title='JMAP Responses'> | <section anchor="responses" numbered="true" toc="default"> | |||
| <name>JMAP Responses</name> | ||||
| <t>The specification extends the Response object with two | <t>The specification extends the Response object with two | |||
| additional arguments when used over a WebSocket: | additional arguments when used over a WebSocket: | |||
| <list style='symbols'> | </t> | |||
| <t>@type: "String" | <ul spacing="normal"> | |||
| <vspace blankLines="1"/> | <li> | |||
| This MUST be the string "Response".</t> | <t>@type: "String"</t> | |||
| <t>This <bcp14>MUST</bcp14> be the string "Response".</t> | ||||
| <t>requestId: "String" (optional; MUST be returned if an | </li> | |||
| id is included in the request) | <li> | |||
| <vspace blankLines="1"/> | <t>requestId: "String" (optional; <bcp14>MUST</bcp14> be | |||
| The client-specified identifier in the corresponding request.</t> | returned if an identifier is included in the request)</t> | |||
| </list></t> | <t>The client-specified identifier in the corresponding | |||
| </section> <!-- responses --> | request.</t> | |||
| </li> | ||||
| </ul> | ||||
| </section> | ||||
| <!-- responses --> | ||||
| <section anchor='errors' title='JMAP Request-Level Errors'> | <section anchor="errors" numbered="true" toc="default"> | |||
| <name>JMAP Request-Level Errors</name> | ||||
| <t>The specification extends the Problem Details object | <t>The specification extends the Problem Details object | |||
| for request-level errors | for request-level errors (see <xref target="RFC8620" | |||
| (see Section 3.6.1 of <xref target='RFC8620' />) | sectionFormat="of" section="3.6.1"/>) with two additional arguments | |||
| with two additional arguments when used over a WebSocket: | when used over a WebSocket:</t> | |||
| <ul spacing="normal"> | ||||
| <list style='symbols'> | <li> | |||
| <t>@type: "String" | <t>@type: "String"</t> | |||
| <vspace blankLines="1"/> | <t>This <bcp14>MUST</bcp14> be the string "RequestError".</t> | |||
| This MUST be the string "RequestError".</t> | </li> | |||
| <li> | ||||
| <t>requestId: "String" (optional; MUST be returned if given | <t>requestId: "String" (optional; <bcp14>MUST</bcp14> be | |||
| in the request) | returned if given in the request)</t> | |||
| <vspace blankLines="1"/> | <t>The client-specified identifier in the corresponding | |||
| The client-specified identifier in the corresponding request.</t> | request.</t> | |||
| </list></t> | </li> | |||
| </section> <!-- errors --> | </ul> | |||
| </section> | ||||
| <!-- errors --> | ||||
| <section anchor='push' title='JMAP Push Notifications'> | <section anchor="push" numbered="true" toc="default"> | |||
| <t>JMAP over WebSocket servers that support push | <name>JMAP Push Notifications</name> | |||
| <t>JMAP-over-WebSocket servers that support push | ||||
| notifications on the WebSocket will advertise a | notifications on the WebSocket will advertise a | |||
| "supportsPush" property with a value of true in | "supportsPush" property with a value of true in | |||
| the "urn:ietf:params:jmap:websocket" server capabilities | the "urn:ietf:params:jmap:websocket" server capabilities | |||
| object.</t> | object.</t> | |||
| <section anchor="pushformat" numbered="true" toc="default"> | ||||
| <section anchor='pushformat' title='Notification Format'> | <name>Notification Format</name> | |||
| <t>All push notifications take the form of a standard | <t>All push notifications take the form of a standard | |||
| StateChange object (see Section 7.1 of | StateChange object (see <xref target="RFC8620" sectionFormat="of" | |||
| <xref target='RFC8620' />).</t> | section="7.1"/>).</t> | |||
| <t>The specification extends the StateChange object with one | <t>The specification extends the StateChange object with one | |||
| additional argument when used over a WebSocket: | additional argument when used over a WebSocket: | |||
| </t> | ||||
| <ul spacing="normal"> | ||||
| <li> | ||||
| <t>pushState: "String" (optional)</t> | ||||
| <t>A (preferably short) string that encodes the entire server | ||||
| state visible to the user (not just the objects returned in | ||||
| this call).</t> | ||||
| <t>The purpose of the "pushState" token is to allow a client | ||||
| to immediately get any changes that occurred while it was | ||||
| disconnected (see <xref target="pushenable" | ||||
| format="default"/>). If the server does not support | ||||
| "pushState" tokens, the client will have to issue a series of | ||||
| "/changes" requests (see <xref target="RFC8620" | ||||
| sectionFormat="of" section="5.2"/>) upon reconnection to | ||||
| update its state to match that of the server.</t> | ||||
| </li> | ||||
| </ul> | ||||
| </section> | ||||
| <!-- format --> | ||||
| <list style='symbols'> | <section anchor="pushenable" numbered="true" toc="default"> | |||
| <t>pushState: "String" (optional) | <name>Enabling Notifications</name> | |||
| <vspace blankLines="1"/> | ||||
| A (preferably short) string that encodes the entire | ||||
| server state visible to the user (not | ||||
| just the objects returned in this call). | ||||
| <vspace blankLines="1"/> | ||||
| The purpose of the "pushState" token is to allow a | ||||
| client to immediately get any changes that occurred | ||||
| while is was disconnected (see <xref target='pushenable'/>). | ||||
| If the server does not support "pushState" tokens, the | ||||
| client will have issue a series of "/changes" requests | ||||
| (see Section 5.2 of <xref target='RFC8620' />) | ||||
| upon reconnection to update its state to match that of | ||||
| the server.</t> | ||||
| </list></t> | ||||
| </section> <!-- format --> | ||||
| <section anchor='pushenable' title='Enabling Notifications'> | ||||
| <t>A client enables push notifications from the server for | <t>A client enables push notifications from the server for | |||
| the current connection by | the current connection by | |||
| sending a WebSocketPushEnable object to the server. A | sending a WebSocketPushEnable object to the server. A | |||
| WebSocketPushEnable object has the following properties: | WebSocketPushEnable object has the following properties: | |||
| <list style='symbols'> | </t> | |||
| <t>@type: "String" | <ul spacing="normal"> | |||
| <vspace blankLines="1"/> | <li> | |||
| This MUST be the string "WebSocketPushEnable".</t> | <t>@type: "String"</t> | |||
| <t>This <bcp14>MUST</bcp14> be the string | ||||
| <t>dataTypes: "String[]|null" | "WebSocketPushEnable".</t> | |||
| <vspace blankLines="1"/> | </li> | |||
| A list of data type names (e.g. "Mailbox", | <li> | |||
| "Email") that the client is interested in. | <t>dataTypes: "String[]|null"</t> | |||
| A StateChange notification will only be sent if the data | <t>A list of data type names (e.g., "Mailbox" or "Email") that | |||
| for one of these types changes. Other types are omitted | the client is interested in. A StateChange notification will | |||
| from the TypeState object. If null, changes will be | only be sent if the data for one of these types changes. | |||
| pushed for all supported data types.</t> | Other types are omitted from the TypeState object. If null, | |||
| changes will be pushed for all supported data types.</t> | ||||
| <t>pushState: "String" (optional) | </li> | |||
| <vspace blankLines="1"/> | <li> | |||
| The last "pushState" token | <t>pushState: "String" (optional)</t> | |||
| that the client received from the server. | <t>The last "pushState" token that the client received from | |||
| Upon receipt of a "pushState" token, the server | the server. Upon receipt of a "pushState" token, the server | |||
| SHOULD immediately send all changes since that state | <bcp14>SHOULD</bcp14> immediately send all changes since that | |||
| token.</t> | state token.</t> | |||
| </list></t> | </li> | |||
| </section> <!-- enabling --> | </ul> | |||
| </section> | ||||
| <!-- enabling --> | ||||
| <section anchor='pushdisable' title='Disabling Notifications'> | <section anchor="pushdisable" numbered="true" toc="default"> | |||
| <name>Disabling Notifications</name> | ||||
| <t>A client disables push notifications from the server | <t>A client disables push notifications from the server | |||
| for the current connection by | for the current connection by | |||
| sending a WebSocketPushDisable object to the server. A | sending a WebSocketPushDisable object to the server. A | |||
| WebSocketPushDisable object has the following property: | WebSocketPushDisable object has the following property: | |||
| <list style='symbols'> | </t> | |||
| <t>@type: "String" | <ul spacing="normal"> | |||
| <vspace blankLines="1"/> | <li> | |||
| This MUST be the string "WebSocketPushDisable".</t> | <t>@type: "String"</t> | |||
| </list></t> | <t>This <bcp14>MUST</bcp14> be the string "WebSocketPushDisable" | |||
| </section> <!-- disabling --> | .</t> | |||
| </li> | ||||
| </ul> | ||||
| </section> | ||||
| <!-- disabling --> | ||||
| </section> <!-- push --> | </section> | |||
| <!-- push --> | ||||
| </section> <!-- messages --> | </section> | |||
| <!-- messages --> | ||||
| <section title='Examples'> | <section numbered="true" toc="default"> | |||
| <name>Examples</name> | ||||
| <t>The following examples show WebSocket JMAP opening | <t>The following examples show WebSocket JMAP opening | |||
| handshakes, a JMAP Core/echo request and response, and a | handshakes, a JMAP Core/echo request and response, and a | |||
| subsequent closing handshake. | subsequent closing handshake. | |||
| The examples assume that the JMAP WebSocket URL endpoint has been | The examples assume that the JMAP WebSocket URL endpoint has been | |||
| advertised in the JMAP Session object as having a path of | advertised in the JMAP Session object as having a path of | |||
| "/jmap/ws/" and that TLS negotiation has already succeeded. | "/jmap/ws/" and that TLS negotiation has already succeeded. | |||
| Note that folding of header fields is for editorial purposes | Note that folding of header fields is for editorial purposes | |||
| only.</t> | only.</t> | |||
| <t keepWithNext="true"> | ||||
| <figure> | ||||
| <preamble> | ||||
| WebSocket JMAP connection via HTTP/1.1 with push | WebSocket JMAP connection via HTTP/1.1 with push | |||
| notifications for mail | notifications for mail <xref target="RFC8621" format="default"/> | |||
| <xref target='RFC8621' /> enabled. | is enabled. This example assumes that the client has cached | |||
| This example assumes that the client has cached pushState | pushState "aaa" from a previous connection. | |||
| "aaa" from a previous connection. | </t> | |||
| </preamble> | <artwork name="" type="" align="left" alt=""><![CDATA[ | |||
| <artwork><![CDATA[ | ||||
| [[ From Client ]] [[ From Server ]] | [[ From Client ]] [[ From Server ]] | |||
| GET /jmap/ws/ HTTP/1.1 | GET /jmap/ws/ HTTP/1.1 | |||
| Host: server.example.com | Host: server.example.com | |||
| Upgrade: websocket | Upgrade: websocket | |||
| Connection: Upgrade | Connection: Upgrade | |||
| Authorization: Basic Zm9vOmJhcg== | Authorization: Basic Zm9vOmJhcg== | |||
| Sec-WebSocket-Key: | Sec-WebSocket-Key: | |||
| dGhlIHNhbXBsZSBub25jZQ== | dGhlIHNhbXBsZSBub25jZQ== | |||
| Sec-WebSocket-Protocol: jmap | Sec-WebSocket-Protocol: jmap | |||
| skipping to change at line 557 ¶ | skipping to change at line 519 ¶ | |||
| } | } | |||
| "pushState": "ccc" | "pushState": "ccc" | |||
| } | } | |||
| WS_CLOSE | WS_CLOSE | |||
| WS_CLOSE | WS_CLOSE | |||
| [WebSocket connection closed] | [WebSocket connection closed] | |||
| ]]></artwork> | ]]></artwork> | |||
| </figure> | <t keepWithNext="true"> | |||
| WebSocket JMAP connection on an HTTP/2 stream that also | ||||
| <figure> | negotiates <xref target="RFC7692" format="default">compression</xref | |||
| <preamble> | >: | |||
| WebSocket JMAP connection on a HTTP/2 stream which also | </t> | |||
| negotiates <xref target='RFC7692'>compression</xref>: | <artwork name="" type="" align="left" alt=""><![CDATA[ | |||
| </preamble> | ||||
| <artwork><![CDATA[ | ||||
| [[ From Client ]] [[ From Server ]] | [[ From Client ]] [[ From Server ]] | |||
| SETTINGS | SETTINGS | |||
| SETTINGS_ENABLE_CONNECT_PROTOCOL = 1 | SETTINGS_ENABLE_CONNECT_PROTOCOL = 1 | |||
| HEADERS + END_HEADERS | HEADERS + END_HEADERS | |||
| :method = CONNECT | :method = CONNECT | |||
| :protocol = websocket | :protocol = websocket | |||
| :scheme = https | :scheme = https | |||
| :path = /jmap/ws/ | :path = /jmap/ws/ | |||
| skipping to change at line 612 ¶ | skipping to change at line 570 ¶ | |||
| DATA + END_STREAM | DATA + END_STREAM | |||
| WS_CLOSE | WS_CLOSE | |||
| DATA + END_STREAM | DATA + END_STREAM | |||
| WS_CLOSE | WS_CLOSE | |||
| [WebSocket connection closed] | [WebSocket connection closed] | |||
| [HTTP/2 stream closed] | [HTTP/2 stream closed] | |||
| ]]></artwork> | ]]></artwork> | |||
| </figure> | </section> | |||
| <!-- examples --> | ||||
| </section> <!-- examples --> | ||||
| </section> <!-- jmap --> | ||||
| <section title='Security Considerations' anchor='security'> | </section> | |||
| <t>The security considerations for both WebSocket (see Section | <!-- jmap --> | |||
| 10 of <xref target='RFC6455' />) and JMAP (see Section 8 of | ||||
| <xref target='RFC8620' />) apply to the WebSocket | ||||
| JMAP subprotocol. | ||||
| Specific security considerations are described in subsections of | ||||
| this section.</t> | ||||
| <section title='Connection Confidentiality and Integrity'> | <section anchor="security" numbered="true" toc="default"> | |||
| <name>Security Considerations</name> | ||||
| <t>The security considerations for both WebSocket (see <xref | ||||
| target="RFC6455" sectionFormat="of" section="10"/>) and JMAP (see <xref | ||||
| target="RFC8620" sectionFormat="of" section="8"/>) apply to the | ||||
| WebSocket JMAP subprotocol. Specific security considerations are | ||||
| described below.</t> | ||||
| <section numbered="true" toc="default"> | ||||
| <name>Connection Confidentiality and Integrity</name> | ||||
| <t>To ensure the confidentiality and integrity of | <t>To ensure the confidentiality and integrity of | |||
| data sent and received via JMAP over WebSocket, the WebSocket | data sent and received via JMAP over WebSocket, the WebSocket | |||
| connection MUST use <xref target='RFC5246'>TLS 1.2</xref> | connection <bcp14>MUST</bcp14> use <xref target="RFC5246" format="defaul | |||
| or later, following the recommendations in <xref | t">TLS 1.2</xref> | |||
| target='RFC7525'>BCP 195</xref>. | or later, following the recommendations in <xref target="RFC7525" format | |||
| Servers SHOULD support <xref target='RFC8446'>TLS 1.3</xref> or | ="default">BCP 195</xref>. | |||
| Servers <bcp14>SHOULD</bcp14> support <xref target="RFC8446" format="def | ||||
| ault">TLS 1.3</xref> or | ||||
| later.</t> | later.</t> | |||
| </section> | </section> | |||
| <section numbered="true" toc="default"> | ||||
| <section title='Non-Browser Clients'> | <name>Non-browser Clients</name> | |||
| <t>JMAP over WebSocket can be used by clients both running | <t>JMAP over WebSocket can be used by clients both running | |||
| inside and outside of a web browser. As such, the security | inside and outside of a web browser. As such, the security | |||
| considerations in Sections 10.2 and 10.1 of | considerations in Sections <xref target="RFC6455" section="10.2" | |||
| <xref target='RFC6455' /> apply to those respective | sectionFormat="bare"/> and <xref target="RFC6455" section="10.1" | |||
| environments.</t> | sectionFormat="bare"/> of <xref target="RFC6455" format="default"/> | |||
| apply to those respective environments.</t> | ||||
| </section> | </section> | |||
| </section> | </section> | |||
| <!-- | <!-- | |||
| <section title='Privacy Considerations' anchor='privacy'> | <section title='Privacy Considerations' anchor='privacy'> | |||
| <t>TODO</t> | <t>TODO</t> | |||
| </section> | </section> | |||
| --> | --> | |||
| <section title='IANA Considerations' anchor='iana'> | <section anchor="iana" numbered="true" toc="default"> | |||
| <name>IANA Considerations</name> | ||||
| <section title='Registration of the WebSocket JMAP Subprotocol'> | <section numbered="true" toc="default"> | |||
| <t>This specification requests IANA to register the WebSocket | <name>Registration of the WebSocket JMAP Subprotocol</name> | |||
| JMAP subprotocol under the "WebSocket Subprotocol Name" | <t>Per this specification, IANA has registered the following in the | |||
| Registry with the following data: | "WebSocket Subprotocol Name Registry" within the "WebSocket Protocol | |||
| Registries". | ||||
| <list style="hanging"> | ||||
| <t hangText="Subprotocol Identifier:">jmap</t> | ||||
| <t hangText="Subprotocol Common Name:"> | ||||
| WebSocket Transport for JMAP (JSON Meta Application Protocol)</t> | ||||
| <t hangText="Subprotocol Definition:">RFCXXXX (this document)</t> | ||||
| </list></t> | ||||
| </t> | ||||
| <dl newline="false" spacing="normal"> | ||||
| <dt>Subprotocol Identifier:</dt> | ||||
| <dd>jmap</dd> | ||||
| <dt>Subprotocol Common Name:</dt> | ||||
| <dd>WebSocket Transport for JMAP (JSON Meta Application | ||||
| Protocol)</dd> | ||||
| <dt>Subprotocol Definition:</dt> | ||||
| <dd>RFC 8887</dd> | ||||
| </dl> | ||||
| </section> | </section> | |||
| </section> <!-- IANA --> | ||||
| <section title='Acknowledgments'> | ||||
| <t>The author would like to thank the following individuals for | ||||
| contributing their ideas and support for writing this | ||||
| specification: Neil Jenkins, Robert Mueller, and Chris Newman.</t> | ||||
| </section> | </section> | |||
| <!-- IANA --> | ||||
| </middle> | </middle> | |||
| <back> | <back> | |||
| <references title='Normative References'> | <references> | |||
| &rfc2119; | <name>References</name> | |||
| &rfc2818; | <references> | |||
| &rfc5246; | <name>Normative References</name> | |||
| &rfc6455; | <xi:include href="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/refer | |||
| &rfc7235; | ence.RFC.2119.xml"/> | |||
| &rfc7525; | <xi:include href="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/refer | |||
| &rfc7540; | ence.RFC.2818.xml"/> | |||
| &rfc7692; | <xi:include href="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/refer | |||
| &rfc8174; | ence.RFC.5246.xml"/> | |||
| &rfc8441; | <xi:include href="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/refer | |||
| &rfc8446; | ence.RFC.6455.xml"/> | |||
| &rfc8620; | <xi:include href="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/refer | |||
| ence.RFC.7235.xml"/> | ||||
| </references> | <xi:include href="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/refer | |||
| ence.RFC.7525.xml"/> | ||||
| <references title='Informative References'> | <xi:include href="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/refer | |||
| &rfc8621; | ence.RFC.7540.xml"/> | |||
| <xi:include href="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/refer | ||||
| ence.RFC.7692.xml"/> | ||||
| <xi:include href="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/refer | ||||
| ence.RFC.8174.xml"/> | ||||
| <xi:include href="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/refer | ||||
| ence.RFC.8441.xml"/> | ||||
| <xi:include href="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/refer | ||||
| ence.RFC.8446.xml"/> | ||||
| <xi:include href="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/refer | ||||
| ence.RFC.8620.xml"/> | ||||
| </references> | ||||
| <references> | ||||
| <name>Informative References</name> | ||||
| <xi:include href="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/refer | ||||
| ence.RFC.8621.xml"/> | ||||
| </references> | ||||
| </references> | </references> | |||
| <section numbered="false" toc="default"> | ||||
| <section title="Change History (To be removed by RFC Editor before | <name>Acknowledgments</name> | |||
| publication)"> | <t>The author would like to thank the following individuals for | |||
| <t>Changes since ietf-06: | contributing their ideas and support for writing this | |||
| <list style='symbols'> | specification: <contact fullname="Neil Jenkins"/>, <contact | |||
| <t>Removed open issue on security of WebSocket compression, | fullname="Robert Mueller"/>, and <contact fullname="Chris Newman"/>.</t> | |||
| per Alexey Melnikov.</t> | </section> | |||
| </list> | ||||
| </t> | ||||
| <t>Changes since ietf-05: | ||||
| <list style='symbols'> | ||||
| <t>Renamed "webSocketUrl" to "url" and "supportsWebSocketPush" | ||||
| to "supportsPush", per Benjamin Schwartz.</t> | ||||
| <t>Added a security subsection with a nod to Sections 10.1 and | ||||
| 10.2 of RFC6455, per Leif Johansson.</t> | ||||
| <t>Clarified "unsupported JMAP" vs "unsupported JSON", per | ||||
| Benjamin Kaduk.</t> | ||||
| <t>Refer to RFC 7525 as BCP 195, per Benjamin Kaduk.</t> | ||||
| <t>Several editorial improvements from Benjamin Kaduk.</t> | ||||
| <t>Several editorial improvements from Murray Kucherawy.</t> | ||||
| </list> | ||||
| </t> | ||||
| <t>Changes since ietf-04: | ||||
| <list style='symbols'> | ||||
| <t>Require the use of TLS for JMAP over WebSocket | ||||
| (per Alissa Cooper and others).</t> | ||||
| <t>Added a section explaining how to handle unsupported messages | ||||
| (per Bob Briscoe).</t> | ||||
| <t>Added a section specifically addressing authentication of | ||||
| the WebSocket (per Leif Johansson).</t> | ||||
| <t>Corrected references into specific sections of RFC 8620 | ||||
| (per Martin Vigoureax).</t> | ||||
| <t>Made RFC 7692 a normative reference (per Barry Leiba).</t> | ||||
| <t>Clarified that the "maxConcurrentRequests" limit applies to | ||||
| the sum of all requests on the current connection (per | ||||
| Benjamin Kaduk).</t> | ||||
| <t>Clarified that the "pushState" token represents the entire | ||||
| server state visible to the user (per Banjamin Kaduk).</t> | ||||
| <t>Clarified that "WebSocketPushEnable/Disable" only | ||||
| effect the current connection (per Benjamin Kaduk).</t> | ||||
| <t>Several editorial improvements from Benjamin Kaduk.</t> | ||||
| </list> | ||||
| </t> | ||||
| <t>Changes since ietf-03: | ||||
| <list style='symbols'> | ||||
| <t>Updated JMAP Mail reference to RFC 8621.</t> | ||||
| <t>Specified that requestId MUST be present in a response if | ||||
| given in the request.</t> | ||||
| </list> | ||||
| </t> | ||||
| <t>Changes since ietf-02: | ||||
| <list style='symbols'> | ||||
| <t>Updated JMAP Core reference to RFC 8620.</t> | ||||
| <t>Added 'WebSocketPushDisable' object.</t> | ||||
| <t>Editorial and formatting changes.</t> | ||||
| </list> | ||||
| </t> | ||||
| <t>Changes since ietf-01: | ||||
| <list style='symbols'> | ||||
| <t>Changed 'wsURL' to 'webSocketUrl' and removed push query option.</t> | ||||
| <t>Added 'supportsWebSocketPush' capability.</t> | ||||
| <t>Added '@type' argument to Request object.</t> | ||||
| <t>Added 'WebSocketPushEnable' object.</t> | ||||
| <t>Added 'pushState' argument to StateChange object.</t> | ||||
| <t>Updated example.</t> | ||||
| <t>Minor Editorial changes.</t> | ||||
| </list> | ||||
| </t> | ||||
| <t>Changes since ietf-00: | ||||
| <list style='symbols'> | ||||
| <t>Added text describing advertisement of and selection of optional | ||||
| push notifications.</t> | ||||
| <t>Minor Editorial changes.</t> | ||||
| </list> | ||||
| </t> | ||||
| <t>Changes since murchison-02: | ||||
| <list style='symbols'> | ||||
| <t>Renamed as a JMAP WG document.</t> | ||||
| <t>Allow out of order processing.</t> | ||||
| <t>Allow push notifications.</t> | ||||
| <t>Modified examples.</t> | ||||
| <t>Add Security Considerations text.</t> | ||||
| <t>Minor Editorial changes.</t> | ||||
| </list> | ||||
| </t> | ||||
| <t>Changes since murchison-01: | ||||
| <list style='symbols'> | ||||
| <t>Updated WebSocket over HTTP/2 reference to RFC8144.</t> | ||||
| </list> | ||||
| </t> | ||||
| <t>Changes since murchison-00: | ||||
| <list style='symbols'> | ||||
| <t>Fleshed out section on discovery of support for JMAP over | ||||
| WebSocket.</t> | ||||
| <t>Allow JSON Problem Details objects to be returned by the | ||||
| server for toplevel errors.</t> | ||||
| <t>Mentioned the ability to compress JMAP API requests.</t> | ||||
| <t>Minor Editorial changes.</t> | ||||
| </list> | ||||
| </t> | ||||
| </section> | ||||
| </back> | </back> | |||
| </rfc> | </rfc> | |||
| End of changes. 86 change blocks. | ||||
| 488 lines changed or deleted | 372 lines changed or added | |||
This html diff was produced by rfcdiff 1.48. The latest version is available from http://tools.ietf.org/tools/rfcdiff/ | ||||