modules/xmpp/filetransfer.py
author Mikael Berthe <mikael@lilotux.net>
Tue, 01 May 2007 12:26:35 +0200
changeset 0 93b25987d3e5
permissions -rw-r--r--
Initial Mercurial repository Imported from Neutron' svn, with a few changes
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     1
##   filetransfer.py 
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     2
##
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     3
##   Copyright (C) 2004 Alexey "Snake" Nezhdanov
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     4
##
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     5
##   This program is free software; you can redistribute it and/or modify
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     6
##   it under the terms of the GNU General Public License as published by
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     7
##   the Free Software Foundation; either version 2, or (at your option)
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     8
##   any later version.
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     9
##
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    10
##   This program is distributed in the hope that it will be useful,
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    11
##   but WITHOUT ANY WARRANTY; without even the implied warranty of
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    12
##   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    13
##   GNU General Public License for more details.
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    14
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    15
# $Id: filetransfer.py,v 1.6 2004/12/25 20:06:59 snakeru Exp $
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    16
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    17
"""
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    18
This module contains IBB class that is the simple implementation of JEP-0047.
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    19
Note that this is just a transport for data. You have to negotiate data transfer before
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    20
(via StreamInitiation most probably). Unfortunately SI is not implemented yet.
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    21
"""
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    22
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    23
from protocol import *
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    24
from dispatcher import PlugIn
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    25
import base64
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    26
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    27
class IBB(PlugIn):
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    28
    """ IBB used to transfer small-sized data chunk over estabilished xmpp connection.
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    29
        Data is split into small blocks (by default 3000 bytes each), encoded as base 64
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    30
        and sent to another entity that compiles these blocks back into the data chunk.
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    31
        This is very inefficiend but should work under any circumstances. Note that 
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    32
        using IBB normally should be the last resort.
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    33
    """
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    34
    def __init__(self):
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    35
        """ Initialise internal variables. """
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    36
        PlugIn.__init__(self)
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    37
        self.DBG_LINE='ibb'
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    38
        self._exported_methods=[self.OpenStream]
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    39
        self._streams={}
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    40
        self._ampnode=Node(NS_AMP+' amp',payload=[Node('rule',{'condition':'deliver-at','value':'stored','action':'error'}),Node('rule',{'condition':'match-resource','value':'exact','action':'error'})])
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    41
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    42
    def plugin(self,owner):
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    43
        """ Register handlers for receiving incoming datastreams. Used internally. """
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    44
        self._owner.RegisterHandlerOnce('iq',self.StreamOpenReplyHandler) # Move to StreamOpen and specify stanza id
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    45
        self._owner.RegisterHandler('iq',self.IqHandler,ns=NS_IBB)
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    46
        self._owner.RegisterHandler('message',self.ReceiveHandler,ns=NS_IBB)
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    47
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    48
    def IqHandler(self,conn,stanza):
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    49
        """ Handles streams state change. Used internally. """
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    50
        typ=stanza.getType()
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    51
        self.DEBUG('IqHandler called typ->%s'%typ,'info')
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    52
        if typ=='set' and stanza.getTag('open',namespace=NS_IBB): self.StreamOpenHandler(conn,stanza)
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    53
        elif typ=='set' and stanza.getTag('close',namespace=NS_IBB): self.StreamCloseHandler(conn,stanza)
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    54
        elif typ=='result': self.StreamCommitHandler(conn,stanza)
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    55
        elif typ=='error': self.StreamOpenReplyHandler(conn,stanza)
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    56
        else: conn.send(Error(stanza,ERR_BAD_REQUEST))
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    57
        raise NodeProcessed
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    58
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    59
    def StreamOpenHandler(self,conn,stanza):
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    60
        """ Handles opening of new incoming stream. Used internally. """
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    61
        """
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    62
<iq type='set' 
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    63
    from='romeo@montague.net/orchard'
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    64
    to='juliet@capulet.com/balcony'
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    65
    id='inband_1'>
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    66
  <open sid='mySID' 
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    67
        block-size='4096'
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    68
        xmlns='http://jabber.org/protocol/ibb'/>
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    69
</iq>
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    70
"""
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    71
        err=None
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    72
        sid,blocksize=stanza.getTagAttr('open','sid'),stanza.getTagAttr('open','block-size')
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    73
        self.DEBUG('StreamOpenHandler called sid->%s blocksize->%s'%(sid,blocksize),'info')
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    74
        try: blocksize=int(blocksize)
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    75
        except: err=ERR_BAD_REQUEST
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    76
        if not sid or not blocksize: err=ERR_BAD_REQUEST
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    77
        elif sid in self._streams.keys(): err=ERR_UNEXPECTED_REQUEST
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    78
        if err: rep=Error(stanza,err)
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    79
        else:
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    80
            self.DEBUG("Opening stream: id %s, block-size %s"%(sid,blocksize),'info')
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    81
            rep=Protocol('iq',stanza.getFrom(),'result',stanza.getTo(),{'id':stanza.getID()})
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    82
            self._streams[sid]={'direction':'<'+str(stanza.getFrom()),'block-size':blocksize,'fp':open('/tmp/xmpp_file_'+sid,'w'),'seq':0,'syn_id':stanza.getID()}
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    83
        conn.send(rep)
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    84
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    85
    def OpenStream(self,sid,to,fp,blocksize=3000):
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    86
        """ Start new stream. You should provide stream id 'sid', the endpoind jid 'to',
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    87
            the file object containing info for send 'fp'. Also the desired blocksize can be specified.
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    88
            Take into account that recommended stanza size is 4k and IBB uses base64 encoding
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    89
            that increases size of data by 1/3."""
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    90
        if sid in self._streams.keys(): return
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    91
        if not JID(to).getResource(): return
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    92
        self._streams[sid]={'direction':'|>'+to,'block-size':blocksize,'fp':fp,'seq':0}
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    93
        self._owner.RegisterCycleHandler(self.SendHandler)
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    94
        syn=Protocol('iq',to,'set',payload=[Node(NS_IBB+' open',{'sid':sid,'block-size':blocksize})])
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    95
        self._owner.send(syn)
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    96
        self._streams[sid]['syn_id']=syn.getID()
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    97
        return self._streams[sid]
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    98
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    99
    def SendHandler(self,conn):
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   100
        """ Send next portion of data if it is time to do it. Used internally. """
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   101
        self.DEBUG('SendHandler called','info')
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   102
        for sid in self._streams.keys():
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   103
            stream=self._streams[sid]
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   104
            if stream['direction'][:2]=='|>': cont=1
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   105
            elif stream['direction'][0]=='>':
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   106
                chunk=stream['fp'].read(stream['block-size'])
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   107
                if chunk:
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   108
                    datanode=Node(NS_IBB+' data',{'sid':sid,'seq':stream['seq']},base64.encodestring(chunk))
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   109
                    stream['seq']+=1
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   110
                    if stream['seq']==65536: stream['seq']=0
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   111
                    conn.send(Protocol('message',stream['direction'][1:],payload=[datanode,self._ampnode]))
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   112
                else:
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   113
                    """ notify the other side about stream closing
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   114
                        notify the local user about sucessfull send
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   115
                        delete the local stream"""
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   116
                    conn.send(Protocol('iq',stream['direction'][1:],'set',payload=[Node(NS_IBB+' close',{'sid':sid})]))
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   117
                    conn.Event(self.DBG_LINE,'SUCCESSFULL SEND',stream)
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   118
                    del self._streams[sid]
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   119
                    self._owner.UnregisterCycleHandler(self.SendHandler)
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   120
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   121
                    """
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   122
<message from='romeo@montague.net/orchard' to='juliet@capulet.com/balcony' id='msg1'>
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   123
  <data xmlns='http://jabber.org/protocol/ibb' sid='mySID' seq='0'>
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   124
    qANQR1DBwU4DX7jmYZnncmUQB/9KuKBddzQH+tZ1ZywKK0yHKnq57kWq+RFtQdCJ
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   125
    WpdWpR0uQsuJe7+vh3NWn59/gTc5MDlX8dS9p0ovStmNcyLhxVgmqS8ZKhsblVeu
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   126
    IpQ0JgavABqibJolc3BKrVtVV1igKiX/N7Pi8RtY1K18toaMDhdEfhBRzO/XB0+P
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   127
    AQhYlRjNacGcslkhXqNjK5Va4tuOAPy2n1Q8UUrHbUd0g+xJ9Bm0G0LZXyvCWyKH
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   128
    kuNEHFQiLuCY6Iv0myq6iX6tjuHehZlFSh80b5BVV9tNLwNR5Eqz1klxMhoghJOA
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   129
  </data>
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   130
  <amp xmlns='http://jabber.org/protocol/amp'>
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   131
    <rule condition='deliver-at' value='stored' action='error'/>
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   132
    <rule condition='match-resource' value='exact' action='error'/>
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   133
  </amp>
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   134
</message>
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   135
"""
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   136
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   137
    def ReceiveHandler(self,conn,stanza):
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   138
        """ Receive next portion of incoming datastream and store it write
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   139
            it to temporary file. Used internally.
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   140
        """
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   141
        sid,seq,data=stanza.getTagAttr('data','sid'),stanza.getTagAttr('data','seq'),stanza.getTagData('data')
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   142
        self.DEBUG('ReceiveHandler called sid->%s seq->%s'%(sid,seq),'info')
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   143
        try: seq=int(seq); data=base64.decodestring(data)
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   144
        except: seq=''; data=''
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   145
        err=None
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   146
        if not sid in self._streams.keys(): err=ERR_ITEM_NOT_FOUND
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   147
        else:
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   148
            stream=self._streams[sid]
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   149
            if not data: err=ERR_BAD_REQUEST
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   150
            elif seq<>stream['seq']: err=ERR_UNEXPECTED_REQUEST
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   151
            else:
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   152
                self.DEBUG('Successfull receive sid->%s %s+%s bytes'%(sid,stream['fp'].tell(),len(data)),'ok')
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   153
                stream['seq']+=1
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   154
                stream['fp'].write(data)
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   155
        if err:
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   156
            self.DEBUG('Error on receive: %s'%err,'error')
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   157
            conn.send(Error(Iq(to=stanza.getFrom(),frm=stanza.getTo(),payload=[Node(NS_IBB+' close')]),err,reply=0))
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   158
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   159
    def StreamCloseHandler(self,conn,stanza):
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   160
        """ Handle stream closure due to all data transmitted.
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   161
            Raise xmpppy event specifying successfull data receive. """
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   162
        sid=stanza.getTagAttr('close','sid')
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   163
        self.DEBUG('StreamCloseHandler called sid->%s'%sid,'info')
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   164
        if sid in self._streams.keys():
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   165
            conn.send(stanza.buildReply('result'))
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   166
            conn.Event(self.DBG_LINE,'SUCCESSFULL RECEIVE',self._streams[sid])
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   167
            del self._streams[sid]
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   168
        else: conn.send(Error(stanza,ERR_ITEM_NOT_FOUND))
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   169
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   170
    def StreamBrokenHandler(self,conn,stanza):
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   171
        """ Handle stream closure due to all some error while receiving data.
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   172
            Raise xmpppy event specifying unsuccessfull data receive. """
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   173
        syn_id=stanza.getID()
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   174
        self.DEBUG('StreamBrokenHandler called syn_id->%s'%syn_id,'info')
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   175
        for sid in self._streams.keys():
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   176
            stream=self._streams[sid]
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   177
            if stream['syn_id']==syn_id:
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   178
                if stream['direction'][0]=='<': conn.Event(self.DBG_LINE,'ERROR ON RECEIVE',stream)
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   179
                else: conn.Event(self.DBG_LINE,'ERROR ON SEND',stream)
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   180
                del self._streams[sid]
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   181
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   182
    def StreamOpenReplyHandler(self,conn,stanza):
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   183
        """ Handle remote side reply about is it agree or not to receive our datastream.
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   184
            Used internally. Raises xmpppy event specfiying if the data transfer
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   185
            is agreed upon."""
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   186
        syn_id=stanza.getID()
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   187
        self.DEBUG('StreamOpenReplyHandler called syn_id->%s'%syn_id,'info')
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   188
        for sid in self._streams.keys():
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   189
            stream=self._streams[sid]
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   190
            if stream['syn_id']==syn_id:
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   191
                if stanza.getType()=='error':
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   192
                    if stream['direction'][0]=='<': conn.Event(self.DBG_LINE,'ERROR ON RECEIVE',stream)
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   193
                    else: conn.Event(self.DBG_LINE,'ERROR ON SEND',stream)
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   194
                    del self._streams[sid]
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   195
                elif stanza.getType()=='result':
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   196
                    if stream['direction'][0]=='|':
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   197
                        stream['direction']=stream['direction'][1:]
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   198
                        conn.Event(self.DBG_LINE,'STREAM COMMITTED',stream)
93b25987d3e5 Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   199
                    else: conn.send(Error(stanza,ERR_UNEXPECTED_REQUEST))