diff -r 000000000000 -r 164170e6151a pkiutilities/ocsp/src/transaction.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pkiutilities/ocsp/src/transaction.cpp Tue Jan 26 15:20:08 2010 +0200 @@ -0,0 +1,186 @@ +// Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// Implementation for OCSP Transaction object. +// +// + +#include "transaction.h" +#include "requestencoder.h" +#include "responsedecoder.h" +#include "ocsp.h" +#include "panic.h" + +#include +#include + +COCSPTransaction* COCSPTransaction::NewL(const TDesC8& aURI, + MOCSPTransport& aTransport, const TUint aRetryCount, const TInt aTimeout) + { + COCSPTransaction* self = new (ELeave) COCSPTransaction(aTransport, aRetryCount, aTimeout); + CleanupStack::PushL(self); + self->ConstructL(aURI); + CleanupStack::Pop(self); + return self; + } + +COCSPTransaction::COCSPTransaction(MOCSPTransport& aTransport, const TUint aRetryCount, const TInt aTimeout) : + CActive(EPriorityNormal), + iTransport(aTransport), + iRetryCount(aRetryCount), + iTimeout(aTimeout) + { + CActiveScheduler::Add(this); + } + + +void COCSPTransaction::ConstructL(const TDesC8& aURI) + { + iURI = aURI.AllocL(); + } + + +COCSPTransaction::~COCSPTransaction() + { + Cancel(); + delete iURI; + delete iRequestEncoder; + delete iResponseDecoder; + } + + +// Create the request, then send it off +void COCSPTransaction::SendRequest(COCSPRequest& aRequest, TRequestStatus& aStatus) + { + __ASSERT_ALWAYS(!iRequest, Panic(KErrInUse)); + iClientRequestStatus = &aStatus; + aStatus = KRequestPending; + + iRequest = &aRequest; + iState = ESendRequest; + SetActive(); + + TRequestStatus* status = &iStatus; + User::RequestComplete(status, KErrNone); + } + + +// Safe regardless of whether we have a request outstanding +void COCSPTransaction::CancelRequest() + { + Cancel(); + } + + +COCSPResponse* COCSPTransaction::TakeResponse() + { + __ASSERT_ALWAYS(iResponseDecoder, Panic(KErrNotReady)); + return iResponseDecoder->TakeResponse(); + } + + +void COCSPTransaction::CompleteClient(const TInt aStatus) + { + User::RequestComplete(iClientRequestStatus, aStatus); + } + + +void COCSPTransaction::RunL() + { + TInt err = iStatus.Int(); + switch (iState) + { + case ESendRequest: + __ASSERT_ALWAYS(err == KErrNone, Panic(KErrCorrupt)); + iRequestEncoder = COCSPRequestEncoder::NewL(*iRequest); + iTransport.SendRequest(*iURI, iRequestEncoder->Encoding(), iTimeout, iStatus); + iState = EFinished; + SetActive(); + break; + + case EFinished: + { + // Depending on the error retry the request + // Retry if + // - More attempts remaining AND + // - error is OCSP::KErrTransportTimeout OR + // - error is OCSP::KErrTransportFailure (HTTP response malformed) OR + // - invalid response received (OCSPReponse malformed) OR + // - OCSPResponseStatus is OCSP::EServerInternalError OR + // - OCSPResponseStatus is OCSP::ETryLater + // + // We won't retry if + // - error is OCSP::KErrInvalidURI OR + // - error is OCSP::KErrServerNotFound + + TBool retryNeeded = EFalse; + TInt errDecode = KErrNone; + if ((err == OCSP::KErrTransportTimeout) || (err == OCSP::KErrTransportFailure)) + { + retryNeeded = ETrue; + } + else if (err == KErrNone) + { + TRAP(errDecode, iResponseDecoder = COCSPResponseDecoder::NewL(iTransport.GetResponse())); + if ((errDecode == OCSP::EMalformedResponse) || + (errDecode == OCSP::EServerInternalError) || (errDecode == OCSP::ETryLater)) + { + retryNeeded = ETrue; + } + } + + --iRetryCount; + if (retryNeeded && iRetryCount > 0) + { + __ASSERT_ALWAYS(iResponseDecoder == NULL, Panic(KErrCorrupt)); + iTransport.SendRequest(*iURI, iRequestEncoder->Encoding(), iTimeout, iStatus); + SetActive(); + } + else + { + // If retry is not needed and there was an error (including +ve) then pass it up else complete normally + if (err != KErrNone) + { + User::Leave(err); + } + if (errDecode != KErrNone) + { + User::Leave(errDecode); + } + CompleteClient(KErrNone); + } + } + break; + + default: + Panic(KErrCorrupt); + } + } + + +TInt COCSPTransaction::RunError(TInt aError) + { + CompleteClient(aError); + return KErrNone; + } + + +void COCSPTransaction::DoCancel() + { + iTransport.CancelRequest(); + if (iClientRequestStatus) + { + CompleteClient(KErrCancel); + } + } +