--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/applayerprotocols/httptransportfw/Test/T_HttpPipeliningTest/CTestServerStreamManager.cpp Tue Feb 02 01:09:52 2010 +0200
@@ -0,0 +1,408 @@
+// 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 <minputstream.h>
+#include <moutputstream.h>
+
+#include "CTestServerStreamManager.h"
+#include "httptestutils.h"
+#include "MPipeliningTestCase.h"
+#include "ctestcasepipelinefallback.h"
+
+const TInt KTimeOut = 50000000;
+const TInt KResponseBatchSize = 5;
+_LIT8(KTxtConnectionClose, "Connection: Close");
+
+CTestServerStreamManager* CTestServerStreamManager::NewL(CHTTPTestUtils& aTestUtils, TInt aConnectionIndex, MPipeliningTestCase* aTestCase, MInputStream* aInputStream, MOutputStream* aOutputStream)
+ {
+ CTestServerStreamManager* self = new (ELeave) CTestServerStreamManager(aTestUtils, aConnectionIndex, aTestCase, aInputStream, aOutputStream);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+CTestServerStreamManager::CTestServerStreamManager(CHTTPTestUtils& aTestUtils, TInt aConnectionIndex, MPipeliningTestCase* aTestCase, MInputStream* aInputStream, MOutputStream* aOutputStream)
+: CTimer(EPriorityNormal), iTestUtils(aTestUtils), iInputStream(aInputStream), iOutputStream(aOutputStream), iTestCase(aTestCase), iConnectionIndex(aConnectionIndex)
+ {
+ CActiveScheduler::Add(this);
+
+ iTransCount = iTestCase->TransactionCount(iConnectionIndex);
+
+ iInputStream->Bind(*this);
+ iOutputStream->Bind(*this);
+ }
+
+CTestServerStreamManager::~CTestServerStreamManager()
+ {
+ Cancel();
+ if(iInputStream!=NULL)
+ iInputStream->Close();
+ if(iOutputStream!=NULL)
+ iOutputStream->Close();
+ delete iDataStore;
+ delete iDataToSend;
+
+ delete iHttpTimer;
+ delete iASW;
+ }
+
+void CTestServerStreamManager::ConstructL()
+ {
+ CTimer::ConstructL();
+ iHttpTimer = new(ELeave) CHttpTimer(*this);
+ iASW = new(ELeave) CActiveSchedulerWait();
+ }
+
+// From MInputStreamObserver
+void CTestServerStreamManager::ReceivedDataIndL(const TDesC8& aBuffer)
+ {
+ // Got data
+ _LIT(KTxtGotData, "Server - received request data.");
+ iTestUtils.LogIt(KTxtGotData());
+ iTestUtils.DumpData(aBuffer, ETrue);
+
+ if(iDataStore==NULL)
+ iDataStore = aBuffer.AllocL(); // First data chunk received
+ else
+ {
+ // Already got data before so append the data to the existing data
+ TInt newLength = (iDataStore->Length()) + aBuffer.Length();
+ iDataStore = iDataStore->ReAllocL( newLength );
+ TPtr8 buf = iDataStore->Des();
+ buf.Append(aBuffer);
+ }
+
+ iInputStream->ReceivedDataRes();
+
+ _LIT(KTxtTitle, "Defect Fix INC036954");
+ if (iTestCase->TestCaseName().Match(KTxtTitle) == 0)
+ {
+ iInputStream->ShutdownReq();
+ }
+ else
+ {
+ // Try processing the requests
+ SendDataL();
+ }
+ }
+
+void CTestServerStreamManager::SecureServerCnf()
+ {
+ }
+
+void CTestServerStreamManager::InputStreamCloseInd(TInt aError)
+ {
+ _LIT(KTxtInputClosed, "Server - Input stream %d closed. Error: %d.");
+ iTestUtils.LogIt(KTxtInputClosed(), iConnectionIndex+1, aError);
+
+ iInputStream = NULL;
+ }
+
+void CTestServerStreamManager::MInputStreamObserver_Reserved()
+ {
+ User::Invariant();
+ }
+
+// From MOutputStreamObserver
+void CTestServerStreamManager::SendDataCnfL()
+ {
+ _LIT(KTxtDataSent, "Server - Data Sent.");
+ iTestUtils.LogIt(KTxtDataSent());
+ if( iMoreResponseBatches )
+ {
+ // If there is more batches to process try and process them
+ iMoreResponseBatches = EFalse;
+ TRAPD(err, SendDataL());
+ if(err!=KErrNone)
+ {
+ _LIT(KTxtSendError, "Server - Error %d sending data. Closing stream.");
+ iTestUtils.LogIt(KTxtSendError(), err);
+ iInputStream->ShutdownReq();
+ }
+ }
+ else
+ {
+ delete iDataToSend;
+ iDataToSend = NULL;
+
+ // Do we need to close the connection
+ if(iCloseConnection)
+ {
+ _LIT(KTxtCloseConn, "Server - Closing connection.");
+ iTestUtils.LogIt(KTxtCloseConn());
+
+ if( (iTestCase->TestCaseName().Match(_L("Test Case 3")) == 0) || (iTestCase->TestCaseName().Match(_L("CINC073400")) == 0) || (iTestCase->TestCaseName().Match(_L("Test Case 19")) == 0) )
+ {
+ TTimeIntervalMicroSeconds32 time(5000000);
+ iHttpTimer->After(time);
+ iASW->Start();
+ }
+
+ if(iInputStream)
+ iInputStream->ShutdownReq();
+ }
+ _LIT(KTxtTitle, "Defect Fix CINC077703");
+ if (iTestCase->TestCaseName().Match(KTxtTitle) == 0)
+ {
+ iInputStream->ShutdownReq();
+ }
+
+ }
+ }
+
+void CTestServerStreamManager::SecureClientCnf()
+ {
+ }
+
+void CTestServerStreamManager::OutputStreamCloseInd(TInt aError)
+ {
+ _LIT(KTxtOutputClosed, "Server - Output stream %d closed. Error: %d.");
+ iTestUtils.LogIt(KTxtOutputClosed(), iConnectionIndex+1, aError);
+
+ iOutputStream = NULL;
+ }
+
+void CTestServerStreamManager::MOutputStreamObserver_Reserved()
+ {
+ }
+
+TBool CTestServerStreamManager::ProcessRequestL()
+ {
+ TBool processingRequest = ETrue;
+ TInt currentBatch = 0;
+ while( (processingRequest && (iCurrentTrans < iTransCount)) && (currentBatch<KResponseBatchSize) )
+ {
+ // Do we have enough data to respond to the current transaction?
+ TPtrC8 rawRequest = iTestCase->GetRawRequest(iConnectionIndex, iCurrentTrans);
+ TInt requestLength = rawRequest.Length();
+ TPtrC8 dataWindow = iDataStore->Mid(iDataPos);
+ // Test pipeline fallback scenario
+ _LIT(KTxtTitle, "Test Case Pipeline Fallback");
+ if (iTestCase->TestCaseName().Match(KTxtTitle) == 0)
+ {
+ CTestCasePipelineFallback* pipelineFallback = (CTestCasePipelineFallback*)(iTestCase);
+ if(pipelineFallback->FallingBack())
+ {
+ _LIT(KTxtSendError, "Fallingback .");
+ iTestUtils.LogIt(KTxtSendError());
+
+ // we are fallingback. We should receive the exact request size as we
+ // will be processing the request one by one
+ if(dataWindow.Length() > requestLength)
+ {
+ User::Leave(KErrCancel);
+ }
+ }
+ else
+ {
+ _LIT(KTxtSendError, "Not Fallingback.");
+ iTestUtils.LogIt(KTxtSendError());
+
+ // If we are not fallingback then we need to close the connection twice
+ // We are pipelining as well as batching. Shutdown the connection
+ // First time we get only one request. Just process.
+ if(dataWindow.Length() > requestLength)
+ {
+ _LIT(KTxtSendError, "Incremented and shutdown.");
+ iTestUtils.LogIt(KTxtSendError());
+
+ // We have to shut down 2 times
+ iInputStream->ShutdownReq();
+ pipelineFallback->IncFallingBack();
+ break;
+ }
+ }
+ }
+
+ if( requestLength <= dataWindow.Length() )
+ {
+ // Check that the raw request and the actual request match
+ if( dataWindow.FindF(rawRequest) != 0 )
+ {
+ _LIT(KTxtRequestDataMismatch, "Server - Fail. Request data for transaction %d does not match expected data.");
+ iTestUtils.LogIt(KTxtRequestDataMismatch(), iCurrentTrans+1);
+ _LIT(KTxtExpectedData, "Server - Expected data: %S");
+ iTestUtils.LogIt(KTxtExpectedData(), &rawRequest);
+ iTestUtils.LogIt(KTxtExpectedData(), &dataWindow);
+
+ User::Leave(KErrNotFound);
+ }
+
+ // Prepare the response data to send
+ iDataPos += requestLength;
+ processingRequest = ETrue;
+ TPtrC8 rawResponse = iTestCase->GetRawResponse(iConnectionIndex, iCurrentTrans);
+ if(iDataToSend==NULL)
+ iDataToSend = rawResponse.AllocL();
+ else
+ {
+ TInt responseLength = rawResponse.Length();
+ iDataToSend = iDataToSend->ReAllocL( (iDataToSend->Length()) + responseLength );
+ TPtr8 buffer = iDataToSend->Des();
+ buffer.Append(rawResponse);
+ }
+
+ // Check for a Connection: Close in the request
+ iCloseConnection = IsConnectionCloseInData(rawRequest, rawResponse);
+ if(iCloseConnection)
+ processingRequest = EFalse;
+
+ ++iCurrentTrans;
+ ++currentBatch;
+ }
+ else
+ {
+ // No more requests can be processed
+ processingRequest = EFalse;
+ }
+
+ // Flag that we have more processing to do with we are still processing the data
+ // but we have reached the maximum batch size.
+ if( processingRequest && currentBatch==KResponseBatchSize)
+ iMoreResponseBatches = ETrue;
+ else
+ iMoreResponseBatches = EFalse;
+
+ }
+
+ if(iDataToSend!=NULL)
+ return ETrue;
+
+ return EFalse;
+ }
+
+TBool CTestServerStreamManager::IsConnectionCloseInData(const TDesC8& aRequest, const TDesC8& aResponse) const
+ {
+ if( (aRequest.FindF(KTxtConnectionClose()) != KErrNotFound) || (aResponse.FindF(KTxtConnectionClose()) != KErrNotFound) )
+ {
+ // Either the request or response has Connection: Close header
+ _LIT(KTxtConnectionCloseDetected, "Server - Connection: Close detected in request or response, transaction: %d");
+ iTestUtils.LogIt(KTxtConnectionCloseDetected(), iCurrentTrans+1);
+
+ return ETrue;
+ }
+
+ return EFalse;
+ }
+
+void CTestServerStreamManager::SendDataL()
+ {
+ Cancel();
+
+ _LIT(KTcTitle, "CRecvTimeOut");
+ if (iTestCase->TestCaseName().Match(KTcTitle) == 0)
+ {
+ _LIT(KTxtTimeout, "Server - Data Send Timeout.");
+ iTestUtils.LogIt(KTxtTimeout());
+ After(61000000);
+ return;
+ }
+
+ if( !iMoreResponseBatches )
+ {
+ // Try processing the requests
+ if( ProcessRequestL() )
+ {
+ // We have enough, send the response.
+ iOutputStream->SendDataReqL(*iDataToSend);
+
+ _LIT(KTxtSendData, "Server - Sending response data.");
+ iTestUtils.LogIt(KTxtSendData());
+ iTestUtils.DumpData(*iDataToSend, ETrue);
+ }
+ else
+ {
+ After(KTimeOut); // Start the inactivity timer
+ }
+
+ }
+ }
+
+void CTestServerStreamManager::RunL()
+ {
+ _LIT(KTcTitle, "CRecvTimeOut");
+ if (iTestCase->TestCaseName().Match(KTcTitle) == 0)
+ {
+ _LIT(KTxtTimeout, "TC-Receive Timeout Timer RunL.");
+ iTestUtils.LogIt(KTxtTimeout());
+ return;
+ }
+
+
+ if( iStatus.Int() == KErrNone )
+ {
+ // The connection has timed out.
+ _LIT(KTxtTimedOut, "Server - Fail, Connection %d timed out. Current transaction: %d");
+ iTestUtils.LogIt(KTxtTimedOut(), iConnectionIndex+1, iCurrentTrans+1);
+
+ iInputStream->ShutdownReq();
+ }
+ }
+
+MHttpResponse* CTestServerStreamManager::CurrentResponse()
+ {
+ return NULL;
+ }
+
+void CTestServerStreamManager::OnReceiveTimeOut()
+ {
+
+ }
+
+void CTestServerStreamManager::OnSendTimeOut()
+ {
+
+ }
+
+TInt CTestServerStreamManager::SendTimeOutVal()
+ {
+ return 0;
+ }
+
+void CTestServerStreamManager::TimeOut()
+ {
+ iASW->AsyncStop();
+ }
+
+
+CHttpTimer::CHttpTimer(MTimerClient& aClient)
+:CActive(EPriorityStandard), iClient(aClient)
+ {
+ CActiveScheduler::Add(this);
+ iTimer.CreateLocal();
+ }
+
+CHttpTimer::~CHttpTimer()
+ {
+ Cancel();
+ iTimer.Close();
+ }
+
+void CHttpTimer::After(TTimeIntervalMicroSeconds32 anInterval)
+ {
+ iTimer.After(iStatus, anInterval);
+ SetActive();
+ }
+
+void CHttpTimer::DoCancel()
+ {
+
+ }
+
+void CHttpTimer::RunL()
+ {
+ iClient.TimeOut();
+ }