Submitting following changes -
AuthApps for Last.fm and Twitter added
API for checking ServiceAuthorization added for SMFCredMgrClient
API added for forcefully removing credential details from SMFCredMgr
Extra argument checks in SMfClient APIs
APIs for service login and logout from SMFClient
Redundant members removed from SmfServerSymbian
DSM bug fixes
Test Apps included
/**
* Copyright (c) 2010 Sasken Communication Technologies Ltd.
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of the "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html"
*
* Initial Contributors:
* Chandradeep Gandhi, Sasken Communication Technologies Ltd - Initial contribution
*
* Contributors:
* Manasij Roy, Nalina Hariharan
*
* Description:
* The Transport Manager Utility class provides the http/https transaction
* methods for the smf framework
*
*/
// Include files
#define EMULATORTESTING
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QSettings>
#include <zlib.h>
#ifdef EMULATORTESTING
// For proxy settings on emulator only - REMOVE for device
#include <QNetworkProxy>
#endif
#include "smftransportmanagerutil.h"
#include "smfpluginmanager.h"
// Static Global constants
static const char kSmfUserAgent[] = "SmfFrameWork";
static const char kSmfCacheControl[] = "no-cache";
static const char kSmfAcceptEncoding[] = "gzip";
// Static data initialisation
SmfTransportManagerUtil* SmfTransportManagerUtil::m_myInstance = NULL;
/**
* Method to get the instance of SmfTransportManagerUtil class
* @return The instance of SmfTransportManager class
*/
SmfTransportManagerUtil* SmfTransportManagerUtil::getInstance ( )
{
if(NULL == m_myInstance)
m_myInstance = new SmfTransportManagerUtil( );
return m_myInstance;
}
/**
* Constructor with default argument
* @param aParent The parent object
*/
SmfTransportManagerUtil::SmfTransportManagerUtil ( )
: m_networkAccessManager ( this )
{
// Storage of settings (Only data usage as of now)
m_settings = new QSettings("Sasken", "SmfTransportManager");
// Create the settings if no data is stored
if( !m_settings->contains("Sent Data") )
m_settings->setValue("Sent Data", 0);
if( !m_settings->contains("Received Data") )
m_settings->setValue("Received Data", 0);
#ifdef EMULATORTESTING
qDebug()<<"Using PROXY SETTINGS!!!, change for device testing";
// Reading the keys, CSM Stubbed - START
QFile winFile("c:\\data\\DoNotShare.txt");
if (!winFile.open(QIODevice::ReadOnly))
{
qDebug()<<"File to read the windows username and password could not be opened, returning!!!";
return;
}
QByteArray winArr = winFile.readAll();
QList<QByteArray> winList = winArr.split(' ');
winFile.close();
QString httpUser(winList[0]);
QString httpPass(winList[1]);
// For proxy settings on emulator only - REMOVE for device
QString httpProxy = "10.1.0.214";
QString httpPort = "3128";
//==Classes used from Network Module==
QNetworkProxy proxy;
proxy.setType(QNetworkProxy::HttpProxy);
proxy.setHostName(httpProxy);
proxy.setPort(httpPort.toInt());
proxy.setUser(httpUser);
proxy.setPassword(httpPass);
QNetworkProxy::setApplicationProxy(proxy);
#endif
}
/**
* Destructor
*/
SmfTransportManagerUtil::~SmfTransportManagerUtil ( )
{
m_activeNetwReplyList.clear();
if(m_settings)
delete m_settings;
if(m_myInstance)
delete m_myInstance;
}
/**
* Method that does a http GET request. Returns the unique QNetworkReply
* instance for this transaction to the plugin manager to trace the
* proper response.
* @param aRequest The request formed by the plugin
* @param aUrlList The list of accessible Urls for this plugin
* @param aSOPCompliant [out] Output parameter indicating Same Origin
* Policy Compliance. Contains true if the request complies to the policy,
* else false. If it is false, the network request will not performed
* @return The unique QNetworkReply instance for this transaction
*/
QNetworkReply* SmfTransportManagerUtil::get (
QNetworkRequest &aRequest,
const QList<QUrl> &aUrlList,
bool &aSOPCompliant )
{
qDebug()<<"Inside SmfTransportManagerUtil::get()";;
bool found = false;
QString hostName = aRequest.url().host();
// Same Origin Policy checking
// Check if the host name of the url in the request created by the
// plugin is among the authorised url host name list
foreach(QUrl url, aUrlList)
{
if(0 == hostName.compare(url.host()))
{
found = true;
break;
}
}
if(found)
{
aSOPCompliant = true;
// Set header to accept gzip encoded data
aRequest.setRawHeader("Accept-encoding", kSmfAcceptEncoding);
// Set the cache control
aRequest.setRawHeader("Cache-Control", kSmfCacheControl);
// Put the same user agent for all requests sent by Smf
aRequest.setRawHeader("User-Agent", kSmfUserAgent);
QNetworkReply* reply = m_networkAccessManager.get(aRequest);
qDebug()<<"QNetworkReply of get() = "<<(long)reply;
connect(&m_networkAccessManager, SIGNAL(finished(QNetworkReply *)),
this, SLOT(networkReplyFinished(QNetworkReply *)));
connect(&m_networkAccessManager, SIGNAL(error(QNetworkReply::NetworkError)),
this, SLOT(networkReplyError(QNetworkReply::NetworkError)));
m_activeNetwReplyList.append(reply);
return reply;
}
else
{
// Error :: SAME ORIGIN POLICY violation!!!
aSOPCompliant = false;
qDebug()<<"SOP violation";
return NULL;
}
}
/**
* Method that does a http POST request. Returns the unique QNetworkReply
* instance for this transaction to the plugin manager to trace the
* proper response.
* @param aRequest The request formed by the plugin
* @param aPostData The data to be posted via http POST request
* @param aUrlList The list of accessible Urls for this plugin
* @param aSOPCompliant [out] Output parameter indicating Same Origin
* Policy Compliance. Contains true if the request complies to the policy,
* else false. If it is false, the network request will not performed
* @return The unique QNetworkReply instance for this transaction
*/
QNetworkReply* SmfTransportManagerUtil::post (
QNetworkRequest &aRequest,
const QByteArray& aPostData,
const QList<QUrl> &aUrlList,
bool &aSOPCompliant )
{
qDebug()<<"Inside SmfTransportManagerUtil::post()";
bool found = false;
QString hostName = aRequest.url().host();
// Same Origin Policy checking
// Check if the host name of the url in the request created by the
// plugin is among the authorised url host name list
foreach(QUrl url, aUrlList)
{
if(0 == hostName.compare(url.host()))
{
found = true;
break;
}
}
if(found)
{
aSOPCompliant = true;
// Set header to accept gzip encoded data
aRequest.setRawHeader("Accept-encoding", kSmfAcceptEncoding);
// Set the cache control
aRequest.setRawHeader("Cache-Control", kSmfCacheControl);
// Put the same user agent for all requests sent by Smf
aRequest.setRawHeader("User-Agent", kSmfUserAgent);
#ifdef DETAILEDDEBUGGING
qDebug()<<"post data size is = "<<aPostData.size();
qDebug()<<"post data is = "<<QString(aPostData);
#endif
QNetworkReply* reply = m_networkAccessManager.post(aRequest, aPostData);
qDebug()<<"QNetworkReply of post() = "<<(long)reply;
connect(&m_networkAccessManager, SIGNAL(finished(QNetworkReply *)),
this, SLOT(networkReplyFinished(QNetworkReply *)));
connect(&m_networkAccessManager, SIGNAL(error(QNetworkReply::NetworkError)),
this, SLOT(networkReplyError(QNetworkReply::NetworkError)));
m_activeNetwReplyList.append(reply);
return reply;
}
else
{
// Error :: SAME ORIGIN POLICY violation!!!
aSOPCompliant = false;
qDebug()<<"SOP violation";
return NULL;
}
}
/**
* Method that does a http HEAD request. Returns the unique QNetworkReply
* instance for this transaction to the plugin manager to trace the
* proper response.
* @param aRequest The request formed by the plugin
* @param aUrlList The list of accessible Urls for this plugin
* @param aSOPCompliant [out] Output parameter indicating Same Origin
* Policy Compliance. Contains true if the request complies to the policy,
* else false. If it is false, the network request will not performed
* @return The unique QNetworkReply instance for this transaction
*/
QNetworkReply* SmfTransportManagerUtil::head (
QNetworkRequest& aRequest,
const QList<QUrl> &aUrlList,
bool &aSOPCompliant )
{
qDebug()<<"Inside SmfTransportManagerUtil::head()";
bool found = false;
QString hostName = aRequest.url().host();
// Same Origin Policy checking
// Check if the host name of the url in the request created by the
// plugin is among the authorised url host name list
foreach(QUrl url, aUrlList)
{
if(0 == hostName.compare(url.host()))
{
found = true;
break;
}
}
if(found)
{
aSOPCompliant = true;
// Set header to accept gzip encoded data
aRequest.setRawHeader("Accept-encoding", kSmfAcceptEncoding);
// Set the cache control
aRequest.setRawHeader("Cache-Control", kSmfCacheControl);
// Put the same user agent for all requests sent by Smf
aRequest.setRawHeader("User-Agent", kSmfUserAgent);
QNetworkReply* reply = m_networkAccessManager.head(aRequest);
qDebug()<<"QNetworkReply of head() = "<<(long)reply;
connect(&m_networkAccessManager, SIGNAL(finished(QNetworkReply *)),
this, SLOT(networkReplyFinished(QNetworkReply *)));
connect(&m_networkAccessManager, SIGNAL(error(QNetworkReply::NetworkError)),
this, SLOT(networkReplyError(QNetworkReply::NetworkError)));
m_activeNetwReplyList.append(reply);
return reply;
}
else
{
// Error :: SAME ORIGIN POLICY violation!!!
aSOPCompliant = false;
qDebug()<<"SOP violation";
return NULL;
}
}
/**
* Method that does a http PUT request. Returns the unique QNetworkReply
* instance for this transaction to the plugin manager to trace the
* proper response.
* @param aRequest The request formed by the plugin
* @param aPostData The data to be posted via http PUT request
* @param aUrlList The list of accessible Urls for this plugin
* @param aSOPCompliant [out] Output parameter indicating Same Origin
* Policy Compliance. Contains true if the request complies to the policy,
* else false. If it is false, the network request will not performed
* @return The unique QNetworkReply instance for this transaction
*/
QNetworkReply* SmfTransportManagerUtil::put (
QNetworkRequest &aRequest,
const QByteArray& aPostData,
const QList<QUrl> &aUrlList,
bool &aSOPCompliant )
{
qDebug()<<"Inside SmfTransportManagerUtil::put()";
bool found = false;
QString hostName = aRequest.url().host();
// Same Origin Policy checking
// Check if the host name of the url in the request created by the
// plugin is among the authorised url host name list
foreach(QUrl url, aUrlList)
{
if(0 == hostName.compare(url.host()))
{
found = true;
break;
}
}
if(found)
{
aSOPCompliant = true;
// Set header to accept gzip encoded data
aRequest.setRawHeader("Accept-encoding", kSmfAcceptEncoding);
// Set the cache control
aRequest.setRawHeader("Cache-Control", kSmfCacheControl);
// Put the same user agent for all requests sent by Smf
aRequest.setRawHeader("User-Agent", kSmfUserAgent);
QNetworkReply* reply = m_networkAccessManager.put(aRequest, aPostData);
qDebug()<<"QNetworkReply of put() = "<<(long)reply;
connect(&m_networkAccessManager, SIGNAL(finished(QNetworkReply *)),
this, SLOT(networkReplyFinished(QNetworkReply *)));
connect(&m_networkAccessManager, SIGNAL(error(QNetworkReply::NetworkError)),
this, SLOT(networkReplyError(QNetworkReply::NetworkError)));
m_activeNetwReplyList.append(reply);
return reply;
}
else
{
// Error :: SAME ORIGIN POLICY violation!!!
aSOPCompliant = false;
qDebug()<<"SOP violation";
return NULL;
}
}
/**
* Method that does a http DELETE request. Returns the unique QNetworkReply
* instance for this transaction to the plugin manager to trace the
* proper response.
* @param aRequest The request formed by the plugin
* @param aUrlList The list of accessible Urls for this plugin
* @param aSOPCompliant [out] Output parameter indicating Same Origin
* Policy Compliance. Contains true if the request complies to the policy,
* else false. If it is false, the network request will not performed
* @return The unique QNetworkReply instance for this transaction
*/
QNetworkReply* SmfTransportManagerUtil::deleteResource (
QNetworkRequest &aRequest,
const QList<QUrl> &aUrlList,
bool &aSOPCompliant )
{
qDebug()<<"Inside SmfTransportManagerUtil::deleteResource()";
bool found = false;
QString hostName = aRequest.url().host();
// Same Origin Policy checking
// Check if the host name of the url in the request created by the
// plugin is among the authorised url host name list
foreach(QUrl url, aUrlList)
{
if(0 == hostName.compare(url.host()))
{
found = true;
break;
}
}
if(found)
{
aSOPCompliant = true;
// Set header to accept gzip encoded data
aRequest.setRawHeader("Accept-encoding", kSmfAcceptEncoding);
// Set the cache control
aRequest.setRawHeader("Cache-Control", kSmfCacheControl);
// Put the same user agent for all requests sent by Smf
aRequest.setRawHeader("User-Agent", kSmfUserAgent);
QNetworkReply* reply = m_networkAccessManager.deleteResource(aRequest);
qDebug()<<"QNetworkReply of deleteResource() = "<<(long)reply;
connect(&m_networkAccessManager, SIGNAL(finished(QNetworkReply *)),
this, SLOT(networkReplyFinished(QNetworkReply *)));
connect(&m_networkAccessManager, SIGNAL(error(QNetworkReply::NetworkError)),
this, SLOT(networkReplyError(QNetworkReply::NetworkError)));
m_activeNetwReplyList.append(reply);
return reply;
}
else
{
// Error :: SAME ORIGIN POLICY violation!!!
aSOPCompliant = false;
qDebug()<<"SOP violation";
return NULL;
}
}
/**
* Method that cancels the service request by cancelling the current
* http transaction.
* @param aCancelReply The QNetworkReply instance whose transaction
* has to be cancelled
* @return Returns true for success, else false
*/
bool SmfTransportManagerUtil::cancelRequest (
QNetworkReply *aCancelReply )
{
qDebug()<<"Inside SmfTransportManagerUtil::cancelRequest()";
// Checks if this transaction is running
if( aCancelReply->isRunning() )
{
// Aborts the running transaction
aCancelReply->abort();
}
// Close the connection
aCancelReply->close();
int index = m_activeNetwReplyList.indexOf(aCancelReply);
if( index >= 0 )
m_activeNetwReplyList.removeAt(index);
return true;
}
/*
* Method that is called whenever a new network configuration is added to the system.
* @param aResult SmfTransportResult
*/
void SmfTransportManagerUtil::configurationAdded ( const SmfTransportResult &aResult )
{
// Inform PM and plugins that a new IAP ia added, and hence resend the request
SmfPluginManager::getInstance()->responseAvailable ( aResult, NULL, NULL );
}
/*
* Method that is called when the state of the network configuration changes.
* @param aResult SmfTransportResult
*/
void SmfTransportManagerUtil::configurationChanged ( const SmfTransportResult &aResult )
{
// Inform PM and plugins that the IAP is changed, and hence resend the request
SmfPluginManager::getInstance()->responseAvailable ( aResult, NULL, NULL );
}
/*
* Method that is called when a configuration is about to be removed from the system.
* The removed configuration is invalid but retains name and identifier.
* @param aResult SmfTransportResult
*/
void SmfTransportManagerUtil::configurationRemoved ( const SmfTransportResult &aResult )
{
// Inform PM and plugins that the IAP is to be deleted, and
// hence resend the request
SmfPluginManager::getInstance()->responseAvailable ( aResult, NULL, NULL );
}
/**
* Method to indicate the http transaction has finished.
* @param aNetworkReply The QNetworkReply instance for which the http
* transaction was made
*/
void SmfTransportManagerUtil::networkReplyFinished ( QNetworkReply *aNetworkReply )
{
qDebug()<<"Inside SmfTransportManagerUtil::networkReplyFinished()";
qDebug()<<"QNetworkReply = "<<(long)aNetworkReply;
qDebug()<<"QNetworkReply error code = "<<aNetworkReply->error();
// remove the QNetworkReply instance from the list of outstanding transactions
int index = m_activeNetwReplyList.indexOf(aNetworkReply);
if( index >= 0 )
m_activeNetwReplyList.removeAt(index);
// indicate the result of transaction to the plugin manager
SmfTransportResult trResult;
convertErrorType(aNetworkReply->error(), trResult);
// Read the response from the device
QByteArray response = aNetworkReply->readAll();
qDebug()<<"Response size is = "<<response.size();
#ifdef DETAILEDDEBUGGING
qDebug()<<"Response is = "<<QString(response);
#endif
// Store the number of bytes of data received
bool converted = false;
quint64 data = m_settings->value("Received Data").toULongLong(&converted);
if(converted)
{
data += response.size();
m_settings->setValue("Received Data", data);
}
SmfError error = SmfUnknownError;
QByteArray *arr = NULL;
#ifdef DETAILEDDEBUGGING
foreach(QByteArray arr, aNetworkReply->rawHeaderList())
qDebug()<<QString(arr)<<" = "<<QString(aNetworkReply->rawHeader(arr));
#endif
// Check if the http response header has the raw header "Content-Encoding:gzip"
bool gzipEncoded = false;
QByteArray headerKey("Content-Encoding");
if(aNetworkReply->hasRawHeader(headerKey))
{
qDebug()<<"Content-Encoding:"<<QString(aNetworkReply->rawHeader(headerKey));
// If http response header has the raw header "Content-Encoding:gzip"
if( "gzip" == QString(aNetworkReply->rawHeader(headerKey)))
{
QByteArray firstByte(1, response[0]);
QByteArray secondByte(1, response[1]);
#ifdef DETAILEDDEBUGGING
qDebug()<<"first byte : "<<QString(firstByte.toHex());
qDebug()<<"second byte : "<<QString(secondByte.toHex());
#endif
// And the header says the response is a valid gzip data.
// If so, inflate the gzip deflated data
if((QString("1f") == QString(firstByte.toHex())) && (QString("8b") == QString(secondByte.toHex())) )
{
gzipEncoded = true;
qDebug()<<"Response is gzip encoded!!! = "<<gzipEncoded;
arr = inflateResponse(response, error);
if(!arr)
trResult = SmfTransportOpGzipError;
}
else
{
qDebug()<<"Header says gzip encoded, but response is not a valid data, so ignoring the header!!!";
arr = new QByteArray(response);
}
}
else
{
qDebug()<<"Unsupported encoding format!!! - error";
trResult = SmfTransportOpUnsupportedContentEncodingFormat;
}
}
else
{
qDebug()<<"Response is not gzip encoded";
arr = new QByteArray(response);
}
// Write the uncompressed data to a file
#ifdef DETAILEDDEBUGGING
if(arr)
{
QFile file1("c:\\data\\networkResponse.txt");
if (!file1.open(QIODevice::WriteOnly))
qDebug()<<"File to write the network response could not be opened";
file1.write(*arr);
file1.close();
}
#endif
SmfPluginManager::getInstance()->responseAvailable ( trResult, aNetworkReply, arr );
}
/**
* Method to inflate a gzipped network response.
* @param aResponse The QByteArray holding the gzip encoded data
* @param aError Argument indicating error
* @return a QByteArray* containing the inflated data. If inflation fails,
* NULL is returned
*/
QByteArray* SmfTransportManagerUtil::inflateResponse ( QByteArray &aResponse, SmfError& aError )
{
qDebug()<<"Inside SmfTransportManagerUtil::inflateResponse()";
// Read the response from the device
qDebug()<<"Encoded response content size = "<<aResponse.size();
if(aResponse.size() <= 0)
{
aError = SmfTMUnknownContentError;
return NULL;
}
// Get the uncompressed size of the response (last 4 bytes of the compressed data as per GZIP format spec)
QByteArray sizeStr;
for(int count = 1 ; count <= 4 ; count++)
sizeStr.append(aResponse[aResponse.size()-count]);
#ifdef DETAILEDDEBUGGING
qDebug()<<"Size string as a string = "<<QString(sizeStr.toHex());
#endif
bool ok = false;
int uncomSize = sizeStr.toHex().toInt(&ok, 16);
qDebug()<<"Size of uncompressed data = "<<uncomSize;
// Initialize the data required for zlib method call
z_stream stream;
unsigned char *out = new unsigned char[uncomSize];
if(out)
qDebug()<<"Memory allocated for output buffer";
else
{
//Error
qDebug()<<"Memory not allocated for output buffer!!!";
aError = SmfMemoryAllocationFailure;
return NULL;
}
stream.zalloc = Z_NULL;
stream.zfree = Z_NULL;
stream.opaque = Z_NULL;
stream.avail_in = 0;
stream.next_in = Z_NULL;
int ret = inflateInit2(&stream, 16+MAX_WBITS);
#ifdef DETAILEDDEBUGGING
qDebug()<<"return value of inflateInit2() = "<<ret;
#endif
if(Z_OK != ret)
{
qDebug()<<"Error in inflateInit2, returning...";
delete[] out;
if(Z_STREAM_ERROR == ret)
aError = SmfTMGzipStreamError;
else if(Z_MEM_ERROR == ret)
aError = SmfTMGzipMemoryError;
else if(Z_DATA_ERROR == ret)
aError = SmfTMGzipDataError;
else
aError = SmfUnknownError;
return NULL;
}
// Initialize the data required for inflate() method call
stream.avail_in = aResponse.size();
stream.next_in = (unsigned char *)aResponse.data();
stream.avail_out = uncomSize;
stream.next_out = out;
ret = inflate(&stream, Z_NO_FLUSH);
#ifdef DETAILEDDEBUGGING
qDebug()<<"return value of inflate() = "<<ret;
#endif
switch (ret)
{
// fall through
case Z_NEED_DICT:
case Z_DATA_ERROR:
case Z_MEM_ERROR:
{
qDebug()<<"Error in inflate, returning...";
(void)inflateEnd(&stream);
delete[] out;
aError = SmfTMGzipDataError;
return NULL;
}
}
qDebug()<<"total bytes read so far = "<<stream.total_in;
qDebug()<<"total bytes output so far = "<<stream.total_out;
// Write the inflated data to a QByteArray
QByteArray *uncompressedData = new QByteArray((char *)out, stream.total_out);
delete[] out;
// If there is some unwanted data at the end of uncompressed data, chop them
int chopLength = uncompressedData->size() - uncomSize;
#ifdef DETAILEDDEBUGGING
qDebug()<<"old size of uncompressed data = "<<uncompressedData->size();
#endif
uncompressedData->chop(chopLength);
#ifdef DETAILEDDEBUGGING
qDebug()<<"new size of uncompressed data = "<<uncompressedData->size();
#endif
return uncompressedData;
}
/**
* Method to deflate a network request to gzip format.
* @param aResponse The QByteArray that has to be gzipped
* @param aError Argument indicating error
* @return a QByteArray* containing the deflated data. If deflation fails,
* NULL is returned
*/
QByteArray* SmfTransportManagerUtil::deflateRequest( QByteArray &aResponse, SmfError& aError )
{
qDebug()<<"Inside SmfTransportManagerUtil::deflateRequest()";
if(aResponse.size() <= 0)
{
aError = SmfTMUnknownContentError;
return NULL;
}
// Initialize the data required for zlib initialize method call
z_stream stream;
stream.zalloc = Z_NULL;
stream.zfree = Z_NULL;
stream.opaque = Z_NULL;
stream.next_in = (unsigned char *)aResponse.data();
stream.avail_in = aResponse.size();
stream.total_out = 0;
int level = Z_DEFAULT_COMPRESSION;
int method = Z_DEFLATED;
int windowBits = 16+MAX_WBITS;
int mem_level = 8;
int strategy = Z_DEFAULT_STRATEGY;
// Call deflateInit2 for gzip compression initialization
int initError = deflateInit2(&stream, level, method, windowBits, mem_level, strategy);
#ifdef DETAILEDDEBUGGING
qDebug()<<"Return value of deflateInit2() = "<<initError;
qDebug()<<"Error msg if any = "<<QString(zError(initError));
#endif
if(Z_OK != initError)
{
qDebug()<<"deflateInit2() failed, returning error = "<<QString(zError(initError));
if(Z_STREAM_ERROR == initError)
aError = SmfTMGzipStreamError;
else if(Z_MEM_ERROR == initError)
aError = SmfTMGzipMemoryError;
else if(Z_DATA_ERROR == initError)
aError = SmfTMGzipDataError;
else
aError = SmfUnknownError;
return NULL;
}
// Initialize the data required for inflate() method call
int out_size = (int)((aResponse.size()*1.01)+17);
unsigned char *out = new unsigned char[out_size];
if(out)
{
qDebug()<<"Memory allocated for output buffer with size = "<<out_size;
memset(out, 0, out_size);
}
else
{
//Error
qDebug()<<"Memory not allocated for output buffer!!!";
deflateEnd(&stream);
aError = SmfTMGzipDataError;
return NULL;
}
stream.next_out = out;
stream.avail_out = out_size;
#ifdef DETAILEDDEBUGGING
qDebug()<<"Before calling deflate()";
qDebug()<<"next_in = "<<(long)stream.next_in;
qDebug()<<"avail_in = "<<stream.avail_in;
qDebug()<<"next_out = "<<(long)stream.next_out;
qDebug()<<"avail_out = "<<stream.avail_out;
qDebug()<<"total_in = "<<stream.total_in;
qDebug()<<"total_out = "<<stream.total_out;
#endif
int deflateStatus;
do
{
stream.next_out = out + stream.total_out;
stream.avail_out = out_size - stream.total_out;
deflateStatus = deflate(&stream, Z_FINISH);
qDebug()<<"Return value of deflate() is = "<<deflateStatus;
qDebug()<<"Error msg if any = "<<QString(zError(deflateStatus));
#ifdef DETAILEDDEBUGGING
qDebug()<<"avail_in = "<<stream.avail_in;
qDebug()<<"avail_out = "<<stream.avail_out;
qDebug()<<"total_in = "<<stream.total_in;
qDebug()<<"total_out = "<<stream.total_out;
#endif
}while(Z_OK == deflateStatus);
if (Z_STREAM_END != deflateStatus)
{
QString errorMsg;
switch (deflateStatus)
{
case Z_ERRNO:
errorMsg.append("Error occured while reading file.");
aError = SmfUnknownError;
break;
case Z_STREAM_ERROR:
errorMsg.append("The stream state was inconsistent (e.g., next_in or next_out was NULL).");
aError = SmfTMGzipStreamError;
break;
case Z_DATA_ERROR:
errorMsg.append("The deflate data was invalid or incomplete.");
aError = SmfTMGzipDataError;
break;
case Z_MEM_ERROR:
errorMsg.append("Memory could not be allocated for processing.");
aError = SmfTMGzipMemoryError;
break;
case Z_BUF_ERROR:
errorMsg.append("Ran out of output buffer for writing compressed bytes.");
aError = SmfTMGzipMemoryError;
break;
case Z_VERSION_ERROR:
errorMsg.append("The version of zlib.h and the version of the library linked do not match.");
aError = SmfUnknownError;
break;
default:
errorMsg.append("Unknown error code.");
aError = SmfUnknownError;
}
qDebug()<<"Error string for deflate() is = "<<errorMsg;
// Free data structures that were dynamically created for the stream.
deflateEnd(&stream);
return NULL;
}
int retVal = deflateEnd(&stream);
qDebug()<<"Return value of deflateEnd() = "<<retVal;
qDebug()<<"Error msg if any = "<<QString(zError(retVal));
#ifdef DETAILEDDEBUGGING
/*QByteArray byteArray;
for (int i=0; i<stream.total_out;i++)
{
QString str(out[i]);
byteArray.clear();
byteArray.append(str.toAscii());
qDebug()<<QString("out[%1] = '%2'").arg(i).arg(QString(byteArray.toHex()));
}*/
#endif
// Write the inflated data to a QByteArray
QByteArray *compressedData = new QByteArray((char*)out, stream.total_out);
delete[] out;
qDebug()<<"Number of bytes of compressed data = "<<compressedData->size();
#ifdef DETAILEDDEBUGGING
qDebug()<<"compressed data = "<<QString(compressedData->toHex());
#endif
return compressedData;
}
/**
* Method called when the QNetworkReply detects an error in processing.
* @param aError The QNetworkReply error code
*/
void SmfTransportManagerUtil::networkReplyError ( QNetworkReply::NetworkError aError )
{
qDebug()<<"Inside SmfTransportManagerUtil::networkReplyError()";
// indicate the error to the plugin manager
SmfTransportResult trResult;
convertErrorType(aError, trResult);
SmfPluginManager::getInstance()->responseAvailable ( trResult, NULL, NULL );
}
/**
* Method to convert QNetworkReply Error to the type SmfTransportResult
* QNetworkRequest received before executing the web query.
* @param aError The QNetworkReply Error
* @param aResult [out] The SmfTransportResult error
*/
void SmfTransportManagerUtil::convertErrorType( const QNetworkReply::NetworkError &aError,
SmfTransportResult &aResult )
{
switch(aError)
{
case QNetworkReply::NoError:
aResult = SmfTransportOpNoError;
break;
case QNetworkReply::ConnectionRefusedError:
aResult = SmfTransportOpConnectionRefusedError;
break;
case QNetworkReply::RemoteHostClosedError:
aResult = SmfTransportOpRemoteHostClosedError;
break;
case QNetworkReply::HostNotFoundError:
aResult = SmfTransportOpHostNotFoundError;
break;
case QNetworkReply::TimeoutError:
aResult = SmfTransportOpTimeoutError;
break;
case QNetworkReply::OperationCanceledError:
aResult = SmfTransportOpOperationCanceledError;
break;
case QNetworkReply::SslHandshakeFailedError:
aResult = SmfTransportOpSslHandshakeFailedError;
break;
case QNetworkReply::ProxyConnectionRefusedError:
aResult = SmfTransportOpProxyConnectionRefusedError;
break;
case QNetworkReply::ProxyConnectionClosedError:
aResult = SmfTransportOpProxyConnectionClosedError;
break;
case QNetworkReply::ProxyNotFoundError:
aResult = SmfTransportOpProxyNotFoundError;
break;
case QNetworkReply::ProxyTimeoutError:
aResult = SmfTransportOpProxyTimeoutError;
break;
case QNetworkReply::ProxyAuthenticationRequiredError:
aResult = SmfTransportOpProxyAuthenticationRequiredError;
break;
case QNetworkReply::ContentAccessDenied:
aResult = SmfTransportOpContentAccessDenied;
break;
case QNetworkReply::ContentOperationNotPermittedError:
aResult = SmfTransportOpContentOperationNotPermittedError;
break;
case QNetworkReply::ContentNotFoundError:
aResult = SmfTransportOpContentNotFoundError;
break;
case QNetworkReply::AuthenticationRequiredError:
aResult = SmfTransportOpAuthenticationRequiredError;
break;
case QNetworkReply::ContentReSendError:
aResult = SmfTransportOpContentReSendError;
break;
case QNetworkReply::ProtocolUnknownError:
aResult = SmfTransportOpProtocolUnknownError;
break;
case QNetworkReply::ProtocolInvalidOperationError:
aResult = SmfTransportOpProtocolInvalidOperationError;
break;
case QNetworkReply::UnknownNetworkError:
aResult = SmfTransportOpUnknownNetworkError;
break;
case QNetworkReply::UnknownProxyError:
aResult = SmfTransportOpUnknownProxyError;
break;
case QNetworkReply::UnknownContentError:
aResult = SmfTransportOpUnknownContentError;
break;
case QNetworkReply::ProtocolFailure:
aResult = SmfTransportOpProtocolFailure;
break;
default:
;
}
}