<?xml version="1.0" encoding="UTF-8"?>
  <?xml-stylesheet type="text/xsl" href="rfc2629.xslt" ?>
  <!-- generated by https://github.com/cabo/kramdown-rfc version 1.7.31 (Ruby 3.2.3) -->


<!DOCTYPE rfc  [
  <!ENTITY nbsp    "&#160;">
  <!ENTITY zwsp   "&#8203;">
  <!ENTITY nbhy   "&#8209;">
  <!ENTITY wj     "&#8288;">

]>


<rfc ipr="trust200902" docName="draft-gondwana-jmap-blobext-00" category="std" consensus="true" submissionType="IETF" updates="8620" tocInclude="true" sortRefs="true" symRefs="true">
  <front>
    <title abbrev="JMAP Blob Extended">JMAP Blob Extensions</title>

    <author initials="B." surname="Gondwana" fullname="Bron Gondwana">
      <organization>Fastmail</organization>
      <address>
        <email>brong@fastmailteam.com</email>
      </address>
    </author>

    <date year="2026" month="February" day="21"/>

    
    
    <keyword>Internet-Draft</keyword>

    <abstract>


<?line 29?>

<t>The JMAP base protocol (RFC8620) provides the ability to upload and download
arbitrary binary data.  This binary data is called a "blob", and can be used
in all other JMAP extensions.</t>

<t>The JMAP blob extension (RFC9404) added additional ways to create and access
blobs by making inline method calls within a standard JMAP request.</t>

<t>This extension adds more methods to work with blobs, including handling large
blobs by processing them in chunks (building on RFC9404's blob construction
support), and providing ways to efficiently describe small changes.</t>



    </abstract>



  </front>

  <middle>


<?line 42?>

<section anchor="introduction"><name>Introduction</name>

<t>The JMAP Blob extension (<xref target="JMAP-BLOB"/> — JSON Blob Management) offers additional
ways to create blobs, and query where they are used.</t>

<t>This extension builds on that work, offering ways to find more information about
the internal structure of the server's blob store in order to work efficiently
with it, and ways to efficiently transfer small changes to an existing blob
without copying all the data.</t>

</section>
<section anchor="addition-to-the-capabilities-object"><name>Addition to the Capabilities Object</name>

<t>The capabilities object is returned as part of the JMAP Session
object; see <xref target="JMAP-CORE"/>, Section 2.</t>

<t>This document defines an additional capability URI.</t>

<section anchor="urnietfparamsjmapblobext"><name>urn:ietf:params:jmap:blobext</name>

<t>The capability <spanx style="verb">urn:ietf:params:jmap:blobext</spanx> being present in the
"accountCapabilities" property of an account represents support for
these extended properties on that account.  If this capability is
present in one or more "accountCapabilities" properties then the
server MUST also include the key in the "capabilities" property.</t>

<t>The value of this property in the JMAP session "capabilities"
property MUST be an empty object.</t>

<t>The value of this property in an account's "accountCapabilities"
property is an object that MUST contain the following information
on server capabilities and permissions for that account:</t>

<t><list style="symbols">
  <t>resumableUploadUrl: "String|null"  <vspace blankLines='1'/>
If present, a <xref target="URI-TEMPLATE"/> which supports <xref target="HTTP-RESUMABLE-UPLOADS"/>.
  This MAY be the same as the uploadUrl, and has the same keys.</t>
  <t>chunkSize: "UnsignedInt|null"  <vspace blankLines='1'/>
The size in octets which the server users to split large files
  into chunks.  If a client uploads blobs with exactly this size
  except for the final chunk, and uses Blob/upload with data
  blobs containing these chunks, it is expected that the server
  can optimise these chunks.  Servers MUST allow other sizes
  for the individual data blocks in Blob/upload though, and will
  then choose whether to store them as an array of blobs still,
  or to combine them.</t>
</list></t>

<section anchor="capability-example"><name>Capability Example</name>

<t>TODO</t>

</section>
</section>
<section anchor="additions-to-blobget"><name>Additions to Blob/get</name>

<t>Blob/get returns an additional parameter (returned by default when this capability
is included in <spanx style="verb">using</spanx>)</t>

<t><list style="symbols">
  <t>chunks: Array[DataSourceObject]  <vspace blankLines='1'/>
An array of one or more data source objects.  The file is created by concatenating the
  DataSourceObjects in the listed order.  While it is expected that DataSourceObjects will
  include the entire blob and offset, it is legal for the server to give offset and length
  values which do not cover the entire blob in the same way that Blob/upload can, and
  client MUST use the length and offset to figure out what to append to the resulting file.</t>
  <t>rdiffSignature: blobId  <vspace blankLines='1'/>
Returns a blobId which can be fetched to download the rdiff signature of the blobId being
  fetched.</t>
</list></t>

</section>
<section anchor="additions-to-datasourceobject"><name>Additions to DataSourceObject</name>

<t>All DataSourceObjects (including <spanx style="verb">data:</spanx> objects) can have an offset and length to trim the
final values, though it's just a waste of data when applied to data: objects.  This allows
client and server code to be more consistent for all types.</t>

<t>Every DataSourceObject (on both upload and get) is extended to include any supported
digest which is requested, so a client could request 'digest:sha' and every DataSourceObject
would include the 'digest:sha' as well as the top level, allowing each blob to be separately
validated.</t>

<t>There is a new parameter to each DataSourceObject</t>

<t><list style="symbols">
  <t>rdiffPatch: blobId  <vspace blankLines='1'/>
If provided, apply the patch in the given blobId to the result of this DataSourceObject
  AFTER applying any length and offset.  If a digest value is given, the digest is calculated
  on the resulting octets AFTER applying the patch.  The sequence is:  <vspace blankLines='1'/>
1) decode any base64 or fetch any blob
  2) apply and offset or length to find the raw octets
  3) apply any rdiffPatch to get new raw octets
  4) check any supported digest: value that was provided to ensure the result matches</t>
</list></t>

<t>NOTE: do we want to add any ability to create zip/tar files out of multiple blobs here?</t>

</section>
</section>
<section anchor="security-considerations"><name>Security Considerations</name>

<t>Other than the security considerations present in <xref target="JMAP-CORE"/> and <xref target="JMAP-BLOB"/>, this document
adds the security considerations around ridff handling, including server load and denial of
service risks, and any ability to smuggle content through security scanners by splitting it into
multiple parts is exacerbated by the ability to split things into parts and use rdiff patches.</t>

</section>
<section anchor="iana-considerations"><name>IANA Considerations</name>

<section anchor="jmap-capability-registration-for-urnietfparamsjmapblobext"><name>JMAP Capability Registration for urn:ietf:params:jmap:blobext</name>

<t>IANA is requested to register the "Blob Extended" Capability as follows</t>

<t>Capability: urn:ietf:params:jmap:filenode</t>

<t>Reference: this document</t>

</section>
</section>
<section anchor="todo"><name>TODO</name>

<t><list style="symbols">
  <t>Look into ZIP files, compression, etc.</t>
</list></t>

</section>
<section anchor="changes"><name>Changes</name>

<t>EDITOR: please remove this section before publication.</t>

<t>The source of this document exists on github at: https://github.com/brong/draft-gondwana-jmap-blobext/</t>

<t><strong>draft-gondwana-jmap-blobext-00</strong></t>

<t><list style="symbols">
  <t>initial proposal</t>
</list></t>

</section>
<section anchor="acknowledgements"><name>Acknowledgements</name>

<t>TODO</t>

<t>{backmatter}</t>

</section>


  </middle>

  <back>



    <references title='Normative References' anchor="sec-normative-references">



<reference anchor="URI-TEMPLATE">
  <front>
    <title>URI Template</title>
    <author fullname="J. Gregorio" initials="J." surname="Gregorio"/>
    <author fullname="R. Fielding" initials="R." surname="Fielding"/>
    <author fullname="M. Hadley" initials="M." surname="Hadley"/>
    <author fullname="M. Nottingham" initials="M." surname="Nottingham"/>
    <author fullname="D. Orchard" initials="D." surname="Orchard"/>
    <date month="March" year="2012"/>
    <abstract>
      <t>A URI Template is a compact sequence of characters for describing a range of Uniform Resource Identifiers through variable expansion. This specification defines the URI Template syntax and the process for expanding a URI Template into a URI reference, along with guidelines for the use of URI Templates on the Internet. [STANDARDS-TRACK]</t>
    </abstract>
  </front>
  <seriesInfo name="RFC" value="6570"/>
  <seriesInfo name="DOI" value="10.17487/RFC6570"/>
</reference>

<reference anchor="JMAP-CORE">
  <front>
    <title>The JSON Meta Application Protocol (JMAP)</title>
    <author fullname="N. Jenkins" initials="N." surname="Jenkins"/>
    <author fullname="C. Newman" initials="C." surname="Newman"/>
    <date month="July" year="2019"/>
    <abstract>
      <t>This document specifies a protocol for clients to efficiently query, fetch, and modify JSON-based data objects, with support for push notification of changes and fast resynchronisation and for out-of- band binary data upload/download.</t>
    </abstract>
  </front>
  <seriesInfo name="RFC" value="8620"/>
  <seriesInfo name="DOI" value="10.17487/RFC8620"/>
</reference>

<reference anchor="JMAP-BLOB">
  <front>
    <title>JSON Meta Application Protocol (JMAP) Blob Management Extension</title>
    <author fullname="B. Gondwana" initials="B." role="editor" surname="Gondwana"/>
    <date month="August" year="2023"/>
    <abstract>
      <t>The JSON Meta Application Protocol (JMAP) base protocol (RFC 8620) provides the ability to upload and download arbitrary binary data via HTTP POST and GET on a defined endpoint. This binary data is called a "blob".</t>
      <t>This extension adds additional ways to create and access blobs by making inline method calls within a standard JMAP request.</t>
      <t>This extension also adds a reverse lookup mechanism to discover where blobs are referenced within other data types.</t>
    </abstract>
  </front>
  <seriesInfo name="RFC" value="9404"/>
  <seriesInfo name="DOI" value="10.17487/RFC9404"/>
</reference>


<reference anchor="HTTP-RESUMABLE-UPLOADS">
   <front>
      <title>Resumable Uploads for HTTP</title>
      <author fullname="Marius Kleidl" initials="M." surname="Kleidl">
         <organization>Transloadit</organization>
      </author>
      <author fullname="Guoye Zhang" initials="G." surname="Zhang">
         <organization>Apple Inc.</organization>
      </author>
      <author fullname="Lucas Pardue" initials="L." surname="Pardue">
         <organization>Cloudflare</organization>
      </author>
      <date day="20" month="October" year="2025"/>
      <abstract>
	 <t>   HTTP data transfers can encounter interruption due to reasons such as
   canceled requests or dropped connections.  If the intended recipient
   can indicate how much of the data was received prior to interruption,
   a sender can resume data transfer at that point instead of attempting
   to transfer all of the data again.  HTTP range requests support this
   concept of resumable downloads from server to client.  This document
   describes a mechanism that supports resumable uploads from client to
   server using HTTP.

	 </t>
      </abstract>
   </front>
   <seriesInfo name="Internet-Draft" value="draft-ietf-httpbis-resumable-upload-10"/>
   
</reference>




    </references>





  </back>

<!-- ##markdown-source:
H4sIAAAAAAAAA4VY0VIjuxF911eo2IcFCgPZbDa5k4fELGzCLVgoMJVKbm4F
zYxsa5kZTSQNxndDVT4iX5gvyemWxh4biuzLGo3U3eo+fbpbo9FIBBMqnckf
L8fX8qSyuTx7CrrxxjZeqDx3+vHFx1KXorRFo2ocLJ2ahtHMNuVCNWr0rVbt
KMdW/RRGx8fCd3ltPImbLFtsPz+bfBGFCnpm3TKTPpSia0v87TP5u08fjoXN
va00/S1M6zIZXOfDh+PjH44/iAe9XFhXQkoTtGt0GJ2SduGDasp/qMo20LDU
XrQmkz8FWxxIb11weurxa1nTj5+FUF2YW5cJORIS/0wD3SeH8k/pDrwYL3fi
bLO5bt0sk1+UD7UyFa9o+pXJHFtnf5ymL0Gr+rCwtRCNdbUK5lFnvPvu5nw0
Obu8vhhPzjJ58+Xzp9/89pi/kJNHn69u4jL7YrV8cnF1wss/fDz+yMt/nkyu
Rzdnt3eX45OLs9Hd9cXV+PQWnhmdHhodpqN5CG1u/Mhp39Uqr/SoayurSiFM
M13bJEajkVS5D04VQYjJXMdo58pr2ToLJ9pK7iaL9mjp0ZTay4CdKjeVCUsZ
rIzCJeIgS7toWJNyuYFct5S5aeg/xFkdSjmZGz9ckvizUFWlcV7uEHh2DlhS
oRqZa9l5AM40ElukhV4XTdQroB4ODSeYrj6x5eS0PanKkhSUpQn4oCq5UEtP
phdOA3+sUBWF9l6QDFi4lLV6MM0MCKlMo2WtgZuSTfVyYcKcbJIMPuXKqN7p
f3baB7YI11obAsVe1tb1Ylg10PzAkthsgNQ0RdWVpHMOqRX9qJSb6bVJCADZ
SF/gihonZDHvmgcvd/POVHwW6tK13/vokAJeQiYVdHXkZNsiLfaik2NE6Vjv
ED2dmsLoJlSIj/aFMwiCr8n9BcyaaXI44aY2ZVlpId5RQjpbJvnrYJxsBeP7
9xWcn5/lf//9H/nj7dXXuO0SKTbTNdTuSTudaucHwRJbwUruIvvhb+BoAVho
8shSKhch8zIG7CBP7glzFdj7B1HX8PpTA6kcqVWmUPxy2wVBqDdMPgBQ9GiH
jXbK+eC1e9Su97kPUQY4owRm+3APvCs49CbEi7zmfqRP42HfpvtpF1JDPxkf
yHJSx7JgIkLdLmmR9pNRnHQUo3HyJp2mD59VGxPYQOJV/k33BFAMP1j+QCnq
NO7aUA552SoX+ltzpG81k7yI238PV2iZok2c9vx8gC0MD/mhDwxqSEfxBsjg
c+hSzTA/V2YsiTXpCu8kDMiI3jIYoGqfUbnJUrnZMn4p79/afQ9mITe1IEiy
wRAotNgBBdiuCUPn7FCOtNpBJK5MRsY98Eg67WXKKQnAEEhAnjqVyv4wOzMh
LwkAF56TD5n/VmYb1K+1UahpAFDE45vGmUjK8RoRifLy7nYCIHibiIUzRKKM
puvKneLVeyZCfVRVl8ANE1dOSGc57j7GfUuQWO1lC3LNcK1b8iAD5P8qWHsZ
6fTqvdc6DCMnAZX9y1rBeUElW6e2quwicvkqpwXsTo7agDyzonapb/EU042w
oWruy1VdvePKd+fQA+zcBmKSv/+r6apqR3ChRoBTNJHlSIlhAwAOXMxNMe/R
4/H99cL+/HzI0jhvLsd/JZcy46BNoXyk311vSKSTeVrmLQg5kfZ+rBW35hc0
Nzt3YMUZEhrkvWEyRcZjC8OvCBp2RTPXHEcE65iHfAuvxSIF5qzQfMWeiria
61IEuZJFRZyWrIwUGasoMgW9B5EdXY4Ux77qqdBtSM4n2cwJJDLeDxZ4rhxH
qfdgWcR2fDzKTxhI1RJZGW1CoWVK008tMIMc5fCur8cSqPuwbTDAgd44jRvd
8jbfJxiwlToTMj+6oDcc1cSgwHawnpsdGFagWsO3Q+OJu2fzVAhMFVtLTudi
bi1Uo8CxAnI5Fxau/iqSpnOKuSleGkWhqg5Su8pF09Y5NTB0hHn03Zr8l+jp
Vd1SGZ9cnV4xy/aVggPMVs406LX/lSrBNl8zyaJzd3J3VSpy6iCmqqsCXaDZ
5jphfM9MJXnkvqPG5n5vhVR05mO63E+ncN2t7VyhY6X6OUJ1PLj8kCnZ0573
J2LwhxHYhFFuOLmRYAsBEppIGhUSTlj0tkbf816FqouDXNUh9C9zlvgKnl5K
WEV2SMfICuNiS8PhR0PideghWukZfNuDKWUfwjJD+5628qlKN7MwZ+HMqn3O
llY2lroCPrelLt2IKQLtRzR7CEvkAGMyJkTMYMZ8F3MiqR3YHTuoGXdFHUVd
8ZJqW1TDvvUg8qzY2xQOJiZXmun0FnykqKPK2L7zMkb5psdbWk1XS+PBVIdi
rll2P3pEJSRR+l5k364kEVz9Y6LG84cvob8dQCHGaKpehnV33bbfE/Ky+x50
e2zkXD1yBXwRLvaHMzWDLjJcDN5BIgSAAPXvG0ZgXH6B4ZKvwejmfIJbEZR4
d1K8AXaqi0RNXqTIkeK+4FlCnyX/ccLQgEC4biLjcvOIgZ2KxtkjNdjbt5a7
1FCD9IajH8hhT/Ytdxnt6qGummVf5+j9wKCPDSmQ3Fzy3KRLGtnX1QL1tir7
j/J9PJX5uXrP+vSrpokFnxrm2OZJ5IbGBVOBDLZFOB411c2+S9CqiDNZ8pHX
xG5Bo2dHgAw9WMT5gqYO8rNs9GLAgNTGk4iXCEpIv1YA3SbKuVPg6RpOoMAu
2byWdvaZSlnf9BDeSKZVF/VCJfPkl8nZTRTKswFi8SJz+0KdQhN7MwhknQdx
loif4rxedBW5IdaZZiuvU9+wpXd1n0TGngLbFKQmi0741R4KBoOTbKRXiE8f
idU5SeMaDTu09cNe8tKAfLBznVk8yLFZapEM4oO/Xh9cDqLBrAoZFMmtEx+R
x3NdPGyCOLkjS66KM6XyqygyChrfxWLdx6kmXegRhPh6RW9AIOgFsW8TebIs
WcngaSWNvL+Y9igoF5ss5lZEvCZ3o3inyk9w/APNepi1OkfnP1Neo1Bxwwul
V7GJwByZ6knaV2zsG05FG1Mc+3pjij+IqOtnOcHvHG+JVg49NHLalGDn/pVj
+PKRGGr9nqQbA2K0U55qDNDijH9I0/+Wr3zdzWYV0xlzWZg7ptGVMR583FDn
hrrPrSujlUotOlaxcifNtz4ymSq0y/tWYevVKza/9BA087HnjQdTf5pKUBsj
Dr6gl5Lx1/GLqKDw8DQ16Mpu9MzQqxyPzETJb4++LHbIo2SeYxmp7u9sPODu
DHUpnwYkmLJezl5XSfhrkKBC3Ogp8Ib0zbYwgGvGXnJfXlj7ED3zt/PriN0D
6kcJYDRdHUgkNj9PfI5vG6g3p+eTq5tMIg70COl0jd4lDQfpCSHXUypabZdX
pmAXpYGyb/mmmxbFpxKev2eYEjo0WkhbeiL12dFRXKLn2iN+xT164037CJfa
f/vNe3+fLo6hIxBsaUq1XlX8AlM8NHZR6TK+c/m+5f6eq+IBvIBQPYv/AXW7
0lCVFwAA

-->

</rfc>

