diff options
Diffstat (limited to 'kopete/protocols/msn/msnsocket.cpp')
-rw-r--r-- | kopete/protocols/msn/msnsocket.cpp | 1099 |
1 files changed, 0 insertions, 1099 deletions
diff --git a/kopete/protocols/msn/msnsocket.cpp b/kopete/protocols/msn/msnsocket.cpp deleted file mode 100644 index 2bb33c97..00000000 --- a/kopete/protocols/msn/msnsocket.cpp +++ /dev/null @@ -1,1099 +0,0 @@ -/* - msnsocket.cpp - Base class for the sockets used in MSN - - Copyright (c) 2002-2003 by Martijn Klingens <klingens@kde.org> - Copyright (c) 2002-2005 by Olivier Goffart <ogoffart at kde.org> - Copyright (c) 2005 by Gregg Edghill <gregg.edghill@gmail.com> - - Kopete (c) 2002-2005 by the Kopete developers <kopete-devel@kde.org> - - Portions of this code are taken from KMerlin, - (c) 2001 by Olaf Lueg <olueg@olsd.de> - - ************************************************************************* - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - ************************************************************************* -*/ - -#include "msnsocket.h" -//#include "msnprotocol.h" - -#include <tqregexp.h> -#include <tqtimer.h> - -#include <kdebug.h> -#include <tdeconfig.h> -#include <kbufferedsocket.h> -#include <kserversocket.h> -#include <kresolver.h> -#include <tdelocale.h> -#include <tdemessagebox.h> -#include <kurl.h> - -#include "kopeteuiglobal.h" - -using namespace KNetwork; - -class MimeMessage -{ - public: - MimeMessage(const TQString &msg) : message(msg) {} - - TQString getValue(const TQString &key) - { - TQRegExp rx(key+": ([^\r\n]+)"); - rx.search(message); - return rx.cap(1); - } - private: - TQString message; -}; - -MSNSocket::MSNSocket(TQObject* parent) : TQObject (parent) -{ - m_onlineStatus = Disconnected; - m_socket = 0L; - m_useHttp = false; - m_timer = 0L; -} - -MSNSocket::~MSNSocket() -{ - //if ( m_onlineStatus != Disconnected ) - // disconnect(); - delete m_timer; - m_timer = 0L; - doneDisconnect(); - if ( m_socket ) - m_socket->deleteLater(); -} - -void MSNSocket::connect( const TQString &server, uint port ) -{ - if ( m_onlineStatus == Connected || m_onlineStatus == Connecting ) - { - kdWarning( 14140 ) << k_funcinfo << "Already connected or connecting! Not connecting again." << endl; - return; - } - - if( m_onlineStatus == Disconnecting ) - { - // Cleanup first. - // FIXME: More generic!!! - kdWarning( 14140 ) << k_funcinfo << "We're still disconnecting! Deleting socket the hard way first." << endl; - delete m_socket; - } - - setOnlineStatus( Connecting ); - m_id = 0; - //m_lastId = 0; - m_waitBlockSize = 0; - m_buffer = Buffer( 0 ); - - //m_sendQueue.clear(); - - m_server = server; - m_port = port; - - if(!m_useHttp) - m_socket = new TDEBufferedSocket( server, TQString::number(port) ); - else { - m_socket = new TDEBufferedSocket( m_gateway, "80" ); - } - - m_socket->enableRead( true ); - - // enableWrite eats the CPU, and we only need it when the queue is - // non-empty, so disable it until we have actual data in the queue - m_socket->enableWrite( false ); - - TQObject::connect( m_socket, TQT_SIGNAL( readyRead() ), this, TQT_SLOT( slotDataReceived() ) ); - TQObject::connect( m_socket, TQT_SIGNAL( readyWrite() ), this, TQT_SLOT( slotReadyWrite() ) ); - TQObject::connect( m_socket, TQT_SIGNAL( hostFound() ), this, TQT_SLOT( slotHostFound() ) ); - TQObject::connect( m_socket, TQT_SIGNAL( connected( const KResolverEntry&) ), this, TQT_SLOT( slotConnectionSuccess() ) ); - TQObject::connect( m_socket, TQT_SIGNAL( gotError( int ) ), this, TQT_SLOT( slotSocketError( int ) ) ); - TQObject::connect( m_socket, TQT_SIGNAL( closed( ) ), this, TQT_SLOT( slotSocketClosed( ) ) ); - - if(m_useHttp) - { - if(m_timer == 0L) - { - m_timer = new TQTimer(this, "Http poll timer"); - // Connect the slot HttpPoll with the timer timeout signal. - TQObject::connect(m_timer, TQT_SIGNAL(timeout()), this, TQT_SLOT(slotHttpPoll())); - } - } - - aboutToConnect(); - - // start the asynchronous connection - m_socket->connect(); -} - -void MSNSocket::disconnect() -{ - if(m_useHttp) - if(m_timer->isActive()) { - // If the timer is still active, stop the timer. - m_timer->stop(); - } - - if ( m_socket ) - m_socket->closeNow(); - else - slotSocketClosed(); -} - -void MSNSocket::aboutToConnect() -{ - /* Empty default implementation */ -} - -void MSNSocket::doneConnect() -{ - setOnlineStatus( Connected ); -} - -void MSNSocket::doneDisconnect() -{ - setOnlineStatus( Disconnected ); -} - -void MSNSocket::setOnlineStatus( MSNSocket::OnlineStatus status ) -{ - if ( m_onlineStatus == status ) - return; - - m_onlineStatus = status; - emit onlineStatusChanged( status ); -} - -void MSNSocket::slotSocketError( int error ) -{ - kdWarning( 14140 ) << k_funcinfo << "Error: " << error << " (" << m_socket->TDESocketBase::errorString() << ")" << endl; - - if(!TDESocketBase::isFatalError(error)) - return; - //we only care about fatal error - - TQString errormsg = i18n( "There was an error while connecting to the MSN server.\nError message:\n" ); - if ( error == TDESocketBase::LookupFailure ) - errormsg += i18n( "Unable to lookup %1" ).arg( m_socket->peerResolver().nodeName() ); - else - errormsg += m_socket->TDESocketBase::errorString() ; - - //delete m_socket; - m_socket->deleteLater(); - m_socket = 0L; - - setOnlineStatus( Disconnected ); - emit connectionFailed(); - //like if the socket is closed - emit socketClosed(); - - emit errorMessage( ErrorConnectionError, errormsg ); -} - -void MSNSocket::slotDataReceived() -{ - int avail = m_socket->bytesAvailable(); - if ( avail < 0 ) - { - // error! - kdWarning( 14140 ) << k_funcinfo << "bytesAvailable() returned " << avail - << ". This should not happen!" << endl - << "Are we disconnected? Backtrace:" << endl << kdBacktrace() << endl; - return; - } - - // incoming data, plus an extra char where we pretend a NUL is so the conversion - // to TQCString doesn't go over the end of the allocated memory. - char *buffer = new char[ avail + 1 ]; - int ret = m_socket->readBlock( buffer, avail ); - - if ( ret < 0 ) - { - kdWarning( 14140 ) << k_funcinfo << "readBlock() returned " << ret << "!" <<endl; - } - else if ( ret == 0 ) - { - kdWarning( 14140 ) << k_funcinfo << "readBlock() returned no data!" <<endl; - } - else - { - if ( avail ) - { - if ( ret != avail) - { - kdWarning( 14140 ) << k_funcinfo << avail << " bytes were reported available, " - << "but readBlock() returned only " << ret << " bytes! Proceeding anyway." << endl; - } - } - else - { - kdDebug( 14140 ) << k_funcinfo << "Read " << ret << " bytes into 4kb block." << endl; - } - - - TQString rawData; - - if(m_useHttp) - { - bool error = false; - TQByteArray bytes; - - // Check if all data has arrived. - rawData = TQString(TQCString(buffer, avail + 1)); - bool headers = (rawData.find(TQRegExp("HTTP/\\d\\.\\d (\\d+) ([^\r\n]+)")) != -1); - - if(headers) - { - // The http header packet arrived. - int endOfHeaders = rawData.find("\r\n\r\n"); - if((endOfHeaders + 4) == avail) - { - // Only the response headers data is included. - TQRegExp re("Content-Length: ([^\r\n]+)"); - if(re.search(rawData) != -1) - { - bool valid; - int l = re.cap(1).toInt(&valid); - if(valid && l > 0) - { - // The packet contains the headers but does not contain the content data; - // buffer the data received and read again. - m_buffer.add(buffer, avail); - - delete[] buffer; - // Update how much data remains. - m_remaining = l; - return; - } - } - } - } - else - { - // Write the received data to the buffer. - m_buffer.add(buffer, avail); - - m_remaining -= avail; - if(m_remaining != 0) - { - // We have not received all the content data, read again. - delete[] buffer; - return; - } - - // At this point, we have all the bytes returned from the web request. - bytes = m_buffer.take(m_buffer.size()); - } - - if(bytes.size() == 0) - { - // The response headers and the content came in one packet. - bytes.assign(buffer, avail); - } - - - // Create the web response object from the response bytes. - WebResponse response(bytes); - - if(response.getStatusCode() == 100) { - return; - } - - if(response.getStatusCode() == 200) - { - // If we received a valid response, read the required headers. - // Retrieve the X-MSN-Messenger header. - TQString header = response.getHeaders()->getValue("X-MSN-Messenger"); - - TQStringList parts = TQStringList::split(";", header.replace(" ", "")); - if(!header.isNull() && (parts.count() >= 2)) - { - if(parts[0].find("SessionID", 0) != -1) - { - // Assign the session id. - m_sessionId = parts[0].section("=", 1, 1); - }else - error = true; - - if(parts[1].find("GW-IP", 0) != -1) - { - // Assign the gateway IP address. - m_gwip = parts[1].section("=", 1, 1); - }else - error = true; - - - if(parts.count() > 2) - if((parts[2].find("Session", 0) != -1) && (parts[2].section("=", 1, 1) == "close")) - { - // The http session has been closed by the server, disconnect. - kdDebug(14140) << k_funcinfo << "Session closed." << endl; - m_bCanPoll = false; - disconnect(); - return; - } - }else - error = true; - - // Retrieve the content length header. - header = response.getHeaders()->getValue("Content-Length"); - - if(!header.isNull()) - { - bool valid; - int length = header.toInt(&valid); - if(valid && (length == 0)) - { - // If the response content length is zero, there is nothing to do. - m_pending = false; - return; - } - - if(valid && (length > 0)) - { - // Otherwise, if the content length is greater than zero, get the web response stream. - TQDataStream *stream = response.getResponseStream(); - buffer = new char[length]; - // Read the web response content. - stream->readRawBytes(buffer, length); - ret = length; - }else - error = true; - }else - error = true; - }else - error = true; - - if(error) - { - kdDebug(14140) << k_funcinfo << "Http error: " << response.getStatusCode() << " " - << response.getStatusDescription() << endl; - - // If we encountered an error, disconnect and return. - m_bCanPoll = false; - // Disconnect from the service. - disconnect(); - return; - } - } - - // Simple check to avoid dumping the binary data from the icons and emoticons to kdDebug: - // all MSN commands start with one or more uppercase characters. - // For now just check the first three chars, let's see how accurate it is. - // Additionally, if we receive an MSN-P2P packet, strip off anything after the P2P header. - rawData = TQString( TQCString( buffer, ((!m_useHttp)? avail : ret) + 1 ) ).stripWhiteSpace().replace( - TQRegExp( "(P2P-Dest:.[a-zA-Z@.]*).*" ), "\\1\n\n(Stripped binary data)" ); - - bool isBinary = false; - for ( uint i = 0; i < 3 ; ++i ) - { - if ( (rawData[ i ] < 'A' || rawData[ i ] > 'Z') && (rawData[ i ] < '0' || rawData[ i ] > '9') ) - isBinary = true; - } - - if ( isBinary ) - kdDebug( 14141 ) << k_funcinfo << "(Stripped binary data)" << endl; - else - kdDebug( 14141 ) << k_funcinfo << rawData << endl; - - // fill the buffer with the received data - m_buffer.add( buffer, ret ); - - slotReadLine(); - - if(m_useHttp) { - // Set data pending to false. - m_pending = false; - } - } - - // Cleanup. - delete[] buffer; -} - -void MSNSocket::slotReadLine() -{ - // We have data, first check if it's meant for a block read, otherwise - // parse the first line (which will recursively parse the other lines) - if ( !pollReadBlock() ) - { - if ( m_buffer.size() >= 3 && ( m_buffer.data()[ 0 ] == '\0' || m_buffer.data()[ 0 ]== '\1' ) ) - { - bytesReceived( m_buffer.take( 3 ) ); - TQTimer::singleShot( 0, this, TQT_SLOT( slotReadLine() ) ); - return; - } - - int index = -1; - for ( uint x = 0; m_buffer.size() > x + 1; ++x ) - { - if ( ( m_buffer[ x ] == '\r' ) && ( m_buffer[ x + 1 ] == '\n' ) ) - { - index = x; - break; - } - } - - if ( index != -1 ) - { - TQString command = TQString::fromUtf8( m_buffer.take( index + 2 ), index ); - command.replace( "\r\n", "" ); - //kdDebug( 14141 ) << k_funcinfo << command << endl; - - // Don't block the GUI while parsing data, only do a single line! - // (Done before parseLine() to prevent a potential crash) - TQTimer::singleShot( 0, this, TQT_SLOT( slotReadLine() ) ); - - parseLine( command ); - // WARNING: At this point 'this' can be deleted (when disconnecting) - } - } -} - -void MSNSocket::readBlock( uint len ) -{ - if ( m_waitBlockSize ) - { - kdWarning( 14140 ) << k_funcinfo << "Cannot wait for data block: still waiting for other block of size " - << m_waitBlockSize << "! Data will not be returned." << endl; - return; - } - - m_waitBlockSize = len; - - //kdDebug( 14140 ) << k_funcinfo << "Preparing for block read of size " << len << endl; - - // Try to return the data now, if available. Otherwise slotDataReady - // will do this whenever all data is there. - pollReadBlock(); -} - -bool MSNSocket::pollReadBlock() -{ - if ( !m_waitBlockSize ) - { - return false; - } - else if ( m_buffer.size() < m_waitBlockSize ) - { - kdDebug( 14140 ) << k_funcinfo << "Waiting for data. Received: " << m_buffer.size() << ", required: " << m_waitBlockSize << endl; - return true; - } - - TQByteArray block = m_buffer.take( m_waitBlockSize ); - - //kdDebug( 14140 ) << k_funcinfo << "Successfully read block of size " << m_waitBlockSize << endl; - - m_waitBlockSize = 0; - emit blockRead( block); - - return false; -} - -void MSNSocket::parseLine( const TQString &str ) -{ - TQString cmd = str.section( ' ', 0, 0 ); - TQString data = str.section( ' ', 2 ).replace( "\r\n" , "" ); - - bool isNum; - uint id = str.section( ' ', 1, 1 ).toUInt( &isNum ); - - // In some rare cases, like the 'NLN' / 'FLN' commands no id at all - // is sent. Here it's actually a real parameter... - if ( !isNum ) - data = str.section( ' ', 1, 1 ) + " " + data; - - //if ( isNum && id ) - // m_lastId = id; - - //kdDebug( 14140 ) << k_funcinfo << "Parsing command " << cmd << " (ID " << id << "): '" << data << "'" << endl; - - data.replace( "\r\n", "" ); - bool isError; - uint errorCode = cmd.toUInt( &isError ); - if ( isError ) - handleError( errorCode, id ); - else - parseCommand( cmd, id, data ); -} - -void MSNSocket::handleError( uint code, uint /* id */ ) -{ - kdDebug(14140) << k_funcinfo << endl; - TQString msg; - ErrorType type = ErrorServerError; - switch ( code ) - { -/* - // We cant show message for error we don't know what they are or not related to the correct socket - // Theses following messages are not so instructive - case 205: - msg = i18n ( "An invalid username has been specified.\nPlease correct it, and try to reconnect.\n" ); - break; - case 201: - msg = i18n ( "Fully Qualified domain name missing.\n" ); - break; - case 207: - msg = i18n ( "You are already logged in!\n" ); - break; - case 208: - msg = i18n ( "You specified an invalid username.\nPlease correct it, and try to reconnect.\n"); - break; - case 209: - msg = i18n ( "Your nickname is invalid. Please check it, correct it,\nand try to reconnect.\n" ); - break; - case 210: - msg = i18n ( "Your list has reached its maximum capacity.\nNo more contacts can be added, unless you remove some first.\n" ); - break; - case 216: - msg = i18n ( "This user is not in your contact list.\n " ); - break; - case 300: - msg = i18n ( "Some required fields are missing. Please fill them in and try again.\n" ); - break; - case 302: - msg = i18n ( "You are not logged in.\n" ); - break; -*/ - case 500: - msg = i18n ( "An internal server error occurred. Please try again later." ); - type = MSNSocket::ErrorCannotConnect; - break; - case 502: - msg = i18n ( "It is no longer possible to perform this operation. The MSN server does not allow it anymore." ); - type = MSNSocket::ErrorServerError; - break; - case 600: - case 910: - case 912: - case 921: - case 922: - msg = i18n ( "The MSN server is busy. Please try again later." ); - type = MSNSocket::ErrorConnectionError; - break; - case 601: - case 604: - case 605: - case 914: - case 915: - case 916: - case 917: - msg = i18n ( "The server is not available at the moment. Please try again later." ); - type = MSNSocket::ErrorCannotConnect; - break; - // Server error - default: - // FIXME: if the error causes a disconnect, it will crash, but we can't disconnect every time - msg = i18n( "Unhandled MSN error code %1 \n" - "Please fill a bug report with a detailed description and if possible the last console debug output." ).arg( code ); - // "See http://www.hypothetic.org/docs/msn/basics.php for a description of all error codes." - break; - } - - if ( !msg.isEmpty() ) - emit errorMessage( type, msg ); - - return; -} - -int MSNSocket::sendCommand( const TQString &cmd, const TQString &args, bool addId, const TQByteArray &body, bool binary ) -{ - if ( !m_socket ) - { - kdWarning( 14140 ) << k_funcinfo << "m_socket == NULL!" << endl; - return -1; - } - - TQCString data = cmd.utf8(); - if ( addId ) - data += " " + TQString::number( m_id ).utf8(); - - if ( !args.isEmpty() ) - data += " " + args.utf8(); - - // Add length in bytes, not characters - if ( !body.isEmpty() ) - data += " " + TQString::number( body.size() - (binary ? 0 : 1 ) ).utf8(); - - data += "\r\n"; - - - // the command will be sent in slotReadyWrite - TQByteArray bytes; - const uint length = data.length(); - bytes.duplicate(data.data(), length); - if(!body.isEmpty()) - { - uint l = body.size() - (binary ? 0 : 1); - bytes.resize(length + l); - for(uint i=0; i < l; i++) - bytes[length + i] = body[i]; - } - - // Add the request to the queue. - m_sendQueue.append(bytes); - m_socket->enableWrite(true); - - if ( addId ) - { - ++m_id; - return m_id - 1; - } - - return 0; -} - -void MSNSocket::slotReadyWrite() -{ - if ( !m_sendQueue.isEmpty() ) - { - // If the command queue is not empty, retrieve the first command. - TQValueList<TQByteArray>::Iterator it = m_sendQueue.begin(); - - if(m_useHttp) - { - // If web response data is not pending, send the http request. - if(!m_pending) - { - m_pending = true; - // Temporarily disable http polling. - m_bCanPoll = false; - // Set the host to the msn gateway by default. - TQString host = m_gateway; - TQString query; // Web request query string. - - if(m_bIsFirstInTransaction) - { - query.append("Action=open&Server="); - query.append(m_type); - - query += "&IP=" + m_server; - - m_bIsFirstInTransaction = false; - } - else - { - // If this is not the first request sent in the transaction, - // only add the session Id. - host = m_gwip; - query += "SessionID=" + m_sessionId; - } - - // Create the web request headers. - TQString s = makeHttpRequestString(host, query, (*it).size()); - - uint length = s.length(); - // Create the web request bytes. - TQByteArray bytes(length + (*it).size()); - - // Copy the request headers into the request bytes. - for(uint i=0; i < length; i++) - bytes[i] = s.ascii()[i]; - // Copy the request body into the request bytes. - for(uint i=0; i < (*it).size(); i++) - bytes[length + i] = (*it)[i]; - - kdDebug( 14141 ) << k_funcinfo << "Sending http command: " << TQString(*it).stripWhiteSpace() << endl; - - // Write the request bytes to the socket. - m_socket->writeBlock(bytes.data(), bytes.size()); - - // Remove the request from the request queue. - m_sendQueue.remove(it); - - if(m_sendQueue.isEmpty()) - { - // Disable sending requests. - m_socket->enableWrite(false); - // If the request queue is empty, poll the server. - m_bCanPoll = true; - } - } - } - else - { - // Otherwise, send the command normally. - - // Simple check to avoid dumping the binary data from the icons and emoticons to kdDebug: - // When sending an MSN-P2P packet, strip off anything after the P2P header. - TQString debugData = TQString( *it ).stripWhiteSpace().replace( - TQRegExp( "(P2P-Dest:.[a-zA-Z@.]*).*" ), "\\1\n\n(Stripped binary data)" ); - kdDebug( 14141 ) << k_funcinfo << "Sending command: " << debugData << endl; - - m_socket->writeBlock( *it, ( *it ).size() ); - m_sendQueue.remove( it ); - - // If the queue is empty agalin stop waiting for readyWrite signals - // because of the CPU usage - if ( m_sendQueue.isEmpty() ) - m_socket->enableWrite( false ); - } - } - else - { - m_socket->enableWrite( false ); - - if(m_useHttp) - { - // If the request queue is empty, poll the server. - m_bCanPoll = true; - } - } -} - -TQString MSNSocket::escape( const TQString &str ) -{ - //return ( KURL::encode_string( str, 106 ) ); - //It's not needed to encode everything. The official msn client only encode spaces and % - //If we encode more, the size can be longer than excepted. - - int old_length= str.length(); - TQChar *new_segment = new TQChar[ old_length * 3 + 1 ]; - int new_length = 0; - - for ( int i = 0; i < old_length; i++ ) - { - unsigned short character = str[i].unicode(); - - if( character <= 32 || character == '%' ) - { - new_segment[ new_length++ ] = '%'; - - unsigned int c = character / 16; - c += (c > 9) ? ('A' - 10) : '0'; - new_segment[ new_length++ ] = c; - - c = character % 16; - c += (c > 9) ? ('A' - 10) : '0'; - new_segment[ new_length++ ] = c; - } - else - new_segment[ new_length++ ] = str[i]; - } - - TQString result = TQString(new_segment, new_length); - delete [] new_segment; - return result; - -} - -TQString MSNSocket::unescape( const TQString &str ) -{ - TQString str2 = KURL::decode_string( str, 106 ); - //remove msn+ colors code - str2 = str2.replace( TQRegExp("[\\x1-\\x8]"), "" ); // old msn+ colors - // added by kaoul <erwin.kwolek at gmail.com> - str2 = str2.replace( TQRegExp("\\xB7[&@\'#0]"),""); // dot ... - str2 = str2.replace( TQRegExp("\\xB7\\$,?\\d{1,2}"),""); // dot dollar (comma)? 0-99 - - return str2; -} - -void MSNSocket::slotConnectionSuccess() -{ - if(m_useHttp) - { - // If we are connected, set the data pending flag to false, - // and disable http polling. - m_pending = false; - m_bCanPoll = false; - // If we are connected, start the timer. - m_timer->start(2000, false); - } - - //kdDebug( 14140 ) << k_funcinfo << endl; - doneConnect(); -} - -void MSNSocket::slotHostFound() -{ - // nothing to do -} - -void MSNSocket::slotSocketClosed() -{ - kdDebug( 14140 ) << k_funcinfo << "Socket closed. " << endl; - - if ( !m_socket || m_onlineStatus == Disconnected ) - { - kdDebug( 14140 ) << k_funcinfo << "Socket already deleted or already disconnected" << endl; - return; - } - - doneDisconnect(); - - m_buffer = Buffer( 0 ); - //delete m_socket; - m_socket->deleteLater(); - m_socket = 0L; - - emit socketClosed(); -} - -void MSNSocket::slotHttpPoll() -{ - if(m_pending || !m_bCanPoll){ - // If data is pending or poll has been temporary disabled, return. - return; - } - - // Create the http request headers. - const TQCString headers = makeHttpRequestString(m_gwip, "Action=poll&SessionID=" + m_sessionId, 0).utf8(); - m_socket->writeBlock(headers, headers.length()); - // Wait for the response. - m_pending = true; - m_socket->enableWrite(true); -} - -// Used in MSNFileTransferSocket -// FIXME: Why is this here if it's only used for file transfer? - Martijn -void MSNSocket::bytesReceived( const TQByteArray & /* data */ ) -{ - kdWarning( 14140 ) << k_funcinfo << "Unknown bytes were received" << endl; -} - -void MSNSocket::sendBytes( const TQByteArray &data ) -{ - if ( !m_socket ) - { - kdWarning( 14140 ) << k_funcinfo << "Not yet connected" << endl; - return; - } - - m_socket->writeBlock( data, data.size() ); - m_socket->enableWrite( true ); -} - -bool MSNSocket::setUseHttpMethod( bool useHttp ) -{ - if( m_useHttp == useHttp ) - return true; - - if( useHttp ) { - TQString s = TQString( this->className() ).lower(); - if( s == "msnnotifysocket" ) - m_type = "NS"; - else if( s == "msnswitchboardsocket" ) - m_type = "SB"; - else - m_type = TQString(); - - if( m_type.isNull() ) - return false; - - m_bCanPoll = false; - m_bIsFirstInTransaction = true; - m_pending = false; - m_remaining = 0; - m_gateway = "gateway.messenger.hotmail.com"; - } - - if ( m_onlineStatus != Disconnected ) - disconnect(); - - m_useHttp = useHttp; - - return true; -} - -bool MSNSocket::useHttpMethod() const -{ - return m_useHttp; -} - -bool MSNSocket::accept( TDEServerSocket *server ) -{ - if ( m_socket ) - { - kdWarning( 14140 ) << k_funcinfo << "Socket already exists!" << endl; - return false; - } - - m_socket = static_cast<TDEBufferedSocket*>(server->accept()); - - if ( !m_socket ) - { -// kdWarning( 14140 ) << k_funcinfo << "Socket not created. Error nb" << server->error() << " : " << server->errorString() << endl; - return false; - } - - kdDebug( 14140 ) << k_funcinfo << "incoming connection accepted" << endl; - - setOnlineStatus( Connecting ); - - m_id = 0; - //m_lastId = 0; - m_waitBlockSize = 0; - - m_socket->setBlocking( false ); - m_socket->enableRead( true ); - m_socket->enableWrite( true ); - - TQObject::connect( m_socket, TQT_SIGNAL( readyRead() ), this, TQT_SLOT( slotDataReceived() ) ); - TQObject::connect( m_socket, TQT_SIGNAL( readyWrite() ), this, TQT_SLOT( slotReadyWrite() ) ); - TQObject::connect( m_socket, TQT_SIGNAL( closed() ), this, TQT_SLOT( slotSocketClosed() ) ); - TQObject::connect( m_socket, TQT_SIGNAL( gotError( int ) ), this, TQT_SLOT( slotSocketError( int ) ) ); - - doneConnect(); - return true; -} - -TQString MSNSocket::getLocalIP() -{ - if ( !m_socket ) - return TQString(); - - const TDESocketAddress address = m_socket->localAddress(); - - TQString ip = address.nodeName(); - - kdDebug( 14140 ) << k_funcinfo << "IP: " << ip <<endl; - //delete address; - return ip; -} - -MSNSocket::Buffer::Buffer( unsigned int sz ) -: TQByteArray( sz ) -{ -} - -MSNSocket::Buffer::~Buffer() -{ -} - -void MSNSocket::Buffer::add( char *str, unsigned int sz ) -{ - char *b = new char[ size() + sz ]; - for ( uint f = 0; f < size(); f++ ) - b[ f ] = data()[ f ]; - for ( uint f = 0; f < sz; f++ ) - b[ size() + f ] = str[ f ]; - - duplicate( b, size() + sz ); - delete[] b; -} - -TQByteArray MSNSocket::Buffer::take( unsigned blockSize ) -{ - if ( size() < blockSize ) - { - kdWarning( 14140 ) << k_funcinfo << "Buffer size " << size() << " < asked size " << blockSize << "!" << endl; - return TQByteArray(); - } - - TQByteArray rep( blockSize ); - for( uint i = 0; i < blockSize; i++ ) - rep[ i ] = data()[ i ]; - - char *str = new char[ size() - blockSize ]; - for ( uint i = 0; i < size() - blockSize; i++ ) - str[ i ] = data()[ blockSize + i ]; - duplicate( str, size() - blockSize ); - delete[] str; - - return rep; -} - -TQString MSNSocket::makeHttpRequestString(const TQString& host, const TQString& query, uint contentLength) -{ - TQString s( - "POST http://" + host + "/gateway/gateway.dll?" + query + " HTTP/1.1\r\n" + - "Accept: */*\r\n" + - "Accept-Language: en-us\r\n" + - "User-Agent: MSMSGS\r\n" + - "Host: " + host + "\r\n" + - "Proxy-Connection: Keep-Alive\r\n" + - "Connection: Keep-Alive\r\n" + - "Pragma: no-cache\r\n" + - "Content-Type: application/x-msn-messenger\r\n" + - "Content-Length: " + TQString::number(contentLength) + "\r\n" + - "\r\n"); - return s; -} - -MSNSocket::WebResponse::WebResponse(const TQByteArray& bytes) -{ - m_statusCode = 0; - m_stream = 0; - - int headerEnd; - TQString header; - TQString data(TQCString(bytes, bytes.size() + 1)); - - // Parse the HTTP status header - TQRegExp re("HTTP/\\d\\.\\d (\\d+) ([^\r\n]+)"); - headerEnd = data.find("\r\n"); - header = data.left( (headerEnd == -1) ? 20 : headerEnd ); - - re.search(header); - m_statusCode = re.cap(1).toInt(); - m_statusDescription = re.cap(2); - - // Remove the web response status header. - data = data.mid(headerEnd + 2, (data.find("\r\n\r\n") + 2) - (headerEnd + 2)); - // Create a MimeMessage, removing the HTTP status header - m_headers = new MimeMessage(data); - - // Retrieve the contentlength header. - header = m_headers->getValue("Content-Length"); - if(!header.isNull()) - { - bool valid; - int length = header.toInt(&valid); - if(valid && length > 0) - { - // If the content length is valid, and not zero, - // copy the web response content bytes. - int offset = bytes.size() - length; - - TQByteArray content(length); - for(int i=0; i < length; i++) - content[i] = bytes[offset + i]; - // Create the web response stream from the response content bytes. - m_stream = new TQDataStream(content, IO_ReadOnly); - } - } -} - -MSNSocket::WebResponse::~WebResponse() -{ - delete m_headers; - m_headers = 0; - delete m_stream; - m_stream = 0; -} - -MimeMessage* MSNSocket::WebResponse::getHeaders() -{ - return m_headers; -} - -TQDataStream* MSNSocket::WebResponse::getResponseStream() -{ - return m_stream; -} - -int MSNSocket::WebResponse::getStatusCode() -{ - return m_statusCode; -} - -TQString MSNSocket::WebResponse::getStatusDescription() -{ - return m_statusDescription; -} - - -#include "msnsocket.moc" - -// vim: set noet ts=4 sts=4 sw=4: - |