<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE xep SYSTEM 'xep.dtd' [
  <!ENTITY % ents SYSTEM "xep.ent">
%ents;
]>
<?xml-stylesheet type='text/xsl' href='xep.xsl'?>
<xep>

<header>
  
<title>Redirect and Connection Transfer</title>
  <abstract>This document describes redirection of Jabber queries, and a method to replace the current (non standard) use of 302 to redirect connections.</abstract>
  <legal>This document has been placed in the public domain.</legal>
  <number>0051</number>
  <status>Deferred</status>
  <type>Standards Track</type>
  <sig>Standards</sig>
  <author>
    <firstname>Klaus</firstname>
    <surname>Wolf</surname>
    <email>wolf@bluehands.de</email>
    <jid>klaus@jabber.bluehands.de</jid>
  </author>
  <author>
    <firstname>Richard</firstname>
    <surname>Dobson</surname>
    <email>richard@dobson-i.net</email>
    <jid>richard@dobson-i.net</jid>
  </author>
  <revision>
    <version>0.1</version>
    <date>2002-10-08</date>
    <initials>psa</initials>
    <remark>Initial version.</remark>
  </revision>
  <revision>
    <version>0.0.2</version>
    <date>2002-09-14</date>
    <initials>rd</initials>
    <remark>Added the server transfer section.</remark>
  </revision>
  <revision>
    <version>0.0.1</version>
    <date>2002-07-31</date>
    <initials>hw</initials>
    <remark>Initial version.</remark>
  </revision>
</header>

<section1 topic='Introduction'>
  
<p>
To be written. 
  </p>
</section1>

<section1 topic='IQ Redirect'>

<section2 topic='Introduction'>
  
<p>
  This document describes a general request redirection mechanism for Jabber queries. 
  </p>
<p>
  There are cases where only the receiver of a query, e.g. the receiver of &lt;iq type='get'/&gt; requests, knows the real location of the targeted data object. Reasons might be load balancing, changes in the protocol and/or usage patterns, or an additional level of indirection for improved flexibility. The possible reasons are very similar to reasons for (temporary) HTTP redirection. 
  </p>
<p>
  Redirection adds an additional feature to the protocol. But it also adds also a small amount of complexity to implementations. The mechanism has been designed in a way such that it affects implementations only minimally while providing maximum flexibility. 
  </p>
<p>
  For security reasons the redirection mechanism is only valid for &lt;iq type='get'/&gt; packets. 
  </p>
</section2>

  <section2 topic='Scenario'>
    
<p>
    A client sends a query to a server. The server may well be an other client acting as a server for this transaction. The server decides that it can not serve the original request. It redirects the request to an other server. In order to do so, it sends a redirection query to the client. The redirection query informs the client about the modified query including the new destination. The client then repeats the request by sending the redirected query to other server. 
    </p>
</section2>

  <section2 topic='Redirection Message'>
    
<p>
    The meaning of &lt;iq/&gt; queries is specified by multiple parameters, i.e. JID, &lt;query/&gt; namespace, and namespace specific tags and attributes. Many of these parameters may change during the redirection. To allow for maximum flexibility, the redirection query contains the complete redirected query. 
    </p>
<p>
    The redirection query is identified by the "type" attribute and by the code of an embedded &lt;error/&gt; tag. The code is "302". The redirection is meant to be temporary, not permanent. 
    </p>
<p>
    The original query is returned as a child of the &lt;iq type='error'/&gt;.</p>
<p>
    The redirected query sent from the server back to the client is embedded into the &lt;error/&gt; tag. 
    </p>
<p>
    The envelope of the redirected query must preserve all attributes of the initial query except for the destination JID ("to" attribute). In particular, it must preserve the "id" attribute. 
    </p>
<p>
		The must not redirect any query other than &lt;iq type='get'/&gt;.
    </p>
<p>
    The redirected query may target a different entity than the original query and it may have different parameters. But the redirected query must be manufactured in such a way that the result returned from the redirected query is compatible with the original query. </p>
</section2>

  <section2 topic='Examples'>
    
  <example caption='The original query which will be redirected'>
    &lt;iq type='get' from='jid-A' to='jid-B'&gt;
      original query
    &lt;/iq&gt; 
    </example>

    <example caption='Redirection response to original query'>
    &lt;iq type='error' from='jid-B' to='jid-A'&gt;
      original query
      &lt;error code='302'&gt;redirection message&lt;/error&gt; 
    &lt;/iq&gt; 
    </example>

    <example caption='Redirected query'>
    &lt;iq type='get' from='jid-A' to='jid-C'&gt;
      redirected query
    &lt;/iq&gt; 
    </example>

    <example caption=' A simple redirection which changes the destination JID'>
A: &lt;iq id='5' type='get' from='user@server-A' to='user@server-B&gt; 
A:   &lt;query xmlns='jabber:iq:browse'/&gt; 
A: &lt;/iq&gt; 

B: &lt;iq type='error' from='user@server-B' to='user@server-A'&gt;
B:   &lt;query xmlns='jabber:iq:browse'/&gt;
B:   &lt;error code='302'&gt;
B:     &lt;iq id='5' type='get' to='user@server-C'&gt; 
B:       &lt;query xmlns='jabber:iq:browse'/&gt; 
B:     &lt;/iq&gt; 
B:   &lt;/error&gt;
B: &lt;/iq&gt; 

A: &lt;iq id='5' type='get' from='user@server-A' to='user@server-C'&gt; 
A:   &lt;query xmlns='jabber:iq:browse'/&gt; 
A: &lt;/iq&gt; 
    </example>

    <example caption='A redirection which changes a client-client data request to client-storage'>
A: &lt;iq id='5' type='get' from='user@server-A' to='user@server-B/work'&gt; 
A:   &lt;query xmlns='jabber:iq:app-specific'/&gt; 
A: &lt;/iq&gt; 

B: &lt;iq type='error' from='user@server-B/work' to='user@server-A'&gt; 
B:   &lt;query xmlns='jabber:iq:app-specific'/&gt;
B:   &lt;error code='302'&gt;
B:     &lt;iq id='5' type='get' to='user@server-B'&gt; 
B:       &lt;query xmlns='storage:client:app-specific'/&gt; 
B:     &lt;/iq&gt; 
B:   &lt;/error&gt;
B: &lt;/iq&gt; 

A: &lt;iq id='5' type='get' from='user@server-A' to='user@server-B'&gt; 
A:   &lt;query xmlns='storage:client:app-specific'/&gt; 
A: &lt;/iq&gt; 
    </example>

  </section2>

  <section2 topic='Scope and Validity'>

<p>The client must check the redirected query. The redirected query is valid only if all three of the following conditions are met:</p>
<ol>
<li>the original query is &lt;iq type='get'/&gt;</li>
<li>the redirected query is &lt;iq type='get'/&gt;</li>
<li>the &lt;iq/&gt; envelope of the redirected query has all attributes of the original query except for the &quot;to&quot; attribute</li>
</ol>
    
</section2>

<section2 topic='Repeated Redirections'>
<p>
  If redirections are cascaded then the client should stop the sequence after a reasonable number of redirections. Three consecutive redirects, which make a total of four trials, should be enough. 
	</p>
	<p>
	Applications must not rely on more than three consecutive redirections for a single query.
    </p>
</section2>

<section2 topic='Implementation Note'>
<p>
    The redirection mechanism can be implemented transparently for the protocol engine. The client should unwrap the redirected query, check for validity, and send the data to the connection. </p>
<p>Protocol implementations do not have to create a new request context. The request context of the original query will still be valid since the redirector must preserve the query id.</p>
<p>
		The query id is often used by the protocol engine to relate queries sent and queries received in order to form request-response pairs. Using the  query id  the client can find the related original query when the result of the redirected query returns. 
    </p>
<p>
    However, the client must check the validity before re-sending the redirected query. 
    </p>
</section2>

</section1>

<section1 topic='Server Transfer'>

<section2 topic='Introduction'>
  
<p>
  This document describes a connection transfer mechanism for telling clients (or others) to reconnect to a different address. 
</p>
<p>
  This is useful for transfering people to a different server in a cluster if it is going down for maintenance or during login to transfer the person to a certain server in a cluster. 
</p>
</section2>

<section2 topic='Scenarios'>
   <section3 topic='Scenario 1'>
      A server needs to be shutdown for maintenance by an administrator but there are other servers available in the cluster and the administrator wants to cause the least disruption possible by having the users automatically reconnect to one of the other available servers.
   </section3>
   <section3 topic='Scenario 2'>
      Users of a Jabber cluster are hosted on particular servers, the server the user has connected to is not their server in the cluster, so the server redirects the user to connect to the correct server.
   </section3>
   <section3 topic='Scenario 3'>
      A new server is brought online in the cluster. To reduce the load on the other servers and to balance out the load, the other servers direct some of their users to connect to the new server.
   </section3>
</section2>

<section2 topic='Server Transfer Packet'>
   <p>
      The transfer packet is addressed to the user from the domain they are logged into, it contains the server address to connect to which can be domain name or ip address, it can also contain an optional port number. There is also the domain specified just in case they have to use a different domain name when they log in or to maintain the original domain.
   </p>
</section2>

<section2 topic='Examples'>

<example caption='Server tells client to connect to a different server in the cluster (by ip address)'>
&lt;iq type='set' from='jabber.org' to='user@jabber.org'&gt; 
  &lt;query xmlns='jabber:iq:srvxfr'&gt;
    &lt;domain&gt;jabber.org&lt;/domain&gt;
    &lt;server&gt;123.123.123.122&lt;/server&gt;
  &lt;/query&gt;
&lt;/iq&gt;
</example>

<example caption='Server tells client to connect to a different server in the cluster (by domain name)'>
&lt;iq type='set' from='jabber.org' to='user@jabber.org'&gt; 
  &lt;query xmlns='jabber:iq:srvxfr'&gt;
    &lt;domain&gt;jabber.org&lt;/domain&gt;
    &lt;server&gt;server2.jabber.org&lt;/server&gt;
  &lt;/query&gt;
&lt;/iq&gt;
</example>

<example caption='Server tells client to connect to a different server in the cluster (using a different port number)'>
&lt;iq type='set' from='jabber.org' to='user@jabber.org'&gt; 
  &lt;query xmlns='jabber:iq:srvxfr'&gt;
    &lt;domain&gt;jabber.org&lt;/domain&gt;
    &lt;server&gt;server3.jabber.org:6222&lt;/server&gt;
  &lt;/query&gt;
&lt;/iq&gt;
</example>

<example caption='Server tells client to simply reconnect'>
&lt;iq type='set' from='jabber.org' to='user@jabber.org'&gt; 
  &lt;query xmlns='jabber:iq:srvxfr'&gt;
    &lt;domain&gt;jabber.org&lt;/domain&gt;
    &lt;server&gt;jabber.org&lt;/server&gt;
  &lt;/query&gt;
&lt;/iq&gt;
</example>

</section2>

</section1>

</xep>
