applayerpluginsandutils/httpprotocolplugins/WspProtocolHandler/CWspCOTransaction.cpp
changeset 0 b16258d2340f
equal deleted inserted replaced
-1:000000000000 0:b16258d2340f
       
     1 // Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 // System includes
       
    17 #include <httpstringconstants.h>
       
    18 #include <wsp/mwspcapabilityviewer.h>
       
    19 #include <wsp/mwspcomethodinvoker.h>
       
    20 #include <wsperror.h>
       
    21 
       
    22 // User includes
       
    23 #include <http/rhttpsession.h>
       
    24 #include "cwspcotxdata.h"
       
    25 #include "cwspcorxdata.h"
       
    26 #include "cwspprimitivesender.h"
       
    27 #include "mwspcomethodobserver.h"
       
    28 #include "wsppanic.h"
       
    29 
       
    30 // Class signature
       
    31 #include "cwspcotransaction.h"
       
    32 
       
    33 CWspCOTransaction* CWspCOTransaction::NewL(
       
    34 										   RHTTPTransaction			aTransaction, 
       
    35 										   MWspCOMethodInvoker&		aMethodInvoker, 
       
    36 										   MWspCapabilityViewer&	aNegotiatedCapInfo,
       
    37 										   MWspCOMethodObserver&	aObserver,
       
    38 										   CWspHeaderUtils&			aHdrUtils
       
    39 										   )
       
    40 	{
       
    41 	CWspCOTransaction* self = new (ELeave) CWspCOTransaction(aTransaction, aMethodInvoker, aNegotiatedCapInfo, aObserver, aHdrUtils);
       
    42 	CleanupStack::PushL(self);
       
    43 	self->ConstructL();
       
    44 	CleanupStack::Pop(self);
       
    45 	return self;
       
    46 	}
       
    47 
       
    48 CWspCOTransaction::~CWspCOTransaction()
       
    49 	{
       
    50 	if( iPrimitiveSender )
       
    51 		iPrimitiveSender->Cancel();
       
    52 	delete iPrimitiveSender;
       
    53 	}
       
    54 
       
    55 CWspCOTransaction::CWspCOTransaction(
       
    56 									 RHTTPTransaction			aTransaction, 
       
    57 									 MWspCOMethodInvoker&		aMethodInvoker, 
       
    58 									 MWspCapabilityViewer&		aNegotiatedCapInfo,
       
    59 									 MWspCOMethodObserver&		aObserver,
       
    60 									 CWspHeaderUtils&			aHdrUtils
       
    61 									 )
       
    62 : CProtTransaction(aTransaction), iMethodInvoker(aMethodInvoker),
       
    63 								  iNegotiatedCapInfo(aNegotiatedCapInfo), 
       
    64 								  iObserver(aObserver),
       
    65 								  iHdrUtils(aHdrUtils),
       
    66 								  iMethodState(ENullMethod)
       
    67 	{
       
    68 	__OPEN_LOG("WspProtocolHandler.txt")
       
    69 	}
       
    70 
       
    71 void CWspCOTransaction::ConstructL()
       
    72 	{
       
    73 	iPrimitiveSender = CWspPrimitiveSender::NewL(*this);	
       
    74 	}
       
    75 
       
    76 void CWspCOTransaction::InitRequestL()
       
    77 	{
       
    78 	__ASSERT_DEBUG( iMethodState == ENullMethod, Panic(KWspPanicMethodAlreadyActive) );
       
    79 
       
    80 	// Reset all the flags
       
    81 	ResetFlags();
       
    82 
       
    83 	// Set the request data
       
    84 	STATIC_CAST(CWspCOTxData*, iTxData)->SetRequestDataL();
       
    85 	}
       
    86 
       
    87 void CWspCOTransaction::NotifyMoreRequestData()
       
    88 	{
       
    89 	__ASSERT_DEBUG( iMethodState == ENullMethod || iMethodState == ERequesting, Panic(KWspPanicBadMethodState) );
       
    90 
       
    91 	// Inform the Tx data object that there is more data
       
    92 	STATIC_CAST(CWspCOTxData*, iTxData)->NotifyMoreRequestData();
       
    93 	}
       
    94 
       
    95 void CWspCOTransaction::AbortRequest()
       
    96 	{
       
    97 	// Check the state - ignore if in the WSP method transaction is in the Null
       
    98 	// or Aborting state.
       
    99 	if( iMethodState != ENullMethod && iMethodState != EAborting && !iFinalResPending )
       
   100 		{
       
   101 		// The client has cancelled the method - set flag.
       
   102 		iClientMethodAbort = ETrue;
       
   103 
       
   104 		// Do abort...
       
   105 		MethodAbort();
       
   106 		}
       
   107 	}
       
   108 
       
   109 void CWspCOTransaction::Suicide()
       
   110 	{
       
   111 	// Check the WSP method transaction state
       
   112 	if( iMethodState == EAborting || iFinalResPending )
       
   113 		{
       
   114 		// Waiting for the S-MethodAbort.ind primitive or the final .res primitive
       
   115 		// to be sent. Need to flag self-destruction suicide when the primitive
       
   116 		// is received/sent.
       
   117 		iSuicide = ETrue;
       
   118 		}
       
   119 	else
       
   120 		{
       
   121 		__ASSERT_DEBUG( iMethodState == ENullMethod, Panic(KWspPanicBadMethodState) );
       
   122 
       
   123 		// The WSP method transaction is finished or not started - safe to 
       
   124 		// delete now.
       
   125 		delete this;
       
   126 		}
       
   127 	}
       
   128 
       
   129 void CWspCOTransaction::ResetFlags()
       
   130 	{
       
   131 	iMoreRequestData		= EFalse;
       
   132 	iSentMethodResultRes	= EFalse;
       
   133 	iClientMethodAbort		= EFalse;
       
   134 	iSuicide				= EFalse;
       
   135 	iFinalResPending		= EFalse;
       
   136 	}
       
   137 
       
   138 CWspHeaderUtils& CWspCOTransaction::GetWspHeaderUtils() const
       
   139 	{
       
   140 	return iHdrUtils;
       
   141 	}
       
   142 
       
   143 void CWspCOTransaction::MethodInvoke()
       
   144 	{
       
   145 	__ASSERT_DEBUG( iMethodState == ENullMethod, Panic(KWspPanicMethodAlreadyActive) );
       
   146 
       
   147 	__LOG1(_L("Trans %d - Sending S-MethodInvoke.req"), Transaction().Id());
       
   148 	
       
   149 	// Down-cast to derived CTxData object
       
   150 	CWspCOTxData* txData = STATIC_CAST(CWspCOTxData*, iTxData);
       
   151 
       
   152 	// Get the request body data supplier
       
   153 	MHTTPDataSupplier& dataSupplier = txData->RequestBodyData();
       
   154 	TPtrC8 bodyData;
       
   155 	iMoreRequestData = !dataSupplier.GetNextDataPart(bodyData);
       
   156 
       
   157 	// Send the S-MethodInvoke.req primitive
       
   158 	RHTTPRequest request = iTrans.Request();
       
   159 	iMethodInvoker.MethodInvokeReq(
       
   160 								  *this, 
       
   161 								  request.Method(), 
       
   162 								  request.URI(), 
       
   163 								  txData->RequestHeadersData(),
       
   164 								  bodyData,
       
   165 								  iMoreRequestData
       
   166 								  );
       
   167 	// WSP method transaction is requesting - update state
       
   168 	iMethodState = ERequesting;
       
   169 
       
   170 	__LOG(_L("---Method in Requesting state"));
       
   171 
       
   172 	// Release request body data
       
   173 	dataSupplier.ReleaseData();
       
   174 	}
       
   175 
       
   176 void CWspCOTransaction::MethodInvokeData()
       
   177 	{
       
   178 	__ASSERT_DEBUG( iNegotiatedCapInfo.GetProtocolOptions() & ELargeDataTransfer, Panic(KWspPanicLDTNotSuppoted) );
       
   179 	__ASSERT_DEBUG( iMethodState == ERequesting, Panic(KWspPanicNotExpectingMoreRequestData) );
       
   180 
       
   181 	__LOG1(_L("Trans %d - Sending S-MethodInvokeData.req"), Transaction().Id());
       
   182 
       
   183 	// Down-cast to derived CTxData object
       
   184 	CWspCOTxData* txData = STATIC_CAST(CWspCOTxData*, iTxData);
       
   185 
       
   186 	// Get the request body data supplier
       
   187 	MHTTPDataSupplier& dataSupplier = txData->RequestBodyData();
       
   188 	TPtrC8 bodyData;
       
   189 	iMoreRequestData = !dataSupplier.GetNextDataPart(bodyData);
       
   190 
       
   191 	// Send the S-MethodInvoke.req primitive
       
   192 	iMethodInvoker.MethodInvokeDataReq(
       
   193 									  *this, 
       
   194 									  bodyData,
       
   195 									  txData->RequestHeadersData(),
       
   196 									  iMoreRequestData
       
   197 									  );
       
   198 
       
   199 	__LOG(_L("---Method in Requesting state"));
       
   200 
       
   201 	// WSP method transaction remains in requesting state - do nothing.
       
   202 	// Release request body data
       
   203 	dataSupplier.ReleaseData();
       
   204 	}
       
   205 
       
   206 void CWspCOTransaction::MethodAbort()
       
   207 	{
       
   208 	__ASSERT_DEBUG( iMethodState != EAborting && iMethodState != ENullMethod, Panic(KWspPanicBadMethodState) );
       
   209 
       
   210 	__LOG1(_L("Trans %d - Sending S-MethodAbort.req"), Transaction().Id());
       
   211 
       
   212 	// Cancel any pending primitives that are waiting to be sent
       
   213 	iPrimitiveSender->Cancel();
       
   214 
       
   215    	// Abort the method - send the S-MethodAbort.req
       
   216    	iMethodInvoker.MethodAbortReq(*this);
       
   217    
       
   218    	// WSP method transaction is aborting - update state
       
   219    	iMethodState = EAborting;
       
   220 
       
   221 	__LOG(_L("---Method in Aborting state"));
       
   222 	}
       
   223 
       
   224 void CWspCOTransaction::MethodResultRes()
       
   225 	{
       
   226 	// Send the S-MethodResult.res primitive
       
   227 	iMethodInvoker.MethodResultRes(*this, KNullDesC8());
       
   228 
       
   229 	// Ensure the S-MethodResultData.res is not sent again
       
   230 	iSentMethodResultRes = ETrue;
       
   231 
       
   232 	// Sent the .res primitive - update.
       
   233 	PostResProcessing();
       
   234 	}
       
   235 
       
   236 void CWspCOTransaction::MethodResultDataRes()
       
   237 	{
       
   238 	// Send the S-MethodResultData.cnf primitive
       
   239 	iMethodInvoker.MethodResultDataRes(*this, KNullDesC8());
       
   240 
       
   241 	// Sent the .res primitive - update.
       
   242 	PostResProcessing();
       
   243 	}
       
   244 
       
   245 void CWspCOTransaction::PostResProcessing()
       
   246 	{
       
   247 	// Check the WSP method transaction state
       
   248 	if( iMethodState == ECompleting )
       
   249 		{
       
   250 		__ASSERT_DEBUG( iFinalResPending, Panic(KWspPanicBadMethodState) );
       
   251 
       
   252 		// WSP method state is in the Null state - update state
       
   253 		iMethodState = ENullMethod;
       
   254 
       
   255 		__LOG(_L("---Method in Null state"));
       
   256 
       
   257 		// Reset the final .res pending flag
       
   258 		iFinalResPending = EFalse;
       
   259 
       
   260 		// Need to inform observer that this method has sent the final .res 
       
   261 		// primitive.
       
   262 		iObserver.NotifyMethodComplete();
       
   263 
       
   264 		// Check to see if the transaction has been closed.
       
   265 		if( iSuicide )
       
   266 			{
       
   267 			__LOG(_L("---Transaction has been closed - suiciding!"));
       
   268 
       
   269 			// Transaction is closed - self-destruct
       
   270 			delete this;
       
   271 			}
       
   272 		}
       
   273 #ifdef _DEBUG
       
   274 	else
       
   275 		{
       
   276 		__ASSERT_DEBUG( iMethodState == EWaiting2, Panic(KWspPanicBadMethodState) );
       
   277 		__LOG(_L("---Method in Waiting2 state"));
       
   278 		}
       
   279 #endif
       
   280 	}
       
   281 
       
   282 void CWspCOTransaction::ProcessResponseDataL(const TDesC8& aResponseHeaders, MHTTPDataSupplier& aResponseBody, TBool aMoreData)
       
   283 	{
       
   284 	// Create the rx data object
       
   285 	CreateRxDataL(iObserver);
       
   286 	
       
   287 	// Set-up the response data object
       
   288 	STATIC_CAST(CWspCORxData*, iRxData)->SetResponseDataL(aResponseHeaders, aResponseBody, aMoreData);
       
   289 	}
       
   290 
       
   291 /*
       
   292  *	Methods from CProtTransaction
       
   293  */
       
   294 
       
   295 void CWspCOTransaction::CreateTxDataL()
       
   296 	{
       
   297 	__ASSERT_DEBUG( iTxData == NULL, Panic(KWspPanicTxDataObjectNotReset) );
       
   298 
       
   299 	iTxData = CWspCOTxData::NewL(*this, *this, iNegotiatedCapInfo);
       
   300 	}
       
   301 
       
   302 void CWspCOTransaction::CreateRxDataL(MRxDataObserver& aObserver)
       
   303 	{
       
   304 	__ASSERT_DEBUG( iRxData == NULL, Panic(KWspPanicRxDataObjectNotReset) );
       
   305 
       
   306 	iRxData = CWspCORxData::NewL(*this, aObserver, *this);	
       
   307 	}
       
   308 
       
   309 /*
       
   310  *	Methods from MWspCOMethodCallback
       
   311  */
       
   312 
       
   313 void CWspCOTransaction::MethodInvokeCnf()
       
   314 	{
       
   315 	__ASSERT_DEBUG( iMethodState == ERequesting, Panic(KWspPanicBadMethodState) );
       
   316 
       
   317 	__LOG1(_L("Trans %d - Received S-MethodInvoke.cnf"), Transaction().Id());
       
   318 	__LOG1(_L("---More Data flag : %d."), iMoreRequestData);
       
   319 
       
   320 	// Inform the Tx data object that cnf has been received.
       
   321 	STATIC_CAST(CWspCOTxData*, iTxData)->ReceivedCnf();
       
   322 
       
   323 	// Is the requst complete? Stay in requesting if not.
       
   324 	if( !iMoreRequestData )
       
   325 		{
       
   326 		// The request is complete - all the request body data has been received
       
   327 		// and, as iMoreRequestData is cleared, all the headers and body data 
       
   328 		// have been sent. Can delete the Tx data object.
       
   329 		ResetTxData();
       
   330 
       
   331 		// WSP method transaction is waiting - update state
       
   332 		iMethodState = EWaiting;
       
   333 
       
   334 		__LOG(_L("---Method in Waiting state"));
       
   335 		}
       
   336 #if defined (_DEBUG) && defined (_LOGGING)
       
   337 	else
       
   338 		__LOG(_L("---Method in Requesting state"));
       
   339 #endif
       
   340 	}
       
   341 
       
   342 void CWspCOTransaction::MethodInvokeDataCnf()
       
   343 	{
       
   344 	__ASSERT_DEBUG( iMethodState == ERequesting, Panic(KWspPanicBadMethodState) );
       
   345 
       
   346 	__LOG1(_L("Trans %d - Received S-MethodInvokeData.cnf"), Transaction().Id());
       
   347 	__LOG1(_L("---More Data flag : %d."), iMoreRequestData);
       
   348 
       
   349 	// Inform the Tx data object that cnf has been received.
       
   350 	STATIC_CAST(CWspCOTxData*, iTxData)->ReceivedCnf();
       
   351 
       
   352 	// Is the requst complete? Stay in requesting if not.
       
   353 	if( !iMoreRequestData )
       
   354 		{
       
   355 		// The request is complete - all the request body data has been received
       
   356 		// and, as iMoreRequestData is cleared, all the headers and body data 
       
   357 		// have been sent. Can delete the Tx data object.
       
   358 		ResetTxData();
       
   359 
       
   360 		// WSP method transaction is waiting - update state
       
   361 		iMethodState = EWaiting;
       
   362 
       
   363 		__LOG(_L("---Method in Waiting state"));
       
   364 		}
       
   365 #if defined (_DEBUG) && defined (_LOGGING)
       
   366 	else
       
   367 		__LOG(_L("---Method in Requesting state"));
       
   368 #endif
       
   369 	}
       
   370 
       
   371 void CWspCOTransaction::MethodAbortInd(TWspReason aReason)
       
   372 	{
       
   373 	__ASSERT_DEBUG( iMethodState != ENullMethod, Panic(KWspPanicBadMethodState) );
       
   374 
       
   375 	__LOG1(_L("Trans %d - Received S-MethodAbort.ind"), Transaction().Id());
       
   376 	__LOG1(_L("---Abort reason : %d"), aReason);
       
   377 
       
   378 	// Cancel any pending primitives that are waiting to be sent
       
   379 	iPrimitiveSender->Cancel();
       
   380 	if( iFinalResPending )
       
   381 		{
       
   382 		// Reset the final .res pending flag
       
   383 		iFinalResPending = EFalse;
       
   384 
       
   385 		// Need to inform observer that this method has sent the final .res 
       
   386 		// primitive.
       
   387 		iObserver.NotifyMethodComplete();
       
   388 		}
       
   389 
       
   390 	// The method has been aborted - check to see if the client initiated the 
       
   391 	// abort or not.
       
   392 	if( !iClientMethodAbort )
       
   393 		{
       
   394 		__LOG(_L("---Method was aborted by the proxy - need to  inform the client."));
       
   395 
       
   396 		// The method was NOT aborted by the client - need to fail the 
       
   397 		// transaction. Check the abort reason for EOutOfMemory.
       
   398 		THTTPEvent event = THTTPEvent::EFailed;
       
   399 		if( aReason == EOutOfMemory )
       
   400 			{
       
   401 			// Send KErrNoMemory event - the validation filter will ensure an 
       
   402 			// EFailed event is also sent.
       
   403 			event = KErrNoMemory;
       
   404 			}
       
   405 		TRAPD(err, Transaction().SendEventL(event,
       
   406 											THTTPEvent::EIncoming,
       
   407 											THTTPFilterHandle::EProtocolHandler));
       
   408 
       
   409 		// Get the protocol handler to deal with the method abort.
       
   410 		iObserver.HandleMethodAbort(*this);				
       
   411 
       
   412 		// If the event could not be sent, we must take more drastic action.  Note that
       
   413 		// this _must_ follow the observer's handling of method abort, since the use
       
   414 		// of RHTTPTransaction::Fail() is drastic, and could result in the whole
       
   415 		// transaction having been deleted by the time we get back here.
       
   416 		if (err != KErrNone)
       
   417 			Transaction().Fail(THTTPFilterHandle::EProtocolHandler);
       
   418 		}
       
   419 
       
   420 	// WSP method transaction is now Null - update state
       
   421 	iMethodState = ENullMethod;
       
   422 
       
   423 	__LOG(_L("---Method in Null state"));
       
   424 
       
   425 	// Check to see if the client has closed the transaction. In this case the
       
   426 	// suicide flag is set and need to self-destruct.
       
   427 	if( iSuicide )
       
   428 		{
       
   429 		__LOG(_L("---Transaction has been closed - suiciding!"));
       
   430 
       
   431 		// Transaction is closed - self-destruct
       
   432 		delete this;
       
   433 		}
       
   434 	}
       
   435 
       
   436 void CWspCOTransaction::MethodResultInd(
       
   437 										TInt					aStatus, 
       
   438 										const TDesC8&			aResponseHeaders, 
       
   439 										MHTTPDataSupplier&		aResponseBody,
       
   440 										TBool					aMoreData
       
   441 										)
       
   442 	{
       
   443 	__ASSERT_DEBUG( iMethodState == EWaiting, Panic(KWspPanicBadMethodState) );
       
   444 
       
   445 	__LOG1(_L("Trans %d - Received S-MethodResult.ind"), Transaction().Id());
       
   446 	__LOG1(_L("---More Data flag : %d."), aMoreData);
       
   447 
       
   448 	// Are there more S-MethodResultData primitives to follow?
       
   449 	if( aMoreData )
       
   450 		{
       
   451 		// WSP method transaction is in Waiting2 state - update state
       
   452 		iMethodState = EWaiting2;
       
   453 
       
   454 		__LOG(_L("---Method in Waiting2 state"));
       
   455 		}
       
   456 	else
       
   457 		{
       
   458 		// WSP method transaction is in Completing state - update state
       
   459 		iMethodState = ECompleting;
       
   460 
       
   461 		__LOG(_L("---Method in Completing state"));
       
   462 		}
       
   463 
       
   464 	// Decode response status code from WSP binary representation
       
   465 	TInt httpStatus = 0;
       
   466 	if ((aStatus >= 0x10) && (aStatus <= 0x65))
       
   467 		{
       
   468 		// Calculate this status code in decimal
       
   469 		httpStatus = 100*(aStatus/0x10);
       
   470 		if (httpStatus == 500)
       
   471 			httpStatus = 416;
       
   472 		if (httpStatus == 600)
       
   473 			httpStatus = 500;
       
   474 		httpStatus += aStatus & 0xf;
       
   475 		}
       
   476 
       
   477 	// Set the response status
       
   478 	iTrans.Response().SetStatusCode(httpStatus);
       
   479 
       
   480 	// Process the response header and body data.
       
   481 	TRAPD(error, ProcessResponseDataL(aResponseHeaders, aResponseBody, aMoreData));
       
   482 
       
   483 	// Check everything went ok
       
   484 	if( error != KErrNone )
       
   485 		{
       
   486 		// Ok the S-MethodResult primitive was not dealt with correctly - abort
       
   487 		// the method
       
   488 		iPrimitiveSender->InitiateSend(ESMethodAbort);
       
   489 
       
   490 		__LOG1(_L("---Could not deal with S-MethodResult.ind primitive. Error : %d"), error);
       
   491 		__LOG( _L("---Aborting the method."));
       
   492 		}
       
   493 	}
       
   494 
       
   495 void CWspCOTransaction::MethodResultDataInd(const TDesC8& aTrailerHeaders, TBool aMoreData)
       
   496 	{
       
   497 	__ASSERT_DEBUG( iMethodState == EWaiting2, Panic(KWspPanicBadMethodState) );
       
   498 
       
   499 	__LOG1(_L("Trans %d - Received S-MethodResultData.ind"), Transaction().Id());
       
   500 	__LOG1(_L("---More Data flag : %d."), aMoreData);
       
   501 
       
   502 	// Are there more S-MethodResultData primitives to follow? If there are
       
   503 	// more S-MethodResultData primitives to follow then the WSP method 
       
   504 	// transaction remains in Waiting2 state - no need to update the state.
       
   505 	if( !aMoreData )
       
   506 		{
       
   507 		// No more S-MethodResultData primitives to follow. WSP method 
       
   508 		// transaction is in Completing state - update state
       
   509 		iMethodState = ECompleting;
       
   510 
       
   511 		__LOG(_L("---Method in Completing state"));
       
   512 		}
       
   513 #if defined (_DEBUG) && defined (_LOGGING)
       
   514 	else
       
   515 		__LOG(_L("---Method in EWaiting2 state"));
       
   516 #endif
       
   517 
       
   518 	// Update the response data object
       
   519 	TRAPD(error, 
       
   520 		  STATIC_CAST(CWspCORxData*, iRxData)->UpdateResponseDataL(aTrailerHeaders, aMoreData));
       
   521 
       
   522 	// Check everything went ok
       
   523 	if( error != KErrNone )
       
   524 		{
       
   525 		// Ok the S-MethodResultData primitive was not dealt with correctly - 
       
   526 		// abort the method
       
   527 		iPrimitiveSender->InitiateSend(ESMethodAbort);
       
   528 
       
   529 		__LOG1(_L("---Could not deal with S-MethodResultData.ind primitive. Error : %d"), error);
       
   530 		__LOG( _L("---Aborting the method."));
       
   531 		}
       
   532 	}
       
   533 
       
   534 /*
       
   535  * Methods from MWspPrimitiveSenderCallback
       
   536  */
       
   537 
       
   538 void CWspCOTransaction::SendPrimitiveL(TWspPrimitive aPrimitive)
       
   539 	{
       
   540 	// Check that the primitive is one that is supported
       
   541 	switch( aPrimitive )
       
   542 		{
       
   543 	case ESMethodInvokeData:
       
   544 		{
       
   545 		MethodInvokeData();
       
   546 		} break;
       
   547 	case ESMethodResult:
       
   548 		{
       
   549 		MethodResultRes();
       
   550 		} break;
       
   551 	case ESMethodResultData:
       
   552 		{
       
   553 		MethodResultDataRes();
       
   554 		} break;
       
   555 	case ESMethodAbort:
       
   556 		{
       
   557 		MethodAbort();
       
   558 		} break;
       
   559 	default:
       
   560 		// Unsupported primitive
       
   561 		User::Leave(KWspErrUnsupportedSendPrimitive);
       
   562 		break;
       
   563 		}
       
   564 	}
       
   565 
       
   566 TInt CWspCOTransaction::WspPrimitiveSenderCallbackError(TInt /*aError*/)
       
   567 	{
       
   568 	// Ok, sending one of the primitives failed. Abort the method
       
   569 	iPrimitiveSender->InitiateSend(ESMethodAbort);
       
   570 
       
   571 	// Signal that this leave has been dealt with.
       
   572 	return KErrNone;
       
   573 	}
       
   574 
       
   575 /*
       
   576  * Methods from MWspCORxDataCallback
       
   577  */
       
   578 
       
   579 void CWspCOTransaction::AbortResponse()
       
   580 	{
       
   581 	iPrimitiveSender->InitiateSend(ESMethodAbort);
       
   582 	}
       
   583 
       
   584 void CWspCOTransaction::SendResponsePrimitive()
       
   585 	{
       
   586 	// Set the pending last response primitive flag
       
   587 	iFinalResPending = iMethodState == ECompleting;
       
   588 
       
   589 	// Is this the final .res?
       
   590 	if( iFinalResPending ) 
       
   591 		{
       
   592 		// Inform the observer that this method needs to send the final .res primitive
       
   593 		iObserver.NotifyPendingCompletingMethod();
       
   594 		}
       
   595 
       
   596 	// Check to see if the S-MethodResult primitive has already been responded.
       
   597 	if( iSentMethodResultRes )
       
   598 		{
       
   599 		// Need to send the S-MethodResultData.res
       
   600 		iPrimitiveSender->InitiateSend(ESMethodResultData);
       
   601 		}
       
   602 	else
       
   603 		{
       
   604 		// Need to send the S-MethodResult.res
       
   605 		iPrimitiveSender->InitiateSend(ESMethodResult);
       
   606 		}	
       
   607 	}
       
   608 
       
   609 /*
       
   610  * Methods from MWspCOTxDataCallback
       
   611  */
       
   612 
       
   613 void CWspCOTransaction::SendInvokePrimitive()
       
   614 	{
       
   615 	// Need to check the state to see what primitive to send.
       
   616 	if( iMethodState == ENullMethod )
       
   617 		{
       
   618 		// Need to send S-MethodInvoke.req primitive - ok to send here as this
       
   619 		// would have been caused either by InitRequestL() or by 
       
   620 		// otifyMoreRequestData()
       
   621 		MethodInvoke();
       
   622 		}
       
   623 	else
       
   624 		{
       
   625 		__ASSERT_DEBUG( iMethodState == ERequesting, Panic(KWspPanicBadMethodState) );
       
   626 
       
   627 		// Need to send S-MethodInvokeData.req - defer sending as could be in 
       
   628 		// callstack from either MethodInvokeCnf() or MethodInvokeDataCnf().
       
   629 		iPrimitiveSender->InitiateSend(ESMethodInvokeData);
       
   630 		}
       
   631 	}
       
   632 
       
   633 void CWspCOTransaction::AbortInvoke()
       
   634 	{
       
   635 	// Check the state - no need to send S-MethodAbort primitive if the method
       
   636 	// is still in the null state.
       
   637 	if( iMethodState == ENullMethod )
       
   638 		{
       
   639 		// Inform the client that the tranaction has failed.
       
   640 		TRAPD(err, Transaction().SendEventL(THTTPEvent::EFailed,
       
   641 											THTTPEvent::EIncoming,
       
   642 											THTTPFilterHandle::EProtocolHandler));
       
   643 
       
   644 		// Get the protocol handler to deal with the method abort.
       
   645 		iObserver.HandleMethodAbort(*this);				
       
   646 
       
   647 		// If the event could not be sent, we must take more drastic action.  Note that
       
   648 		// this _must_ follow the observer's handling of method abort, since the use
       
   649 		// of RHTTPTransaction::Fail() is drastic, and could result in the whole
       
   650 		// transaction having been deleted by the time we get back here.
       
   651 		if (err != KErrNone)
       
   652 			Transaction().Fail(THTTPFilterHandle::EProtocolHandler);
       
   653 		}
       
   654 	else
       
   655 		{
       
   656 		__ASSERT_DEBUG( iMethodState == ERequesting, Panic(KWspPanicBadMethodState) );
       
   657 
       
   658 		// Send MethodAbort.req primitive - defer sending as could be in 
       
   659 		// callstack from either MethodInvokeCnf() or MethodInvokeDataCnf().
       
   660 		iPrimitiveSender->InitiateSend(ESMethodAbort);
       
   661 		}
       
   662 	}