applayerprotocols/httptransportfw/Test/T_HttpPipeliningTest/CTestServerStreamManager.cpp
changeset 0 b16258d2340f
child 3 5ee1d9ce5878
--- /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();
+	}