summaryrefslogtreecommitdiffstats
path: root/kopete/protocols/msn/msnsocket.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kopete/protocols/msn/msnsocket.cpp')
-rw-r--r--kopete/protocols/msn/msnsocket.cpp1099
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:
-