2 msnsocket.h - Base class for the sockets used in MSN
4 Copyright (c) 2002 by Martijn Klingens <klingens@kde.org>
5 Copyright (c) 2002-2004 by Olivier Goffart <ogoffart@kde.org>
6 Copyright (c) 2005 by Gregg Edghill <gregg.edghill@gmail.com>
8 Kopete (c) 2002-2007 by the Kopete developers <kopete-devel@kde.org>
10 Portions of this code are taken from KMerlin,
11 (c) 2001 by Olaf Lueg <olueg@olsd.de>
13 *************************************************************************
15 * This program is free software; you can redistribute it and/or modify *
16 * it under the terms of the GNU General Public License as published by *
17 * the Free Software Foundation; either version 2 of the License, or *
18 * (at your option) any later version. *
20 *************************************************************************
27 #include <qdatastream.h>
28 #include <qstringlist.h>
30 #include <qabstractsocket.h>
33 #include "kopete_export.h"
40 * @author Martijn Klingens <klingens@kde.org>
42 * MSNSocket encapsulates the common functionality shared by the Dispatch
43 * Server, the Notification Server and the Switchboard Server. It is
44 * inherited by the various specialized classes.
46 class KOPETE_MSN_SHARED_EXPORT MSNSocket
: public QObject
51 MSNSocket(QObject
* parent
=0l);
55 * Asynchronously read a block of data of the specified size. When the
56 * data is available, the blockRead() signal will be emitted with the
59 * NOTE: As the block queue takes precedence over the line-based
60 * command-processing this method can effectively block all
61 * communications when passed a wrong length!
63 void read( uint len
);
66 * OnlineStatus encapsulates the 4 states a connection can be in,
67 * Connecting, Connected, Disconnecting, Disconnected. Connecting
68 * and Disconnecting are in the default implementation not used,
69 * because the socket connect is an atomic operation and not yet
70 * performed asynchronously.
71 * In derived classes, like the Notification Server, this state is
72 * actively used, because merely having a socket connection established
73 * by no means indicates we're actually online - the rest of the
74 * handshake likely has to follow first.
76 enum OnlineStatus
{ Connecting
, Connected
, Disconnecting
, Disconnected
};
77 enum LookupStatus
{ Processing
, Success
, Failed
};
78 enum Transport
{ TcpTransport
, HttpTransport
};
79 enum ErrorType
{ ErrorNormal
, ErrorInternal
, ErrorInformation
, ErrorSorry
};
81 OnlineStatus
onlineStatus() { return m_onlineStatus
; }
84 * return the local ip.
85 * Used for filetransfer
91 virtual bool setUseHttpMethod( bool useHttp
);
92 bool useHttpMethod() const;
97 void connect( const QString
&server
, uint port
);
98 virtual void disconnect();
102 * Send an MSN command to the socket
104 * For debugging it's convenient to have this method public, but using
105 * it outside this class is deprecated for any other use!
107 * The size of the body (if any) is automatically added to the argument
108 * list and shouldn't be explicitly specified! This size is in bytes
109 * instead of characters to reflect what actually goes over the wire.
111 * if the param binary is set to true, then, the body is send as a binary message
115 int sendCommand( const QString
&cmd
, const QString
&args
= QString(),
116 bool addId
= true, const QByteArray
&body
= QByteArray() , bool binary
=false );
120 * A block read is ready.
121 * After this the normal line-based reads go on again
123 void blockRead( const QByteArray
&block
);
126 * The online status has changed
128 void onlineStatusChanged( MSNSocket::OnlineStatus status
);
131 * The connection failed
133 void connectionFailed();
136 * The connection was closed
141 * A error has occurred. Handle the display of the message.
143 void errorMessage( int type
, const QString
&msg
);
147 * Convenience method: escape spaces with '%20' for use in the protocol.
148 * Doesn't escape any other sequence.
150 QString
escape( const QString
&str
);
153 * And the other way round...
155 QString
unescape( const QString
&str
);
158 * Set the online status. Emits onlineStatusChanged.
160 void setOnlineStatus( OnlineStatus status
);
163 * This method is called directly before the socket will actually connect.
164 * Override in derived classes to setup whatever is needed before connect.
166 virtual void aboutToConnect();
169 * Directly after the connect, this method is called. The default
170 * implementation sets the OnlineStatus to Connected, be sure to override
171 * this if a handshake is required.
173 virtual void doneConnect();
176 * Directly after the disconnect, this method is called before the actual
177 * cleanup takes place. The socket is close here. Cleanup internal
180 virtual void doneDisconnect();
183 * Handle an MSN error condition.
184 * The default implementation displays a generic error message and
185 * closes the connection. Override to allow more graceful handling and
188 virtual void handleError( uint code
, uint id
);
191 * Handle an MSN command response line.
192 * This method is pure virtual and *must* be overridden in derived
195 virtual void parseCommand( const QString
&cmd
, uint id
,
196 const QString
&data
) = 0;
199 * Used in MSNFileTransferSocket
201 virtual void bytesReceived( const QByteArray
& );
202 bool accept( QTcpServer
* );
203 void sendBytes( const QByteArray
&data
);
205 const QString
&server() { return m_server
; }
206 uint
port() { return m_port
; }
209 * The last confirmed ID by the server
214 void slotDataReceived();
216 * If the socket emits a connectionFailed() then this slot is called
217 * to handle the error.
219 void slotSocketError( QAbstractSocket::SocketError error
);
222 * Calls connectDone() when connection is successfully established.
224 void slotConnectionSuccess();
227 * Check if new lines of data are available and process the first line
231 void slotSocketClosed();
236 * Sends a poll request to the msn gateway when using HttpTransport.
237 * equivalent to sending a PNG command over TcpTransport.
244 virtual void slotReadyWrite();
248 * Check if we're waiting for a block of raw data. Emits blockRead()
249 * when the data is available.
250 * Returns true when still waiting and false when there is no pending
251 * read, or when the read is successfully handled.
253 bool pollReadBlock();
256 * The id of the message sent to the MSN server. This ID will increment
257 * for each subsequent message sent.
262 * Queue of pending commands (should be mostly empty, but is needed to
263 * send more than one command to the server)
265 QList
<QByteArray
> m_sendQueue
;
268 * Parse a single line of data.
269 * Will call either parseCommand or handleError depending on the type of
272 void parseLine( const QString
&str
);
274 QTcpSocket
*m_socket
;
275 OnlineStatus m_onlineStatus
;
281 * The size of the requested block for block-based reads
285 class Buffer
: public QByteArray
288 Buffer( unsigned size
= 0 );
290 QByteArray
take( int size
);
298 * Makes a http request headers string using the specified, host, query, and content length.
299 * return: The string containing the http request headers.
301 QString
makeHttpRequestString(const QString
& host
, const QString
& query
, uint contentLength
);
303 bool m_useHttp
; // Indicates whether to use the msn http gateway to connect to the msn service.
304 bool m_bCanPoll
; // Indicates whether polling of the http server is allowed.
305 bool m_bIsFirstInTransaction
; // Indicates whether pending message to be sent is the first in the transaction.
306 // If so, the gateway is used.
307 // Use the gateway only for initial connected state; Otherwise, use the host.
308 QString m_gateway
; // Msn http gateway domain name.
309 QString m_gwip
; // The ip address of the msn gateway.
310 QString m_sessionId
; // session id.
311 QTimer
*m_timer
; // Msn http poll timer.
312 QString m_type
; // Indicates the type of socket being used. NS or SB
313 bool m_pending
; // Indicates whether a http response is pending.
314 int m_remaining
; // Indicates how many bytes of content data remain
315 // to be received if the content bytes are sent in
316 // a separate packet(s).
319 * Provides access to information returned from a URI request.
324 WebResponse(const QByteArray
& bytes
);
328 * Gets the headers associated with this response from the server.
330 MimeMessage
* getHeaders();
332 * Gets the data stream used to read the body of the response from the server.
334 QDataStream
* getResponseStream();
336 * Gets the status code of the response.
340 * Gets the status description returned with the response.
342 QString
getStatusDescription();
345 MimeMessage
*m_headers
;
346 QDataStream
*m_stream
;
348 QString m_statusDescription
;