msnsockethttp.h

/*************************************************************************** msnsockethttp.h - description ------------------- begin : Thu Apr 4 2008 copyright : (C) 2008 by Valerio Pilo email : valerio@kmess.org ***************************************************************************//*************************************************************************** * * * 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. * * * ***************************************************************************/#ifndef MSNSOCKETHTTP_H#define MSNSOCKETHTTP_H#include "msnsocketbase.h"#include <QHash>#include <QNetworkAccessManager>#include <QNetworkRequest>#include <QStringList>#include <QTime>#include <QTimer>// Forward declarationsclass CurrentAccount;
class QNetworkReply;
class QSslError;
/** * @brief Basic I/O functionality for the MSN server protocol over a HTTP connection. * * This is a low-level class used used by MsnConnection. * The class provides the following facilities: * - HTTP-only connection to the MSN servers, with exclusive usage of ports 80 and 443. * - sending/receiving raw protocol data. * * With HTTP the server has no way of contacting the client by itself. Everytime we * send a request to the server (the "MSN HTTP Gateway"), it will send along with the answer * a full list of messages which we didn't receive yet. So if we've got nothing to send, * we're forced to periodically send 'poll' requests. These are bogus calls which exist only * to allow the gateway to send any new message back. * * In any given moment, there may only be one active message. This means that if we send two * subsequent requests, we will be disconnected immediately with a '400 Bad Request' response. * Therefore, this class implements a 1-item-wide sending window. It's not necessary to apply * it to receiving also, since the server just responds in order. * * Data from the server (the "HTTP Gateway") is handled by the slotDataReceived() slot. * This method receives responses to HTTP requests made by the class; they contain a list of * new undelivered messages. The slotDataReceived() method splits it up to individual commands * and forwards the received commands to MsnConnection individually. * * Simple scheme of requests/responses: * - Got a request to send. Send it immediately. * - Received a response with messages. Have queued requests? * - Yes. Send the next now. * - No. Send a polling request now. * - Received an empty response (without messages). Have queued requests? * - Yes. Send the next now. * - No. What kind of message was last sent? * - A command. Send a poll in 5 seconds. * - A poll. Send another poll in 10 seconds. * * @author Valerio Pilo <valerio@kmess.org> * @ingroup NetworkCore */00075class MsnSocketHttp : publicMsnSocketBase
{
Q_OBJECT
public: // Public methods// The constructorMsnSocketHttp( ServerType serverType );
// The destructor~MsnSocketHttp();
// Connect to the given servervoidconnectToServer( const QString& server = QString(), const quint16 port = 0 );
// Disconnect from the servervoiddisconnectFromServer( bool isTransfer = false );
// Return the local IP address
QString getLocalIp() const;
// Set whether to send pings or notvoidsetSendPings( bool sendPings );
// Write data to the socket without conversions
qint64 writeBinaryData( const QByteArray& data );
// Write data to the socket
qint64 writeData( const QString& data );
private: // Private methods// Clean up the connectionvoidcleanUp();
// Dump the content of requests and repliesvoid dump( void *obj, QByteArray data, bool isRequest );
// Sends the next queued requestvoidsendNextRequest();
// Change the server connection gatewayvoidsetGateway( QString host );
private slots: // Private slots// Send a polling message to the server, to retrieve pending commandsvoidslotQueryServer();
// Read received data and pass along the contained commandsvoidslotReplyReceived( QNetworkReply *reply );
private: // Private structures// Structure to hold all the useful data about an HTTP requeststruct RequestInfo
{
// Special request parameters to be sent along with the data
QString requestQueryString;
// The actual contents of the request
QByteArray data;
};
private: // Private attributes// URL to specify in the queries
QString baseServerPath_;
// State variable to detect whether it's possible or not to send another requestbool canSendRequests_;
// Time at which the last request has been sent
QTime lastRequestTime_;
// Saved gateway address
QString gatewayAddress_;
// The HTTP interface
QNetworkAccessManager *http_;
// true if the last sent request was a polling messagebool lastRequestWasPolling_;
// true if the last received response didn't carry any new commandsbool lastResponseWasEmpty_;
// Time counter to regularly report pings to the application
QDateTime lastPing_;
// Next request's ID
QString nextRequestId_;
// Next request's parameters
QString nextRequestParameters_;
// A timer to regularly query the server for new commands
QTimer pollingTimer_;
// List of requests waiting to be sent
QList<RequestInfo> queuedRequests_;
// Container for never-changing request information
QNetworkRequest requestHeader_;
// Are we sending pings?bool sendPings_;
// Hashmap of non answered requests
QList<QNetworkReply*> unansweredRequests_;
};
#endif