siprofileft.cpp

00001 /*
00002   Copyright (c) 2007 by Jakob Schroeter <js@camaya.net>
00003   This file is part of the gloox library. http://camaya.net/gloox
00004 
00005   This software is distributed under a license. The full license
00006   agreement can be found in the file LICENSE in this distribution.
00007   This software may not be copied, modified, sold or distributed
00008   other than expressed in the named license agreement.
00009 
00010   This software is distributed without any warranty.
00011 */
00012 
00013 
00014 #include "siprofileft.h"
00015 
00016 #include "siprofilefthandler.h"
00017 #include "simanager.h"
00018 #include "dataform.h"
00019 #include "socks5bytestream.h"
00020 #include "socks5bytestreammanager.h"
00021 
00022 #include <cstdlib>
00023 
00024 namespace gloox
00025 {
00026 
00027   SIProfileFT::SIProfileFT( ClientBase* parent, SIProfileFTHandler* sipfth, SIManager* manager,
00028                             SOCKS5BytestreamManager* s5Manager )
00029     : m_parent( parent ), m_manager( manager ), m_handler( sipfth ),
00030       m_socks5Manager( s5Manager ), m_delManager( false ), m_delS5Manager( false ), m_ranged( false )
00031   {
00032     if( !m_manager )
00033     {
00034       m_delManager = true;
00035       m_manager = new SIManager( m_parent );
00036     }
00037 
00038     m_manager->registerProfile( XMLNS_SI_FT, this );
00039 
00040     if( !m_socks5Manager )
00041     {
00042       m_socks5Manager = new SOCKS5BytestreamManager( m_parent, this );
00043       m_delS5Manager = true;
00044     }
00045   }
00046 
00047   SIProfileFT::~SIProfileFT()
00048   {
00049     m_manager->removeProfile( XMLNS_SI_FT );
00050 
00051     if( m_delManager )
00052       delete m_manager;
00053 
00054     if( m_socks5Manager && m_delS5Manager )
00055       delete m_socks5Manager;
00056   }
00057 
00058   const std::string SIProfileFT::requestFT( const JID& to, const std::string& name, long size,
00059                                             const std::string& hash, const std::string& desc,
00060                                             const std::string& date, const std::string& mimetype )
00061   {
00062     if( name.empty() || size <= 0 || !m_manager )
00063       return std::string();
00064 
00065     Tag* file = new Tag( "file", "xmlns", XMLNS_SI_FT );
00066     file->addAttribute( "name", name );
00067     file->addAttribute( "size", size );
00068     if( !hash.empty() )
00069       file->addAttribute( "hash", hash );
00070     if( !date.empty() )
00071       file->addAttribute( "date", date );
00072     if( !desc.empty() )
00073       new Tag( file, "desc", desc );
00074     if( m_ranged )
00075       new Tag( file, "range" );
00076 
00077     Tag* feature = new Tag( "feature", "xmlns", XMLNS_FEATURE_NEG );
00078     DataFormField* dff = new DataFormField( "stream-method", "", "", DataFormField::FieldTypeListSingle );
00079     StringMap sm;
00080     sm["s5b"] = XMLNS_BYTESTREAMS;
00081 //     sm["ibb"] = XMLNS_IBB;
00082 //     sm["oob"] = XMLNS_IQ_OOB;
00083     dff->setOptions( sm );
00084     DataForm df( DataForm::FormTypeForm );
00085     df.addField( dff );
00086     feature->addChild( df.tag() );
00087 
00088     return m_manager->requestSI( this, to, XMLNS_SI_FT, file, feature, mimetype );;
00089   }
00090 
00091   void SIProfileFT::acceptFT( const JID& to, const std::string& id, StreamType type )
00092   {
00093     if( !m_manager )
00094       return;
00095 
00096     Tag* feature = new Tag( "feature", "xmlns", XMLNS_FEATURE_NEG );
00097     DataFormField* dff = new DataFormField( "stream-method" );
00098     switch( type )
00099     {
00100       case FTTypeS5B:
00101         dff->setValue( XMLNS_BYTESTREAMS );
00102         break;
00103 /*      case FTTypeIBB:
00104         dff->setValue( XMLNS_IBB );
00105         break;
00106       case FTTypeOOB:
00107         dff->setValue( XMLNS_IQ_OOB );
00108         break;*/
00109     }
00110     DataForm df( DataForm::FormTypeSubmit );
00111     df.addField( dff );
00112     feature->addChild( df.tag() );
00113 
00114     m_manager->acceptSI( to, id, 0, feature );
00115   }
00116 
00117   void SIProfileFT::declineFT( const JID& to, const std::string& id, SIManager::SIError reason,
00118                                const std::string& text )
00119   {
00120     if( !m_manager )
00121       return;
00122 
00123     m_manager->declineSI( to, id, reason, text );
00124   }
00125 
00126   void SIProfileFT::dispose( SOCKS5Bytestream* s5b )
00127   {
00128     if( m_socks5Manager )
00129       m_socks5Manager->dispose( s5b );
00130   }
00131 
00132   void SIProfileFT::setStreamHosts( StreamHostList hosts )
00133   {
00134     if( m_socks5Manager )
00135       m_socks5Manager->setStreamHosts( hosts );
00136   }
00137 
00138   void SIProfileFT::addStreamHost( const JID& jid, const std::string& host, int port )
00139   {
00140     if( m_socks5Manager )
00141       m_socks5Manager->addStreamHost( jid, host, port );
00142   }
00143 
00144   void SIProfileFT::handleSIRequest( const JID& from, const std::string& id, const std::string& profile,
00145                                      Tag* si, Tag* ptag, Tag* /*fneg*/ )
00146   {
00147     if( profile != XMLNS_SI_FT || !ptag || !si )
00148       return;
00149 
00150     if( m_handler )
00151     {
00152       std::string desc;
00153       long offset = 0;
00154       long length = -1;
00155       if( ptag->hasChild( "desc" ) )
00156         desc = ptag->findChild( "desc" )->cdata();
00157       Tag* r = ptag->findChild( "range" );
00158       if( r )
00159       {
00160         if( r->hasAttribute( "offset" ) )
00161           offset = atol( r->findAttribute( "offset" ).c_str() );
00162         if( r->hasAttribute( "length" ) )
00163           length = atol( r->findAttribute( "length" ).c_str() );
00164       }
00165       const std::string& mt = si->findAttribute( "mime-type" );
00166       m_handler->handleFTRequest( from, id, si->findAttribute( "id" ), ptag->findAttribute( "name" ),
00167                                   atol( ptag->findAttribute( "size" ).c_str() ),
00168                                   ptag->findAttribute( "hash" ), ptag->findAttribute( "date" ),
00169                                   mt.empty() ? "binary/octet-stream" : mt, desc, FTTypeS5B, offset, length );
00170     }
00171   }
00172 
00173   void SIProfileFT::handleSIRequestResult( const JID& from, const std::string& sid,
00174                                            Tag* /*si*/, Tag* /*ptag*/, Tag* fneg )
00175   {
00176 
00177     if( m_socks5Manager && fneg && fneg->hasChild( "x", "xmlns", XMLNS_X_DATA ) )
00178     {
00179       DataForm df( fneg->findChild( "x", "xmlns", XMLNS_X_DATA ) );
00180       DataFormField* dff = df.field( "stream-method" );
00181       if( dff && dff->value() == XMLNS_BYTESTREAMS )
00182       {
00183         // check return value:
00184         m_socks5Manager->requestSOCKS5Bytestream( from, SOCKS5BytestreamManager::S5BTCP, sid );
00185       }
00186     }
00187 
00188 //     if( m_handler )
00189 //       m_handler->handleFTRequestResult( from, sid );
00190   }
00191 
00192   void SIProfileFT::handleSIRequestError( Stanza* stanza, const std::string& sid )
00193   {
00194     if( m_handler )
00195       m_handler->handleFTRequestError( stanza, sid );
00196   }
00197 
00198   void SIProfileFT::handleIncomingSOCKS5BytestreamRequest( const std::string& sid, const JID& /*from*/ )
00199   {
00200 // TODO: check for valid sid/from tuple
00201     m_socks5Manager->acceptSOCKS5Bytestream( sid );
00202   }
00203 
00204   void SIProfileFT::handleIncomingSOCKS5Bytestream( SOCKS5Bytestream* s5b )
00205   {
00206     if( m_handler )
00207       m_handler->handleFTSOCKS5Bytestream( s5b );
00208   }
00209 
00210   void SIProfileFT::handleOutgoingSOCKS5Bytestream( SOCKS5Bytestream *s5b )
00211   {
00212     if( m_handler )
00213       m_handler->handleFTSOCKS5Bytestream( s5b );
00214   }
00215 
00216   void SIProfileFT::handleSOCKS5BytestreamError( Stanza* stanza, const std::string& sid )
00217   {
00218     if( m_handler )
00219       m_handler->handleFTRequestError( stanza, sid );
00220   }
00221 
00222 }

Generated on Sat Nov 10 08:50:27 2007 for gloox by  doxygen 1.5.3-20071008