diff -r 000000000000 -r b16258d2340f applayerprotocols/httpexamples/TestWebBrowser/src/browsertransaction.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/applayerprotocols/httpexamples/TestWebBrowser/src/browsertransaction.cpp Tue Feb 02 01:09:52 2010 +0200 @@ -0,0 +1,340 @@ +// Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// + +#include "browsertransaction.h" +#include "httpexampleutils.h" +#include "htmlhandler.h" + +#include + +_LIT8(KHtmlParserDataType, "text/html"); +_LIT8(KXmlParserDataType, "text/xml"); + + +_LIT8(KUserAgent, "Test web browser/1.0"); + +CBrowserTransaction::CBrowserTransaction ( RHTTPSession& aSession, + CHttpExampleUtils& aTestUtils, + MBrowserTransactionObserver* aObserver, + TBool aParseHtml /* = EFalse */ ) +: iSession ( aSession ), + iTransObserver ( aObserver ), + iTestUtils ( aTestUtils ), + iParseHtml ( aParseHtml ), + iSavingBody ( EFalse ) + { + + } + +CBrowserTransaction::~CBrowserTransaction () + { + iFileServer.Close(); + delete iFilePath; + delete iHtmlHandler; + } + +CBrowserTransaction* CBrowserTransaction::NewLC ( RHTTPSession& aSession, + CHttpExampleUtils& aTestUtils, + MBrowserTransactionObserver* aObserver, + const TDesC& aFilePath, + TBool aParseHtml /* = EFalse */ ) + { + CBrowserTransaction* me = new( ELeave ) CBrowserTransaction ( aSession, aTestUtils, aObserver, aParseHtml ); + CleanupStack::PushL ( me ); + me->ConstructL ( aFilePath ); + return me; + } + +void CBrowserTransaction::ConstructL ( const TDesC& aFilePath ) + { + User::LeaveIfError ( iFileServer.Connect () ); + iFilePath = aFilePath.AllocL (); + } + +CBrowserTransaction* CBrowserTransaction::NewL ( RHTTPSession& aSession, + CHttpExampleUtils& aTestUtils, + MBrowserTransactionObserver* aObserver, + const TDesC& aFilePath, + TBool aParseHtml /* = EFalse */ ) + { + CBrowserTransaction* me = CBrowserTransaction::NewLC ( aSession, aTestUtils, aObserver, aFilePath, aParseHtml ); + CleanupStack::Pop ( me ); + return me; + } + +/** + Open a new transaction and set the Date header field. + + @param aUri [in] Request URI. + */ +void CBrowserTransaction::CreateTransactionL ( const TDesC8& aUri ) + { + + TUriParser8 uri; + uri.Parse ( aUri ); + RStringF get = iSession.StringPool().StringF ( HTTP::EGET, RHTTPSession::GetTable() ); + // Open a new transaction. + iTransaction = iSession.OpenTransactionL ( uri, *this, get ); + + // Add current date header + TTime time; + time.UniversalTime(); + THTTPHdrVal hdrVal( time.DateTime() ); + RHTTPHeaders hdr = iTransaction.Request().GetHeaderCollection(); + hdr.SetFieldL( iSession.StringPool().StringF( HTTP::EDate, RHTTPSession::GetTable() ), hdrVal ); + + RStringF valStr = iSession.StringPool().OpenFStringL(KUserAgent); + THTTPHdrVal val(valStr); + hdr.SetFieldL(iSession.StringPool().StringF( HTTP::EUserAgent, RHTTPSession::GetTable() ), val); + valStr.Close(); + + // Set the accept header. + SetAcceptHdrL (); + } + +/** + Submit the transaction. + */ +void CBrowserTransaction::StartTransactionL () + { + // Submit the transaction + iTransaction.SubmitL (); + } + +/** + Extract content type header from the HTTP response headers. + */ +void CBrowserTransaction::ExtractContentTypeL ( RHTTPResponse& aResponse, RStringF& aContentTypeValue ) + { + RHTTPHeaders hdr = aResponse.GetHeaderCollection(); + + RStringF contentType = iSession.StringPool ().StringF ( HTTP::EContentType, RHTTPSession::GetTable() ); + + THTTPHdrVal fieldVal; + TInt ret = hdr.GetField ( contentType, 0, fieldVal ); + if ( ret != KErrNone ) + { + User::Leave ( KErrNotFound ); + } + + aContentTypeValue = fieldVal.StrF (); + } + +/** + Load the parser plugin. text/html or text/xml type. + */ +void CBrowserTransaction::LoadPluginL ( TMimeType aType ) + { + // Load the corresponding plugin based on the type. If it is of "xml" type + // load xml plugin else load html plugin. + iHtmlHandler = CHtmlHandler::NewL ( *iTransObserver, ( aType == eXml ) ? KXmlParserDataType() : KHtmlParserDataType() ); + } + +void CBrowserTransaction::SetAcceptHdrL () + { + // Set the following HTTP Accept header. + // text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,*/*;q=0.5 + RHTTPHeaders hdr = iTransaction.Request ().GetHeaderCollection(); + RStringPool stringPool = iSession.StringPool (); + + RStringF textXml = stringPool.OpenFStringL ( _L8 ( "text/xml" ) ); + CleanupClosePushL ( textXml ); + + RStringF appXml = stringPool.OpenFStringL ( _L8 ( "application/xml" ) ); + CleanupClosePushL ( appXml ); + + RStringF appXhtmlXml = stringPool.OpenFStringL ( _L8 ( "application/xhtml+xml" ) ); + CleanupClosePushL ( appXhtmlXml ); + + RStringF textHtml = stringPool.OpenFStringL ( _L8 ( "text/html" ) ); + CleanupClosePushL ( textHtml ); + + RStringF any = stringPool.OpenFStringL ( _L8 ( "*/*" ) ); + CleanupClosePushL ( any ); + + THTTPHdrVal hdrVal ( textXml ); + hdr.SetFieldL ( stringPool.StringF ( HTTP::EAccept, RHTTPSession::GetTable () ), hdrVal ); + + hdrVal.SetStrF ( appXml ); + hdr.SetFieldL ( stringPool.StringF ( HTTP::EAccept, RHTTPSession::GetTable () ), hdrVal ); + + hdrVal.SetStrF ( appXhtmlXml ); + hdr.SetFieldL ( stringPool.StringF ( HTTP::EAccept, RHTTPSession::GetTable () ), hdrVal ); + + hdrVal.SetStrF ( textHtml ); + THTTPHdrVal q; + q.SetInt( THTTPHdrVal::TQConv( 0.9 ) ); + + hdr.SetFieldL ( stringPool.StringF ( HTTP::EAccept, RHTTPSession::GetTable () ), hdrVal, + stringPool.StringF ( HTTP::EQ, RHTTPSession::GetTable() ), q ); + + q.SetInt ( THTTPHdrVal::TQConv( 0.5 ) ); + hdrVal.SetStrF ( any ); + hdr.SetFieldL ( stringPool.StringF ( HTTP::EAccept, RHTTPSession::GetTable () ), hdrVal, + stringPool.StringF ( HTTP::EQ, RHTTPSession::GetTable() ), q ); + + CleanupStack::PopAndDestroy ( 5 ); // Destroy textXml, appXml, appXhtmlXml, textHtml & any. + } + + +void CBrowserTransaction::MHFRunL(RHTTPTransaction aTransaction, const THTTPEvent& aEvent) + { + switch (aEvent.iStatus) + { + case THTTPEvent::EGotResponseHeaders: + { + // HTTP response headers have been received. + RHTTPResponse resp = aTransaction.Response(); + TInt status = resp.StatusCode(); + if ( iParseHtml ) + { + RStringF contentTypeValue; + ExtractContentTypeL ( resp, contentTypeValue ); + TMimeType type = GetMimeType ( contentTypeValue ); + if ( type != eUnknown ) + { + TRAPD ( err, LoadPluginL ( type ) ); + if ( err != KErrNone ) + { + iTestUtils.Test().Printf(_L("\nUnable to load the parser plugin.\n")); + User::Leave ( KErrNotFound ); + } + else + { + iTestUtils.Test().Printf(_L("\nPlugin loaded.\n")); + } + } + else + { + iParseHtml = EFalse; + } + } + + if ( resp.HasBody() && ( status >= 200 ) && ( status < 300 ) && ( status != 204 ) ) + { + iFileServer.MkDirAll( iFilePath->Des() ); + User::LeaveIfError ( iRespBodyFile.Replace ( iFileServer, iFilePath->Des(), EFileWrite|EFileShareExclusive ) ); + iSavingBody = ETrue; + } + } break; + case THTTPEvent::EGotResponseBodyData: + { + // Get the body data supplier + iRespBody = aTransaction.Response().Body(); + // Append to the output file. + TPtrC8 bodyData; + TBool lastChunk = iRespBody->GetNextDataPart( bodyData ); + + if ( iParseHtml ) + { + iHtmlHandler->ParseHtmlContentL( bodyData ); + } + + if ( iSavingBody ) + { + iRespBodyFile.Write( bodyData ); + } + + + if ( lastChunk ) + { + if ( iParseHtml ) + { + iHtmlHandler->ParseEndL (); + } + if ( iSavingBody ) + { + iRespBodyFile.Close(); + } + } + + // Done with that bit of body data + iRespBody->ReleaseData(); + + } break; + case THTTPEvent::EResponseComplete: + { + // The transaction's response is complete + iTestUtils.Test().Printf(_L("\nTransaction Complete\n")); + } break; + case THTTPEvent::ESucceeded: + { + iTestUtils.Test().Printf(_L("Transaction Successful\n")); + aTransaction.Close(); + iTransObserver->OnTransactionClose ( this ); + } break; + case THTTPEvent::EFailed: + { + iTestUtils.Test().Printf(_L("Transaction Failed\n")); + aTransaction.Close(); + iTransObserver->OnTransactionClose ( this ); + } break; + case THTTPEvent::ERedirectedPermanently: + { + iTestUtils.Test().Printf(_L("Permanent Redirection\n")); + } break; + case THTTPEvent::ERedirectedTemporarily: + { + iTestUtils.Test().Printf(_L("Temporary Redirection\n")); + } break; + case THTTPEvent::ERedirectRequiresConfirmation: + { + // 301(Moved Permanently), 302(Found) or 307(Temporary Redirect) status is received + // from a transaction and hence ERedirectRequiresConfirmation is sent by filter + // client has opted to close the transaction + iTestUtils.Test().Printf(_L("Redirect requires confirmation\n")); + aTransaction.Close(); + iTransObserver->OnTransactionClose ( this ); + } break; + default: + { + iTestUtils.Test().Printf(_L("\n"), aEvent.iStatus); + // close off the transaction if it's an error + if (aEvent.iStatus < 0) + { + aTransaction.Close(); + iTransObserver->OnTransactionClose ( this ); + } + } break; + } + } + +TInt CBrowserTransaction::MHFRunError(TInt aError, RHTTPTransaction aTransaction, const THTTPEvent& aEvent) + { + iTestUtils.Test().Printf(_L("MHFRunError fired with error code %d\n"), aError); + iTestUtils.PressAnyKey (); + + return KErrNone; + } + + +CBrowserTransaction::TMimeType CBrowserTransaction::GetMimeType ( const RStringF& aType ) + { + // Find the type has "xml" or "html". HTTP header will be set to + // text/xml,application/xml,application/xhtml+xml,text/html + TMimeType type ( eUnknown ); + TPtrC8 ptrType ( aType.DesC() ); + + if ( ptrType.FindF ( _L8 ("xml") ) != KErrNotFound ) + { + type = eXml; + } + + if ( ptrType.FindF ( _L8 ("html") ) != KErrNotFound ) + { + type = eHtml; + } + return type; + }