hotspotfw/internetconnectivitytestservice/src/ictshttphandler.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Wed, 09 Jun 2010 10:53:40 +0300
branchRCL_3
changeset 18 aaabc7526ded
parent 10 dff6ebfd236f
permissions -rw-r--r--
Revision: 201021 Kit: 2010123

/*
* 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:   Class for HTTP GET testing
*
*/



#include <implementationproxy.h>
#include <uri8.h> 

#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()");
    RHTTPTransaction notActive;
    if ( iHttpTransaction != notActive )
        {
        iHttpTransaction.Close();
        }
    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<TInt>( &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::EGET, RHTTPSession::GetTable() );
    
        TBuf8<KMaxIpLength> 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();
    RHTTPTransaction notActive;
    if ( iHttpTransaction != notActive )
        {
        iHttpTransaction.Close();
        }
    }

// ---------------------------------------------------------------------------
// CIctsHttpHandler::RunL
// ---------------------------------------------------------------------------
//
void CIctsHttpHandler::RunL()
    {
    DEBUG("CIctsHttpHandler::RunL()");
    RHTTPTransaction notActive;
    if ( iHttpTransaction != notActive )
        {
        iHttpTransaction.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 )
    {
    DEBUG1("CIctsHttpHandler::MHFRunL aEvent.iStatus: %d", 
            aEvent.iStatus);
    // See HTTP event statuses. Only ESucceeded and EFailed are needed. 
    switch (aEvent.iStatus) 
        {
        case THTTPEvent::EGotResponseHeaders:
            {
            DEBUG("CIctsHttpHandler::THTTPEvent::EGotResponseHeaders");
            if ( CheckStatusCodeL( aTransaction ) )
                {
                // Redirection found. Transaction can be canceled.
                aTransaction.Cancel();
                }
            }
            break;
        case THTTPEvent::ESucceeded:
            {
            DEBUG("CIctsHttpHandler::MHFRunL Succeeded");
            CTimer::Cancel();
            iOwner.HttpEventL( EConnectionOk, iString );
            iString = KNullDesC;
            }
            break;

        case THTTPEvent::EFailed:
            {
            DEBUG("CIctsHttpHandler::MHFRunL Failed");
            CTimer::Cancel();
            iOwner.HttpEventL( EConnectionNotOk, iString );    
            iString = KNullDesC;
            }
            break;
    
        default:
            {
            DEBUG1( "CIctsHttpHandler::MHFRunL default: %d", aEvent.iStatus ); 
            // Do nothing. Timer will take care of error situations.
            } 
            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 ) );
    }

// ----------------------------------------------------------------------------
// CIctsHttpHandler::CheckStatusCodeL
// ----------------------------------------------------------------------------    
TBool CIctsHttpHandler::CheckStatusCodeL( RHTTPTransaction aTransaction )
    {
    DEBUG1("CIctsHttpHandler::CheckStatusCodeL response statuscode: %d", 
                aTransaction.Response().StatusCode());
          
    TBool ret ( EFalse );
    
    switch ( aTransaction.Response().StatusCode() )
        {
        case KMovedPermanently:
        case KFound:
        case KSeeOther:
        case KTemporaryRedirect:
            {
            DEBUG("CIctsHttpHandler::CheckStatusCodeL Redirect");
            CTimer::Cancel();
            ret = ETrue;
            
            //parse the headers and look for location header
            RHTTPHeaders hdr =aTransaction.Response().GetHeaderCollection();
            RStringPool strP = aTransaction.Session().StringPool();
            RStringF location = 
                    strP.StringF( HTTP::ELocation,RHTTPSession::GetTable() );
            THTTPHdrVal hVal;
            if( hdr.GetField( location, 0, hVal ) == KErrNone ) 
                {
                DEBUG("CIctsHttpHandler::CheckStatusCodeL location header");
                // Location header is present
                RStringF fieldValStr = strP.StringF(hVal.StrF());
                const TDesC8& fieldValDesC = fieldValStr.DesC();
                iString.Copy( fieldValDesC );
                iOwner.HttpEventL( EHttpAuthenticationNeeded, iString );
                }
            else
                {
                DEBUG("CIctsHttpHandler::CheckStatusCodeL no location header");
                // No location header. Can't redirect.
                iOwner.HttpEventL( EConnectionNotOk, iString );
                iString = KNullDesC;
                }
            }
            break;
        
        default:
            // Do nothing
            break;
        }
    return ret;
    }

//  End of File