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/ |