0.12 RC1 major additions (see document)

git-svn-id: file:///home/ksmith/gitmigration/svn/xmpp/trunk@204 4b5297f7-1745-476d-ba37-a9c6900126ab
This commit is contained in:
Ian Paterson 2006-11-23 20:08:59 +00:00
parent 21599767a7
commit 1c89c984f7
1 changed files with 374 additions and 207 deletions

View File

@ -16,6 +16,7 @@
<dependencies>
<spec>XMPP Core</spec>
<spec>XMPP IM</spec>
<spec>XEP-0004</spec>
<spec>XEP-0030</spec>
<spec>XEP-0059</spec>
<spec>XEP-0060</spec>
@ -36,6 +37,12 @@
</author>
&stpeter;
&infiniti;
<revision>
<version>0.12</version>
<date>2006-11-23</date>
<initials>ip</initials>
<remark><p>All modes allow multiple body children of to and from elements; changed namespace and collection element name to chat; renamed all value of save attribute to message; added stream value of the save attribute, thread attribute, save wrapper element, and Linking Collections and Associating Attributes sections</p></remark>
</revision>
<revision>
<version>0.11</version>
<date>2006-11-06</date>
@ -121,17 +128,17 @@
<query xmlns='http://jabber.org/protocol/disco#info'/>
</iq>
]]></example>
<p>For each feature defined herein, if the server supports that feature it MUST return a &lt;feature/&gt; element with the 'var' attribute set to 'http://jabber.org/protocol/archive#name', where 'name' is 'auto' for the <link url='#auto'>Automated Archiving</link> feature, 'encrypt' for the <em>server-side</em> encryption feature (see <link url='#auto'>Automated Archiving</link>), 'manage' for the <link url='#manage'>Archive Management</link> feature, 'manual' for the <link url='#manual'>Manual Archiving</link> feature, or 'pref' for the <link url='#pref'>Archiving Preferences</link> feature.</p>
<p>For each feature defined herein, if the server supports that feature it MUST return a &lt;feature/&gt; element with the 'var' attribute set to 'urn:xmpp:archive#name', where 'name' is 'auto' for the <link url='#auto'>Automated Archiving</link> feature, 'encrypt' for the <em>server-side</em> encryption feature (see <link url='#auto'>Automated Archiving</link>), 'manage' for the <link url='#manage'>Archive Management</link> feature, 'manual' for the <link url='#manual'>Manual Archiving</link> feature, or 'pref' for the <link url='#pref'>Archiving Preferences</link> feature.</p>
<example caption='Server Service Discovery response'>
<![CDATA[
<iq type='result' to='romeo@montague.net/orchard' id='disco1'>
<query xmlns='http://jabber.org/protocol/disco#info'/>
...
<feature var='http://jabber.org/protocol/archive#auto'/>
<feature var='http://jabber.org/protocol/archive#encrypt'/>
<feature var='http://jabber.org/protocol/archive#manage'/>
<feature var='http://jabber.org/protocol/archive#manual'/>
<feature var='http://jabber.org/protocol/archive#pref'/>
<feature var='urn:xmpp:archive#auto'/>
<feature var='urn:xmpp:archive#encrypt'/>
<feature var='urn:xmpp:archive#manage'/>
<feature var='urn:xmpp:archive#manual'/>
<feature var='urn:xmpp:archive#pref'/>
...
</query>
</iq>
@ -153,12 +160,12 @@
<p>In order to determine its user's current Save Mode(s) and OTR Mode(s), a client sends an empty &lt;pref/&gt; element to its server:</p>
<example caption='Client Requests Archiving Preferences'><![CDATA[
<iq type='get' id='pref1'>
<pref xmlns='http://jabber.org/protocol/archive'/>
<pref xmlns='urn:xmpp:archive'/>
</iq>
]]></example>
<p>The server responds with the default Save Mode and OTR Mode (a single &lt;default/&gt; element) and any specific Save Modes and OTR Modes for individual contacts (zero or more &lt;item/&gt; elements).</p>
<p>Each &lt;default/&gt; or &lt;item/&gt; element in the response MUST include a 'save' attribute, whose value MAY be 'false' (the client MUST save no messages), 'body' (the client SHOULD save only &lt;body/&gt; elements) or 'all' (the client SHOULD save the full XML content of each &MESSAGE; element).</p>
<p>Note: Support for the 'all' value is optional and, to conserve bandwidth and storage space, it is RECOMMENDED that client implementations do not specify the 'all' value.</p>
<p>Each &lt;default/&gt; or &lt;item/&gt; element in the response MUST include a 'save' attribute, whose value MAY be 'false' (the saving entity MUST save nothing), 'body' (the saving entity SHOULD save only &BODY; elements), 'message' (the saving entity SHOULD save the full XML content of each &MESSAGE; element) or 'stream' (the saving entity SHOULD save every byte that passes over the stream in either direction). Note: The upload, retrieval and management of 'stream' archives is <em>currently</em> beyond the scope of this document.</p>
<p>Note: Support for the 'message' value is optional and, to conserve bandwidth and storage space, it is RECOMMENDED that client implementations do not specify the 'message' value. <note>Stream compression typically does not mitigate bandwidth and storage issues since collections SHOULD be encrypted, and since clients running in constrained runtime environments typically cannot take advantage of stream compression (no binary data, only XML, may be transfered).</note></p>
<p>Note: When archiving <em>locally</em> a client MAY save the full XML content of each &MESSAGE; element even if the Save Mode is 'body'.</p>
<p>Each &lt;default/&gt; or &lt;item/&gt; element in the response whose 'save' attribute is not set to 'false' is RECOMMENDED to also include an 'expire' attribute which indicates how many seconds after messages are archived that the server SHOULD delete them.</p>
<p>Each &lt;default/&gt; or &lt;item/&gt; element in the response MUST include an 'otr' attribute, whose value MAY be 'require', 'prefer', 'approve', 'concede', 'oppose' or 'forbid'. The client MUST be guided by the specified 'otr' attribute value when negotiating (see &xep0155;) whether or not all messages exchanged with a contact will be <link url='#otr'>Off The Record</link>. Note: If the OTR Mode is 'require' then the Save Mode MUST be 'false'.</p>
@ -166,10 +173,10 @@
<p>The server MUST also include an &lt;auto/&gt; element reflecting the current <link url='#auto'>Automated Archiving</link> settings for <em>this stream</em>.</p>
<example caption='Server Returns Preferences'><![CDATA[
<iq type='result' id='pref1' to='juliet@capulet.com/chamber'>
<pref xmlns='http://jabber.org/protocol/archive'>
<pref xmlns='urn:xmpp:archive'>
<default save='body' otr='concede' expire='31536000'/>
<item jid='romeo@montague.net' save='false' otr='require'/>
<item jid='benvolio@montague.net' save='all' expire='630720000' otr='forbid'/>
<item jid='benvolio@montague.net' save='message' expire='630720000' otr='forbid'/>
<method type='auto' use='forbid'/>
<method type='local' use='concede'/>
<method type='manual' use='prefer'/>
@ -180,7 +187,7 @@
<p>If the user has never set the default Modes, the 'save' and 'otr' attributes SHOULD specify the server's default settings, and the 'unset' attribute SHOULD be set to 'true'. Note: The 'unset' attribute defaults to 'false'.</p>
<example caption='Server Returns Service Default Preferences'><![CDATA[
<iq type='result' id='pref1' to='juliet@capulet.com/chamber'>
<pref xmlns='http://jabber.org/protocol/archive'>
<pref xmlns='urn:xmpp:archive'>
<default save='false' otr='concede' unset='true'/>
<method type='auto' use='concede'/>
<method type='local' use='concede'/>
@ -195,7 +202,7 @@
<p>A client may set the default Modes:</p>
<example caption='Client Sets Default Modes'><![CDATA[
<iq type='set' id='pref2'>
<pref xmlns='http://jabber.org/protocol/archive'>
<pref xmlns='urn:xmpp:archive'>
<default save='false' otr='prefer'/>
</pref>
</iq>
@ -207,28 +214,28 @@
<p>The server then MUST inform all of the user's connected resources that have previously requested the user's archiving preferences:</p>
<example caption='Server Pushes New Modes'><![CDATA[
<iq type='set' id='push1' to='juliet@capulet.com/chamber'>
<pref xmlns='http://jabber.org/protocol/archive'>
<pref xmlns='urn:xmpp:archive'>
<default save='false' otr='prefer'/>
</pref>
</iq>
<iq type='set' id='push2' to='juliet@capulet.com/pda'>
<pref xmlns='http://jabber.org/protocol/archive'>
<pref xmlns='urn:xmpp:archive'>
<default save='false' otr='prefer'/>
</pref>
</iq>
]]></example>
<p>The server MAY be configured to return a &lt;feature-not-implemented/&gt; error in the following cases:</p>
<ul>
<li><p>If it does not allow the saving of full message stanza content, and the client set the value of the 'save' attribute to 'all', and any of the user's connected resources have <link url='#auto'>Automated Archiving</link> enabled.</p></li>
<li><p>If administrator policies require that at least the &lt;body/&gt; (or the full content) of every message is logged automatically, and the client sets the value of the 'save' attribute to 'false' (or 'body').</p></li>
<li><p>If it does not allow the saving of full message stanza content, and the client set the value of the 'save' attribute to 'message' or 'stream', and any of the user's connected resources have <link url='#auto'>Automated Archiving</link> enabled.</p></li>
<li><p>If administrator policies require that at least the &lt;body/&gt; elements (or the full content) of every message are logged automatically, and the client sets the value of the 'save' attribute to 'false' (or 'body').</p></li>
</ul>
</section2>
<section2 topic='Setting Modes for a Contact' anchor='pref-jid'>
<p>A client may use a similar protocol to set the Modes for a particular contact or domain of contacts (bare JID, full JID or domain). Note: It is STRONGLY RECOMMENDED for the value of the 'jid' attribute to be a bare JID (&BAREJID;).</p>
<example caption='Client Sets Modes for a Contact'><![CDATA[
<iq type='set' id='pref3'>
<pref xmlns='http://jabber.org/protocol/archive'>
<pref xmlns='urn:xmpp:archive'>
<item jid='romeo@montague.net' save='body' expire='604800' otr='concede'/>
</pref>
</iq>
@ -238,13 +245,13 @@
]]></example>
<example caption='Server Pushes New Modes'><![CDATA[
<iq type='set' id='push3' to='juliet@capulet.com/chamber'>
<pref xmlns='http://jabber.org/protocol/archive'>
<pref xmlns='urn:xmpp:archive'>
<item jid='romeo@montague.net' save='body' expire='604800' otr='concede'/>
</pref>
</iq>
<iq type='set' id='push4' to='juliet@capulet.com/pda'>
<pref xmlns='http://jabber.org/protocol/archive'>
<pref xmlns='urn:xmpp:archive'>
<item jid='romeo@montague.net' save='body' expire='604800' otr='concede'/>
</pref>
</iq>
@ -254,7 +261,7 @@
<section2 topic='Setting Archiving Method Preferences' anchor='pref-jid'>
<example caption='Client Sets Method Preferences'><![CDATA[
<iq type='set' id='pref4'>
<pref xmlns='http://jabber.org/protocol/archive'>
<pref xmlns='urn:xmpp:archive'>
<method type='auto' use='concede'/>
<method type='local' use='forbid'/>
<method type='manual' use='prefer'/>
@ -266,7 +273,7 @@
]]></example>
<example caption='Server Pushes New Method Preferences'><![CDATA[
<iq type='set' id='push5' to='juliet@capulet.com/chamber'>
<pref xmlns='http://jabber.org/protocol/archive'>
<pref xmlns='urn:xmpp:archive'>
<method type='auto' use='concede'/>
<method type='local' use='forbid'/>
<method type='manual' use='prefer'/>
@ -274,7 +281,7 @@
</iq>
<iq type='set' id='push6' to='juliet@capulet.com/pda'>
<pref xmlns='http://jabber.org/protocol/archive'>
<pref xmlns='urn:xmpp:archive'>
<method type='auto' use='concede'/>
<method type='local' use='forbid'/>
<method type='manual' use='prefer'/>
@ -393,34 +400,39 @@
<li>A client wants to maintain a unified archive for messages that were transmitted both in and out-of-band (e.g. SMS or email)</li>
<li>A client wants to append private notes to a conversation</li>
</ul>
<p>Therefore, often a client will want to send or receive a sequence of messages, optionally add private notes to the sequence, optionally encrypt the sequence, and then ask the server to store it. Such messages and notes SHOULD be stored on the server in the form of a "collection".</p>
<p>Therefore, often a client will want to send or receive a sequence of messages, optionally add private notes to the sequence, optionally encrypt the sequence, and then ask the server to archive it. Such messages and notes SHOULD be stored on the server in the form of a "collection".</p>
</section2>
<section2 topic='Collections' anchor='manual-collection'>
<p>A "collection" is a set of messages to/from the same user that are received near each other in time or as part of the same conversation thread. A collection is intended to mimic the natural flow of human conversations, which in instant messaging (IM) systems tend to occur in bursts (e.g., a five-minute conversation one day, followed by a ten-minute conversation the next).</p>
<p>Each collection of messages and notes is encapsulated in a &lt;chat/&gt; element.</p>
<p>The client uniquely specifies a collection using a pair of attributes:</p>
<ul>
<li>'with' (the full JID with which the messages were exchanged)</li>
<li>'start' (the UTC start time of the conversation thread, which MUST be UTC and adhere to the DateTime format specified in &xep0082;)</li>
</ul>
<p>A friendly name for the collection MAY be specified with a 'subject' attribute. Note the <link url='#security-subject'>Security Considerations</link> regarding the subject attribute.</p>
<p>The opaque thread ID of the conversation (found in the &THREAD; children of the &MESSAGE; elements whose content is stored in the collection) MAY be specified with a 'thread' attribute.</p>
<p>Note: The content of &MESSAGE; elements that have different thread IDs SHOULD be archived in separate collections. The content of &MESSAGE; elements that have the same thread IDs SHOULD be archived in the same collection. The thread attribute SHOULD NOT be set to any value other than the exact content of the &THREAD; elements. If no &THREAD; elements appeared in the conversation the &lt;chat/&gt; element SHOULD have no thread attribute. Implementations SHOULD use the thread attribute for cross-referencing purposes only, within the archive each collection MUST be uniquely identified by the combination of its 'with' and 'start' attributes.</p>
<p>Each collection MAY contain &lt;note/&gt;, &lt;to/&gt; or &lt;from/&gt; elements (or &lt;EncryptedData/&gt; and &lt;EncryptedKey/&gt; elements - see <link url='#crypt'>Encryption</link>).</p>
<p>The text of each individual private note MUST be encapsulated in a &lt;note/&gt; element. The absolute time the note was created SHOULD be specified with a 'utc' attribute (which MUST be UTC and adhere to the DateTime format specified in <cite>Jabber Date and Time Profiles</cite>).</p>
<p>The content of each individual message MUST be encapsulated in a &lt;to/&gt; or &lt;from/&gt; element. The time in whole seconds of the message relative to the previous message in the collection (or, for the first message, relative to the start of the collection) SHOULD be specified with a 'secs' attribute. Note: When deciding whether to round up or down to a number of whole seconds, entities MUST ensure that the sum of the 'secs' attribute and the 'secs' attributes of the preceeding messages will accurately reflect the absolute time of the message. (e.g., if a sequence of messages occur at exactly 0.51-second intervals then the 'secs' attributes should generally alternate between '0' or '1'.)</p>
<p>The content of each &lt;to/&gt; or &lt;from/&gt; element SHOULD include a &BODY; element. Note: Other elements MAY be included, but they are NOT RECOMMENDED. To conserve bandwidth and storage space <note>Stream compression typically does not mitigate bandwidth and storage issues since collections SHOULD be encrypted, and since clients running in constrained runtime environments typically cannot take advantage of stream compression (no binary data, only XML, may be transfered).</note>, elements qualified by the 'http://jabber.org/protocol/xhtml-im' namespace SHOULD NOT be included. &THREAD; elements and elements qualified by the 'jabber:x:delay', 'jabber:x:event' and 'http://jabber.org/protocol/chatstates' namespaces MUST NOT be included. The server MAY be configured to return a &lt;feature-not-implemented/&gt; error if any &lt;to/&gt; or &lt;from/&gt; element contains anything other than a single &BODY; element.</p>
<p>The content of each &lt;to/&gt; or &lt;from/&gt; element SHOULD depend on the user's <link url='#pref'>Archiving Preferences</link>. &lt;to/&gt; or &lt;from/&gt; elements MUST NOT be empty. Note: A server MAY be configured to return a &lt;feature-not-implemented/&gt; error if any &lt;to/&gt; or &lt;from/&gt; element contains anything other than &BODY; elements.</p>
</section2>
<section2 topic='Uploading Messages to a Collection' anchor='manual-upload'>
<p>The collection of messages and notes to be uploaded are encapsulated in the &lt;store/&gt; element.</p>
<p>A collection of messages and notes is uploaded to the server encapsulated in a &lt;save/&gt; element.</p>
<example caption='Storing messages in a collection'><![CDATA[
<iq type='set' id='up1'>
<store xmlns='http://jabber.org/protocol/archive'
with='juliet@capulet.com/chamber'
<save xmlns='urn:xmpp:archive'>
<chat with='juliet@capulet.com/chamber'
start='1469-07-21T02:56:15Z'
thread='damduoeg08'
subject='She speaks!'>
<from secs='0'><body>Art thou not Romeo, and a Montague?</body></from>
<to secs='11'><body>Neither, fair saint, if either thee dislike.</body></to>
<from secs='14'><body>How cam'st thou hither, tell me, and wherefore?</body></from>
<note utc='1469-07-21T03:04:35Z'>I think she might fancy me.</note>
</store>
</chat>
</save>
</iq>
]]></example>
<p>If the collection does not exist then the server MUST create a new collection. If the collection already exists then the server MUST append the messages to the existing collection.</p>
@ -428,12 +440,24 @@
<example caption='Successful reply'><![CDATA[
<iq type='result' to='romeo@montague.net/orchard' id='up1'/>
]]></example>
<p>If the server cannot service a store request because the collection is too large then it MUST return a &notacceptable; error:</p>
<p>If the server cannot service an upload request because the collection is too large then it MUST return a &notacceptable; error:</p>
<example caption='Unsuccessful reply'><![CDATA[
<iq type='error' to='romeo@montague.net/orchard' id='up1'>
<error code='406' type='modify'>
<not-acceptable xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
</error>
</iq>
]]></example>
</section2>
<section2 topic='Changing the Subject of a Collection' anchor='impl-subject'>
<p>If the client specifies a new value for the 'subject' attribute of any existing collection then the server MUST update the existing value. Note: The client cannot specify new values for the 'with' or 'start' attributes. The only way to change these values is to delete the collection (see <link url='#manage-remove'>Removing a Collection</link>) and then create a new one.</p>
<example caption='Changing the subject of a collection without appending messages'><![CDATA[
<iq type='set' id='subject1'>
<save xmlns='urn:xmpp:archive'>
<chat with='juliet@capulet.com/chamber'
start='1469-07-21T02:56:15Z'
subject='She speaks twice!'/>
</save>
</iq>
]]></example>
</section2>
@ -441,14 +465,15 @@
<p>The client MAY specify an absolute time for any message by providing a longer 'utc' attribute (which MUST be UTC and adhere to the DateTime format specified in <cite>Jabber Date and Time Profiles</cite>) instead of a 'secs' attribute. The absolute time MAY be before the start time of the collection:</p>
<example caption='Storing offline messages in a collection'><![CDATA[
<iq type='set' id='up2'>
<store xmlns='http://jabber.org/protocol/archive'
with='juliet@capulet.com/chamber'
<save xmlns='urn:xmpp:archive'>
<chat with='juliet@capulet.com/chamber'
start='1469-07-21T02:56:15Z'
subject='She speaks!'>
<from utc='1469-07-21T00:32:29Z'><body>Art thou not Romeo, and a Montague?</body></from>
<to secs='11'><body>Neither, fair saint, if either thee dislike.</body></to>
<from secs='14'><body>How cam'st thou hither, tell me, and wherefore?</body></from>
</store>
</chat>
</save>
</iq>
]]></example>
</section2>
@ -456,24 +481,116 @@
<p>A client MAY archive messages that it receives from &xep0045; rooms. The 'with' attribute MUST be the bare JID of the room. The client MUST include a 'name' attribute for each &lt;from/&gt; element to specify the room nickname of the message sender:</p>
<example caption='Storing groupchat messages in a collection'><![CDATA[
<iq type='set' id='up3'>
<store xmlns='http://jabber.org/protocol/archive'
with='balcony@house.capulet.com'
<save xmlns='urn:xmpp:archive'>
<chat with='balcony@house.capulet.com'
start='1469-07-21T03:16:37Z'>
<from secs='0' name='benvolio'><body>She will indite him to some supper.</body></from>
<from secs='0' name='benvolio'><body>She will invite him to some supper.</body></from>
<from secs='5' name='mercutio'><body>A bawd, a bawd, a bawd! So ho!</body></from>
<from secs='11' name='romeo'><body>What hast thou found?</body></from>
</store>
</chat>
</save>
</iq>
]]></example>
</section2>
<section2 topic='Changing the Subject of a Collection' anchor='crypt'>
<p>If the client specifies a new value for the 'subject' attribute of any existing collection then the server MUST update the existing value. Note: The client cannot specify new values for the 'with' or 'start' attributes. The only way to change these values is to delete the collection (see <link url='#manage-remove'>Removing a Collection</link>) and then create a new one.</p>
<example caption='Changing the subject of a collection without appending messages'><![CDATA[
<iq type='set' id='subject1'>
<store xmlns='http://jabber.org/protocol/archive'
with='juliet@capulet.com/chamber'
start='1469-07-21T02:56:15Z'
subject='She speaks twice!'/>
<section2 topic='Linking Collections' anchor='impl-link'>
<p>Collections MAY be linked together by including a &lt;previous/&gt; and/or &lt;next/&gt; element. Each such element MUST include both a 'with' and a 'start' element to identify the other collection to which the collection is linked. For example, the &lt;previous/&gt; and &lt;next/&gt; elements in the two examples below are being used to link a groupchat between Romeo, Benvolio and Mercutio to a private chat that Romeo was having with Benvolio before they invited Mercutio to join them. Note: Collections MAY be linked in only one direction, they are not required to be double-linked in the way the examples below are.</p>
<example caption='Private chat linked to later groupchat'><![CDATA[
<iq type='set' id='link1'>
<save xmlns='urn:xmpp:archive'>
<chat with='benvolio@capulet.com'
start='1469-07-21T03:01:54Z'>
<next with='balcony@house.capulet.com' start='1469-07-21T03:16:37Z'/>
<to secs='0'><body>O, I am fortune's fool!</body></from>
<from secs='7'><body>Why dost thou stay?</body></from>
</chat>
</save>
</iq>
]]></example>
<example caption='Groupchat linked to earlier private chat'><![CDATA[
<iq type='set' id='link2'>
<save xmlns='urn:xmpp:archive'>
<chat with='balcony@house.capulet.com'
start='1469-07-21T03:16:37Z'>
<previous with='benvolio@capulet.com' start='1469-07-21T03:01:54Z'/>
<from secs='0' name='benvolio'><body>She will invite him to some supper.</body></from>
<from secs='5' name='mercutio'><body>A bawd, a bawd, a bawd! So ho!</body></from>
<from secs='11' name='romeo'><body>What hast thou found?</body></from>
</chat>
</save>
</iq>
]]></example>
<p>A collection MUST NOT contain more than one &lt;previous/&gt; and one &lt;next/&gt; element. If a &lt;previous/&gt; element is uploaded to a collection that already contains one then the older &lt;previous/&gt; element MUST be discarded. The same requirement applies for &lt;next/&gt; elements.</p>
<p>When a collection is retrieved (see <link url='#manage-retrieve'>Retrieving a Collection</link>) the &lt;previous/&gt; and &lt;next/&gt; elements MUST appear as the first elements in the collection, whatever order they were uploaded in.</p>
<p>&lt;previous/&gt; and &lt;next/&gt; elements MAY be removed from a collection simply by uploading a &lt;previous/&gt; and/or &lt;next/&gt; element without any 'with' or 'start' attributes. Note: The server SHOULD NOT return an error if it finds that a link to be deleted does not exist.</p>
<example caption='Deleting any links to other collections'><![CDATA[
<iq type='set' id='link3'>
<save xmlns='urn:xmpp:archive'>
<chat with='balcony@house.capulet.com'
start='1469-07-21T03:16:37Z'>
<previous/>
<next/>
</chat>
</save>
</iq>
]]></example>
</section2>
<section2 topic='Associating Attributes with a Collection' anchor='impl-form'>
<p>A client MAY append attributes to a collection by including an x:data form of type 'submit' (see &xep0004;) when it uploads to a collection.</p>
<p>A collection MUST NOT contain more than one x:data form. If a form is uploaded to a collection that already contains one then the older form element MUST be discarded. When a collection is retrieved (see <link url='#manage-retrieve'>Retrieving a Collection</link>) the x:data form MUST appear as the first element in the collection after any &lt;previous/&gt; or &lt;next/&gt; elements, whatever order it was uploaded in. Upon retrieval the 'type' attribute of the form MAY be 'submit' or 'form'.</p>
<example caption='Private chat with attributes form'><![CDATA[
<iq type='set' id='form1'>
<save xmlns='urn:xmpp:archive'>
<chat with='benvolio@capulet.com'
start='1469-07-21T03:01:54Z'>
<x xmlns='jabber:x:data' type='submit'>
<field var='FORM_TYPE'><value>urn:xmpp:archive</value></field>
<field var='task'><value>1</value></field>
<field var='important'><value>1</value></field>
<field var='action_before'><value>1469-07-29T12:00:00Z</value></field>
</x>
<to secs='0'><body>O, I am fortune's fool!</body></from>
<from secs='7'><body>Why dost thou stay?</body></from>
</chat>
</save>
</iq>
]]></example>
<p>The content of the uploaded x:data form MAY be encrypted (see <link url='#crypt'>Encryption</link>).</p>
<example caption='Private chat with encrypted attributes form'><![CDATA[
<iq type='set' id='form2'>
<save xmlns='urn:xmpp:archive'>
<chat with='benvolio@capulet.com'
start='1469-07-21T03:01:54Z'>
<x xmlns='jabber:x:data' type='submit'>
<EncryptedData xmlns='http://www.w3.org/2001/04/xmlenc#'
Type='http://www.w3.org/2001/04/xmlenc#Content'>
<EncryptionMethod Algorithm='http://www.w3.org/2001/04/xmlenc#aes128-cbc'/>
<KeyInfo xmlns='http://www.w3.org/2000/09/xmldsig#'>
<KeyName>dataKey1</KeyName>
</KeyInfo>
<CipherData><CipherValue>+OGQ0SR+ysraP6LnD43m77VkIVni5c7yPeIbkFdicZ</CipherValue></CipherData>
</EncryptedData>
</x>
<EncryptedKey xmlns='http://www.w3.org/2001/04/xmlenc#'>
<CarriedKeyName>dataKey1</CarriedKeyName>
<EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5"/>
<KeyInfo xmlns='http://www.w3.org/2000/09/xmldsig#'>
<KeyName>romeoPublicKey1fingerprint</KeyName>
</KeyInfo>
<CipherData><CipherValue>E5Qbvfa2gI5lBZMAHryv4g</CipherValue></CipherData>
</EncryptedKey>
</chat>
</save>
</iq>
]]></example>
<p>The x:data form MAY be removed from a collection simply by uploading an empty form. Note: The server SHOULD NOT return an error if it finds that the form to be deleted does not exist.</p>
<example caption='Deleting the attributes form'><![CDATA[
<iq type='set' id='form3'>
<save xmlns='urn:xmpp:archive'>
<chat with='benvolio@capulet.com'
start='1469-07-21T03:01:54Z'>
<x xmlns='jabber:x:data' type='submit'/>
</chat>
</save>
</iq>
]]></example>
</section2>
@ -488,8 +605,8 @@
<p>Note: A collection that contains &lt;EncryptedData/&gt; or &lt;EncryptedKey/&gt; elements MUST NOT contain &lt;to/&gt; or &lt;from/&gt; or &lt;note/&gt; elements.</p>
<example caption='Storing encrypted messages and keys in a collection'><![CDATA[
<iq type='set' id='crypt1'>
<store xmlns='http://jabber.org/protocol/archive'
with='juliet@capulet.com/chamber'
<save xmlns='urn:xmpp:archive'>
<chat with='juliet@capulet.com/chamber'
start='1469-07-23T19:22:31Z'
subject='She speaks!'>
<EncryptedData xmlns='http://www.w3.org/2001/04/xmlenc#'
@ -516,7 +633,8 @@
</KeyInfo>
<CipherData><CipherValue>E5Qbvfa2gI5lBZMAHryv4g</CipherValue></CipherData>
</EncryptedKey>
</store>
</chat>
</save>
</iq>
]]></example>
<p>The &lt;CipherData/&gt; child of each &lt;EncryptedData/&gt; element contains the base64-encoded symmetric-encrypted messages. The &lt;EncryptionMethod/&gt; and &lt;KeyInfo/&gt; children specify the symmetric encryption algorithm and the name of the symmetric key used to encrypt the messages.</p>
@ -540,13 +658,13 @@
<p>Otherwise:</p>
<ul>
<li>Automatic archiving MUST default to disabled when each stream is opened.</li>
<li>A client MAY enable or disable automatic archiving for messages sent over its stream at any time. Note: If the client switches off all auto-archiving then the server MUST close and store all active collections.</li>
<li>A client MAY enable or disable automatic archiving for messages sent over its stream at any time. Note: If the client switches off all auto-archiving then the server MUST close and archive all active collections.</li>
<li>Once automatic archiving is switched on then the server MUST automatically archive messages only according to the user's <link url='#pref'>Archiving Preferences</link>.</li>
<li>Note: Both parties to an ESession (see &xep0116;) SHOULD either disable archiving or use an archiving method other than automatic, since ESession decryption keys are short-lived - making it impossible to decrypt automatically archived messages.</li>
</ul>
<example caption='Client enables auto archiving'><![CDATA[
<iq type='set' id='auto1'>
<auto save='true' xmlns='http://jabber.org/protocol/archive'/>
<auto save='true' xmlns='urn:xmpp:archive'/>
</iq>
]]></example>
</section2>
@ -558,7 +676,7 @@
<iq type='set' id='auto2'>
<auto save='true'
encrypt='true'
xmlns='http://jabber.org/protocol/archive'>
xmlns='urn:xmpp:archive'>
<KeyInfo xmlns='http://www.w3.org/2000/09/xmldsig#'>
<KeyValue>
<KeyName>romeoPublicKey3fingerprint</KeyName>
@ -574,12 +692,12 @@
</auto>
</iq>
]]></example>
<p>As soon as the server has finished storing a collection, it MUST securely destroy all copies of the symmetric key it used to encrypt the messages. Note: If the security of the server is compromised, then only the collections being recorded during the attack will be revealed (i.e. only those messages that would have been compromised even if they had not been stored).</p>
<p>As soon as the server has finished archiving a collection, it MUST securely destroy all copies of the symmetric key it used to encrypt the messages. Note: If the security of the server is compromised, then only the collections being recorded during the attack will be revealed (i.e. only those messages that would have been compromised even if they had not been archived).</p>
</section2>
<section2 topic='Not-Implemented Responses' anchor='auto-crypt'>
<p>The server MUST return a &lt;feature-not-implemented/&gt; error in the following cases:</p>
<ul>
<li><p>If the client is trying to enable automatic archiving, but the server does not allow the saving of full message stanza content, and the user has specified the 'all' Save Mode in one of its <link url='#pref'>Archiving Preferences</link>.</p></li>
<li><p>If the client is trying to enable automatic archiving, but the server does not allow the saving of full message stanza content, and the user has specified the 'message' Save Mode in one of its <link url='#pref'>Archiving Preferences</link>.</p></li>
<li><p>If administrator policies require that every message is logged automatically, and the client is trying to disable automatic archiving.</p></li>
<li><p>If the client is trying to enable encryption, but the server does not support encryption or the user did not specify a public key and is not publishing any keys using <cite>Public Key Publishing</cite>.</p></li>
</ul>
@ -599,7 +717,7 @@
<p>The client SHOULD use <cite>Result Set Management</cite> to limit the number of collections returned by the server in a single stanza, taking care not to request a page of collections that is so big it might exceed karma limits.</p>
<example caption='Requesting the first page of a list with same JID'><![CDATA[
<iq type='get' id='juliet1'>
<list xmlns='http://jabber.org/protocol/archive'
<list xmlns='urn:xmpp:archive'
with='juliet@capulet.com'>
<set xmlns='http://jabber.org/protocol/rsm'>
<max>30</max>
@ -609,7 +727,7 @@
]]></example>
<example caption='Requesting the first page of a list with same JID between two times'><![CDATA[
<iq type='get' id='period1'>
<list xmlns='http://jabber.org/protocol/archive'
<list xmlns='urn:xmpp:archive'
with='juliet@capulet.com'
start='1469-07-21T02:00:00Z'
end='1479-07-21T04:00:00Z'>
@ -621,7 +739,7 @@
]]></example>
<example caption='Requesting the first page of a list after a time'><![CDATA[
<iq type='get' id='list1'>
<list xmlns='http://jabber.org/protocol/archive'
<list xmlns='urn:xmpp:archive'
start='1469-07-21T02:00:00Z'>
<set xmlns='http://jabber.org/protocol/rsm'>
<max>30</max>
@ -629,18 +747,18 @@
</list>
</iq>
]]></example>
<p>The server MUST list the collections (empty &lt;store/&gt; elements including all attributes) in chronological order when responding to any request. If the collection contains &lt;EncryptedData/&gt; or &lt;EncryptedKey/&gt; elements then the 'crypt' attribute of the &lt;store/&gt; element MUST be set to 'true':</p>
<p>The server MUST list the collections (empty &lt;chat/&gt; elements including all attributes) in chronological order when responding to any request. If the collection contains &lt;EncryptedData/&gt; or &lt;EncryptedKey/&gt; elements then the 'crypt' attribute of the &lt;chat/&gt; element MUST be set to 'true':</p>
<example caption='Receiving the first page of a list'><![CDATA[
<iq type='result' to='romeo@montague.net/orchard' id='list1'>
<list xmlns='http://jabber.org/protocol/archive'>
<store with='juliet@capulet.com/chamber'
<list xmlns='urn:xmpp:archive'>
<chat with='juliet@capulet.com/chamber'
start='1469-07-21T02:56:15Z'
subject='She speaks!'
crypt='true'/>
.
[28 more collections]
.
<store with='balcony@house.capulet.com'
<chat with='balcony@house.capulet.com'
start='1469-07-21T03:16:37Z'/>
<set xmlns='http://jabber.org/protocol/rsm'>
<first index='0'>1469-07-21T02:56:15Zjuliet@capulet.com</first>
@ -654,12 +772,12 @@
<p>If no collections correspond to the request the server MUST return an empty &lt;list/&gt; element:</p>
<example caption='Receiving an empty list'><![CDATA[
<iq type='result' to='romeo@montague.net/orchard' id='list1'>
<list xmlns='http://jabber.org/protocol/archive'/>
<list xmlns='urn:xmpp:archive'/>
</iq>
]]></example>
<example caption='Requesting the second page of a list'><![CDATA[
<iq type='get' id='list2'>
<list xmlns='http://jabber.org/protocol/archive'
<list xmlns='urn:xmpp:archive'
start='1469-07-21T02:00:00Z'>
<set xmlns='http://jabber.org/protocol/rsm'>
<max>30</max>
@ -675,7 +793,7 @@
<p>The client SHOULD use <cite>Result Set Management</cite> to limit the number of messages returned by the server in a single stanza, taking care not to request a page of messages that is so big it might exceed karma limits.</p>
<example caption='Requesting the first page of a collection'><![CDATA[
<iq type='get' id='page1'>
<retrieve xmlns='http://jabber.org/protocol/archive'
<retrieve xmlns='urn:xmpp:archive'
with='juliet@capulet.com/chamber'
start='1469-07-21T02:56:15Z'>
<set xmlns='http://jabber.org/protocol/rsm'>
@ -686,7 +804,7 @@
]]></example>
<example caption='Receiving the first page of a collection'><![CDATA[
<iq type='result' to='romeo@montague.net/orchard' id='page1'>
<store xmlns='http://jabber.org/protocol/archive'
<chat xmlns='urn:xmpp:archive'
with='juliet@capulet.com/chamber'
start='1469-07-21T02:56:15Z'
subject='She speaks!'>
@ -701,14 +819,14 @@
<last>99</last>
<count>217</count>
</set>
</store>
</chat>
</iq>
]]></example>
<p>Note: In accordance with <cite>Result Set Management</cite>, the client MUST assume the unique IDs it receives in the &lt;first/&gt; and &lt;last/&gt; elements are opaque. Servers MAY adopt a unique ID format other than the one suggested in the example above.</p>
<p>If the specified collection does not exist then the server MUST return an &notfound; error:</p>
<example caption='Unsuccessful reply'><![CDATA[
<iq type='error' to='romeo@montague.net/orchard' id='page1'>
<retrieve xmlns='http://jabber.org/protocol/archive'
<retrieve xmlns='urn:xmpp:archive'
with='juliet@capulet.com/chamber'
start='1469-07-21T02:56:15Z'>
<set xmlns='http://jabber.org/protocol/rsm'>
@ -720,10 +838,10 @@
</error>
</iq>
]]></example>
<p>If the requested collection is empty the server MUST return an empty &lt;store/&gt; element:</p>
<p>If the requested collection is empty the server MUST return an empty &lt;chat/&gt; element:</p>
<example caption='Receiving an empty collection'><![CDATA[
<iq type='result' to='romeo@montague.net/orchard' id='page1'>
<store xmlns='http://jabber.org/protocol/archive'
<chat xmlns='urn:xmpp:archive'
with='juliet@capulet.com/chamber'
start='1469-07-21T02:56:15Z'
subject='She speaks!'/>
@ -731,7 +849,7 @@
]]></example>
<example caption='Requesting the second page of a collection'><![CDATA[
<iq type='get' id='page2'>
<retrieve xmlns='http://jabber.org/protocol/archive'
<retrieve xmlns='urn:xmpp:archive'
with='juliet@capulet.com/chamber'
start='1469-07-21T02:56:15Z'>
<set xmlns='http://jabber.org/protocol/rsm'>
@ -744,7 +862,7 @@
<p>The items in encrypted collections are typically larger - since each &lt;EncryptedData/&gt; element typically contains many messages. So the client SHOULD take even more care not to request a page of &lt;EncryptedData/&gt; elements that is so big it might exceed karma limits.</p>
<example caption='Requesting the first page of an encrypted collection with all versions of keys'><![CDATA[
<iq type='get' id='page1'>
<retrieve xmlns='http://jabber.org/protocol/archive'
<retrieve xmlns='urn:xmpp:archive'
with='juliet@capulet.com/chamber'
start='1469-07-23T19:22:31Z'
<set xmlns='http://jabber.org/protocol/rsm'>
@ -756,7 +874,7 @@
<p>In addition to the requested &lt;EncryptedData/&gt; elements, the server MUST return all the &lt;EncryptedKey/&gt; elements that it possesses for the user whose symmetric key name (wrapped in its &lt;CarriedKeyName/&gt; child) is referenced by the &lt;KeyName/&gt; child of the &lt;KeyInfo/&gt; child of any of the &lt;EncryptedData/&gt; elements in the returned page.</p>
<example caption='Receiving the first page of an encrypted collection'><![CDATA[
<iq type='result' to='romeo@montague.net/orchard' id='page1'>
<store xmlns='http://jabber.org/protocol/archive'
<chat xmlns='urn:xmpp:archive'
with='juliet@capulet.com/chamber'
start='1469-07-23T19:22:31Z'
subject='She speaks!'>
@ -816,13 +934,13 @@
<last>4</last>
<count>7</count>
</set>
</store>
</chat>
</iq>
]]></example>
<p>The client MAY limit the number of &lt;EncryptedKey/&gt; elements that it receives by specifying the name of one or more public keys for which it holds the associated private keys. The name of each public key MUST be wrapped in a &lt;KeyName/&gt; element.</p>
<example caption='Requesting the first page of an encrypted collection with specified version of keys'><![CDATA[
<iq type='get' id='page1'>
<retrieve xmlns='http://jabber.org/protocol/archive'
<retrieve xmlns='urn:xmpp:archive'
with='juliet@capulet.com/chamber'
start='1469-07-23T19:22:31Z'>
<KeyName xmlns='http://www.w3.org/2000/09/xmldsig#'>romeoPublicKey1fingerprint</KeyName>
@ -839,7 +957,7 @@
<p>To request the removal of a single collection the client sends an empty &lt;remove/&gt; element. The 'with' (full JID) and 'start' attributes MUST be included to uniquely identify the collection.</p>
<example caption='Removing a single collection'><![CDATA[
<iq type='set' id='remove1'>
<remove xmlns='http://jabber.org/protocol/archive'
<remove xmlns='urn:xmpp:archive'
with='juliet@capulet.com/chamber'
start='1469-07-21T02:56:15Z'/>
</iq>
@ -847,7 +965,7 @@
<p>The client may remove several collections at once. The 'start' and 'end' elements MAY be specified to indicate a date range. The 'with' attribute MAY be a full JID, bare JID or domain.</p>
<example caption='Removing all collections with a specified bare JID between two times'><![CDATA[
<iq type='set' id='remove2'>
<remove xmlns='http://jabber.org/protocol/archive'
<remove xmlns='urn:xmpp:archive'
with='juliet@capulet.com'
start='1469-07-21T02:00:00Z'
end='1469-07-21T04:00:00Z'/>
@ -857,7 +975,7 @@
<p>If the end date is in the future then then all collections after the start date are removed.</p>
<example caption='Removing all collections after a date'><![CDATA[
<iq type='set' id='remove3'>
<remove xmlns='http://jabber.org/protocol/archive'
<remove xmlns='urn:xmpp:archive'
start='1469-07-21T02:00:00Z'
end='2038-01-01T00:00:00Z'/>
</iq>
@ -865,34 +983,34 @@
<p>If the start date is before all the collections in the archive then all collections prior to the end date are removed.</p>
<example caption='Removing all collections before a date'><![CDATA[
<iq type='set' id='remove4'>
<remove xmlns='http://jabber.org/protocol/archive'
<remove xmlns='urn:xmpp:archive'
start='0000-01-01T00:00:00Z'
end='1469-07-21T04:00:00Z'/>
</iq>
]]></example>
<example caption='Removing all collections'><![CDATA[
<iq type='set' id='remove5'>
<remove xmlns='http://jabber.org/protocol/archive'/>
<remove xmlns='urn:xmpp:archive'/>
</iq>
]]></example>
<p>If the value of the optional 'open' attribute is set to 'true' then only collections that are currently being recorded automatically by the server (see <link url='#auto'>Automated Archiving</link>) are removed.</p>
<example caption='Removing a collection being recorded by the server'><![CDATA[
<iq type='set' id='remove6'>
<remove xmlns='http://jabber.org/protocol/archive'
<remove xmlns='urn:xmpp:archive'
with='juliet@capulet.com/chamber'
open='true'/>
</iq>
]]></example>
<example caption='Removing all collections being recorded by the server'><![CDATA[
<iq type='set' id='remove7'>
<remove xmlns='http://jabber.org/protocol/archive'
<remove xmlns='urn:xmpp:archive'
open='true'/>
</iq>
]]></example>
<p>If the specified collection (or collections) do not exist then the server MUST return an &notfound; error:</p>
<example caption='Unsuccessful reply'><![CDATA[
<iq type='error' to='romeo@montague.net/orchard' id='remove1'>
<remove xmlns='http://jabber.org/protocol/archive'
<remove xmlns='urn:xmpp:archive'
with='juliet@capulet.com/chamber'
start='1469-07-21T02:56:15Z'/>
<error code='404' type='cancel'>
@ -907,7 +1025,7 @@
<p>The client first requests a list of the affected &lt;EncryptedKey/&gt; elements from all collections by sending a &lt;keys/&gt; element to the server:</p>
<example caption='Requesting the first page of a list of keys'><![CDATA[
<iq type='get' id='pubkey1'>
<keys xmlns='http://jabber.org/protocol/archive'>
<keys xmlns='urn:xmpp:archive'>
<KeyName xmlns='http://www.w3.org/2000/09/xmldsig#'>romeoPublicKey1fingerprint</KeyName>
<set xmlns='http://jabber.org/protocol/rsm'>
<max>50</max>
@ -918,8 +1036,8 @@
<p>The server MUST return only &lt;EncryptedKey/&gt; elements whose symmetric encryption key is encrypted with the obsolete public key specified in the &lt;KeyName/&gt; child of the request:</p>
<example caption='Receiving the first page of a list of keys'><![CDATA[
<iq type='result' to='romeo@montague.net/orchard' id='pubkey1'>
<keys xmlns='http://jabber.org/protocol/archive'>
<store with='juliet@capulet.com/chamber'
<keys xmlns='urn:xmpp:archive'>
<chat with='juliet@capulet.com/chamber'
start='1469-07-23T19:22:31Z'>
<EncryptedKey xmlns='http://www.w3.org/2001/04/xmlenc#'>
<CarriedKeyName>dataKey1</CarriedKeyName>
@ -937,7 +1055,7 @@
</KeyInfo>
<CipherData><CipherValue>E5Qbvfa2gI5lBZMAHryv4g</CipherValue></CipherData>
</EncryptedKey>
</store>
</chat>
.
[49 more sets of collection keys]
.
@ -949,11 +1067,11 @@
</keys>
</iq>
]]></example>
<p>The client decrypts each symmetric key with the obsolete private key and encrypts it again with the new public key. The client then wraps each symmetric key in an &lt;EncryptedKey/&gt; element and asks the server to store it in its associated collection on the server (see <link url='#crypt'>Encryption</link>):</p>
<p>The client decrypts each symmetric key with the obsolete private key and encrypts it again with the new public key. The client then wraps each symmetric key in an &lt;EncryptedKey/&gt; element and asks the server to archive it in its associated collection on the server (see <link url='#crypt'>Encryption</link>):</p>
<example caption='Storing encrypted keys in a collection'><![CDATA[
<iq type='set' id='crypt1'>
<store xmlns='http://jabber.org/protocol/archive'
with='juliet@capulet.com/chamber'
<save xmlns='urn:xmpp:archive'>
<chat with='juliet@capulet.com/chamber'
start='1469-07-23T19:22:31Z'>
<EncryptedKey xmlns='http://www.w3.org/2001/04/xmlenc#'>
<CarriedKeyName>dataKey1</CarriedKeyName>
@ -971,7 +1089,8 @@
</KeyInfo>
<CipherData><CipherValue>E5Qbvfa2gI5lBZMAHryv4g</CipherValue></CipherData>
</EncryptedKey>
</store>
</chat>
</save>
</iq>
.
[49 more sets of collection keys]
@ -980,7 +1099,7 @@
<p>Finally, the client asks the server to delete from each collection all &lt;EncryptedKey/&gt; elements whose symmetric encryption key is encrypted with the obsolete public key:</p>
<example caption='Deleting key(s) from a collection'><![CDATA[
<iq type='get' id='delete1'>
<delete xmlns='http://jabber.org/protocol/archive'
<delete xmlns='urn:xmpp:archive'
with='juliet@capulet.com/chamber'
start='1469-07-23T19:22:31Z'>
<KeyName xmlns='http://www.w3.org/2000/09/xmldsig#'>romeoPublicKey1fingerprint</KeyName>
@ -998,7 +1117,7 @@
<example caption='Requesting a page of modifications'>
<![CDATA[
<iq type='get' id='sync1'>
<modified xmlns='http://jabber.org/protocol/archive'>
<modified xmlns='urn:xmpp:archive'>
<set xmlns='http://jabber.org/protocol/rsm'>
<max>50</max>
<after>1469-07-21T01:14:47Z</after>
@ -1009,7 +1128,7 @@
<p>The server MUST return the changed collections in the chronological order that they were changed (most recent last). If a collection has been modified, created or removed <em>after</em> the time specified by the &lt;after/&gt; element then the server MUST include it in the returned result set page of collections (unless the specified maximum page size would be exceeded). Each &lt;changed/&gt; or &lt;removed/&gt; collection element (for modified/created, or removed collections respectively) in the returned list MUST include only 'with' and 'start' attribues. The server MUST set the content of the &lt;last/&gt; element to the UTC time (see <cite>Jabber Date and Time Profiles</cite>) that the last collection on the page was modified.</p>
<example caption='Receiving a page of modifications'><![CDATA[
<iq type='result' to='romeo@montague.net/orchard' id='sync1'>
<modified xmlns='http://jabber.org/protocol/archive'>
<modified xmlns='urn:xmpp:archive'>
<changed with='juliet@capulet.com/chamber'
start='1469-07-21T02:56:15Z'/>
.
@ -1025,31 +1144,31 @@
</iq>
]]></example>
<p>Note: The server should remember the 'with' and 'start' attribues and the time of removal of all deleted collections. If this 'state' cannot be maintained indefinitely, then unless all the user's clients replicate before the server deletes its memory of a removal then it will not be reflected in all the local copies of the archive.</p>
<p>Note: Along with its copy of the archive the client SHOULD store the most recent &lt;last/&gt; time that it received from the server. The next time it synchronizes with the server it SHOULD specify that time when requesting the first result set page (see above).</p>
<p>Note: Along with its copy of the archive the client SHOULD save the most recent &lt;last/&gt; time that it received from the server. The next time it synchronizes with the server it SHOULD specify that time when requesting the first result set page (see above).</p>
<p>After receiving each result set page the client SHOULD delete from its local archive any collections that have been removed from the master archive. The client should also retrieve from the server the content of each collection that has been modified (see <link url='#retrieve'>Retrieving a Collection</link>) and add it to its local copy of the archive (deleting any older version of the same collection that it may already have).</p>
</section1>
<section1 topic='File Format' anchor='fileformat'>
<p><em>Note the file format specified in this section is likely to be deprecated once a standards-based format has been published in a separate specification.</em></p>
<p>So that clients can share archived messages, this document specifies a common format for storage on disk (similar to email formats like mbox and Maildir). The file format uses the same XML constructs as the protocol. Each file may contain messages exchanged with a single JID. Any number of items may be stored in an archive file.</p>
<p>So that clients can share archived messages, this document specifies a common format for storage on disk (similar to email formats like mbox and Maildir). The file format uses the same XML constructs as the protocol. Each file may contain messages exchanged with a single JID. Any number of &lt;chat/&gt; elements may be stored in an archive file.</p>
<example caption='Example file'><![CDATA[
<?xml version='1.0'?>
<archive xmlns='http://jabber.org/protocol/archive'
<archive xmlns='urn:xmpp:archive'
with='juliet@capulet.com'>
<store start='1469-07-21T02:56:15Z' subject='She speaks!'>
<chat start='1469-07-21T02:56:15Z' subject='She speaks!'>
<from secs='0'><body>Art thou not Romeo, and a Montague?</body></from>
<to secs='11'><body>Neither, fair saint, if either thee dislike.</body></to>
<from secs='14'><body>How cam'st thou hither, tell me, and wherefore?</body></from>
</store>
</chat>
</archive>
]]></example>
</section1>
<section1 topic='Implementation Notes' anchor='impl'>
<section2 topic='Time Synchronization' anchor='impl-sync'>
<p>When creating a new collection, it is RECOMMENDED that the client synchronizes the collection start time that it sends to the server with server time. This is important since the user may subsequently retrieve the stored collection using client machines whose UTC clocks are not synchronized with the client machine that stored the collection. (i.e. Either or both of the clients' UTC clocks may be wrong.) The client can achieve this synchronization with server time by using &xep0090; to estimate the difference between the server and client UTC clocks.</p>
<p>When creating a new collection, it is RECOMMENDED that the client synchronizes the collection start time that it sends to the server with server time. This is important since the user may subsequently retrieve the archived collection using client machines whose UTC clocks are not synchronized with the client machine that uploaded the collection. (i.e. Either or both of the clients' UTC clocks may be wrong.) The client can achieve this synchronization with server time by using &xep0090; to estimate the difference between the server and client UTC clocks.</p>
<p>When retrieving collections, it is RECOMMENDED that the client adjusts the start times of the collections it receives from server to be synchronized with the clock of the client machine.</p>
</section2>
<section2 topic='Bandwidth Considerations' anchor='impl-bandwidth'>
<p>When uploading messages using manual archiving, a client SHOULD NOT store one message at a time on the server since this increases both bandwidth consumption and the total number of transactions. It is instead RECOMMENDED that clients store messages only when the conversation thread <em>appears</em> to be terminated, e.g. when the user closes the chat window. If the user reopens the window and the thread continues then the client should append the new messages to the collection when the user closes the window again.</p>
<p>When uploading messages using manual archiving, a client SHOULD NOT upload one message at a time on the server since this increases both bandwidth consumption and the total number of transactions. It is instead RECOMMENDED that clients upload messages only when the conversation thread <em>appears</em> to be terminated, e.g. when the user closes the chat window. If the user reopens the window and the thread continues then the client should append the new messages to the collection when the user closes the window again.</p>
</section2>
<section2 topic='Storage Considerations' anchor='impl-storage'>
<p>Server implementations SHOULD give system administrators the option to disable support for both automated and manual archiving, since archived conversations can consume significant storage space.</p>
@ -1073,18 +1192,43 @@
</section1>
<section1 topic='XMPP Registrar Considerations' anchor='registrar'>
<section2 topic='Protocol Namespaces' anchor='registrar-ns'>
<p>The &REGISTRAR; shall include 'http://jabber.org/protocol/archive' in its registry of protocol namespaces (see &NAMESPACES;):</p>
<p>The &REGISTRAR; shall include 'urn:xmpp:archive' in its registry of protocol namespaces (see &NAMESPACES;):</p>
</section2>
<section2 topic='Service Discovery Features' anchor='registrar-features'>
<p>The XMPP Registrar shall include the following features in its registry of service discovery features (see &DISCOFEATURES;):</p>
<ul>
<li>http://jabber.org/protocol/archive#auto</li>
<li>http://jabber.org/protocol/archive#encrypt</li>
<li>http://jabber.org/protocol/archive#manage</li>
<li>http://jabber.org/protocol/archive#manual</li>
<li>http://jabber.org/protocol/archive#pref</li>
<li>urn:xmpp:archive#auto</li>
<li>urn:xmpp:archive#encrypt</li>
<li>urn:xmpp:archive#manage</li>
<li>urn:xmpp:archive#manual</li>
<li>urn:xmpp:archive#pref</li>
</ul>
</section2>
<section2 topic='Field Standardization' anchor='registrar-formtype'>
<p>&xep0068; defines a process for standardizing the fields used within Data Forms qualified by a particular namespace. The following fields shall be registered for use in Message Archiving:</p>
<code caption='Registry Submission'><![CDATA[
<form_type>
<name>urn:xmpp:archive</name>
<jep>XEP-0136</jep>
<desc>Attributes of a message collection</desc>
<field
var='task'
type='boolean'
label='Collection contains
information about a task'/>
<field
var='important'
type='boolean'
label='Collection is important'/>
<field
var='action_before'
type='text-single'
label='Datetime (see XEP-0082) before
the action discussed in the
collection must be completed'/>
</form_type>
]]></code>
</section2>
</section1>
<section1 topic='XML Schemas' anchor='schema'>
<code><![CDATA[
@ -1092,8 +1236,8 @@
<xs:schema
xmlns:xs='http://www.w3.org/2001/XMLSchema'
targetNamespace='http://jabber.org/protocol/archive'
xmlns='http://jabber.org/protocol/archive'
targetNamespace='urn:xmpp:archive'
xmlns='urn:xmpp:archive'
elementFormDefault='qualified'>
<xs:annotation>
@ -1102,6 +1246,7 @@
herein are:
- archive
- auto
- chat
- delete
- keys
- list
@ -1109,14 +1254,14 @@
- pref
- remove
- retrieve
- store
- save
</xs:documentation>
</xs:annotation>
<xs:element name='archive'>
<xs:complexType>
<xs:sequence>
<xs:element ref='store' minOccurs='1' maxOccurs='unbounded'/>
<xs:element ref='chat' minOccurs='1' maxOccurs='unbounded'/>
</xs:sequence>
<xs:attribute name='with' type='xs:string' use='optional'/>
</xs:complexType>
@ -1143,6 +1288,42 @@
</xs:complexType>
</xs:element>
<xs:element name='chat'>
<xs:complexType>
<xs:choice minOccurs='0' maxOccurs='unbounded'>
<xs:element name='from' type='messageType'/>
<xs:element name='next' type='linkType'/>
<xs:element ref='note'/>
<xs:element name='previous' type='linkType'/>
<xs:element name='to' type='messageType'/>
<xs:any processContents='lax' namespace='##other'/>
</xs:choice>
<xs:attribute name='crypt' use='optional' type='xs:boolean'/>
<xs:attribute name='start' type='xs:dateTime' use='required'/>
<xs:attribute name='subject' type='xs:string' use='optional'/>
<xs:attribute name='thread' use='optional' type='xs:string'/>
<xs:attribute name='with' type='xs:string' use='required'/>
</xs:complexType>
</xs:element>
<xs:complexType name='messageType'>
<xs:sequence>
<xs:element name='body' type='xs:string' minOccurs='0' maxOccurs='unbounded'/>
<xs:any processContents='lax' namespace='##other' minOccurs='0' maxOccurs='unbounded'/>
</xs:sequence>
<xs:attribute name='secs' type='xs:nonNegativeInteger' use='optional'/>
<xs:attribute name='utc' type='xs:dateTime' use='optional'/>
</xs:complexType>
<xs:complexType name='linkType'>
<xs:simpleContent>
<xs:extension base='empty'>
<xs:attribute name='start' type='xs:dateTime' use='optional'/>
<xs:attribute name='with' type='xs:string' use='optional'/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:element name='default'>
<xs:complexType>
<xs:simpleContent>
@ -1163,9 +1344,10 @@
<xs:attribute name='save' use='required'>
<xs:simpleType>
<xs:restriction base='xs:NCName'>
<xs:enumeration value='all'/>
<xs:enumeration value='body'/>
<xs:enumeration value='false'/>
<xs:enumeration value='message'/>
<xs:enumeration value='stream'/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
@ -1206,9 +1388,10 @@
<xs:attribute name='save' use='required'>
<xs:simpleType>
<xs:restriction base='xs:NCName'>
<xs:enumeration value='all'/>
<xs:enumeration value='body'/>
<xs:enumeration value='false'/>
<xs:enumeration value='message'/>
<xs:enumeration value='stream'/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
@ -1220,7 +1403,7 @@
<xs:element name='keys'>
<xs:complexType>
<xs:sequence>
<xs:element ref='store' minOccurs='0' maxOccurs='unbounded'/>
<xs:element ref='chat' minOccurs='0' maxOccurs='unbounded'/>
<xs:any processContents='lax' namespace='##other' minOccurs='0' maxOccurs='unbounded'/>
</xs:sequence>
</xs:complexType>
@ -1229,7 +1412,7 @@
<xs:element name='list'>
<xs:complexType>
<xs:sequence>
<xs:element ref='store' minOccurs='0' maxOccurs='unbounded'/>
<xs:element ref='chat' minOccurs='0' maxOccurs='unbounded'/>
<xs:any processContents='lax' namespace='##other' minOccurs='0' maxOccurs='unbounded'/>
</xs:sequence>
<xs:attribute name='end' type='xs:dateTime' use='optional'/>
@ -1322,30 +1505,14 @@
</xs:complexType>
</xs:element>
<xs:element name='store'>
<xs:element name='save'>
<xs:complexType>
<xs:choice minOccurs='0' maxOccurs='unbounded'>
<xs:element name='from' type='messageType'/>
<xs:element ref='note'/>
<xs:element name='to' type='messageType'/>
<xs:any processContents='lax' namespace='##other'/>
</xs:choice>
<xs:attribute name='crypt' use='optional' type='xs:boolean'/>
<xs:attribute name='start' type='xs:dateTime' use='required'/>
<xs:attribute name='subject' type='xs:string' use='optional'/>
<xs:attribute name='with' type='xs:string' use='required'/>
<xs:sequence>
<xs:element ref='chat' minOccurs='1' maxOccurs='1'/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:complexType name='messageType'>
<xs:sequence>
<xs:element name='body' type='xs:string' minOccurs='0' maxOccurs='1'/>
<xs:any processContents='lax' namespace='##other' minOccurs='0' maxOccurs='unbounded'/>
</xs:sequence>
<xs:attribute name='secs' type='xs:nonNegativeInteger' use='optional'/>
<xs:attribute name='utc' type='xs:dateTime' use='optional'/>
</xs:complexType>
<xs:simpleType name='empty'>
<xs:restriction base='xs:string'>
<xs:enumeration value=''/>