hotspotfw/internetconnectivitytestservice/src/ictshttphandler.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Fri, 12 Mar 2010 15:48:54 +0200
branchRCL_3
changeset 15 dff6ebfd236f
parent 0 56b72877c1cb
child 32 5bbf13e885a0
permissions -rw-r--r--
Revision: 201007 Kit: 201008

/*
* 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 <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::EHEAD,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)
    {
    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();
            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);
                    iOwner.HttpEventL( EHttpAuthenticationNeeded, iString );
                    }
                else
                    {
                    // No location header. Can't use authentication -> redirect.
                    iOwner.HttpEventL( EConnectionNotOk, iString );    
                    }
                }
             else
                {
                // Failed for other reason than redirect
                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();
            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