hotspotfw/internetconnectivitytestservice/src/ictshttphandler.cpp
changeset 0 56b72877c1cb
child 15 dff6ebfd236f
--- /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 <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()");
+    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();
+    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