// Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
// All rights reserved.
// This component and the accompanying materials are made available
// under the terms of "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:
// Nokia Corporation - initial contribution.
//
// Contributors:
//
// Description:
//
#include "chttpclienttestparams.h"
#include <testexecuteserverbase.h>
#include "thttpheadervaluevariant.h"
#include <escapeutils.h>
#include <tinternetdate.h>
_LIT(KMethod, "Method");
_LIT(KUri, "Uri");
_LIT(KRawRequest, "RawRequest");
_LIT(KRawResponse, "RawResponse");
_LIT(KResponseBody, "ResponseBody");
_LIT(KStatusCode, "StatusCode");
_LIT(KResponseFieldCount, "ResponseFieldCount");
_LIT(KHeader, "ResponseHeader%d");
_LIT(KHeaderValue, "ResponseHeader%d.Value%d");
_LIT(KHeaderValueCount, "ResponseHeader%dValueCount");
_LIT(KFieldParamCount, "ResponseHeader%d.Field%dParamCount");
_LIT(KFieldParamName, "ResponseHeader%d.Field%d.ParamName%d");
_LIT(KFieldParamValue, "ResponseHeader%d.Field%d.ParamValue%d");
_LIT(KHeaderParamCount, "ResponseHeader%dParamCount");
_LIT(KHeaderParamName, "ResponseHeader%d.ParamName%d");
_LIT(KHeaderParamValue, "ResponseHeader%d.ParamValue%d");
_LIT(KResponseFileName, "ResponseFileName");
_LIT(KResponseFileNameStore, "ResponseFileNameStore");
_LIT(KRequestFileName, "RequestFileName");
_LIT(KRequestFileNameStore, "RequestFileNameStore");
_LIT(KRequestFieldCount, "RequestFieldCount");
_LIT(KRequestHeader, "RequestHeader%d");
_LIT(KRequestHeaderValueCount, "RequestHeader%dValueCount");
_LIT(KRequestHeaderValue, "RequestHeader%d.Value%d");
_LIT(KRequestHeaderValueParamCount, "RequestHeader%d.Value%dParamCount");
_LIT(KRequestHeaderValueParamName, "RequestHeader%d.Value%d.ParamName%d");
_LIT(KRequestHeaderValueParamValue, "RequestHeader%d.Value%d.ParamValue%d");
_LIT(KRequestBody, "RequestBody");
_LIT(KConnDisconnect, "ConnDisconnect");
_LIT(KExpectedError, "ExpectedError");
_LIT(KNoRetryOnDisconnect, "NoRetryOnDisconnect");
_LIT(KResponseDynamicAndStatic, "ResponseDynamicAndStatic");
_LIT(KOnlineTest, "OnlineTest");
_LIT(KProxyAddress, "ProxyAddress");
_LIT(KResponseTimeout, "ResponseTimeout");
_LIT(KRedirection, "Redirection");
_LIT(KNotifyTransferProgress, "NotifyTransferProgress");
_LIT8(KScriptLF8, "\\n");
_LIT8(KReplaceLF8, "\n");
_LIT8(KScriptCR8, "\\r");
_LIT8(KReplaceCR8, "\r");
void ParseAndReplaceCRLF(HBufC8* aHBufPtr)
{
TInt crPos = 0;
TInt lfPos = 0;
do
{
crPos = ((aHBufPtr->Des()).Find(KScriptCR8()));
if (crPos != KErrNotFound)
{
(aHBufPtr->Des()).Replace(crPos,2, KReplaceCR8());
}
}while (crPos != KErrNotFound );
do
{
lfPos = ((aHBufPtr->Des()).Find(KScriptLF8()));
if (lfPos != KErrNotFound)
{
(aHBufPtr->Des()).Replace(lfPos,2, KReplaceLF8());
}
}while (lfPos != KErrNotFound );
}
CHttpClientTestParams* CHttpClientTestParams::NewL(CTestStep& aTestCase)
{
CHttpClientTestParams* self = new(ELeave) CHttpClientTestParams;
CleanupStack::PushL(self);
self->ConstructL(aTestCase);
CleanupStack::Pop();
return self;
}
void CHttpClientTestParams::ConstructL(CTestStep& aTestCase)
{
TPtrC method;
TPtrC uri;
TPtrC rawRequest;
TPtrC rawResponse;
if(!aTestCase.GetStringFromConfig(aTestCase.ConfigSection(), KMethod(), method) ||
!aTestCase.GetStringFromConfig(aTestCase.ConfigSection(), KUri(), uri) ||
!aTestCase.GetIntFromConfig(aTestCase.ConfigSection(), KStatusCode(), iStatusCode))
{
User::Leave(KErrCorrupt);
}
aTestCase.GetStringFromConfig(aTestCase.ConfigSection(), KRawRequest(), rawRequest);
aTestCase.GetStringFromConfig(aTestCase.ConfigSection(), KRawResponse(), rawResponse);
iMethod = EscapeUtils::ConvertFromUnicodeToUtf8L(method);
iUri = EscapeUtils::ConvertFromUnicodeToUtf8L(uri);
iRawRequest = EscapeUtils::ConvertFromUnicodeToUtf8L(rawRequest);
iRawResponse = EscapeUtils::ConvertFromUnicodeToUtf8L(rawResponse);
ParseAndReplaceCRLF(iRawRequest);
ParseAndReplaceCRLF(iRawResponse);
TPtrC responseBody;
if(aTestCase.GetStringFromConfig(aTestCase.ConfigSection(), KResponseBody(), responseBody))
{
iResponseBody = EscapeUtils::ConvertFromUnicodeToUtf8L(responseBody);
}
TPtrC requestBody;
if(aTestCase.GetStringFromConfig(aTestCase.ConfigSection(), KRequestBody(), requestBody))
{
iRequestBody = EscapeUtils::ConvertFromUnicodeToUtf8L(requestBody);
}
// Now read the headers
// Read the number of headers
TInt responseHeaderCount = 0;
aTestCase.GetIntFromConfig(aTestCase.ConfigSection(), KResponseFieldCount(), responseHeaderCount);
for(TInt i = 0; i < responseHeaderCount; ++i)
{
CHeaderInfo* headerInfo = new(ELeave) CHeaderInfo;
CleanupStack::PushL(headerInfo);
TBuf<32> headerFormat;
headerFormat.Format(KHeader(), i + 1);
TPtrC headerName;
aTestCase.GetStringFromConfig(aTestCase.ConfigSection(), headerFormat, headerName);
headerInfo->iFieldName = EscapeUtils::ConvertFromUnicodeToUtf8L(headerName);
TInt headerValueCount = 0;
TBuf<32> headerValueCountStr;
headerValueCountStr.Format(KHeaderValueCount(), i + 1);
aTestCase.GetIntFromConfig(aTestCase.ConfigSection(), headerValueCountStr, headerValueCount);
for(TInt j = 0; j < headerValueCount; ++j)
{
TBuf<32> headerValueFormat;
headerValueFormat.Format(KHeaderValue(), i + 1, j+ 1);
TPtrC headerValue;
aTestCase.GetStringFromConfig(aTestCase.ConfigSection(), headerValueFormat, headerValue);
CHeaderFieldInfo* fieldInfo = new(ELeave) CHeaderFieldInfo;
CleanupStack::PushL(fieldInfo);
fieldInfo->iFieldValue = EscapeUtils::ConvertFromUnicodeToUtf8L(headerValue);
// Check this field has params.
TBuf<32> headerFieldParamCount;
headerFieldParamCount.Format(KFieldParamCount(), i + 1, j + 1);
TInt paramCount = 0;
aTestCase.GetIntFromConfig(aTestCase.ConfigSection(), headerFieldParamCount, paramCount);
for(TInt k = 0; k < paramCount; ++k)
{
TBuf<48> fieldParamName;
TBuf<48> fieldParamValue;
fieldParamName.Format(KFieldParamName, i + 1, j + 1, k + 1);
fieldParamValue.Format(KFieldParamValue, i + 1, j + 1, k + 1);
TPtrC paramName;
TPtrC paramValue;
aTestCase.GetStringFromConfig(aTestCase.ConfigSection(), fieldParamName, paramName);
aTestCase.GetStringFromConfig(aTestCase.ConfigSection(), fieldParamValue, paramValue);
CHeaderFieldParamInfo* paramInfo = new(ELeave) CHeaderFieldParamInfo;
CleanupStack::PushL(paramInfo);
paramInfo->iParamName = EscapeUtils::ConvertFromUnicodeToUtf8L(paramName);
paramInfo->iParamValue = EscapeUtils::ConvertFromUnicodeToUtf8L(paramValue);
fieldInfo->iFieldParamInfos.AppendL(paramInfo);
CleanupStack::Pop(); // paramInfo
}
headerInfo->iFieldInfos.AppendL(fieldInfo);
CleanupStack::Pop(); // fieldInfo
}
// Check if the header has some params
TBuf<48> headerParamCount;
headerParamCount.Format(KHeaderParamCount(), i + 1);
TInt hdrParamCount = 0;
aTestCase.GetIntFromConfig(aTestCase.ConfigSection(), headerParamCount, hdrParamCount);
for(TInt x = 0; x < hdrParamCount; ++x)
{
TBuf<48> headerParamName;
TBuf<48> headerParamValue;
headerParamName.Format(KHeaderParamName(), i + 1, x + 1);
headerParamValue.Format(KHeaderParamValue(), i + 1, x + 1);
TPtrC paramName;
TPtrC paramValue;
aTestCase.GetStringFromConfig(aTestCase.ConfigSection(), headerParamName, paramName);
aTestCase.GetStringFromConfig(aTestCase.ConfigSection(), headerParamValue, paramValue);
CHeaderFieldParamInfo* paramInfo = new (ELeave) CHeaderFieldParamInfo;
CleanupStack::PushL(paramInfo);
paramInfo->iParamName = EscapeUtils::ConvertFromUnicodeToUtf8L(paramName);
paramInfo->iParamValue = EscapeUtils::ConvertFromUnicodeToUtf8L(paramValue);
headerInfo->iParamInfos.AppendL(paramInfo);
CleanupStack::Pop(); // paramInfo
}
iResponseHeaderInfos.AppendL(headerInfo);
CleanupStack::Pop(); // headerInfo
}
TPtrC fileName;
aTestCase.GetStringFromConfig(aTestCase.ConfigSection(), KResponseFileName(), fileName);
if(fileName.Length() > 0)
{
iFileSender = CFileSender::NewL(fileName);
aTestCase.GetStringFromConfig(aTestCase.ConfigSection(), KResponseFileNameStore(), fileName);
if(fileName.Length() == 0)
{
User::Leave(KErrCorrupt);
}
iFileReceiver = CFileReceiver::NewL(fileName);
}
TPtrC ulFileName;
aTestCase.GetStringFromConfig(aTestCase.ConfigSection(), KRequestFileName(), ulFileName);
if(ulFileName.Length() > 0)
{
iFileSender = CFileSender::NewL(ulFileName);
aTestCase.GetStringFromConfig(aTestCase.ConfigSection(), KRequestFileNameStore(), ulFileName);
if(ulFileName.Length() == 0)
{
User::Leave(KErrCorrupt);
}
iFileReceiver = CFileReceiver::NewL(ulFileName);
}
// Read request headers
TInt reqFieldCount = 0;
aTestCase.GetIntFromConfig(aTestCase.ConfigSection(), KRequestFieldCount(), reqFieldCount);
for(TInt ii = 0; ii < reqFieldCount; ++ii)
{
// Read the request header
TBuf<64> reqHeaderStr;
reqHeaderStr.Format(KRequestHeader(), ii + 1);
TPtrC reqHeaderName;
aTestCase.GetStringFromConfig(aTestCase.ConfigSection(), reqHeaderStr, reqHeaderName);
CHeaderInfo* headerInfo = new(ELeave) CHeaderInfo;
CleanupStack::PushL(headerInfo);
headerInfo->iFieldName = EscapeUtils::ConvertFromUnicodeToUtf8L(reqHeaderName);
// Now read how many fields are present
reqHeaderStr.Format(KRequestHeaderValueCount(), ii + 1);
TInt reqHdrValueCount = 0;
aTestCase.GetIntFromConfig(aTestCase.ConfigSection(), reqHeaderStr, reqHdrValueCount);
for(TInt jj = 0; jj < reqHdrValueCount; ++jj)
{
TPtrC reqHeaderVal;
reqHeaderStr.Format(KRequestHeaderValue(), ii + 1, jj + 1);
aTestCase.GetStringFromConfig(aTestCase.ConfigSection(), reqHeaderStr, reqHeaderVal);
CHeaderFieldInfo* info = new (ELeave) CHeaderFieldInfo;
CleanupStack::PushL(info);
info->iFieldValue = EscapeUtils::ConvertFromUnicodeToUtf8L(reqHeaderVal);
reqHeaderStr.Format(KRequestHeaderValueParamCount, ii + 1, jj + 1);
TInt paramCount = 0;
aTestCase.GetIntFromConfig(aTestCase.ConfigSection(), reqHeaderStr, paramCount);
for(TInt kk = 0; kk < paramCount; ++kk)
{
reqHeaderStr.Format(KRequestHeaderValueParamName(), ii + 1, jj + 1, kk + 1);
TPtrC name;
TPtrC value;
aTestCase.GetStringFromConfig(aTestCase.ConfigSection(), reqHeaderStr, name);
reqHeaderStr.Format(KRequestHeaderValueParamValue(), ii + 1, jj + 1, kk + 1);
aTestCase.GetStringFromConfig(aTestCase.ConfigSection(), reqHeaderStr, value);
CHeaderFieldParamInfo* paramInfo = new (ELeave) CHeaderFieldParamInfo;
CleanupStack::PushL(paramInfo);
paramInfo->iParamName = EscapeUtils::ConvertFromUnicodeToUtf8L(name);
paramInfo->iParamValue = EscapeUtils::ConvertFromUnicodeToUtf8L(value);
info->iFieldParamInfos.AppendL(paramInfo);
CleanupStack::Pop(); // CHeaderFieldParamInfo
}
headerInfo->iFieldInfos.AppendL(info);
CleanupStack::Pop(); // info
}
iRequestHeaderInfos.AppendL(headerInfo);
CleanupStack::Pop();
}
iConnDisconnect = EFalse;
aTestCase.GetBoolFromConfig(aTestCase.ConfigSection(), KConnDisconnect(), iConnDisconnect);
iExpectedError = KErrNone;
aTestCase.GetIntFromConfig(aTestCase.ConfigSection(), KExpectedError(), iExpectedError);
iNoRetryOnDisconnect = EFalse;
aTestCase.GetBoolFromConfig(aTestCase.ConfigSection(), KNoRetryOnDisconnect(), iNoRetryOnDisconnect);
iResponseDynamicAndStatic = EFalse;
aTestCase.GetBoolFromConfig(aTestCase.ConfigSection(), KResponseDynamicAndStatic(), iResponseDynamicAndStatic);
iOnlineTest = EFalse;
aTestCase.GetBoolFromConfig(aTestCase.ConfigSection(), KOnlineTest(), iOnlineTest);
iRedirection = EFalse;
aTestCase.GetBoolFromConfig(aTestCase.ConfigSection(), KRedirection(), iRedirection);
iResponseTimeout = EFalse;
aTestCase.GetBoolFromConfig(aTestCase.ConfigSection(), KResponseTimeout(), iResponseTimeout);
iNotifyTransferProgress = EFalse;
aTestCase.GetBoolFromConfig(aTestCase.ConfigSection(), KNotifyTransferProgress(), iNotifyTransferProgress);
TPtrC proxyAddress;
if(aTestCase.GetStringFromConfig(aTestCase.ConfigSection(), KProxyAddress, proxyAddress))
{
iProxyAddress = EscapeUtils::ConvertFromUnicodeToUtf8L(proxyAddress);
}
}
CHttpClientTestParams::~CHttpClientTestParams()
{
delete iFileSender;
delete iMethod;
delete iUri;
delete iRawRequest;
delete iRawResponse;
delete iResponseBody;
iResponseHeaderInfos.ResetAndDestroy();
}
TInt CHttpClientTestParams::StatusCode() const
{
return iStatusCode;
}
const TDesC8& CHttpClientTestParams::Method() const
{
return *iMethod;
}
const TDesC8& CHttpClientTestParams::Uri() const
{
return *iUri;
}
const TDesC8& CHttpClientTestParams::RawRequest() const
{
return *iRawRequest;
}
const TDesC8& CHttpClientTestParams::RawResponse() const
{
return *iRawResponse;
}
const TDesC8& CHttpClientTestParams::ResponseBody() const
{
if(iResponseBody)
return *iResponseBody;
return KNullDesC8();
}
TBool CHttpClientTestParams::IsFileSending() const
{
return (iFileSender != NULL);
}
const TDesC8& CHttpClientTestParams::ReadFromFile()
{
return iFileSender->Read();
}
TBool CHttpClientTestParams::IsPendingRead() const
{
return iFileSender->MoreToRead();
}
TInt CHttpClientTestParams::WriteToFile(const TDesC8& aData)
{
return iFileReceiver->Write(aData);
}
RFile& CHttpClientTestParams::SourceFile()
{
return iFileSender->iFile;
}
RFile& CHttpClientTestParams::SinkFile()
{
return iFileReceiver->iFile;
}
TBool CHttpClientTestParams::NeedDisconnection() const
{
return iConnDisconnect;
}
TInt CHttpClientTestParams::ExpectedError() const
{
return iExpectedError;
}
TBool CHttpClientTestParams::NoRetryOnDisconnect() const
{
return iNoRetryOnDisconnect;
}
TBool CHttpClientTestParams::ResponseTimeoutEnable() const
{
return iResponseTimeout;
}
TBool CHttpClientTestParams::IsRedirecting() const
{
return iRedirection;
}
TBool CHttpClientTestParams::TransferProgress() const
{
return iNotifyTransferProgress;
}
TBool CHttpClientTestParams::CheckVariantValue(const THttpHeaderValueVariant& aVariant, const TDesC8& aValueToMatch)
{
TBool ret = EFalse;
switch(aVariant.Type())
{
case THttpHeaderValueVariant::EIntType:
{
_LIT8(KIntType, "%d");
TBuf8<16> buf;
buf.Format(KIntType(), aVariant.Int());
ret = (buf.CompareF(aValueToMatch) == 0);
}
break;
case THttpHeaderValueVariant::EStrType:
{
ret = (aVariant.Str().CompareF(aValueToMatch) == 0);
}
break;
case THttpHeaderValueVariant::EDateTimeType:
{
TInternetDate internetDate(aVariant.DateTime());
HBufC8* dateTimeStr = internetDate.InternetDateTimeL(TInternetDate::ERfc1123Format);
ret = aValueToMatch.CompareF(*dateTimeStr) == 0;
delete dateTimeStr;
}
break;
default:
User::Invariant();
}
return ret;
}
CHeaderInfo* CHttpClientTestParams::FindHeaderInfo(const TDesC8& aHeaderName)
{
const TUint count = iResponseHeaderInfos.Count();
for(TInt i = 0; i < count; ++i)
{
if(aHeaderName.CompareF(*iResponseHeaderInfos[i]->iFieldName) == 0)
{
return iResponseHeaderInfos[i];
}
}
return NULL;
}
TBool CHttpClientTestParams::MatchPostFileContent()
{
CFileSender* sender = CFileSender::NewL(iFileSender->FileName());
CleanupStack::PushL(sender);
CFileSender* sender2 = CFileSender::NewL(iFileReceiver->FileName());
CleanupStack::PushL(sender2);
sender2->Read(RawRequest().Length());
TBool ret = ETrue;
while(sender->MoreToRead())
{
if(!sender2->MoreToRead())
{
ret = EFalse;
break;
}
if(sender->Read().CompareF(sender2->Read()) != 0)
{
ret = EFalse;
break;
}
}
CleanupStack::Pop(2); // sender/sender2
return ret;
}
TBool CHttpClientTestParams::MatchFileContent()
{
CFileSender* sender = CFileSender::NewL(iFileSender->FileName());
CleanupStack::PushL(sender);
CFileSender* sender2 = CFileSender::NewL(iFileReceiver->FileName());
CleanupStack::PushL(sender2);
TBool ret = ETrue;
while(sender->MoreToRead())
{
if(!sender2->MoreToRead())
{
ret = EFalse;
break;
}
if(sender->Read().CompareF(sender2->Read()) != 0)
{
ret = EFalse;
break;
}
}
CleanupStack::Pop(2); // sender/sender2
return ret;
}
CHttpClientTestParamArray::CHttpClientTestParamArray()
{
}
CHttpClientTestParamArray::~CHttpClientTestParamArray()
{
iTestParamArray.ResetAndDestroy();
}
void CHttpClientTestParamArray::AddTestParams(CHttpClientTestParams* aParams)
{
iTestParamArray.Append(aParams);
}
CHttpClientTestParams* CHttpClientTestParamArray::MatchingParam(const TDesC8& aData)
{
CHttpClientTestParams* param = NULL;
TInt count = iTestParamArray.Count();
for(TUint i = 0; i < count; ++i)
{
TInt startPos = aData.Locate(' ');
TInt reversePos = aData.LocateReverse(' ') - 1;
TPtrC8 ptr = aData.Mid(startPos + 1, reversePos - startPos);
if (iTestParamArray[i]->Uri().FindF(ptr) != KErrNotFound)
{
param = iTestParamArray[i];
break;
}
}
return param;
}
//Parse Replace \n & \r
void ParseReplaceCRLF(HBufC8* aHBufPtr)
{
TInt crPos = 0;
TInt lfPos = 0;
do
{
crPos = ((aHBufPtr->Des()).Find(KScriptCR8()));
if (crPos != KErrNotFound)
{
(aHBufPtr->Des()).Replace(crPos,2, KReplaceCR8());
}
}
while (crPos != KErrNotFound );
do
{
lfPos = ((aHBufPtr->Des()).Find(KScriptLF8()));
if (lfPos != KErrNotFound)
{
(aHBufPtr->Des()).Replace(lfPos,2, KReplaceLF8());
}
}
while (lfPos != KErrNotFound );
}
CFileSender* CFileSender::NewL(const TDesC& aFileName)
{
CFileSender* self = new(ELeave) CFileSender;
CleanupStack::PushL(self);
self->ConstructL(aFileName);
CleanupStack::Pop(); // self
return self;
}
void CFileSender::ConstructL(const TDesC& aFileName)
{
iFileName = aFileName.AllocL();
User::LeaveIfError(iFs.Connect());
iBuffer.CreateL(16 * 1024);
User::LeaveIfError(iFile.Open(iFs, aFileName, EFileShareReadersOnly));
User::LeaveIfError(iFile.Size(iFileSize));
}
CFileSender::~CFileSender()
{
delete iFileName;
iBuffer.Close();
iFile.Close();
iFs.Close();
}
const TDesC8& CFileSender::Read(TInt aSize)
{
iBuffer.Zero();
iFile.Read(iBuffer, aSize);
iFileSize -= iBuffer.Length();
return iBuffer;
}
const TDesC8& CFileSender::Read()
{
iBuffer.Zero();
iFile.Read(iBuffer);
iFileSize -= iBuffer.Length();
return iBuffer;
}
TInt CFileSender::Size()
{
TInt size;
iFile.Size(size);
return size;
}
TBool CFileSender::MoreToRead() const
{
return iFileSize > 0;
}
CFileSender::CFileSender()
{
}
const TDesC& CFileSender::FileName() const
{
return *iFileName;
}
CFileReceiver* CFileReceiver::NewL(const TDesC& aFileName)
{
CFileReceiver* self = new(ELeave) CFileReceiver;
CleanupStack::PushL(self);
self->ConstructL(aFileName);
CleanupStack::Pop(); // self
return self;
}
TInt CFileReceiver::Write(const TDesC8& aData)
{
return iFile.Write(aData);
}
CFileReceiver::~CFileReceiver()
{
iFile.Close();
iFs.Close();
delete iFileName;
}
void CFileReceiver::ConstructL(const TDesC& aFileName)
{
iFileName = aFileName.AllocL();
User::LeaveIfError(iFs.Connect());
if(iFile.Open(iFs, aFileName, EFileWrite) != KErrNone)
{
User::LeaveIfError(iFile.Create(iFs, aFileName, EFileWrite));
}
}
RFile& CFileReceiver::File()
{
return iFile;
}
const TDesC& CFileReceiver::FileName() const
{
return *iFileName;
}