diff -r 000000000000 -r 56b72877c1cb hotspotfw/internetconnectivitytestservice/src/ictshttphandler.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspotfw/internetconnectivitytestservice/src/ictshttphandler.cpp Thu Dec 17 09:20:28 2009 +0200 @@ -0,0 +1,421 @@ +/* +* Copyright (c) 2006 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: HTTP class for HTTP::HEAD testing +* +*/ + + + +#include +#include + +#include "ictshttphandler.h" +#include "ictsengine.h" +#include "am_debug.h" + +// CONSTANTS +_LIT8( KHeaderName, "X-Nokia-WLAN-Connectivity-Test" ); +_LIT8( KHeaderValue, "true" ); +_LIT8( KHttpPrefix, "http://" ); + +const TInt KMovedPermanently = 301; +const TInt KFound = 302; +const TInt KSeeOther = 303; +const TInt KTemporaryRedirect = 307; +// ======== MEMBER FUNCTIONS ======== + + +// --------------------------------------------------------------------------- +// CIctsHttpHandler::CIctsHttpHandler +// C++ default constructor can NOT contain any code, that +// might leave. +// --------------------------------------------------------------------------- +// +CIctsHttpHandler::CIctsHttpHandler( CIctsEngine& aOwner, + TInt aHttpResponseTime ) : +CTimer( EPriorityLow ), iOwner( aOwner ), +iHttpResponseTime( aHttpResponseTime ), iAttachDone( EFalse ) + { + CActiveScheduler::Add( this ); + } + + +// --------------------------------------------------------------------------- +// CIctsHttpHandler::ConstructL +// --------------------------------------------------------------------------- +// +void CIctsHttpHandler::ConstructL() + { + DEBUG("CIctsHttpHandler::ConstructL()"); + // Open channel to Socket Server + User::LeaveIfError( iSocketServ.Connect() ); + // Open connection + User::LeaveIfError( iConnection.Open(iSocketServ) ); + + CTimer::ConstructL(); + + } + + +// --------------------------------------------------------------------------- +// CIctsHttpHandler::NewL +// --------------------------------------------------------------------------- +// +CIctsHttpHandler* CIctsHttpHandler::NewL( CIctsEngine& aOwner, + TInt aHttpResponseTime ) + { + DEBUG("CIctsHttpHandler::NewL()"); + CIctsHttpHandler* self = new( ELeave ) CIctsHttpHandler( aOwner, aHttpResponseTime ); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + return self; + } + +// --------------------------------------------------------------------------- +// CIctsHttpHandler::~CIctsHttpHandler +// --------------------------------------------------------------------------- +// +CIctsHttpHandler::~CIctsHttpHandler() + { + DEBUG("CIctsHttpHandler::~CIctsHttpHandler()"); + iHttpSession.Close(); + CTimer::Cancel(); + iConnection.Close(); + iSocketServ.Close(); + DEBUG("CIctsHttpHandler::~CIctsHttpHandler() Done"); + } + + +// --------------------------------------------------------------------------- +// CIctsHttpHandler::SetHttpConnectionInfoL +// --------------------------------------------------------------------------- +// +void CIctsHttpHandler::SetHttpConnectionInfoL( RConnection& aConnection, + RSocketServ& aSocketServ) + { + DEBUG("CIctsHttpHandler::SetHttpConnectionInfoL"); + TInt result; + TBuf<16> serviceType; + TUint32 serviceId; + TBuf<100> query; + TUint connCount; + + iHttpSession.Close(); + iHttpSession.OpenL(); + + RStringPool strPool = iHttpSession.StringPool(); + + // Remove first session properties just in case. + RHTTPConnectionInfo connInfo = iHttpSession.ConnectionInfo(); + + // Clear RConnection and Socket Server instances + connInfo.RemoveProperty(strPool.StringF(HTTP::EHttpSocketServ,RHTTPSession::GetTable())); + connInfo.RemoveProperty(strPool.StringF(HTTP::EHttpSocketConnection,RHTTPSession::GetTable())); + + // Clear the proxy settings + THTTPHdrVal proxyUsage(strPool.StringF(HTTP::EUseProxy,RHTTPSession::GetTable())); + connInfo.RemoveProperty(strPool.StringF(HTTP::EProxyUsage,RHTTPSession::GetTable())); + connInfo.RemoveProperty(strPool.StringF(HTTP::EProxyAddress,RHTTPSession::GetTable())); + + // RConnection has been started, set proxy (if defined) and RConnection and + // Socket Server session properties. + + // Proxy + result = aConnection.EnumerateConnections(connCount); + User::LeaveIfError(result); + + // Get service and service type for this connection + // + _LIT(string, "%s\\%s"); + query.Format(string, IAP, IAP_SERVICE); + result = aConnection.GetIntSetting(query, serviceId); + + query.Format(string, IAP, IAP_SERVICE_TYPE); + result = aConnection.GetDesSetting(query, serviceType); + User::LeaveIfError(result); + + + // RConnection and Socket Server + // Now bind the HTTP session with the socket server connection + connInfo.SetPropertyL ( + strPool.StringF(HTTP::EHttpSocketServ, RHTTPSession::GetTable()), + THTTPHdrVal (aSocketServ.Handle()) ); + + TInt connPtr1 = reinterpret_cast(&aConnection); + connInfo.SetPropertyL ( + strPool.StringF(HTTP::EHttpSocketConnection, + RHTTPSession::GetTable() ), THTTPHdrVal (connPtr1) ); + + } + +// --------------------------------------------------------------------------- +// CIctsHttpHandler::SendHttpRequestL +// --------------------------------------------------------------------------- +// +TInt CIctsHttpHandler::SendHttpRequestL( TDesC8& aIPAddress, + TUint32 aIapID, + TUint32 aNetworkId ) + { + + DEBUG("CIctsHttpHandler::SendHttpRequestL"); + + // Cancel possibly outstanding request for polling reasons. + CTimer::Cancel(); + + TConnectionInfo info; + TPckg< TConnectionInfo > pckgInfo( info ); + info.iIapId = aIapID; + info.iNetId = aNetworkId; + + TInt err( KErrNone ); + + if ( !iAttachDone ) + { + err = iConnection.Attach( pckgInfo, RConnection::EAttachTypeMonitor); + DEBUG1("CIctsHttpHandler::SendHttpRequestL attach: %d", err); + } + + if ( KErrNone == err ) + { + iAttachDone = ETrue; + SetHttpConnectionInfoL( iConnection, iSocketServ ); + + // Remove redirect filter + RStringPool stringPool = iHttpSession.StringPool(); + RStringF filterName = stringPool.StringF(HTTP::ERedirect, RHTTPSession::GetTable()); + iHttpSession.FilterCollection().RemoveFilter(filterName); + + RStringPool strPool = iHttpSession.StringPool(); + RStringF method = strPool.StringF(HTTP::EHEAD,RHTTPSession::GetTable()); + + TBuf8 ip; + + TBool httpExists = CheckHttp( aIPAddress ); + if ( !httpExists ) + { + ip.Copy( KHttpPrefix ); + } + ip.Append( aIPAddress ); + + // Parse string to URI + TUriParser8 uri; + uri.Parse(ip); + iHttpTransaction = iHttpSession.OpenTransactionL(uri, *this, method); + RHTTPHeaders hdr = iHttpTransaction.Request().GetHeaderCollection(); + + RStringF headerStrName = strPool.OpenFStringL( KHeaderName() ); + CleanupClosePushL( headerStrName ); + + RStringF headerStrValue = strPool.OpenFStringL( KHeaderValue() ); + CleanupClosePushL( headerStrValue ); + + THTTPHdrVal headerValue( headerStrValue ); + hdr.SetFieldL( headerStrName, headerValue ); + + CleanupStack::PopAndDestroy( &headerStrValue ); + CleanupStack::PopAndDestroy( &headerStrName ); + + iHttpTransaction.SubmitL(); + DEBUG("CIctsHttpHandler::SendHttpGetL SubmitL() done"); + CTimer::After( iHttpResponseTime ); + } + + return err; + } + +// --------------------------------------------------------------------------- +// CIctsHttpHandler::CancelHttpRequestL +// --------------------------------------------------------------------------- +// +void CIctsHttpHandler::CancelHttpRequestL() + { + DEBUG("CIctsHttpHandler::CancelHttpRequestL()"); + CTimer::Cancel(); + iHttpTransaction.Cancel(); + } + +// --------------------------------------------------------------------------- +// CIctsHttpHandler::RunL +// --------------------------------------------------------------------------- +// +void CIctsHttpHandler::RunL() + { + DEBUG("CIctsHttpHandler::RunL()"); + iHttpSession.Close(); + iString = KNullDesC; + iOwner.HttpEventL( ETimeout, iString ); + } + + +// --------------------------------------------------------------------------- +// CIctsHttpHandler::MHFRunL +// +// Inherited from MHTTPTransactionCallback +// Called by framework to pass transaction events. +// --------------------------------------------------------------------------- +// +void CIctsHttpHandler::MHFRunL(RHTTPTransaction aTransaction, + const THTTPEvent& aEvent) + { + DEBUG("CIctsHttpHandler::MHFRunL"); + + switch (aEvent.iStatus) + { + + case THTTPEvent::EGotResponseHeaders: + { + DEBUG("CIctsHttpHandler::THTTPEvent::EGotResponseHeaders"); + } + break; + + case THTTPEvent::EGotResponseBodyData: + { + DEBUG("CIctsHttpHandler::THTTPEvent::EGotResponseBodyData"); + } + break; + + case THTTPEvent::EResponseComplete: + { + DEBUG("CIctsHttpHandler::THTTPEvent::EResponseComplete"); + } + break; + + case THTTPEvent::ESucceeded: + { + DEBUG("CIctsHttpHandler::THTTPEvent::ESucceeded"); + CTimer::Cancel(); + // Indicates that transaction succeeded. + // Transaction can be closed now. It's not needed anymore. + aTransaction.Close(); + iHttpSession.Close(); + iOwner.HttpEventL( EConnectionOk, iString ); + iString = KNullDesC; + } + break; + + case THTTPEvent::EFailed: + { + CTimer::Cancel(); + DEBUG("CIctsHttpHandler::THTTPEvent::EFailed"); + + RHTTPResponse resp = aTransaction.Response(); + TInt status = resp.StatusCode(); + + // Check if redirect was cause of EFailed + if( status == KMovedPermanently || status == KFound || + status == KSeeOther || status == KTemporaryRedirect ) + { + + // Inform the hotspot server that authentication is needed + RHTTPHeaders hdr =aTransaction.Response().GetHeaderCollection(); + RStringPool strP = aTransaction.Session().StringPool(); + RStringF location = strP.StringF(HTTP::ELocation,RHTTPSession::GetTable()); + + //parse the headers and look for location header + THTTPHdrVal hVal; + if(hdr.GetField(location,0,hVal)== KErrNone) + { + DEBUG("CIctsHttpHandler::THTTPEvent::GetField"); + // Location header is present + RStringF fieldValStr = strP.StringF(hVal.StrF()); + const TDesC8& fieldValDesC = fieldValStr.DesC(); + iString.Copy(fieldValDesC); + aTransaction.Close(); + iHttpSession.Close(); + iOwner.HttpEventL( EHttpAuthenticationNeeded, iString ); + } + else + { + // No location header. Can't use authentication -> redirect. + aTransaction.Close(); + iHttpSession.Close(); + iOwner.HttpEventL( EConnectionNotOk, iString ); + } + } + else + { + // Failed for other reason than redirect + aTransaction.Close(); + iHttpSession.Close(); + iOwner.HttpEventL( EConnectionNotOk, iString ); + } + + iString = KNullDesC; + } + break; + + case THTTPEvent::ERedirectedPermanently: + { + // Nothing here + DEBUG("CIctsHttpHandler::THTTPEvent::ERedirectedPermanently"); + } + break; + + case THTTPEvent::ERedirectedTemporarily: + { + // Nothing here + DEBUG("CIctsHttpHandler::THTTPEvent::ERedirectedTemporarily"); + } + break; + + default: + { + DEBUG1( "CIctsHttpHandler::MHFRunL::default iStatus: %d", aEvent.iStatus ); + CTimer::Cancel(); + aTransaction.Close(); + iHttpSession.Close(); + // close the transaction if it's an error + if ( aEvent.iStatus < 0 ) + { + _LIT(string, "Unknown error"); + iString = string; + iOwner.HttpEventL( EConnectionNotOk, iString ); + } + else + { + _LIT(string, "Default"); + iString = string; + iOwner.HttpEventL( EConnectionNotOk, iString ); + } + } + break; + } + } + +// --------------------------------------------------------------------------- +// CIctsHttpHandler::MHFRunError +// +// Inherited from MHTTPTransactionCallback +// Called by framework to pass transaction error. +// --------------------------------------------------------------------------- +// +TInt CIctsHttpHandler::MHFRunError( TInt /*aError*/, + RHTTPTransaction /*aTransaction*/, + const THTTPEvent& /*aEvent*/) + { + DEBUG("CIctsHttpHandler::MHFRunError"); + return KErrNone; + } + +// ---------------------------------------------------------------------------- +// CIctsHttpHandler::CheckHttp +// ---------------------------------------------------------------------------- +TBool CIctsHttpHandler::CheckHttp( TDesC8& aIPAddress ) + { + // The "http://" prefix is expected to be at the beginning of the URI. + return ( 0 == aIPAddress.Find( KHttpPrefix ) ); + } + +// End of File