--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/webservices/wsframework/src/senwebservicesession.cpp Thu Jan 07 16:19:19 2010 +0200
@@ -0,0 +1,2158 @@
+/*
+* Copyright (c) 2002-2005 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 FILES
+#include "senwebservicesession.h"
+
+#include <SenServiceConnection.h> // error codes etc
+
+#include "senservicesession.h"
+#include "SenServiceConnection.h" // session status constants
+#include "SenSoapMessage.h"
+#include "senwsdescription.h"
+#include "msencoreservicemanager.h"
+#include "msenremoteserviceconsumer.h"
+#include "SenXmlUtils.h"
+#include "SenDateUtils.h"
+#include "msentransport.h"
+#include "SenCredential.h"
+//#include "SenPolicy.h"
+#include "SenSoapFault.h"
+#include "sendebug.h"
+#include "senservicemanagerdefines.h"
+#include "senservicepolicy.h"
+#include "seninternalcredential.h"
+#include "sensaxutils.h"
+#include <xmlengnodelist.h>
+#include <SenIdentityProvider.h>
+#include "senlogger.h"
+#include <SenXmlConstants.h>
+
+#include <SenTransportProperties.h>
+// CONSTANTS
+
+namespace
+ {
+ _LIT8(KServiceInterval1,"ServiceInterval");
+ _LIT(KInvalideDate,"19000101:");
+ /* microseconds before actual notOnOrAfter time
+ * when credentials are treated
+ * as expired.
+ */
+ const TInt KClockSlipMicroSeconds = 3*60*1000*1000;
+
+ // constants for parsing
+ _LIT8(KSDFramework,"<ServiceDescription framework=\"");
+ _LIT8(KContractStart, "<Contract>");
+ _LIT8(KContractEnd, "</Contract>");
+ _LIT8(KTagWithAttrEnd, "\">");
+ _LIT8(KEndPointStart, "<Endpoint>");
+ _LIT8(KEndPointStartWithCue, "<Endpoint cue=\"");
+ _LIT8(KTagWithAttrClose, "\"/>");
+ _LIT8(KEndPointEnd, "</Endpoint>");
+ _LIT8(KCredentialsStart, "<Credentials");
+ _LIT8(KCredentialsEnd, "</Credentials>");
+ _LIT8(KNotOnOrAfterFormat, " notOnOrAfter=\"%S\" >");
+ _LIT8(KEmptyTagEnd, " >");
+ _LIT8(KSDEnd, "</ServiceDescription>");
+ // localnames for element(s)
+ _LIT8(KProviderPolicyLocalName, "ProviderPolicy");
+ _LIT8(KNewLine, "\n");
+
+ const TInt KCredIdBufSize = 128;
+ _LIT8(KCredentialIdLocalName, "SenCredentialId");
+ _LIT8(KCredentialIdStart, "<SenCredentialId>");
+ _LIT8(KCredentialIdEnd, "</SenCredentialId>");
+ _LIT8(KEndpointLocalname, "Endpoint");
+// _LIT8(KContractLocalname, "Contract");
+ }
+
+EXPORT_C CSenWebServiceSession::CSenWebServiceSession(TDescriptionClassType aType,
+ MSIF& aFramework)
+: CSenServiceSession(aType, aFramework)
+ {
+ }
+
+EXPORT_C void CSenWebServiceSession::ConstructL()
+ {
+
+ // Sets the local name to "ServiceDescription"
+ // and initiates the inner ipElement
+ CSenServiceSession::BaseConstructL();
+ // Init member variables
+ iClientServerInterval = 0;
+ iValidUntil = Time::NullTTime();
+ iFrameworkId = iFramework.Id().AllocL();
+ }
+
+EXPORT_C CSenWebServiceSession::~CSenWebServiceSession()
+ {
+ delete iSecurity;
+ delete iContract;
+ delete iEndpoint;
+ delete iFrameworkId;
+ iFrameworkId = NULL;
+ delete iTransportCue;
+ iTransportCue = NULL;
+ iCredentialPtr.RemoveCredentialObserver(*this);
+ iCredentialPtr.Close();
+ }
+
+EXPORT_C TPtrC8 CSenWebServiceSession::TransportCue()
+ {
+ if( iTransportCue )
+ {
+ return *iTransportCue;
+ }
+ else
+ {
+ return CSenServiceSession::TransportCue();
+ }
+ }
+
+EXPORT_C TInt CSenWebServiceSession::InitializeFromL(MSenServiceDescription& aServiceDescription)
+ {
+ TLSLOG(KSenCoreServiceManagerLogChannelBase , KMinLogLevel,_L("Zapping filelogged messages (.xml)"));
+
+ // Call superclass method to initialize facets, transport (endpoint) cue, etc..
+ CSenServiceSession::InitializeFromL(aServiceDescription);
+
+ HBufC8* pContract = aServiceDescription.Contract().AllocL();
+ delete iContract;
+ iContract = pContract;
+
+ HBufC8* pEndpoint = aServiceDescription.Endpoint().AllocL();
+ delete iEndpoint;
+ iEndpoint = pEndpoint;
+
+ if(aServiceDescription.DescriptionClassType()
+ ==
+ MSenServiceDescription::EWSDescription
+ ||
+ aServiceDescription.DescriptionClassType()
+ ==
+ MSenServiceDescription::EWSPattern
+ ||
+ aServiceDescription.DescriptionClassType()
+ ==
+ MSenServiceDescription::EIdentityProvider
+ )
+ {
+
+ CSenWSDescription& xmlDesc =
+ (CSenWSDescription&)aServiceDescription;
+
+ CSenElement* pElement =
+ (xmlDesc.AsElement()).Element(KServiceInterval1);
+ if(pElement)
+ {
+ TLex8 lex(pElement->Content());
+ TInt64 val;
+ User::LeaveIfError(lex.Val(val));
+ iClientServerInterval = val;
+ TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase, KNormalLogLevel , _L8("Interval in microseconds (from file): %d"),
+ iClientServerInterval.Int64()));
+ }
+
+ RCredentialList& credentials = xmlDesc.Credentials();
+ TInt count(credentials.Count());
+ for(TInt i=0; i<count; i++)
+ {
+ CSenCredential* pCredential = credentials[i];
+ if(pCredential)
+ {
+ // note: errors while adding single credential must ignored:
+ // - the remaining credentials (array) must be processed..
+
+ //CSenCredential* pCopy = CSenCredential::NewL(*pCredential);
+ //CleanupStack::PushL(pCopy);
+ AddCredentialL(*pCredential);
+ //CleanupStack::Pop(); // pCopy
+ }
+ }
+ // rebuild provider policy definition
+ RebuildFrom(xmlDesc);
+ // update provider policy information (new feature)
+
+ MSenServicePolicy* servicePolicy = ServicePolicy();
+ if(servicePolicy)
+ {
+ MSenServicePolicy* givenServicePolicy = xmlDesc.ServicePolicy();
+ if(givenServicePolicy)
+ (CSenServicePolicy*)servicePolicy->RebuildServicePolicyFrom(*givenServicePolicy);
+ }
+ }
+ SetStatusL();
+ return KErrNone; // err value not currently in use
+ }
+
+EXPORT_C TInt CSenWebServiceSession::ComputeStatusL()
+ {
+ TInt retVal = CSenServiceSession::ComputeStatusL();
+
+ if (retVal == KSenConnectionStatusReady)
+ {
+ TTime now;
+ now.UniversalTime();
+ now += iClientServerInterval;
+
+#ifdef _SENDEBUG
+ if (iValidUntil != Time::NullTTime())
+ {
+ TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase, KNormalLogLevel , _L8("Client-Server Interval in microseconds: %d"),
+ iClientServerInterval.Int64()));
+
+ TBuf8<SenDateUtils::KXmlDateTimeMaxLength> ts;
+ TInt leaveCode(KErrNone);
+ TRAP(leaveCode, SenDateUtils::ToXmlDateTimeUtf82L(ts, now);)
+ if (leaveCode == KErrNone)
+ {
+
+ TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase , KNormalLogLevel, _L8("Fixed client time : %S"), &ts));
+
+ TBuf8<SenDateUtils::KXmlDateTimeMaxLength> ts2;
+ TRAP(leaveCode, SenDateUtils::ToXmlDateTimeUtf82L(ts2, iValidUntil);)
+ TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase , KNormalLogLevel, _L8("Credential time : %S, clockslip: %d micros"), &ts2, KClockSlipMicroSeconds));
+ }
+ leaveCode = 0; // not used
+ }
+#endif // _SENDEBUG
+
+ if ((iValidUntil != Time::NullTTime() ) &&
+ now >
+ (iValidUntil-TTimeIntervalMicroSeconds(KClockSlipMicroSeconds)))
+ {
+ TLSLOG(KSenCoreServiceManagerLogChannelBase , KMinLogLevel ,_L("Credential is expired."));
+ retVal = KSenConnectionStatusExpired;
+ }
+ }
+ return retVal;
+ }
+
+EXPORT_C TBool CSenWebServiceSession::IsExpiredL()
+ {
+ ComputeStatusL();
+ return (CSenServiceSession::StatusL() == KSenConnectionStatusExpired);
+ }
+
+EXPORT_C TInt CSenWebServiceSession::AddCredentialL(
+ CSenCredential& aCredential)
+ {
+ if ( aCredential.AsElement().LocalName() == KCredentialIdLocalName )
+ {
+ delete iSecurity;
+ iSecurity = NULL;
+ iSecurity = aCredential.AsXmlL();
+
+ TInt credentialId;
+ TLex8 lex;
+ lex.Assign(aCredential.AsElement().Content());
+ lex.Val(credentialId);
+
+ TInt error(KErrNone);
+ RSenCredentialPtr credentialPtr;
+ credentialPtr = ((MSenServiceManager&)iFramework.Manager()).CredentialL(credentialId,
+ error);
+ if ( error == KErrNone )
+ {
+ iCredentialPtr = credentialPtr.Clone();
+ iCredentialPtr.AddCredentialObserverL(*this); //codescannerwarnings
+ iValidUntil = iCredentialPtr.Credential()->ValidUntil();
+ if ( iClientServerInterval == 0 )
+ {
+ TPtrC8 value;
+ TInt ret = iCredentialPtr.Credential()->PropertiesL().PropertyL( KServiceInterval1,
+ value );
+ if ( ret == KErrNone )
+ {
+ TLex8 lex(value);
+ TInt64 val;
+ ret = lex.Val(val);
+ if ( ret == KErrNone )
+ {
+ iClientServerInterval = val;
+ }
+ }
+ }
+ }
+ else
+ {
+ // invalidate the session, because we have no credential
+ iValidUntil.Set(KInvalideDate); // way back in history: January 1st 1900
+
+ iCredentialPtr.RemoveCredentialObserver(*this);
+ iCredentialPtr.Close();
+
+ delete iSecurity;
+ iSecurity = NULL;
+
+ TBuf8<KCredIdBufSize> buffer;
+ buffer.Num(KErrNotFound);
+
+ iSecurity = HBufC8::NewL(buffer.Length()+KCredentialIdStart().Length()+KCredentialIdEnd().Length());
+ TPtr8 sec = iSecurity->Des();
+ sec.Append(KCredentialIdStart);
+ sec.Append(buffer);
+ sec.Append(KCredentialIdEnd);
+ }
+ }
+ else
+ {
+ TInt retVal(KErrNone);
+
+ delete iSecurity;
+ iSecurity = NULL;
+ HBufC8* pSecurityToken = 0;
+ retVal = ConstructSecurityTokenL(aCredential, pSecurityToken);
+ if (KErrNone != retVal)
+ {
+ if ( pSecurityToken != NULL )
+ {
+ delete pSecurityToken;
+ pSecurityToken = NULL;
+ iCredentialPtr.RemoveCredentialObserver(*this);
+ iCredentialPtr.Close();
+ }
+ return retVal;
+ }
+
+ iValidUntil = aCredential.ValidUntil(); // SetSecurityL needs up-to-date iValidUntil(!)
+
+ CleanupStack::PushL(pSecurityToken);
+ SetSecurityL(*pSecurityToken);
+ CleanupStack::PopAndDestroy(pSecurityToken);
+ }
+
+ SetStatusL();
+
+ return KErrNone;
+ }
+
+EXPORT_C TInt CSenWebServiceSession::ConstructSecurityTokenL( CSenCredential& aCredential,
+ HBufC8*& aToken )
+ {
+ aToken = aCredential.AsXmlL();
+ return KErrNone;
+ }
+
+EXPORT_C TInt CSenWebServiceSession::NewMessageL( CSenSoapMessage*& aMessage )
+ {
+ aMessage = CSenSoapMessage::NewL();
+ return KErrNone;
+ }
+
+EXPORT_C TInt CSenWebServiceSession::MessageForSendingL( const TDesC8& aBody,
+ const TDesC8& /* aSenderID */,
+ CSenSoapMessage*& aMessage )
+ {
+ TInt retVal(KErrNone);
+ aMessage = CSenSoapMessage::NewL();
+ CleanupStack::PushL(aMessage);
+ SetFrameworkHeadersL(*aMessage);
+ aMessage->SetBodyL(aBody);
+ CleanupStack::Pop(); // aMessage
+ return retVal;
+ }
+
+EXPORT_C TInt CSenWebServiceSession::ParseResponseL( const TDesC8& aResponse,
+ HBufC8*& aParsed )
+ {
+ TLSLOG_L(KSenCoreServiceManagerLogChannelBase , KMinLogLevel ,"CSenWebServiceSession::ParseResponseL(const TDesC8&, HBufC8*&)");
+ // this called only from the synchronous submit(..) methods
+ TInt retVal(KErrNone);
+ CSenSoapMessage* pSoapMessage = NULL;
+ retVal = ParseResponseL(aResponse, pSoapMessage);
+ if(retVal!=KErrNone)
+ {
+ delete pSoapMessage;
+ return retVal;
+ }
+
+ CleanupStack::PushL(pSoapMessage);
+
+ // Check for completeMessages
+ TBool completeServerMessages;
+ HasFacetL(KCompleteMessagesFacet,completeServerMessages);
+ if (completeServerMessages)
+ {
+ aParsed = pSoapMessage->AsXmlL();
+ }
+ else
+ {
+ // If the message contained SOAP fault it will be in the body.
+ // It's up to the client to check for a Fault.
+ aParsed = pSoapMessage->BodyAsStringL();
+ if (!aParsed)
+ {
+ retVal = KErrSenNoSoapBody;
+ TLSLOG_L(KSenCoreServiceManagerLogChannelBase , KMinLogLevel ,"CSenWebServiceSession::ParseResponseL - NULL from BodyAsStringL - return KErrSenNoSoapBody");
+ }
+ }
+
+ CleanupStack::PopAndDestroy(); // pSoapMessage
+ return retVal;
+ }
+
+
+EXPORT_C TInt CSenWebServiceSession::SendSoapMessageToConsumerL( CSenSoapMessage* apMessage,
+ const TInt aTxnId,
+ MSenRemoteServiceConsumer& aConsumer,
+ MSenProperties* aResponseTransportProperties )
+ {
+ if ( !apMessage )
+ {
+ CSLOG_L(aConsumer.ConnectionId() , KMinLogLevel,"CSenWebServiceSession::SendSoapMessageToConsumerL");
+ CSLOG_L(aConsumer.ConnectionId() , KMinLogLevel,"Fatal()!: NULL argument passed instead of valid pointer to CSenSoapMessage");
+ return HandleErrorL( KErrSenInternal, NULL, aTxnId, aConsumer, aResponseTransportProperties );
+ }
+
+ CleanupStack::PushL(apMessage);
+ CSLOG_L(aConsumer.ConnectionId() , KMinLogLevel,"CSenWebServiceSession::SendSoapMessageToConsumerL");
+ TInt retVal(KErrNone);
+ // Check if consumer wishes to receive complete server messages:
+ TBool completeServerMessages;
+ HasFacetL(KCompleteMessagesFacet, completeServerMessages);
+ if(completeServerMessages)
+ {
+ HBufC8* pMessageAsXML = apMessage->AsXmlL();
+ CleanupStack::PopAndDestroy(apMessage);
+ if (pMessageAsXML)
+ {
+ retVal = aConsumer.HandleMessageL( pMessageAsXML, aTxnId, aResponseTransportProperties );
+ }
+ }
+ else
+ {
+ //HBufC8* pBody = apMessage->BodyL().Content().AllocL();
+ HBufC8* pBody = apMessage->BodyAsStringL();
+ CleanupStack::PopAndDestroy(apMessage);
+ retVal = aConsumer.HandleMessageL( pBody, aTxnId, aResponseTransportProperties );
+ }
+ return retVal;
+ }
+
+// SYNC, takes ownership of apSoapMessage
+EXPORT_C TInt CSenWebServiceSession::HandleSoapFaultL( CSenSoapMessage* apSoapMessage,
+ HBufC8*& aResponse /*,
+ CSenTransportProperties*& aResponseTransportProperties */)
+ {
+ if( apSoapMessage )
+ {
+ CleanupStack::PushL(apSoapMessage);
+ CSenSoapFault* pDetached = apSoapMessage->DetachFaultL();
+ CleanupStack::PopAndDestroy( apSoapMessage );
+ TBool completeServerMessages(ETrue);
+ HasFacetL(KCompleteMessagesFacet, completeServerMessages);
+ if(pDetached)
+ {
+ CleanupStack::PushL(pDetached);
+ // Response contains only soapfault in case no completeServerMessages facet
+ // otherwise it should be left empty
+ // aResponse is updated only when detached soap fault is required.
+ if(completeServerMessages == EFalse)
+ {
+ aResponse = pDetached->AsXmlL();
+ }
+ TLSLOG_L(KSenCoreServiceManagerLogChannelBase , KMinLogLevel ,"CSenWebServiceSession::HandleErrorL:");
+ TLSLOG_L(KSenCoreServiceManagerLogChannelBase , KMinLogLevel ,"- successfully detached SOAP fault:");
+ CleanupStack::PopAndDestroy(pDetached); // pDetached
+ // From *this* method, KErrSenSoapFault is *OK return code*,
+ // just like KErrNone generally is..
+ return KErrSenSoapFault;
+ }
+ }
+ return KErrNotFound; // SOAP fault not found
+ }
+
+// ASYNC, takes ownership of apSoapMessage
+EXPORT_C TInt CSenWebServiceSession::HandleSoapFaultL( CSenSoapMessage* apSoapMessage,
+ const TInt aErrorCode,
+ const TInt aTxnId,
+ MSenRemoteServiceConsumer& aConsumer,
+ MSenProperties* aResponseTransportProperties )
+ {
+ TInt retVal( KErrSenInternal );
+ if ( apSoapMessage )
+ {
+ CleanupStack::PushL(apSoapMessage); // ownership is here
+
+ CSenSoapFault* pDetached = apSoapMessage->DetachFaultL();
+ if(pDetached)
+ {
+ CleanupStack::PopAndDestroy( apSoapMessage ); // de-alloc msg, detach OK
+
+ CleanupStack::PushL(pDetached);
+ HBufC8* pAsXml = pDetached->AsXmlL();
+ CleanupStack::PopAndDestroy(pDetached);
+
+ retVal = aConsumer.HandleErrorL(pAsXml, aErrorCode, aTxnId, aResponseTransportProperties);
+ }
+ else
+ {
+ // Could not detach Soap fault (this method was called, but aSoapMessage did not include fault!)
+ HBufC8* pAsXml = apSoapMessage->AsXmlL();
+ CleanupStack::PopAndDestroy( apSoapMessage ); // de-alloc, serialization ok
+ retVal = aConsumer.HandleErrorL(pAsXml, aErrorCode, aTxnId, aResponseTransportProperties);
+ }
+ }
+ else
+ {
+ CSLOG_L(aConsumer.ConnectionId() , KMinLogLevel,"Fatal(!): CSenWebServiceSession::HandleSoapFaultL - apSoapMessage arg is NULL. ");
+ retVal = aConsumer.HandleErrorL(NULL, aErrorCode, aTxnId, aResponseTransportProperties);
+ }
+ return retVal;
+ }
+
+EXPORT_C TInt CSenWebServiceSession::SendToConsumerL( HBufC8* apMessage,
+ const TInt aTxnId,
+ MSenRemoteServiceConsumer& aConsumer,
+ MSenProperties* aResponseTransportProperties )
+ {
+ CleanupStack::PushL( apMessage );
+ CSLOG_L( aConsumer.ConnectionId(), KMinLogLevel,"CSenWebServiceSession::SendToConsumerL - begin" );
+ TInt retVal(KErrNone);
+
+ // Check whether this is a response to one-way request; in such case,
+ // there is no body to validate (but only few response properties):
+ if ( aResponseTransportProperties )
+ {
+ TBool isOnewayMsgRsp(EFalse);
+ aResponseTransportProperties->BoolPropertyL( KSenOnewayMessageOnOff, isOnewayMsgRsp );
+ if ( isOnewayMsgRsp )
+ {
+ // There is no response body to process, halt the execution of this method in here,
+ // and invoke the consumer immediately:
+ CSLOG_L( aConsumer.ConnectionId(), KMinLogLevel,"-- About to invoke MSenRemoteServiceConsumer::HandleMessageL" );
+ CleanupStack::Pop( apMessage );
+ retVal = aConsumer.HandleMessageL( apMessage, aTxnId, aResponseTransportProperties );
+ CSLOG_FORMAT((aConsumer.ConnectionId() , KMinLogLevel, _L8("CSenWebServiceSession::SendToConsumerL - end: HandleMessageL returned: %d"), retVal));
+ return retVal; // skip the SOAP validation, response carries no body
+ }
+ }
+
+
+ // SOAP orientated implementation:
+ CSenSoapMessage* pSoapMessage = NULL;
+ TInt leaveCode(KErrNone);
+
+ if( apMessage && apMessage->Length() > 0 )
+ {
+ TRAP( leaveCode, retVal = ParseResponseL( *apMessage, pSoapMessage ); )
+ }
+ else // apMessage == NULL or descriptor is of zero-length
+ {
+ if ( !apMessage )
+ {
+ CSLOG_L(aConsumer.ConnectionId() , KMinLogLevel,"- Note: apMessage argument is NULL => response is treated through KErrSenNoSoapBody");
+ }
+ retVal = KErrSenNoSoapBody; // clearly, WSS assumes that all messages are SOAP!
+ }
+
+ if( leaveCode != KErrNone )
+ {
+ // Parsing WAS attempted, but it failed(!)
+ CSLOG_L(aConsumer.ConnectionId() , KMinLogLevel,"CSenWebServiceSession::SendToConsumerL");
+ CSLOG_FORMAT((aConsumer.ConnectionId() , KMinLogLevel, _L8("- Error: response could not be parsed into SOAP msg, leave code from parse: %d"), leaveCode));
+ pSoapMessage = NULL;
+ if( retVal==KErrNone )
+ {
+ // indicate with return value, that response is
+ // invalid - even though submit was ok, the
+ // response could NOT be parsed!
+ retVal = leaveCode;
+ }
+ }
+
+ if(retVal == KErrNone)
+ {
+ CleanupStack::PopAndDestroy(apMessage);
+ CleanupStack::PushL( pSoapMessage );
+ // Response was parsed OK, now check whether it is a SOAP fault:
+ if (pSoapMessage->IsFault())
+ {
+ CleanupStack::Pop(pSoapMessage); // next method takes the ownership:
+ retVal = HandleSoapFaultL(pSoapMessage, KErrSenSoapFault, aTxnId, aConsumer, aResponseTransportProperties);
+ if( retVal == KErrSenSoapFault )
+ {
+ // SOAP fault response is treated as "OK"
+ retVal = KErrNone;
+ }
+ }
+ else
+ {
+ // Response is a valid SOAP envelope
+ CSLOG_L(aConsumer.ConnectionId() , KMinLogLevel ,"CSenWebServiceSession::SendToConsumerL:");
+ CSLOG_L(aConsumer.ConnectionId() , KMinLogLevel ,"- Sending SOAP message to consumer.");
+ CleanupStack::Pop(pSoapMessage); // next method takes the ownership:
+ retVal = SendSoapMessageToConsumerL( pSoapMessage, aTxnId, aConsumer, aResponseTransportProperties );
+#ifdef _SENDEBUG
+ if( retVal!=KErrNone )
+ {
+ CSLOG_L(aConsumer.ConnectionId() , KMinLogLevel,"CSenWebServiceSession::SendToConsumerL:");
+ CSLOG_FORMAT((aConsumer.ConnectionId() , KMinLogLevel, _L8("- SendSoapMessageToConsumerL failed: %d"), retVal ));
+ }
+#endif
+ }
+ }
+ else // error recognized
+ {
+ delete pSoapMessage;
+ pSoapMessage = NULL;
+ CSLOG_L(aConsumer.ConnectionId() , KMinLogLevel,"CSenWebServiceSession::SendToConsumerL");
+ CSLOG_L(aConsumer.ConnectionId() , KMinLogLevel,"- Error: response is not a SOAP message!");
+
+ CleanupStack::Pop(apMessage);
+ retVal = HandleErrorL(retVal, apMessage, aTxnId, aConsumer, aResponseTransportProperties);
+ }
+ CSLOG_L( aConsumer.ConnectionId(), KMinLogLevel,"CSenWebServiceSession::SendToConsumerL - end" );
+ return retVal;
+ }
+
+// THIS IS WHAT TRANSPORT SEES:
+EXPORT_C TInt CSenWebServiceSession::SendErrorToConsumerL( const TInt aErrorCode,
+ HBufC8* apError,
+ const TInt aTxnId,
+ MSenRemoteServiceConsumer& aConsumer,
+ MSenProperties* aResponseTransportProperties )
+ {
+ CleanupStack::PushL(apError);
+ TInt retVal(KErrNone);
+
+ // Check whether this is a response to one-way request; in such case,
+ // there is no body to validate (but only few response properties):
+ if ( aResponseTransportProperties )
+ {
+ TBool isOnewayMsgRsp(EFalse);
+ aResponseTransportProperties->BoolPropertyL( KSenOnewayMessageOnOff, isOnewayMsgRsp );
+ if ( isOnewayMsgRsp )
+ {
+ // There is no response body to process, halt the execution of this method in here,
+ // and invoke the consumer immediately:
+ CSLOG_L( aConsumer.ConnectionId(), KMinLogLevel,"-- About to invoke MSenRemoteServiceConsumer::HandleMessageL" );
+ CleanupStack::Pop( apError );
+ retVal = aConsumer.HandleErrorL( apError, aErrorCode, aTxnId, aResponseTransportProperties );
+ CSLOG_FORMAT((aConsumer.ConnectionId() , KMinLogLevel, _L8("CSenWebServiceSession::SendToConsumerL - end: HandleMessageL returned: %d"), retVal));
+ return retVal; // skip the SOAP validation, response carries no body
+ }
+ }
+
+ // SOAP orientated implementation:
+ CSenSoapMessage* pSoapMessage = NULL;
+
+ TInt leaveCode(KErrNone);
+
+ if( apError && apError->Length() > 0 )
+ {
+ TRAP( leaveCode, retVal = ParseResponseL( *apError, pSoapMessage ); )
+ }
+ else // apMessage == NULL or descriptor is of zero-length
+ {
+ if ( !apError )
+ {
+ CSLOG_L(aConsumer.ConnectionId() , KMinLogLevel,"- Note: apError argument is NULL => response is treated through KErrSenNoSoapBody");
+ }
+ retVal = KErrSenNoSoapBody; // clearly, WSS assumes that all messages are SOAP!
+ }
+
+ if( leaveCode != KErrNone )
+ {
+ // Parsing WAS attempted, but it failed(!)
+ pSoapMessage = NULL;
+
+ // THE RESPONSE IS NOT SOAP
+ CSLOG_L(aConsumer.ConnectionId() , KMinLogLevel,"CSenWebServiceSession::SendErrorToConsumerL");
+ CSLOG_L(aConsumer.ConnectionId() , KMinLogLevel,"- Error: response could not be parsed into SOAP msg!");
+ CSLOG_FORMAT((aConsumer.ConnectionId() , KMinLogLevel, _L8("- ParseResponseL leaved: %d"), leaveCode ));
+ if( aErrorCode == KErrNone )
+ {
+ // In this rare case, indicate that SOAP envelope was broken!
+ // So, return KErrSenBrokenSoapEnvelope in here.
+ CSLOG_L(aConsumer.ConnectionId() , KMinLogLevel,"- aErrorCode==KErrNone, but SOAP env is broken!");
+
+ CleanupStack::Pop(apError);
+ retVal = HandleErrorL(KErrSenBrokenSoapEnvelope, apError, aTxnId, aConsumer, aResponseTransportProperties);
+ }
+ else
+ {
+ CSLOG_FORMAT((aConsumer.ConnectionId() , KMinLogLevel, _L8("- Returning error code received from transport: %d"),
+ aErrorCode));
+
+ CleanupStack::Pop(apError);
+ retVal = HandleErrorL(aErrorCode, apError, aTxnId, aConsumer, aResponseTransportProperties);
+ }
+ }
+ else // ParseResponseL did not leave
+ {
+ if (retVal == KErrNone )
+ {
+ CleanupStack::PopAndDestroy(apError);
+ // ParseResponseL OK
+ // Call for functionality which checks certain, "recoverable" SOAP errors:
+ // Some frameworks might be able to handle certain SOAP faults themselves
+ retVal = HandleSoapFaultL(pSoapMessage, aErrorCode, aTxnId, aConsumer, aResponseTransportProperties);
+ }
+ else // parsing failed or apError == NULL
+ {
+ delete pSoapMessage;
+ // ParseResponseL NOT ok!
+ CSLOG_L(aConsumer.ConnectionId() , KMinLogLevel,"CSenWebServiceSession::SendErrorToConsumerL");
+ CSLOG_L(aConsumer.ConnectionId() , KMinLogLevel,"- Error: response is not a SOAP message!");
+ if ( aErrorCode == KErrNone )
+ {
+ // Rare case: for some odd reason transport did not return error code:
+ // - return the error code from ParseResponseL
+ CSLOG_L(aConsumer.ConnectionId() , KNormalLogLevel,"- Transport did not return error code.");
+ CleanupStack::Pop(apError);
+ retVal = HandleErrorL(retVal, apError, aTxnId, aConsumer, aResponseTransportProperties);
+ }
+ else
+ {
+ // Just pass forward the error code received from transport:
+ CSLOG_L(aConsumer.ConnectionId() , KNormalLogLevel,"- Just pass forward error code from transport.");
+ CleanupStack::Pop(apError);
+ retVal = HandleErrorL(aErrorCode, apError, aTxnId, aConsumer, aResponseTransportProperties);
+ }
+ }
+ }
+ return retVal;
+ }
+
+EXPORT_C TInt CSenWebServiceSession::HandleErrorL( const TInt aErrorCode,
+ HBufC8* apError,
+ const TInt aTxnId,
+ MSenRemoteServiceConsumer& aConsumer,
+ MSenProperties* aResponseTransportProperties )
+ {
+ // Current implementation does not handle non-SOAP errors
+ // that occured at transport layer. Instead, the error is
+ // simply passed to consumer:
+ return aConsumer.HandleErrorL(apError, aErrorCode, aTxnId, aResponseTransportProperties);
+ // Frameworks should override this method in order to recover
+ // from specific errors/faults
+ }
+
+
+EXPORT_C CSenXmlReader* CSenWebServiceSession::XmlReader()
+ {
+ return iFramework.Manager().XMLReader();
+ }
+
+EXPORT_C TInt CSenWebServiceSession::ParseResponseL(const TDesC8& aResponse,
+ CSenSoapMessage*& aMessage)
+ {
+ TLSLOG_L(KSenCoreServiceManagerLogChannelBase , KMinLogLevel ,"CSenWebServiceSession::ParseResponseL(TDesC8&, CSenSoapMessage*&");
+
+ TInt retVal(KErrNone);
+ retVal = NewMessageL(aMessage);
+
+ CleanupStack::PushL(aMessage);
+
+ if (retVal != KErrNone)
+ {
+ return retVal;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ TLSLOG(KSenCoreServiceManagerLogChannelBase , KMaxLogLevel ,(_L("******************************************************")));
+ TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase , KMaxLogLevel , _L("Response to be parsed (%d bytes):"), aResponse.Length()));
+ {
+ TLSLOG_ALL(KSenCoreServiceManagerLogChannelBase , KMaxLogLevel ,aResponse);
+ //FILELOGALL(_L("WsLog"), _L("last_rsp.xml"), aResponse);
+ }
+ TLSLOG(KSenCoreServiceManagerLogChannelBase , KMaxLogLevel ,(_L("******************************************************")));
+ //////////////////////////////////////////////////////////////////////////
+
+ aMessage->SetReader(*XmlReader());
+ TInt leaveCode(KErrNone);
+ TLSLOG_L(KSenCoreServiceManagerLogChannelBase , KMinLogLevel ,"- Parsing response into SOAP message object:");
+ TBool normalParsing(ETrue);
+ if ( aResponse.Size() > KSenMaxLengthSaxParsingSoapMsg )
+ {
+ TInt ret(KErrNotFound);
+ TRAP(leaveCode, ret = HandleBodyWithoutParsingL(*aMessage, aResponse);)
+ if (leaveCode == KErrNone && ret == KErrNone)
+ {
+ normalParsing = EFalse;
+ }
+ }
+
+ if ( normalParsing )
+ {
+ TRAP(leaveCode, aMessage->ParseL(aResponse));
+ }
+
+ if(leaveCode==KErrNone)
+ {
+#ifdef _SENDEBUG
+ ///////////////////////////////////////////////////////////////////////
+ TLSLOG(KSenCoreServiceManagerLogChannelBase , KMaxLogLevel ,(_L("---------------------------------------------------")));
+ HBufC8* pAsXml = aMessage->AsXmlL();
+ if(pAsXml)
+ {
+ CleanupStack::PushL(pAsXml);
+ TLSLOG_L(KSenCoreServiceManagerLogChannelBase , KMinLogLevel ,"CSenWebServiceSession::ParseResponseL: OK!");
+ TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase , KMaxLogLevel , _L(" SOAP message (%d bytes)"),
+ pAsXml->Length()));
+ TLSLOG_ALL(KSenCoreServiceManagerLogChannelBase , KMaxLogLevel ,(*pAsXml));
+ CleanupStack::PopAndDestroy(); //pAsXml
+ }
+ TLSLOG(KSenCoreServiceManagerLogChannelBase , KMaxLogLevel ,(_L("---------------------------------------------------")));
+ ///////////////////////////////////////////////////////////////////////
+#endif // _SENDEBUG
+ retVal = ParseMessageL(*aMessage);
+ }
+ else
+ {
+ TLSLOG_L(KSenCoreServiceManagerLogChannelBase , KMinLogLevel ,"- Response is not SOAP message!");
+ retVal = leaveCode;
+ }
+ CleanupStack::Pop(); // aMessage
+ return retVal;
+ }
+
+EXPORT_C TInt CSenWebServiceSession::ParseMessageL(CSenSoapMessage& aSoapMessage)
+ {
+ // We can verify, that SOAP message has Body:
+ if(!aSoapMessage.HasBody())
+ {
+ return KErrSenNoSoapBody;
+ }
+ else
+ {
+ return KErrNone;
+ }
+ /**
+ * We could verify wsse:Security headers
+ * but we don't have a need for that right now.
+ */
+ }
+
+EXPORT_C TInt CSenWebServiceSession::AddConsumerL(MSenRemoteServiceConsumer& aConsumer)
+ {
+ CSLOG_L(aConsumer.ConnectionId() , KMinLogLevel,"CSenWebServiceSession::AddConsumerL");
+ iConsumerList.Reset();
+ TInt retVal = iConsumerList.Append(&aConsumer);
+ return retVal;
+ }
+
+// 2005: refactored GetConsumer() to Consumer()
+// Note: Same as client() in Java Ref. Impl.
+EXPORT_C MSenRemoteServiceConsumer* CSenWebServiceSession::Consumer()
+ {
+ TInt count(iConsumerList.Count());
+ if(count>0)
+ {
+ return iConsumerList[0];
+ }
+ else
+ {
+ return NULL;
+ }
+ }
+
+EXPORT_C TBool CSenWebServiceSession::IsReadyL()
+ {
+ return (CSenServiceSession::StatusL() == KSenConnectionStatusReady);
+ }
+
+EXPORT_C TInt CSenWebServiceSession::SubmitL(const TDesC8& aMessage,
+ const TDesC8& aTransportProperties,
+ MSenRemoteServiceConsumer& aConsumer,
+ HBufC8*& aResponse /*,
+ CSenTransportProperities*& apResponseTransportProperties */)
+ {
+ CSLOG_L(aConsumer.ConnectionId() , KMinLogLevel,"CSenWebServiceSession::SubmitL");
+
+ CSenSoapMessage* pMsg = NULL;
+ TInt retVal( MessageForSendingL(aMessage, aConsumer.Id(), pMsg) );
+ CleanupStack::PushL(pMsg);
+
+ if(retVal!=KErrNone)
+ {
+ CSLOG_FORMAT((aConsumer.ConnectionId() , KMinLogLevel, _L8("- MessageForSendingL returned an error: %d"), retVal));
+ CleanupStack::PopAndDestroy(); // pMsg
+ return retVal;
+ }
+
+ HBufC8* pHttpBody = pMsg->AsXmlL();
+ if ( pHttpBody )
+ {
+ TPtrC8 endpoint = Endpoint();
+ CleanupStack::PushL(pHttpBody);
+ TPtr8 httpBody = pHttpBody->Des();
+ CSLOG_L(aConsumer.ConnectionId() , KMaxLogLevel,"////////////////////////////////////////////////////////");
+ CSLOG_FORMAT((aConsumer.ConnectionId() , KMaxLogLevel, _L8("- Endpoint: %S"), &endpoint));
+ CSLOG_FORMAT((aConsumer.ConnectionId() , KMaxLogLevel, _L8("- Message (%d) about to submit:"),
+ httpBody.Length()));
+ //CSLOG_ALL(aConsumer.ConnectionId() , KMaxLogLevel,(httpBody));
+//wslog FILELOGALL(_L("WsLog"), _L("last_req.xml"), httpBody);
+ CSLOG_L(aConsumer.ConnectionId() , KMaxLogLevel,"////////////////////////////////////////////////////////");
+
+
+ MSenTransport& transport = aConsumer.TransportL();
+ retVal = transport.SubmitL(endpoint, httpBody, aTransportProperties, aResponse, aConsumer);
+
+ CleanupStack::PopAndDestroy(); // pHttpBody
+ }
+
+ CleanupStack::PopAndDestroy(); // pMsg
+
+ if ( !aResponse )
+ {
+ // Response was NULL: probably either out
+ // of heap or some transport malfunction.
+ CSLOG_L(aConsumer.ConnectionId() , KMinLogLevel,"CSenWebServiceSession::SubmitL:");
+ CSLOG_L(aConsumer.ConnectionId() , KMinLogLevel,"- Received NULL from transport.");
+ return retVal;
+ }
+
+ else if( aResponse->Length() < KSenSoapEnvelopeName().Length()*2 )
+ {
+ // No use parsing, Envelope -root element not there
+
+ // deliver non-soap body to consumer
+ CSLOG_L(aConsumer.ConnectionId() , KMinLogLevel,"CSenWebServiceSession::SubmitL:");
+ CSLOG_L(aConsumer.ConnectionId() , KMinLogLevel,"- response is not a SOAP envelope.");
+ return retVal;
+ }
+
+ CSenSoapMessage* pResponseSoapMsg = NULL;
+ TInt leaveCode(KErrNone);
+ TInt parseRetVal(KErrNone);
+ TRAP( leaveCode, parseRetVal = ParseResponseL(*aResponse, pResponseSoapMsg));
+
+ if( leaveCode!=KErrNone ) // parsing leaved!
+ {
+
+ pResponseSoapMsg = NULL;
+
+ // Return directly the response, which was received from
+ // transport. Note that pResponseSoapMsg has already
+ // been deleted because of leave
+ CSLOG_L(aConsumer.ConnectionId() , KMinLogLevel , "CSenWebServiceSession::SubmitL:");
+ CSLOG_L(aConsumer.ConnectionId() , KMinLogLevel , "- Error: response could not be parsed into SOAP msg!");
+
+ CSLOG_FORMAT((aConsumer.ConnectionId() , KMinLogLevel, _L8("- ParseResponseL leaved: %d"), leaveCode ));
+
+ retVal = leaveCode;
+ // else return the error code received from transport (retVal)
+ }
+ else // parsing did not leave..
+ {
+ if ( parseRetVal != KErrNone ) // .. but parsing failed
+ {
+ // Not mandatory, ParseResponseL should take
+ // care of gc, if it returns an error:
+ delete pResponseSoapMsg;
+
+ // NOTE - 2005 change: now the body of such
+ // response will be returned to the caller
+ // (with the error code).
+
+ // Response could not be parsed into SOAP message(!)
+ CSLOG_FORMAT((aConsumer.ConnectionId() , KMinLogLevel, _L8("- Response could not be parsed, error: (%d)"),
+ parseRetVal));
+
+ if(retVal==KErrNone)
+ {
+ CSLOG_L(aConsumer.ConnectionId() , KMinLogLevel,"- Returning error code from ParseResponseL");
+ // transport did not return error, return error from ParseResponseL
+ retVal = parseRetVal;
+ }
+ // else: return the error code received from transport
+ }
+ else // .. and parsing went ok
+ {
+ CleanupStack::PushL( pResponseSoapMsg );
+ CSLOG_L(aConsumer.ConnectionId() , KMinLogLevel,"- Response is a SOAP message");
+
+ // Check whether "complete server messages" is on or off
+ TBool completeServerMessages(EFalse);
+ HasFacetL(KCompleteMessagesFacet, completeServerMessages);
+
+ // Response is OK and SOAP message.
+ if( pResponseSoapMsg->IsFault() )
+ {
+ // Response is a SOAP fault
+ retVal = KErrSenSoapFault; // might change, if framework handles this fault
+ CSLOG_L(aConsumer.ConnectionId() , KMinLogLevel,"Response is a SOAP fault. Calling HandleErrorL.");
+
+ // Check if SOAP fault could be handled by the framework:
+ HBufC8* pResponse = NULL;
+
+ // Note that HandleSoapFaultL -method normally detaches any SOAP fault:
+ CleanupStack::Pop(pResponseSoapMsg);
+ retVal = HandleSoapFaultL(pResponseSoapMsg, pResponse);
+ if(retVal == KErrSenSoapFault)
+ {
+ CSLOG_L(aConsumer.ConnectionId() , KMinLogLevel,"CSenWebServiceSession::SubmitL:");
+ if( completeServerMessages )
+ {
+ CSLOG_L(aConsumer.ConnectionId() , KMinLogLevel,"- Returning SOAP envelope with fault");
+ // The following lines are important when there is a resending
+ // the new response is copied to aResponse.
+ // When there is no resend, then pResponse = NULL no copy happens
+ if(pResponse)
+ {
+ delete aResponse;
+ aResponse = pResponse;
+ }
+ // aResponse will be returned (original response from transport)
+ }
+ else // we can pass the detached fault
+ {
+ CSLOG_L(aConsumer.ConnectionId() , KMinLogLevel,"- Returning detached a SOAP fault.");
+ // Destroy the original response buffer received from transport,
+ // since now the parsed SOAP envelope can be returned
+ delete aResponse;
+ aResponse = pResponse;
+ }
+ }
+ else if ( retVal == KErrNone )
+ {
+ CSLOG_L(aConsumer.ConnectionId() , KMinLogLevel,"CSenWebServiceSession::SubmitL:");
+ CSLOG_L(aConsumer.ConnectionId() , KMinLogLevel,"- Framework handled this SOAP fault.");
+ // KErrNone means that fault was handled
+ // properly (by framework spesific code)
+ // and consumer may receive the response
+ // it requested.
+
+ // Currently there are no SOAP faults handled
+ // in WebServiceSession class, so KErrNone is
+ // never returned. This if -section is here
+ // only for *frameworks to extend*.
+
+ // Destroy the original response buffer received from transport,
+ // since now the parsed SOAP envelope can be returned
+ delete aResponse;
+ aResponse = pResponse;
+ }
+ else if ( retVal == KErrNotFound )
+ {
+ // SOAP fault element could not be found
+ CSLOG_L(aConsumer.ConnectionId() , KMinLogLevel,"CSenWebServiceSession::SubmitL - MAJOR:");
+ CSLOG_L(aConsumer.ConnectionId() , KMinLogLevel,"-IsFault()==true BUT fault element NOT found!");
+ CSLOG_L(aConsumer.ConnectionId() , KMinLogLevel,"-returning KErrSenBrokenSoapFault");
+ retVal = KErrSenBrokenSoapFault;
+ // Note: 2005 change: now the broken (original) response
+ // from the transport is returned, instead of NULL
+ }
+#ifdef _SENDEBUG
+ else
+ {
+ CSLOG_L(aConsumer.ConnectionId() , KMinLogLevel,"CSenWebServiceSession::SubmitL:");
+ CSLOG_FORMAT((aConsumer.ConnectionId() , KMinLogLevel, _L8("- HandleErrorL failed: %d"), retVal));
+ }
+#endif // _SENDEBUG
+
+ }
+ else // This SOAP envelope is NOT a fault
+ {
+ if ( completeServerMessages )
+ {
+ CSLOG_L(aConsumer.ConnectionId() , KMinLogLevel,"CSenWebServiceSession::SubmitL:");
+ CSLOG_L(aConsumer.ConnectionId() , KMinLogLevel,"- Returning complete SOAP envelope.");
+ // Destroy the original response buffer received from
+ // transport, since now the parsed SOAP envelope can
+ // be returned
+
+ delete aResponse;
+ aResponse = NULL;
+ aResponse = pResponseSoapMsg->AsXmlL();
+ }
+ else
+ {
+ HBufC8* pBody = pResponseSoapMsg->BodyAsStringL();
+ if(pBody)
+ {
+ // Destroy the original response buffer received from
+ // transport, since now the SOAP body must be returned
+ delete aResponse;
+ aResponse = pBody;
+ CSLOG_L(aConsumer.ConnectionId() , KMinLogLevel,"CSenWebServiceSession::SubmitL:");
+ CSLOG_L(aConsumer.ConnectionId() , KMinLogLevel,"- Detached SOAP message body.");
+ }
+ else
+ {
+ CSLOG_L(aConsumer.ConnectionId() , KMinLogLevel,"CSenWebServiceSession::SubmitL:");
+ CSLOG_L(aConsumer.ConnectionId() , KMinLogLevel,"- Could not detach SOAP body(!) - return KErrSenNoSoapBody");
+ retVal = KErrSenNoSoapBody;
+ }
+ }
+ CleanupStack::PopAndDestroy(pResponseSoapMsg);
+ }
+ }
+ }
+
+#ifdef _SENDEBUG
+ if(aResponse)
+ {
+ CSLOG_L(aConsumer.ConnectionId() , KMaxLogLevel,"-------------------------------------------------------------------");
+ CSLOG_FORMAT((aConsumer.ConnectionId() , KMaxLogLevel, _L8("Submit response (%d bytes):"),
+ aResponse->Length()));
+ //CSLOG_ALL(aConsumer.ConnectionId() , KMaxLogLevel,( *aResponse ));
+ CSLOG_L(aConsumer.ConnectionId() , KMaxLogLevel,"-------------------------------------------------------------------");
+ }
+#endif
+
+ return retVal;
+ }
+
+EXPORT_C TInt CSenWebServiceSession::SendL( const TDesC8& aMessage,
+ const TDesC8& aTransportProperties,
+ MSenRemoteServiceConsumer& aConsumer,
+ TInt& aTxnId,
+ HBufC8*& /*aRevalidationError*/ )
+ {
+ CSLOG_L(aConsumer.ConnectionId() , KMinLogLevel,"CSenWebServiceSession::SendL");
+
+ CSenSoapMessage* pMsg = NULL;
+ TInt retVal( MessageForSendingL(aMessage, aConsumer.Id(), pMsg) );
+ CleanupStack::PushL(pMsg);
+
+ if(retVal!=KErrNone)
+ {
+ CSLOG_FORMAT((aConsumer.ConnectionId() , KMinLogLevel, _L8("- MessageForSendingL returned an error: %d"), retVal));
+ CleanupStack::PopAndDestroy(); // pMsg
+ return retVal;
+ }
+
+ HBufC8* pHttpBody = pMsg->AsXmlL();
+ if(pHttpBody)
+ {
+ TPtrC8 endpoint = Endpoint();
+ CleanupStack::PushL(pHttpBody);
+ TPtr8 httpBody = pHttpBody->Des();
+ CSLOG_L(aConsumer.ConnectionId() , KMaxLogLevel,"////////////////////////////////////////////////////////");
+ CSLOG_FORMAT((aConsumer.ConnectionId() , KMaxLogLevel, _L8("- Endpoint: %S"), &endpoint));
+ CSLOG_FORMAT((aConsumer.ConnectionId() , KMaxLogLevel, _L8("- Message (%d bytes) about to send:"), httpBody.Length()));
+ CSLOG_ALL(aConsumer.ConnectionId() , KMaxLogLevel,(httpBody));
+//wslog FILELOGALL(_L("WsLog"), _L("last_req.xml"), httpBody);
+ CSLOG_L(aConsumer.ConnectionId() , KMaxLogLevel,"////////////////////////////////////////////////////////");
+
+ MSenTransport& t = aConsumer.TransportL();
+
+ retVal = t.SendL( endpoint, httpBody, aTransportProperties, *this, aConsumer, aTxnId );
+
+ CleanupStack::PopAndDestroy(); // pHttpBody
+ }
+
+ CleanupStack::PopAndDestroy(); // pMsg
+ return retVal;
+ }
+
+
+
+EXPORT_C void CSenWebServiceSession::SetFrameworkHeadersL(CSenSoapMessage& aMsg)
+ {
+ if ( iCredentialPtr.Credential() )
+ {
+ CSenInternalCredential* pCred = iCredentialPtr.Credential();
+ HBufC8* pAsXml = pCred->AsXmlL();
+ CleanupStack::PushL(pAsXml);
+ aMsg.SetSecurityHeaderL(*pAsXml);
+ CleanupStack::PopAndDestroy(pAsXml);
+ }
+ else
+ {
+ // There is no credential available
+ aMsg.SetSecurityHeaderL(KNullDesC8);
+ }
+ }
+
+EXPORT_C TInt CSenWebServiceSession::SetUserNameL(TDesC8& aUsername)
+ {
+ TInt retVal(KErrNone);
+ HBufC8* pToken8 = NULL;
+
+ retVal = CSenWsSecurityHeader::UsernameTokenL(aUsername, pToken8);
+ CleanupStack::PushL(pToken8);
+
+ if(retVal != KErrNone)
+ {
+ CleanupStack::PopAndDestroy(1); // token
+ return retVal;
+ }
+ else if(pToken8)
+ {
+ if(iSecurity == NULL)
+ {
+ iSecurity = pToken8->Des().AllocL();
+ }
+ else
+ {
+ TPtr8 ptr = iSecurity->Des();
+
+ if (ptr.MaxLength() < pToken8->Length() + ptr.Length())
+ {
+ HBufC8* newSecurity = HBufC8::NewLC(pToken8->Length()
+ +ptr.Length());
+ TPtr8 newPtr = newSecurity->Des();
+ newPtr.Append(*iSecurity);
+ newPtr.Append(*pToken8);
+ delete iSecurity;
+ iSecurity = newSecurity;
+ CleanupStack::Pop(); // newSecurity
+ }
+ else
+ {
+ ptr.Append(*pToken8);
+ }
+ }
+ }
+ CleanupStack::PopAndDestroy(); // pToken8
+
+ return retVal;
+ }
+
+EXPORT_C TPtrC8 CSenWebServiceSession::Endpoint()
+ {
+ if(iEndpoint)
+ return *iEndpoint;
+ else
+ return KNullDesC8();
+ }
+
+EXPORT_C TPtrC8 CSenWebServiceSession::Contract()
+ {
+ if(iContract)
+ return *iContract;
+ else
+ return KNullDesC8();
+ }
+
+EXPORT_C TPtrC8 CSenWebServiceSession::FrameworkId()
+ {
+ if(iFrameworkId)
+ return *iFrameworkId;
+ else
+ return KNullDesC8();
+ }
+
+EXPORT_C TPtrC8 CSenWebServiceSession::FrameworkVersion()
+ {
+ return KNullDesC8();
+ }
+
+EXPORT_C void CSenWebServiceSession::SetContractL(const TDesC8& aContract)
+ {
+ HBufC8* pNew = NULL;
+ if(aContract!=KNullDesC8)
+ {
+ pNew = aContract.AllocL();
+ }
+
+ delete iContract;
+ iContract = pNew;
+ }
+
+EXPORT_C void CSenWebServiceSession::SetEndPointL(const TDesC8& aEndpoint)
+ {
+ HBufC8* pNew =NULL;
+ if(aEndpoint!=KNullDesC8)
+ {
+ pNew = aEndpoint.AllocL();
+ }
+
+ delete iEndpoint;
+ iEndpoint = pNew;
+
+ SetStatusL();
+ }
+
+EXPORT_C void CSenWebServiceSession::SetSecurityL(const TDesC8& aSecurity)
+ {
+ TLSLOG_L(KSenCoreServiceManagerLogChannelBase , KMinLogLevel ,"CSenWebServiceSession::SetSecurityL");
+ TInt retVal(KErrNone);
+
+ if ( aSecurity.Length() < 1 )
+ {
+ delete iSecurity;
+ iSecurity = NULL;
+ iCredentialPtr.RemoveCredentialObserver(*this);
+ iCredentialPtr.Close();
+
+ // invalidate the session, because we have no credential
+ //iValidUntil.Set(_L("19000101:")); // way back in history: January 1st 1900
+ //acording to ID-WSF no need of reset the credential here
+ }
+ else
+ {
+ if ( HasSecurity() )
+ {
+ iCredentialPtr.RemoveCredentialObserver(*this);
+ ((MSenServiceManager&)iFramework.Manager()).UpdateCredentialL(
+ iCredentialPtr.Credential()->IdentifierL().IdL(),
+ aSecurity,
+ retVal);
+ if ( retVal == KErrNone )
+ {
+ iCredentialPtr.AddCredentialObserverL(*this);
+ CSenInternalCredential* pCred = iCredentialPtr.Credential();
+
+ if ( iClientServerInterval.Int64() != 0 )
+ {
+ TBuf8<64> buf;
+ buf.AppendNum(iClientServerInterval.Int64());
+ pCred->PropertiesL().SetPropertyL(KServiceInterval1, buf);
+ }
+ FillCredentialIdentifierL(pCred->IdentifierL());
+
+ TTime validUntil = iValidUntil;
+ pCred->PropertiesL().SetValidUntilL(validUntil);
+ }
+ else
+ {
+ delete iSecurity;
+ iSecurity = NULL;
+ iCredentialPtr.Close();
+
+ // invalidate the session, because we have no credential
+ iValidUntil.Set(KInvalideDate); // way back in history: January 1st 1900 //CodeScannerWarnings
+ }
+ }
+ else
+ {
+ RSenCredentialPtr credentialPtr =
+ ((MSenServiceManager&)iFramework.Manager()).AddCredentialL(aSecurity, retVal);
+
+ if ( retVal == KErrNone )
+ {
+
+ iCredentialPtr.RemoveCredentialObserver(*this);
+ iCredentialPtr.Close();
+ iCredentialPtr = credentialPtr.Clone();
+ iCredentialPtr.AddCredentialObserverL(*this); //codescannerwarnings
+
+ CSenInternalCredential* pCred = iCredentialPtr.Credential();
+
+ if ( iClientServerInterval.Int64() != 0 )
+ {
+ TBuf8<64> buf;
+ buf.AppendNum(iClientServerInterval.Int64());
+ pCred->PropertiesL().SetPropertyL(KServiceInterval1, buf);
+ }
+ FillCredentialIdentifierL(pCred->IdentifierL()); //codescannerwarnings
+
+ TTime validUntil = iValidUntil;
+ pCred->PropertiesL().SetValidUntilL(validUntil);
+
+ SetCredentialIdL(pCred->IdentifierL().IdL());
+ }
+ else
+ {
+ delete iSecurity;
+ iSecurity = NULL;
+ iCredentialPtr.RemoveCredentialObserver(*this);
+ iCredentialPtr.Close();
+
+ // invalidate the session, because we have no credential
+ iValidUntil.Set(KInvalideDate); // way back in history: January 1st 1900
+ }
+ }
+ }
+ }
+
+/*
+EXPORT_C TInt CSenWebServiceSession::RemoveConsumerL(MSenRemoteServiceConsumer& aConsumer)
+ {
+ LOG_WRITE_L("CSenWebServiceSession::RemoveConsumerL");
+ CSenServiceSession::RemoveConsumerL(aConsumer);
+
+ // If this session has no consumers, we can hold our grip to the credential
+ // (note: this does NOT mean that credential is removed, not at all(!), but
+ // that new search for the credential has to be performed).
+
+ // NOTE: this cannot be done at ws service session layer as long as ID-WSF does not
+ // use credential sharing / lookup mechanism in cases where session is found invalid
+ // (this is done in WS-* framework plug-in)
+ TInt count(iConsumerList.Count());
+ if( count == 0 )
+ {
+ LOG_WRITE_L("- Credential count == 0");
+ LOG_WRITE_L("-> Closing the handle to the credential owned by Credential Manager.");
+ SetSecurityL(KNullDesC8);
+ }
+ }
+*/
+void CSenWebServiceSession::SetCredentialIdL(TInt aCredentialId)
+ {
+ TBuf8<KCredIdBufSize> buffer;
+ buffer.Num(aCredentialId);
+
+ delete iSecurity;
+ iSecurity = NULL;
+ TInt leaveCode( KErrNone );
+ TRAP( leaveCode, iSecurity = HBufC8::NewL( buffer.Length()+KCredentialIdStart().Length()+KCredentialIdEnd().Length() ); )
+ if( !leaveCode && iSecurity )
+ {
+ TPtr8 sec = iSecurity->Des();
+ sec.Append( KCredentialIdStart );
+ sec.Append( buffer);
+ sec.Append( KCredentialIdEnd );
+ }
+#ifdef _SENDEBUG
+ else
+ {
+ TLSLOG_L(KSenCoreServiceManagerLogChannelBase , KMinLogLevel ,"CSenWebServiceSession::SetCredentialId(): iSecurity = HBufC8::NewL leaved (OOM)!");
+ }
+#endif // _SENDEBUG
+ }
+
+EXPORT_C TInt CSenWebServiceSession::GetCredentialIdL()
+ {
+ TInt retVal(0);
+ if (HasSecurity())
+ {
+ retVal = iCredentialPtr.Credential()->IdentifierL().IdL(); //codescannerwarnings
+ }
+ return retVal;
+ }
+
+
+EXPORT_C void CSenWebServiceSession::FillCredentialIdentifierL(CSenCredentialIdentifier& aIdentifier)
+ {
+ TLSLOG_L(KSenCoreServiceManagerLogChannelBase , KMinLogLevel ,"CSenWebServiceSession::FillCredentialIdentifierL");
+ if ( iEndpoint )
+ {
+ TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase , KNormalLogLevel , _L8("- Setting endpoint to credential as property: %S"), iEndpoint ));
+ aIdentifier.SetPropertyL(KEndpointLocalname, *iEndpoint);
+ }
+ }
+
+EXPORT_C TInt CSenWebServiceSession::TryToSearchValidCredentialL()
+ {
+ TLSLOG_L(KSenCoreServiceManagerLogChannelBase , KMinLogLevel ,"CSenWebServiceSession::TryToSearchValidCredentialL()");
+
+ // Get CredentialIdentifier which should include ProviderID
+ CSenCredentialIdentifier* pCredIdentifier = CSenCredentialIdentifier::NewLC();
+ FillCredentialIdentifierL(*pCredIdentifier);
+
+ CSenWSDescription* pPattern = CSenWSDescription::NewLC();
+ CSenElement& patternElement = ((CSenWSDescription*)pPattern)->AsElement();
+
+ TPtrC8 providerId(KNullDesC8);
+
+ RXmlEngNodeList<TXmlEngElement> list;
+ CleanupClosePushL(list);
+ TXmlEngElement element = pCredIdentifier->AsElementL();
+ element.GetChildElements(list);
+ while ( list.HasNext() )
+ {
+ TXmlEngElement element = list.Next();
+ if ( element.Name() != KSenIdpProviderIdLocalname )
+ {
+ CSenElement& addedElement = patternElement.AddElementL(element.Name());
+ addedElement.SetContentL(element.Text());
+ }
+ else
+ {
+ providerId.Set(element.Text());
+ }
+ }
+
+ CSenIdentityProvider* pIdentityProvider = NULL;
+ if ( providerId != KNullDesC8 )
+ {
+ TLSLOG_L(KSenCoreServiceManagerLogChannelBase , KMinLogLevel ,"CSenWebServiceSession::TryToSearchValidCredentialL():");
+ TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase , KNormalLogLevel , _L8("- Trying to search IdentityProvider using ProviderId : %S"), &providerId));
+ CSenWSDescription* pIdpPattern = CSenWSDescription::NewLC();
+ pIdpPattern->SetEndPointL(providerId);
+ pIdentityProvider = iFramework.Manager().IdentityProviderL(*pIdpPattern);
+ CleanupStack::PopAndDestroy(pIdpPattern);
+ }
+
+ RSenCredentialPtrArray credentialPtrsArray;
+ CleanupClosePushL(credentialPtrsArray);
+
+ TInt retVal(KErrNone);
+ if ( pIdentityProvider )
+ {
+ TLSLOG_L(KSenCoreServiceManagerLogChannelBase , KMinLogLevel ,"CSenWebServiceSession::TryToSearchValidCredentialL() - IdentityProvider was found. Trying to search related Credentials.");
+ retVal = ((MSenServiceManager&)iFramework.Manager()).CredentialsL(*pPattern,
+ *pIdentityProvider,
+ credentialPtrsArray);
+ }
+ else
+ {
+ TLSLOG_L(KSenCoreServiceManagerLogChannelBase , KMinLogLevel ,"CSenWebServiceSession::TryToSearchValidCredentialL() - FATAL: IdentityProvider was NOT found:");
+ TLSLOG_L(KSenCoreServiceManagerLogChannelBase , KMinLogLevel ,"- Trying to search Credentials without IdentityProvider information.");
+ retVal = ((MSenServiceManager&)iFramework.Manager()).CredentialsL(*pPattern,
+ credentialPtrsArray);
+ }
+
+ if ( (retVal == KErrNone) && (credentialPtrsArray.Count() > 0) )
+ {
+ TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase , KNormalLogLevel ,_L8("CSenWebServiceSession::TryToSearchValidCredentialL(): %d Credentials found."), credentialPtrsArray.Count()));
+ // Take the first valid Credential from found Credentials array.
+ TBool credentialOK(EFalse);
+ TInt count = credentialPtrsArray.Count();
+ for (TInt i=0; i < count; i++)
+ {
+ SetCredentialPtrL(credentialPtrsArray[0]);//codescannerwarnings
+ iValidUntil = iCredentialPtr.Credential()->PropertiesL().ValidUntilL(); //codescannerwarnings
+
+ if ( ComputeStatusL() == KSenConnectionStatusReady)
+ {
+ credentialOK = ETrue;
+ break;
+ }
+ }
+
+ if ( credentialOK )
+ {
+ TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase , KMinLogLevel , _L8("CSenWebServiceSession::TryToSearchValidCredentialL(): Valid Credential were found. CredentialId : %d"),
+ iCredentialPtr.Credential()->IdentifierL().IdL())); //codescannerwarnings
+ retVal = KErrNone;
+ }
+ else
+ {
+ TLSLOG_L(KSenCoreServiceManagerLogChannelBase , KMinLogLevel ,"CSenWebServiceSession::TryToSearchValidCredentialL(): Valid Credentials were not found.");
+ SetSecurityL(KNullDesC8);
+ retVal = KErrNotFound;
+ }
+ }
+ else
+ {
+ TLSLOG_L(KSenCoreServiceManagerLogChannelBase , KMinLogLevel ,"CSenWebServiceSession::TryToSearchValidCredentialL(): Credentials were not found.");
+ retVal = KErrNotFound;
+ }
+
+ CleanupStack::PopAndDestroy(&credentialPtrsArray);
+
+ CleanupStack::PopAndDestroy(&list); // Close()
+ CleanupStack::PopAndDestroy(pPattern);
+ CleanupStack::PopAndDestroy(pCredIdentifier);
+
+ return retVal;
+ }
+
+EXPORT_C const TTime& CSenWebServiceSession::ValidUntilL()
+ {
+ if (iValidUntil != Time::NullTTime())
+ {
+ return iValidUntil;
+ }
+ else
+ {
+ const TTime& MAX_TIME = Time::MaxTTime();
+ return MAX_TIME; // if no expiration was set, the session is
+ // valid forever(!)
+ }
+ }
+
+EXPORT_C void CSenWebServiceSession::WriteAsXMLToL(RWriteStream& aWriteStream)
+ {
+ _LIT8(KTouch, "touch");
+ aWriteStream.WriteL(KSDFramework);
+ aWriteStream.WriteL(FrameworkId());
+ CSenElement* elem = &AsElement();
+
+ const TDesC8* attrVal = elem->AttrValue(KTouch);
+ if(attrVal != NULL)
+ {
+ aWriteStream.WriteL(KSenDblQuot);
+ aWriteStream.WriteL(KSenSpace);
+ aWriteStream.WriteL(KTouch);
+ aWriteStream.WriteL(KSenEqualsDblQuot);
+ aWriteStream.WriteL(*attrVal);
+ }
+ aWriteStream.WriteL(KTagWithAttrEnd);
+
+ // write contract
+ if(iContract && iContract->Length()>0)
+ {
+ aWriteStream.WriteL(KContractStart);
+ aWriteStream.WriteL(*iContract);
+ aWriteStream.WriteL(KContractEnd);
+ }
+
+ // write endpoint
+ TPtrC8 cue = TransportCue();
+ if(iEndpoint && iEndpoint->Length()>0)
+ {
+ if( iTransportCue && iTransportCue->Length()>0)
+ {
+ // both cue and endpoint
+ aWriteStream.WriteL(KEndPointStartWithCue);
+ aWriteStream.WriteL(*iTransportCue);
+ aWriteStream.WriteL(KTagWithAttrEnd);
+ aWriteStream.WriteL(*iEndpoint);
+ aWriteStream.WriteL(KEndPointEnd);
+
+ }
+ else
+ {
+ // just endpoint
+ aWriteStream.WriteL(KEndPointStart);
+ aWriteStream.WriteL(*iEndpoint);
+ aWriteStream.WriteL(KEndPointEnd);
+ }
+ }
+ else if ( iTransportCue && iTransportCue->Length() > 0 )
+ {
+ // only cue, but no endpoint
+ aWriteStream.WriteL(KEndPointStartWithCue);
+ aWriteStream.WriteL(*iTransportCue);
+ aWriteStream.WriteL(KTagWithAttrClose);
+ }
+
+ // write security credentials
+ if(iSecurity)
+ {
+ aWriteStream.WriteL(KCredentialsStart);
+ if (iValidUntil != Time::NullTTime())
+ {
+ HBufC8* dateDes = HBufC8::NewLC(256);
+ TPtr8 datePtr = dateDes->Des();
+ SenDateUtils::ToXmlDateTimeUtf82L(datePtr, iValidUntil);
+ HBufC8* tempBuf = HBufC8::NewLC(KNotOnOrAfterFormat().Length() +
+ datePtr.Length());
+
+ TPtr8 ptr = tempBuf->Des();
+ ptr.Format(KNotOnOrAfterFormat, dateDes);
+
+ aWriteStream.WriteL(ptr);
+ CleanupStack::PopAndDestroy(2); // tempBuf, dateDes
+ tempBuf = NULL;
+ }
+ else
+ {
+ aWriteStream.WriteL(KEmptyTagEnd);
+ }
+
+ aWriteStream.WriteL(*iSecurity);
+ aWriteStream.WriteL(KCredentialsEnd);
+ }
+
+ CSenElement* pProviderPolicyElement =
+ AsElement().Element(KProviderPolicyLocalName);
+
+ if(pProviderPolicyElement)
+ {
+ HBufC8* pProviderPolicyAsXmlUtf8 = pProviderPolicyElement->AsXmlL();
+ if(pProviderPolicyAsXmlUtf8)
+ {
+ CleanupStack::PushL(pProviderPolicyAsXmlUtf8);
+ aWriteStream.WriteL(*pProviderPolicyAsXmlUtf8);
+ CleanupStack::PopAndDestroy(); // pProviderPolicyAsXmlUtf8
+ }
+ }
+
+ WriteExtensionsAsXMLToL(aWriteStream);
+
+ //Writing the ServicePolicy to XML
+ MSenServicePolicy* servicePolicy = ServicePolicy();
+ if(servicePolicy)
+ {
+ CSenServicePolicy* ele = (CSenServicePolicy*)servicePolicy;
+ CSenElement* pServicePolicyElement = &ele->AsElement();
+ if(pServicePolicyElement)
+ {
+ HBufC8* pServicePolicyAsXmlUtf8 = pServicePolicyElement->AsXmlL();
+ if(pServicePolicyAsXmlUtf8)
+ {
+ CleanupStack::PushL(pServicePolicyAsXmlUtf8);
+ aWriteStream.WriteL(*pServicePolicyAsXmlUtf8);
+ CleanupStack::PopAndDestroy(); // pProviderPolicyAsXmlUtf8
+ }
+ }
+ }
+
+ aWriteStream.WriteL(KSDEnd);
+ aWriteStream.WriteL(KNewLine);
+
+
+
+ }
+
+
+
+EXPORT_C TInt CSenWebServiceSession::SubmitSoapL(const TDesC8& aSoapMessage,
+ const TDesC8& aTransportProperties,
+ MSenRemoteServiceConsumer& aConsumer,
+ HBufC8*& aResponse)
+ {
+ CSLOG_L(aConsumer.ConnectionId() , KMinLogLevel,"CSenWebServiceSession::SubmitSoapL:");
+ TPtrC8 endpoint = Endpoint();
+#ifdef _SENDEBUG
+ CSLOG_L(aConsumer.ConnectionId() , KMaxLogLevel,"////////////////////////////////////////////////////////");
+ CSLOG_FORMAT((aConsumer.ConnectionId() , KMaxLogLevel, _L8("- Endpoint: %S"), &endpoint));
+ CSLOG_FORMAT((aConsumer.ConnectionId() , KMaxLogLevel, _L8("- Message (%d bytes) about to submit:"), aSoapMessage.Length()));
+ CSLOG_ALL(aConsumer.ConnectionId() , KMaxLogLevel,( aSoapMessage ));
+ CSLOG_L(aConsumer.ConnectionId() , KMaxLogLevel,"////////////////////////////////////////////////////////");
+#endif
+
+ MSenTransport& t = aConsumer.TransportL();
+
+ TInt retVal = t.SubmitL(endpoint, aSoapMessage, aTransportProperties, aResponse, aConsumer);
+
+ if(!aResponse)
+ {
+ // Response was NULL: probably either out
+ // of heap or some transport malfunction.
+ CSLOG_L(aConsumer.ConnectionId() , KMinLogLevel,"CSenWebServiceSession::SubmitSoapL:");
+ CSLOG_L(aConsumer.ConnectionId() , KMinLogLevel,"- Received NULL from transport.");
+ return retVal;
+ }
+ else if(aResponse->Length() < KSenSoapEnvelopeName().Length()*2)
+ {
+ // No use parsing, Envelope -root element not there.
+ // Just deliver this "non-soap" response to consumer
+ CSLOG_L(aConsumer.ConnectionId() , KMinLogLevel,"CSenWebServiceSession::SubmitSoapL:");
+ CSLOG_L(aConsumer.ConnectionId() , KMinLogLevel,"- Response is not a SOAP envelope.");
+ return retVal;
+ }
+
+ // Attempt to parse the response here. SOAP faults
+ // are to be searched after,
+ CSenSoapMessage* pResponseSoapMsg = NULL;
+ TInt leaveCode(KErrNone);
+ TInt parseRetCode(KErrNone);
+ TRAP( leaveCode, (parseRetCode =
+ ParseResponseL(*aResponse, pResponseSoapMsg)) );
+
+ if(leaveCode!=KErrNone)
+ {
+ // Return directly the response, which was received from
+ // transport. Note that pResponseSoapMsg has already
+ // been deleted because of leave
+ CSLOG_L(aConsumer.ConnectionId() , KMinLogLevel,"CSenWebServiceSession::SubmitSoapL:");
+ CSLOG_FORMAT((aConsumer.ConnectionId() , KMinLogLevel, _L8(" - ParseResponseL leaved: %d"), leaveCode ));
+
+ if(retVal==KErrNone) // retVal still SubmitL() return value
+ {
+ // Indicate with return value, that response is
+ // invalid - even though submit was ok, the
+ // response could NOT be parsed(!).
+ retVal = leaveCode;
+ }
+ }
+ else // ParseResponseL did not leave..
+ {
+ if(parseRetCode != KErrNone) // .. but returned an error
+ {
+ // Not mandatory, ParseResponseL should take
+ // care of gc, if it returns an error:
+ delete pResponseSoapMsg;
+ CSLOG_L(aConsumer.ConnectionId() , KMinLogLevel,"CSenWebServiceSession::SubmitSoapL:");
+
+ CSLOG_FORMAT((aConsumer.ConnectionId() , KMinLogLevel, _L8("- Parsing failed, error: %d"),
+ parseRetCode));
+
+ if(retVal==KErrNone) // submit was ok
+ {
+ // Indicate with return value, that response is
+ // invalid - even though submit was ok, the
+ // response could NOT be parsed!
+ retVal = parseRetCode;
+ }
+ }
+ else // .. and parsing was successful
+ {
+ CleanupStack::PushL(pResponseSoapMsg);
+ CSLOG_L(aConsumer.ConnectionId() , KMinLogLevel,"CSenWebServiceSession::SubmitSoapL:");
+ CSLOG_L(aConsumer.ConnectionId() , KMinLogLevel,"- Response is a SOAP message");
+
+ TBool completeServerMessages(ETrue);
+ HasFacetL(KCompleteMessagesFacet, completeServerMessages);
+
+ // response is OK and in SOAP form.
+ if(pResponseSoapMsg->IsFault())
+ {
+ // Response is a SOAP fault
+ retVal = KErrSenSoapFault; // might change, if framework handles this fault
+ CSLOG_L(aConsumer.ConnectionId() , KMinLogLevel,"CSenWebServiceSession::SubmitSoapL:");
+
+ CSLOG_L(aConsumer.ConnectionId() , KMinLogLevel,"- Response is a SOAP fault. Calling HandleErrorL.");
+
+ // Check if this SOAP fault could be handled by the framework
+ HBufC8* pResponse = NULL;
+ CleanupStack::Pop(pResponseSoapMsg);
+ retVal = HandleSoapFaultL(pResponseSoapMsg, pResponse/*, aResponseTransportProperties */);
+
+ if(retVal == KErrSenSoapFault)
+ {
+ CSLOG_L(aConsumer.ConnectionId() , KMinLogLevel,"CSenWebServiceSession::SubmitSoapL:");
+ if(completeServerMessages)
+ {
+ CSLOG_L(aConsumer.ConnectionId() , KMinLogLevel,"- Returning SOAP envelope with fault");
+ // The following lines are important when there is a resending
+ // the new response is copied to aResponse.
+ // When there is no resend, then pResponse = NULL no copy happens
+ if(pResponse)
+ {
+ delete aResponse;
+ aResponse = pResponse;
+ } // aResponse will be returned (original response from transport)
+ }
+ else // Pass the detached fault
+ {
+ CSLOG_L(aConsumer.ConnectionId() , KMinLogLevel,"- Returning detached a SOAP fault.");
+ // Destroy the original response buffer received from transport,
+ // since now the parsed SOAP envelope can be returned
+ delete aResponse;
+ aResponse = pResponse;
+ }
+ }
+ else if(retVal == KErrNone)
+ {
+ CSLOG_L(aConsumer.ConnectionId() , KMinLogLevel,"CSenWebServiceSession::SubmitSoapL:");
+ CSLOG_L(aConsumer.ConnectionId() , KMinLogLevel,"- Framework handled this SOAP fault.");
+ // KErrNone means that fault was handled
+ // properly (by framework spesific code)
+ // and consumer may receive the response
+ // it requested.
+
+ // Currently there are no SOAP faults handled
+ // in WebServiceSession class, so KErrNone is
+ // never returned. This if -section is here
+ // only for *frameworks to extend*.
+
+ // Destroy the original response buffer received from transport,
+ // since now the parsed SOAP envelope can be returned
+ delete aResponse;
+ aResponse = pResponse;
+ }
+ else if(retVal==KErrNotFound)
+ {
+ // SOAP fault element could not be found
+ CSLOG_L(aConsumer.ConnectionId() , KMinLogLevel,"CSenWebServiceSession::SubmitSoapL - MAJOR:");
+ CSLOG_L(aConsumer.ConnectionId() , KMinLogLevel,"-IsFault()==true BUT fault element NOT found!");
+ CSLOG_L(aConsumer.ConnectionId() , KMinLogLevel,"-returning KErrSenBrokenSoapFault");
+ retVal = KErrSenBrokenSoapFault;
+ // Note: 2005 change: now the broken (original) response
+ // from the transport is returned, instead of NULL
+ }
+#ifdef _SENDEBUG
+ else
+ {
+ CSLOG_L(aConsumer.ConnectionId() , KMinLogLevel,"CSenWebServiceSession::SubmitSoapL:");
+ CSLOG_FORMAT((aConsumer.ConnectionId() , KMinLogLevel, _L8("- HandleErrorL failed: %d"), retVal));
+ }
+#endif // _SENDEBUG
+ }
+ else // this SOAP envelope is NOT a fault
+ {
+ CSLOG_L(aConsumer.ConnectionId() , KMinLogLevel,"CSenWebServiceSession::SubmitSoapL:");
+ CSLOG_L(aConsumer.ConnectionId() , KMinLogLevel,"- Response is a SOAP envelope.");
+
+ // Check complete server messages on/off
+ if(!completeServerMessages)
+ {
+ HBufC8* pBody = pResponseSoapMsg->BodyAsStringL();
+ if(pBody)
+ {
+ // Destroy the original response buffer received from transport,
+ // since now the parsed SOAP envelope can be returned
+ delete aResponse;
+ aResponse = pBody;
+ CSLOG_L(aConsumer.ConnectionId() , KMinLogLevel,"CSenWebServiceSession::SubmitSoapL:");
+ CSLOG_L(aConsumer.ConnectionId() , KMinLogLevel,"- Detached SOAP message body.");
+ }
+ else
+ {
+ CSLOG_L(aConsumer.ConnectionId() , KMinLogLevel,"CSenWebServiceSession::SubmitSoapL:");
+ CSLOG_L(aConsumer.ConnectionId() , KMinLogLevel,"- Could not detach SOAP body(!) - return KErrSenNoSoapBody");
+ // Note: 2005 change: now the broken (original) response
+ // from the transport is returned, instead of NULL
+ retVal = KErrSenNoSoapBody;
+ }
+ }
+
+ CleanupStack::PopAndDestroy(pResponseSoapMsg);
+ }
+ // else { // return complete server message }
+
+ }
+ }
+
+#ifdef _SENDEBUG
+ if(aResponse)
+ {
+
+ CSLOG_L(aConsumer.ConnectionId() , KMaxLogLevel,"------------------------------------------------------------");
+ CSLOG_L(aConsumer.ConnectionId() , KMaxLogLevel,"CSenWebServiceSession::SubmitSoapL:");
+ CSLOG_FORMAT((aConsumer.ConnectionId() , KMaxLogLevel, _L8("- Response (%d bytes):"), aResponse->Length()));
+ CSLOG_ALL(aConsumer.ConnectionId() , KMaxLogLevel,( *aResponse ));
+ CSLOG_L(aConsumer.ConnectionId() , KMaxLogLevel,"------------------------------------------------------------");
+ }
+#endif
+ return retVal;
+ }
+
+EXPORT_C TInt CSenWebServiceSession::SendSoapL( const TDesC8& aSoapMessage,
+ const TDesC8& aTransportProperties,
+ MSenRemoteServiceConsumer& aConsumer,
+ TInt& aTxnId,
+ HBufC8*& /* aRevalidationError*/ ) // SIFs should utilize aRevalidationError
+ {
+ CSLOG_L(aConsumer.ConnectionId() , KMinLogLevel,"CSenWebServiceSession::SendSoapL:");
+ TPtrC8 endpoint = Endpoint();
+#ifdef _SENDEBUG
+ CSLOG_L(aConsumer.ConnectionId() , KMaxLogLevel,"////////////////////////////////////////////////////////");
+ CSLOG_FORMAT((aConsumer.ConnectionId() , KMaxLogLevel, _L8("- Endpoint: %S:"), &endpoint));
+ CSLOG_FORMAT((aConsumer.ConnectionId() , KMaxLogLevel, _L8("- Message (%d bytes) about to send:"),
+ aSoapMessage.Length()));
+ CSLOG_ALL(aConsumer.ConnectionId() , KMaxLogLevel,( aSoapMessage ));
+ CSLOG_L(aConsumer.ConnectionId() , KMaxLogLevel,"////////////////////////////////////////////////////////");
+#endif
+
+ MSenTransport& t = aConsumer.TransportL();
+ TInt retVal( t.SendL(endpoint, aSoapMessage, aTransportProperties, *this, aConsumer, aTxnId) );
+ CSLOG_L(aConsumer.ConnectionId() , KMinLogLevel,"CSenWebServiceSession::SendSoapL:");
+
+ CSLOG_FORMAT((aConsumer.ConnectionId() , KMinLogLevel, _L8("- Received transaction ID: %d"), aTxnId));
+ return retVal;
+ }
+
+
+
+// NOTE: the ownership of the consumer-pointer(s), which are copied (appended)
+// into aConsumers array is NOT transfered to the caller!
+
+// 2005: refactored GetConsumers() to Consumers()
+EXPORT_C TInt CSenWebServiceSession::Consumers(RServiceConsumerArray& aConsumers) const
+ {
+ TInt count(iConsumerList.Count());
+ {
+ for(TInt i=0; i<count; i++)
+ {
+ // creates a copy of pointers, but ownership is NOT transferred!
+ TInt error = aConsumers.Append(iConsumerList[i]);
+ if(error != KErrNone)
+ return error;
+ }
+ }
+ return KErrNone;
+ }
+
+EXPORT_C TTimeIntervalMicroSeconds
+ CSenWebServiceSession::ClientServerInterval()
+ {
+ return iClientServerInterval;
+ }
+
+EXPORT_C void CSenWebServiceSession::SetClientServerIntervalL(
+ TTimeIntervalMicroSeconds aInterval) //codescannerwarnings
+ {
+ iClientServerInterval = aInterval;
+ if ( iCredentialPtr.Credential() )
+ {
+ TBuf8<64> buf;
+ buf.AppendNum(iClientServerInterval.Int64());
+ iCredentialPtr.Credential()->PropertiesL().SetPropertyL(KServiceInterval1, buf); //CodeScannerWarnings
+ }
+ }
+
+EXPORT_C TBool CSenWebServiceSession::HasConsumer() const
+ {
+ if (iConsumerList.Count() > 0)
+ {
+ return ETrue;
+ }
+ else
+ {
+ return EFalse;
+ }
+ }
+
+EXPORT_C void CSenWebServiceSession::StartTransaction()
+ {
+ // Nothing in framework base class level
+ }
+
+EXPORT_C void CSenWebServiceSession::TransactionCompleted()
+ {
+ // Nothing in framework base class level
+ }
+
+EXPORT_C TBool CSenWebServiceSession::HasSuperClass( TDescriptionClassType aType )
+ {
+ if( aType == MSenServiceDescription::EServiceSession ) // direct superclass!
+ {
+ // If asked type is the know *direct* father/mother, return true:
+ return ETrue;
+ }
+ else
+ {
+ // Otherwise, ask from direct superclass (may invoke chain of recursive calls)
+ return CSenServiceSession::HasSuperClass( aType );
+ }
+ }
+
+EXPORT_C TInt CSenWebServiceSession::SetTransportCueL(const TDesC8& aCue)
+ {
+ HBufC8* pNew =NULL;
+ if(aCue!=KNullDesC8)
+ {
+ pNew = aCue.AllocL();
+ }
+ delete iTransportCue;
+ iTransportCue = pNew;
+
+ return KErrNone;
+ }
+
+EXPORT_C HBufC8* CSenWebServiceSession::SecurityL()
+ {
+ if ( HasSecurity() )
+ {
+ return iCredentialPtr.Credential()->AsXmlL();
+ }
+ else
+ {
+ return NULL;
+ }
+ }
+
+EXPORT_C TBool CSenWebServiceSession::HasSecurity()
+ {
+ if ( iCredentialPtr.Credential() )
+ {
+ return ETrue;
+ }
+
+ return EFalse;
+ }
+
+EXPORT_C void CSenWebServiceSession::SetCredentialPtrL(RSenCredentialPtr aCredentialPtr) //codescannerwarnings
+ {
+ // Stop observing the removal of credential as this instance is itself doing the removal
+ iCredentialPtr.RemoveCredentialObserver(*this);
+ //temp pointer eliminate self deleting when counter = 1 and aCredentail points same data as iCredentialPtr
+ // in other words there is a chance that closing iCredentialPtr make dirty aCredentialPtr. Temp ptr keeps balance so
+ // that counter has proper value.
+ RSenCredentialPtr tempPtr = iCredentialPtr.Clone();
+ iCredentialPtr.Close();
+ iCredentialPtr = aCredentialPtr.Clone();
+ tempPtr.Close();
+ // Start observing the new credential
+ iCredentialPtr.AddCredentialObserverL(*this); //codescannerwarnings
+ SetCredentialIdL(iCredentialPtr.Credential()->IdentifierL().IdL()); //codescannerwarnings
+ }
+
+EXPORT_C TInt CSenWebServiceSession::SendToHostletL(MSenRemoteHostlet& aReceiver,
+ const TDesC8& aMessage,
+ const TInt aTxnId,
+ MSenRemoteServiceConsumer& aFrom,
+ MSenProperties* aProperties)
+ {
+ // default impelementation routes the request directly to the hostlet
+ // Handler aware framework could load the required handlers in here
+ // to enable addressing / message correlation etc.
+ return CSenServiceSession::SendToHostletL(aReceiver, aMessage, aTxnId, aFrom, aProperties);
+ }
+
+EXPORT_C TInt CSenWebServiceSession::ProvideHostletResponseL( MSenRemoteHostlet& aProvider,
+ const TInt aTxnId,
+ const TInt aServiceCode,
+ const TDesC8& aRecipientsConsumerId,
+ CSenChunk& aMessageChunk)
+ {
+ return CSenServiceSession::ProvideHostletResponseL( aProvider,
+ aTxnId,
+ aServiceCode,
+ aRecipientsConsumerId,
+ aMessageChunk );
+ }
+
+TInt CSenWebServiceSession::HandleBodyWithoutParsingL(CSenSoapMessage& aMessage,
+ const TDesC8& aResponse)
+ {
+ TInt ret;
+ TInt endTagStart;
+ TInt endTagEnd;
+ TInt startTagStart;
+ TInt startTagEnd;
+ TPtrC8 prefix;
+
+ ret = SenSaxUtils::SearchEndTagL(aResponse,KSenSoapEnvelopeBodyName,
+ endTagStart, endTagEnd, prefix);
+ if ( ret != KErrNotFound )
+ {
+ ret = SenSaxUtils::SearchStartTagL(aResponse,prefix,KSenSoapEnvelopeBodyName,
+ startTagStart, startTagEnd);
+ if ( ret != KErrNotFound )
+ {
+ TPtrC8 startPart(aResponse.Ptr(),startTagEnd+1);
+ TPtrC8 endPart(aResponse.Ptr()+endTagStart,aResponse.Size()-endTagStart);
+ HBufC8* pXmlWithoutBody = HBufC8::NewLC(startPart.Length()+endPart.Length());
+ pXmlWithoutBody->Des().Append(startPart);
+ pXmlWithoutBody->Des().Append(endPart);
+
+ aMessage.ParseL(*pXmlWithoutBody);
+ CleanupStack::PopAndDestroy(pXmlWithoutBody);
+
+ TPtrC8 bodyContent(aResponse.Ptr()+startTagEnd+1, endTagStart-startTagEnd-1);
+ aMessage.SetBodyL(bodyContent);
+ }
+ }
+
+ return ret;
+ }
+
+EXPORT_C void CSenWebServiceSession::CredentialChanged(TSenCredentialChange aChange,
+ TAny* /* aPointer */)
+ {
+ if ( aChange == MSenCredentialObserver::EDestroyed )
+ {
+ iValidUntil.Set(KInvalideDate); // way back in history: January 1st 1900 \\CodeScannerWarnings
+ TRAP_IGNORE( SetStatusL(); )
+ }
+ }
+
+EXPORT_C TInt CSenWebServiceSession::AddCredentialObserverL(CSenInternalCredential& aCredential)
+{
+ TInt error(KErrNone);
+ RSenCredentialPtr credentialPtr =
+ ((MSenServiceManager&)iFramework.Manager()).CredentialL(
+ aCredential.IdentifierL().IdL(), error);
+ if ( error == KErrNone )
+ {
+ iCredentialPtr.RemoveCredentialObserver(*this);
+ iCredentialPtr.Close();
+ iCredentialPtr = credentialPtr.Clone();
+ iCredentialPtr.AddCredentialObserverL(*this);
+ iValidUntil = credentialPtr.Credential()->PropertiesL().ValidUntilL();
+ if ( iClientServerInterval == 0 )
+ {
+ TPtrC8 value;
+ TInt ret = iCredentialPtr.Credential()->PropertiesL().PropertyL(_L8("ServiceInterval"),
+ value);
+ if ( ret == KErrNone )
+ {
+ TLex8 lex(value);
+ TInt64 val;
+ ret = lex.Val(val);
+ if ( ret == KErrNone )
+ {
+ iClientServerInterval = val;
+ }
+ }
+ }
+
+ }
+ CredentialChanged(MSenCredentialObserver::EAdded, NULL);
+ SetStatusL();
+
+ return KErrNone;
+}
+
+// End of File