pnpmobileservices/pnpms/PnpPaosFilter/src/PnpPaosFilter.cpp
changeset 18 7d11f9a6646f
parent 4 75a71fdb4c92
child 21 c707676bf59f
equal deleted inserted replaced
4:75a71fdb4c92 18:7d11f9a6646f
     1 /*
       
     2 * Copyright (c) 2005-2006 Nokia Corporation and/or its subsidiary(-ies). 
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  PnP Paos filter implementation
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include <e32std.h>
       
    20 #include <http.h>
       
    21 #include <apgcli.h>             // for RApaLsSession
       
    22 #include <apacmdln.h>           // for CApaCommandLine
       
    23 #include <centralrepository.h>  // link against centralrepository.lib
       
    24 
       
    25 #include "PnpPaosFilter.h"
       
    26 #include "PnpPaosLogger.h"
       
    27 #include "PnpPaosXml.h"
       
    28 #include "PnpPaosFilterPrivateCRKeys.h"
       
    29 
       
    30 
       
    31 
       
    32 _LIT8( KPaosContentType, "application/vnd.paos+xml" );
       
    33 _LIT8( KPnpPaosFilterName, "PnpPaosFilter" );
       
    34 _LIT8( KPaosHeaderName, "PAOS" );
       
    35 _LIT8( KPaosHeader, "ver=\"urn:liberty:paos:2003-08\"; urn:\"http://pnpms.nokia.com/signkey\"" );
       
    36 _LIT8( KDummyResponse, "<!-- Dummy -->" );
       
    37 _LIT8( KHttp, "http://" );
       
    38 _LIT8( KHttps, "https://" );
       
    39 
       
    40 CEComFilter* CPnpPaosFilter::InstantiateL( TAny* aSession )
       
    41     {
       
    42     LOGSTRING("CPnpPaosFilter::InstantiateL()");
       
    43     // Cast TAny to RHTTPSession
       
    44     RHTTPSession* pSession = static_cast<RHTTPSession*>(aSession);
       
    45     CPnpPaosFilter* filter = CPnpPaosFilter::NewL( pSession );
       
    46     LOGSTRING("CPnpPaosFilter::InstantiateL() - done");
       
    47     return filter;
       
    48     }
       
    49 
       
    50 CPnpPaosFilter* CPnpPaosFilter::NewL( RHTTPSession* pSession )
       
    51     {
       
    52     LOGSTRING("CPnpPaosFilter::NewL()");
       
    53     CPnpPaosFilter* pNew = new (ELeave) CPnpPaosFilter( pSession);
       
    54     CleanupStack::PushL(pNew);
       
    55     pNew->ConstructL();
       
    56     CleanupStack::Pop();
       
    57     LOGSTRING("CPnpPaosFilter::NewL() - done");
       
    58     return pNew;
       
    59     }
       
    60 
       
    61 CPnpPaosFilter::CPnpPaosFilter( RHTTPSession* pSession ) :
       
    62     iTransactionId(-1),
       
    63     iSession( pSession ),
       
    64     iMakePaosResponse( EFalse )
       
    65 #ifndef __SERIES60_ 
       
    66     ,iHdcPaosPostDone( EFalse )
       
    67 #endif
       
    68     {
       
    69     LOGSTRING("constructor CPnpPaosFilter()");
       
    70     }
       
    71 
       
    72 void CPnpPaosFilter::ReadAllowedDomainsL()
       
    73     {
       
    74     LOGSTRING("CPnpPaosFilter::ReadAllowedDomainsL()");
       
    75     RLibrary library;
       
    76     const TUidType hdcuid( KNullUid, KNullUid, KHdcUtilDllUid );
       
    77     TInt result = library.Load( KHdcDllFileName, hdcuid );
       
    78     LOGSTRING2( "Hdc Library load result: %i", result );
       
    79     // If there is no HDC installed, cannot add allowed HDC domains
       
    80     if( result == KErrNone )
       
    81         {
       
    82         CleanupClosePushL( library );
       
    83         LOGSTRING("CPnpPaosFilter::ReadAllowedDomainsL() 2");
       
    84         // Function at ordinal 1 is NewLC
       
    85         TLibraryFunction entry = library.Lookup(1);
       
    86         // Call the function to create new hdc dll object
       
    87         LOGSTRING("CPnpPaosFilter::ReadAllowedDomainsL() 3");
       
    88         CHdcToPaosInterface* hdcUtil = ( CHdcToPaosInterface* ) entry();
       
    89         hdcUtil->TrustedDomainsL( iTrustedHdcDomains );
       
    90         LOGSTRING("CPnpPaosFilter::ReadAllowedDomainsL() 4");
       
    91         CleanupStack::PopAndDestroy( hdcUtil );
       
    92         CleanupStack::PopAndDestroy(); // library.Close()
       
    93         LOGSTRING("CPnpPaosFilter::ReadAllowedDomainsL() 5");
       
    94         }
       
    95 
       
    96     // PnP trusted domains could be handled as in HDC case, by maintaining
       
    97     // a list of trusted domains as browser bookmarks (changeable only 
       
    98     // in a Device Managament session, not by the user)
       
    99     //AllowedDomainsArray pnpDomains = pnpUtil->AllowedDomainsL();
       
   100     LOGSTRING("CPnpPaosFilter::ReadAllowedDomainsL() - done");
       
   101     }
       
   102     
       
   103 void CPnpPaosFilter::ReadAllowedPnpDomainsL()
       
   104     {
       
   105     LOGSTRING("CPnpPaosFilter::ReadAllowedPnpDomainsL()");
       
   106     // Create PnP-MS home domain filter
       
   107     // Read allowed pnp domains from cenrep
       
   108     CRepository* repository = CRepository::NewLC( KCRUidPnpPaosFilter );
       
   109     
       
   110     TBuf<KMaxURLLength> buffer;
       
   111     TUint32 domainNbr;
       
   112     TrustedDomain domain;
       
   113     for (domainNbr = KPnPPaosFilterHomeDomain1; domainNbr <= KPnPPaosFilterHomeDomainLast; domainNbr++)
       
   114         {
       
   115         User::LeaveIfError( repository->Get( domainNbr, buffer ) );
       
   116         if(buffer.Length() > 0)
       
   117             {
       
   118             domain.Copy( buffer );
       
   119             iTrustedPnpDomains.Append( domain );
       
   120             }
       
   121         }
       
   122     CleanupStack::PopAndDestroy( repository );
       
   123     LOGSTRING("CPnpPaosFilter::ReadAllowedPnpDomainsL() - done");
       
   124     }
       
   125 
       
   126 void CPnpPaosFilter::ConstructL()
       
   127     {
       
   128     LOGSTRING("CPnpPaosFilter::ConstructL()");
       
   129 
       
   130     iSessionStringPool = iSession->StringPool();
       
   131     iFilterName = iSessionStringPool.OpenFStringL( KPnpPaosFilterName );
       
   132     TInt err( KErrNone );
       
   133     TRAP( err, iPnpPaosXml = CPnpPaosXml::NewL() );
       
   134     LOGSTRING2( "iPnpPaosXml err: %i", err );
       
   135 
       
   136     TRAP( err, ReadAllowedDomainsL() );
       
   137     if( err != KErrNone )
       
   138         {
       
   139         LOGSTRING2( "Could not read allowed domains for HelpDeskConnect PAOS: %i", err );
       
   140         }
       
   141         
       
   142     TRAP( err, ReadAllowedPnpDomainsL() );
       
   143     if( err != KErrNone )
       
   144         {
       
   145         LOGSTRING2( "Could not read allowed domains for PnP PAOS: %i", err );
       
   146         }
       
   147 
       
   148 
       
   149     LOGSTRING("CPnpPaosFilter::ConstructL() add filters");
       
   150 
       
   151     // Add the filter to the queue and register for selected incoming and
       
   152     // outgoing events.
       
   153     iSession->FilterCollection().AddFilterL(
       
   154         *this,
       
   155         THTTPEvent::ESubmit,              // Transaction event
       
   156         RStringF(),                       // Any header field
       
   157         KAnyStatusCode,                   // HTTP status code
       
   158         MHTTPFilter::EClientFilters,      // Position in filter chain
       
   159         //MHTTPFilter::EProtocolHandler,      // Position in filter chain
       
   160         iFilterName );                    // Filter name
       
   161 
       
   162     iSession->FilterCollection().AddFilterL(
       
   163         *this,
       
   164         THTTPEvent::EGotResponseHeaders,
       
   165         RStringF(),
       
   166         200,
       
   167         MHTTPFilter::EClientFilters,      // Position in filter chain
       
   168         //MHTTPFilter::EProtocolHandler,      // Position in filter chain
       
   169         iFilterName );
       
   170 
       
   171     iSession->FilterCollection().AddFilterL(
       
   172         *this,
       
   173         THTTPEvent::EGotResponseBodyData,
       
   174         RStringF(),
       
   175         200,
       
   176         MHTTPFilter::EClientFilters,      // Position in filter chain
       
   177         //MHTTPFilter::EProtocolHandler,      // Position in filter chain
       
   178         iFilterName );
       
   179 
       
   180     iSession->FilterCollection().AddFilterL(
       
   181         *this,
       
   182         THTTPEvent::EResponseComplete,
       
   183         RStringF(),
       
   184         200,
       
   185         MHTTPFilter::EClientFilters,      // Position in filter chain
       
   186         //MHTTPFilter::EProtocolHandler,      // Position in filter chain
       
   187         iFilterName );
       
   188 
       
   189     LOGSTRING("CPnpPaosFilter::ConstructL() - done");
       
   190     }
       
   191 
       
   192 CPnpPaosFilter::~CPnpPaosFilter()
       
   193     {
       
   194     LOGSTRING("CPnpPaosFilter::~CPnpPaosFilter()");
       
   195 
       
   196     if( iLoadCount )
       
   197         {
       
   198         // As we're already in a destructor, MHFUnload must not delete us again
       
   199         iLoadCount = -1;
       
   200         if (iSession)
       
   201             {
       
   202             // Removes all registrations of this filter:
       
   203             iSession->FilterCollection().RemoveFilter( iFilterName );
       
   204             }
       
   205         }
       
   206     iFilterName.Close();
       
   207     iTrustedPnpDomains.Close();
       
   208 
       
   209     delete iPaosPostUrl;
       
   210     delete iPnpPaosXml;
       
   211 
       
   212     // RArray must be closed before destructing
       
   213     iTrustedHdcDomains.Close();
       
   214 
       
   215     // we do not own iSessionStringPool, we do not close it.
       
   216     // we do not own iSession
       
   217 
       
   218     LOGSTRING("CPnpPaosFilter::~CPnpPaosFilter() - done");
       
   219     }
       
   220 
       
   221 void CPnpPaosFilter::HostFromUriL( CUri8* aUri )
       
   222     {
       
   223     LOGSTRING( "Original URI:" );
       
   224     LOGTEXT( aUri->Uri().UriDes() );
       
   225 
       
   226     /** The userinfo component specifier */
       
   227     aUri->RemoveComponentL( EUriUserinfo );
       
   228     LOGTEXT( aUri->Uri().UriDes() );
       
   229     /** The path component specifier */
       
   230     aUri->RemoveComponentL( EUriPath );
       
   231     LOGTEXT( aUri->Uri().UriDes() );
       
   232     /** The query component specifier */
       
   233     aUri->RemoveComponentL( EUriQuery );
       
   234     LOGTEXT( aUri->Uri().UriDes() );
       
   235     /** The fragment component specifier */
       
   236     aUri->RemoveComponentL( EUriFragment );
       
   237     LOGTEXT( aUri->Uri().UriDes() );
       
   238 
       
   239     // Only EUriHost (The host component specifier) and
       
   240     // EUriPort (The port component specifier) are left
       
   241     }
       
   242 
       
   243 void CPnpPaosFilter::MHFRunL( RHTTPTransaction aTransaction,
       
   244                              const THTTPEvent& aEvent)
       
   245     {
       
   246     LOGSTRING3( "CPnpPaosFilter::MHFRunL( TxnId: %d, event: %d )", aTransaction.Id(), aEvent.iStatus );
       
   247     switch( aEvent.iStatus )
       
   248         {
       
   249         case THTTPEvent::ESubmit:
       
   250             {
       
   251             LOGSTRING( "CPnpPaosFilter::MHFRunL:ESubmit");
       
   252 
       
   253             // Generate as little overhead as possible:
       
   254 
       
   255             // If this is the case maybe PAOS requests should be allowed only from certain URLs...
       
   256             // Now only nokia.com or help-portal.com are allowed URLs
       
   257             CUri8* uri = CUri8::NewLC( aTransaction.Request().URI() );
       
   258             HostFromUriL( uri );
       
   259             TPtrC8 host = uri->Uri().UriDes();
       
   260 
       
   261             // Check if a PAOS query is allowed from the domain
       
   262             
       
   263             if( IsPaosHomeDomainL( host ) )
       
   264                 {
       
   265                 LOGSTRING("PnP Mobile Services Allows PAOS-requests from the domain");
       
   266                 RHTTPHeaders headers = aTransaction.Request().GetHeaderCollection();
       
   267                 AddPaosHeadersL( headers );
       
   268                 // From HTTP stack documentation:
       
   269                 // It's important to note that a filter object is per-session, and so might be shared by several 
       
   270                 // transactions. This means that if you have per-transaction state that you need to store, it 
       
   271                 // must be stored in the transaction's property set. DO NOT STORE ANY PER-TRANSACTION INFORMATION 
       
   272                 // IN THE FILTER OBJECT. 
       
   273 
       
   274                 iMakePaosResponse = ETrue;
       
   275                 }
       
   276             else
       
   277                 {		    				
       
   278                 if( host.Size() <= 255) 	   
       
   279                     { 
       
   280                     if( iTrustedHdcDomains.Find( host ) != KErrNotFound )
       
   281                         {
       
   282                         LOGSTRING("HelpDeskConnect Allows PAOS-requests from the domain");
       
   283                         RHTTPHeaders headers = aTransaction.Request().GetHeaderCollection();
       
   284                         AddPaosHeadersL( headers );
       
   285                         iMakePaosResponse = ETrue;
       
   286                         }
       
   287                     else
       
   288                         {
       
   289                         iMakePaosResponse = EFalse;
       
   290                         }
       
   291                     }
       
   292                 } 
       
   293             CleanupStack::PopAndDestroy( uri );
       
   294             break;
       
   295             }
       
   296         case THTTPEvent::EGotResponseHeaders:
       
   297             {
       
   298             LOGSTRING( "CPnpPaosFilter::MHFRunL:EGotResponseHeaders" );
       
   299 
       
   300             if( !iMakePaosResponse ) break;
       
   301 
       
   302             RHTTPHeaders headers = aTransaction.Response().GetHeaderCollection();
       
   303             if( IsPaosContentTypeL( headers ) )
       
   304                 {
       
   305                 iTransactionId = aTransaction.Id();
       
   306 
       
   307                 delete iPaosPostUrl;
       
   308                 iPaosPostUrl = 0;
       
   309                 iPaosPostUrl = CUri8::NewL( aTransaction.Request().URI() );
       
   310                 HostFromUriL( iPaosPostUrl );
       
   311                 }
       
   312             else
       
   313                 {
       
   314                 iMakePaosResponse = EFalse;
       
   315                 }
       
   316             break;
       
   317             }
       
   318         case THTTPEvent::EGotResponseBodyData:
       
   319             {
       
   320             LOGSTRING( "CPnpPaosFilter::MHFRunL:EGotResponseBodyData" );
       
   321 
       
   322             // Check if we are allowed to make a PAOS response
       
   323             if( iMakePaosResponse && aTransaction.Id() == iTransactionId )
       
   324                 {
       
   325                 if( !iPnpPaosXml ) 
       
   326                     {
       
   327                     User::Leave( KErrGeneral );
       
   328                     }
       
   329                 TBool lastPart( EFalse );
       
   330                 // Received another body data chunk
       
   331                 MHTTPDataSupplier* pBody = aTransaction.Response().Body();
       
   332                 if( pBody )
       
   333                     {
       
   334                     lastPart = iPnpPaosXml->CollectResponseBodyL( *pBody );
       
   335                     }
       
   336 
       
   337                 // check if more data is expected
       
   338                 if( lastPart )
       
   339                     {
       
   340                     PostPaosResponseL( aTransaction );
       
   341                     }
       
   342                 }
       
   343 #ifndef __SERIES60_ 
       
   344             // check if expecting a HDC trigger file
       
   345             else if( iHdcPaosPostDone )
       
   346                 {
       
   347                 // Received another body data chunk
       
   348                 MHTTPDataSupplier* pBody = aTransaction.Response().Body();
       
   349                 if( pBody )
       
   350                     {
       
   351                     iPnpPaosXml->CollectResponseBodyL( *pBody );
       
   352                     }
       
   353                 }
       
   354 #endif
       
   355             break;
       
   356             }
       
   357         case THTTPEvent::EResponseComplete:
       
   358             {
       
   359             LOGSTRING( "CPnpPaosFilter::MHFRunL:EResponseComplete" );
       
   360 
       
   361 #ifndef __SERIES60_ 
       
   362             // if( contenttype == trigger )
       
   363             if( iHdcPaosPostDone )
       
   364                 {
       
   365                 HandleHdcTriggerL();
       
   366                 aTransaction.Cancel( THTTPFilterHandle::ECurrentFilter );
       
   367                 }
       
   368 #endif
       
   369             break;
       
   370             }
       
   371         default:
       
   372             {
       
   373             // We ignore other events. We shouldn't receive other events though.
       
   374             break;
       
   375             }
       
   376         }
       
   377     LOGSTRING( "CPnpPaosFilter::MHFRunL - done" );
       
   378     }
       
   379 
       
   380 
       
   381 void CPnpPaosFilter::PostPaosResponseL( RHTTPTransaction& aTransaction )
       
   382     {
       
   383     // For some mysterious reason the http transaction has to be cancelled here (EGotResponseBodyData),
       
   384     // otherwise browser will have the PAOS request concatenated with the resulting
       
   385     // html page (or at least the resulting html page shows an extra text "setOfKeys"
       
   386     // so it seems to concatenate at least part of the PAOS request)
       
   387 
       
   388     // Since transaction is cancelled in EGotResponseBodyData event, there is no
       
   389     // point in listening for EResponseComplete event anymore
       
   390 
       
   391     CPnpPaosXml::TPaosStates status( CPnpPaosXml::EPaosStatusUnknown );
       
   392 
       
   393     TRAPD( err, iPnpPaosXml->ParseL( status ) );
       
   394     if( err == KErrNone )
       
   395         {
       
   396         iMakePaosResponse = EFalse;
       
   397         iTransactionId = -1;
       
   398         LOGSTRING( "PAOS post URL:" );
       
   399         /*
       
   400         "responseConsumerURL attribute, with a URL as its value.This URL SHOULD be relative to the URL that
       
   401         was requested by the user agent (in the HTTP request that resulted in the creation of the SOAP message). If the
       
   402         URL nevertheless is absolute it MUST have http or https as the protocol and SHOULD have a domain that is
       
   403         owned by the same party as the owner of the domain in the URL of the HTTP request."
       
   404         [Liberty Reverse HTTP binding for SOAP Specification]
       
   405         */
       
   406         const TDesC8& paosPostUrl = iPnpPaosXml->GetPaosPostUrlL();
       
   407         if( paosPostUrl.Find( KHttp ) != KErrNotFound || paosPostUrl.Find( KHttps ) != KErrNotFound )
       
   408             {
       
   409             LOGSTRING( "Absolute URL" );
       
   410             delete iPaosPostUrl;
       
   411             iPaosPostUrl = 0;
       
   412             TUriParser8 uriParser;
       
   413             User::LeaveIfError( uriParser.Parse( paosPostUrl ) );
       
   414             iPaosPostUrl = CUri8::NewL( uriParser );
       
   415             }
       
   416         else
       
   417             {
       
   418             LOGSTRING( "Relative URL" );
       
   419             iPaosPostUrl->SetComponentL( paosPostUrl, EUriPath );
       
   420             }
       
   421         LOGTEXT( iPaosPostUrl->Uri().UriDes() );
       
   422 
       
   423         switch( status )
       
   424             {
       
   425         case CPnpPaosXml::EPaosStatusUnknown:
       
   426             LOGSTRING( "EPaosStatusUnknown" );
       
   427             // Do nothing, was: User::Leave( KErrArgument );
       
   428             break;
       
   429         case CPnpPaosXml::EPaosStatusRequestingPnPKeys:
       
   430             {
       
   431             LOGSTRING( "EPaosStatusRequestingPnPKeys" );
       
   432             CUri8* uri = CUri8::NewLC( aTransaction.Request().URI() );
       
   433             HostFromUriL( uri );
       
   434             // Also remove scheme
       
   435             uri->RemoveComponentL( EUriScheme );
       
   436             LOGTEXT( uri->Uri().UriDes() );
       
   437 
       
   438             TPtrC8 host = uri->Uri().UriDes();
       
   439             // check the domain was an allowed domain of PnP-MS home domain filter
       
   440             if( IsPaosHomeDomainL( host ) )
       
   441                 {
       
   442                 PaosPostL( aTransaction );
       
   443                 }
       
   444             CleanupStack::PopAndDestroy( uri );
       
   445             break;
       
   446             }
       
   447         case CPnpPaosXml::EPaosStatusRequestingHdcKeys:
       
   448             {
       
   449             LOGSTRING( "EPaosStatusRequestingHdcKeys" );
       
   450             CUri8* uri = CUri8::NewLC( aTransaction.Request().URI() );
       
   451             HostFromUriL( uri );
       
   452             TPtrC8 host = uri->Uri().UriDes();
       
   453             
       
   454             TBool isTrusted( EFalse );
       
   455             for( TInt i(0); i < iTrustedHdcDomains.Count(); i++ )
       
   456                 {
       
   457                 HdcTrustedDomain trustedDomain = iTrustedHdcDomains[i];
       
   458                 if( host.Find( trustedDomain ) != KErrNotFound )
       
   459                     isTrusted = ETrue;
       
   460                 }
       
   461             // check the domain was an allowed domain of HDC home domain filter
       
   462             if( isTrusted )
       
   463                 {
       
   464                 PaosPostL( aTransaction );
       
   465 #ifndef __SERIES60_ 
       
   466                 iHdcPaosPostDone = ETrue;
       
   467 #endif
       
   468                 }
       
   469 #ifdef _DEBUG
       
   470             else
       
   471                 {
       
   472                 LOGSTRING("Not an allowed domain!");
       
   473                 LOGTEXT( host );
       
   474                 LOGSTRING("domains:");
       
   475                 for( TInt j(0); j < iTrustedHdcDomains.Count(); j++ )
       
   476                     {
       
   477                     LOGTEXT( iTrustedHdcDomains[j] );
       
   478                     }
       
   479                 }
       
   480 #endif
       
   481             CleanupStack::PopAndDestroy( uri );
       
   482             break;
       
   483             }
       
   484         default:
       
   485             {
       
   486             // We ignore other events. We shouldn't receive other events though.
       
   487             break;
       
   488             }
       
   489             }
       
   490         }
       
   491     else
       
   492         {
       
   493         LOGSTRING2( "Error in ParseL: %i", err );
       
   494         }
       
   495 
       
   496     LOGSTRING("iPnpPaosXml->ResetPaosRequest()");
       
   497     iPnpPaosXml->ResetPaosRequest();
       
   498     }
       
   499 
       
   500 #ifndef __SERIES60_ 
       
   501 void CPnpPaosFilter::HandleHdcTriggerL()
       
   502     {
       
   503     LOGSTRING("Create file");
       
   504     iHdcPaosPostDone = EFalse;
       
   505 
       
   506     _LIT( KTempDocumentName, "C:\\Temp\\trigger.trg" );
       
   507 
       
   508     RFs rfs;
       
   509     User::LeaveIfError( rfs.Connect() );
       
   510     CleanupClosePushL( rfs );
       
   511     TInt err = rfs.MkDir( KTempDocumentName );
       
   512     // The folder may already exist, do not leave in that case
       
   513     if( err != KErrNone && err != KErrAlreadyExists )
       
   514         {
       
   515         User::Leave( err ); 
       
   516         }
       
   517 
       
   518     RFile file;
       
   519     User::LeaveIfError( file.Replace( rfs, KTempDocumentName, EFileWrite ) );
       
   520     CleanupClosePushL( file );
       
   521     LOGSTRING("File created");
       
   522     // A HDC PAOS post was made and we expect the response to be a HDC trigger file
       
   523     const TPtrC8 hdcTriggerData = iPnpPaosXml->ResponseBodyL();
       
   524     file.Write( hdcTriggerData );
       
   525     LOGSTRING("File written");
       
   526     iPnpPaosXml->ResetPaosRequest();
       
   527 
       
   528     CleanupStack::PopAndDestroy(); // rfs
       
   529     CleanupStack::PopAndDestroy(); // file
       
   530 
       
   531     LOGSTRING("Starting app");
       
   532     RApaLsSession appArcSession;
       
   533     User::LeaveIfError( appArcSession.Connect() );
       
   534     CleanupClosePushL( appArcSession );
       
   535 
       
   536     CApaCommandLine* cmdLine = CApaCommandLine::NewLC();
       
   537     TApaAppInfo info;
       
   538     const TUid KHdcUid = { 0x1020433F };
       
   539     User::LeaveIfError( appArcSession.GetAppInfo( info, KHdcUid ) );
       
   540 #ifdef RD_APPS_TO_EXES
       
   541     cmdLine->SetExecutableNameL( info.iFullName );
       
   542 #else
       
   543     cmdLine->SetLibraryNameL( info.iFullName );
       
   544 #endif
       
   545     cmdLine->SetCommandL( EApaCommandOpen );
       
   546     cmdLine->SetDocumentNameL( KTempDocumentName );
       
   547     err = appArcSession.StartApp( *cmdLine );
       
   548     if( err != KErrNone )
       
   549         {
       
   550         LOGSTRING2( "StartApp err %i", err );
       
   551         User::Leave( err );
       
   552         }
       
   553     LOGSTRING("Cancel transaction");
       
   554     CleanupStack::PopAndDestroy( cmdLine );
       
   555     CleanupStack::PopAndDestroy(); // appArcSession
       
   556     LOGSTRING("done");
       
   557     }
       
   558 #endif 
       
   559 
       
   560 
       
   561 TBool CPnpPaosFilter::GetNextDataPart( TPtrC8& aDataPart )
       
   562     {
       
   563     LOGSTRING("CPnpPaosFilter::GetNextDataPart");
       
   564     aDataPart.Set( KDummyResponse );
       
   565     return ETrue;
       
   566     }
       
   567 
       
   568 void CPnpPaosFilter::ReleaseData()
       
   569     {
       
   570     LOGSTRING("CPnpPaosFilter::ReleaseData");
       
   571     }
       
   572 
       
   573 TInt CPnpPaosFilter::OverallDataSize()
       
   574     {
       
   575     LOGSTRING("CPnpPaosFilter::OverallDataSize");
       
   576     return KDummyResponse().Length();
       
   577     }
       
   578 
       
   579 TInt CPnpPaosFilter::Reset()
       
   580     {
       
   581     LOGSTRING("CPnpPaosFilter::Reset");
       
   582     return KErrNone;
       
   583     }
       
   584 
       
   585 void CPnpPaosFilter::AddPaosHeadersL( RHTTPHeaders& requestHeaders )
       
   586     {
       
   587     LOGSTRING( "CPnpPaosFilter::AddPaosHeadersL" );
       
   588 
       
   589     // Add PAOS header
       
   590     THTTPHdrVal paosVer;
       
   591     RStringF paosVerStr = iSessionStringPool.OpenFStringL( KPaosHeader );
       
   592     CleanupClosePushL( paosVerStr );
       
   593     paosVer.SetStrF( paosVerStr );
       
   594     RStringF paosStr = iSessionStringPool.OpenFStringL( KPaosHeaderName );
       
   595     CleanupClosePushL( paosStr );
       
   596     requestHeaders.SetFieldL( paosStr, paosVerStr );
       
   597     CleanupStack::PopAndDestroy(); // paosStr.Close()
       
   598     CleanupStack::PopAndDestroy(); // paosVerStr.Close()
       
   599 
       
   600     // Add PAOS content type to accept header
       
   601     THTTPHdrVal acceptHdr;
       
   602     requestHeaders.GetField(
       
   603         iSessionStringPool.StringF( HTTP::EAccept, RHTTPSession::GetTable() ), 0, acceptHdr );
       
   604 
       
   605     if (acceptHdr.Type() == 0x04) //Worst case scenario, if transaction does not have accept header.
       
   606     {
       
   607         RStringF valStr = iSessionStringPool.OpenFStringL(_L8("*/*"));
       
   608    		THTTPHdrVal val(valStr);
       
   609     	requestHeaders.SetFieldL(iSessionStringPool.StringF(HTTP::EAccept, RHTTPSession::GetTable() ), val);
       
   610     	valStr.Close();
       
   611    	    requestHeaders.GetField(
       
   612  	       iSessionStringPool.StringF( HTTP::EAccept, RHTTPSession::GetTable() ), 0, acceptHdr );
       
   613 
       
   614     }
       
   615 
       
   616 
       
   617     RStringF acceptStr = acceptHdr.StrF();
       
   618     TPtrC8 accept = acceptStr.DesC();
       
   619     if( accept.Find( KPaosContentType ) == KErrNotFound )
       
   620         {
       
   621         HBufC8* acceptBuf = HBufC8::NewLC( KPaosContentType().Length() );
       
   622         TPtr8 acceptBufPtr = acceptBuf->Des();
       
   623         acceptBufPtr.Append( KPaosContentType );
       
   624         SetHttpHeaderL( requestHeaders, HTTP::EAccept, *acceptBuf );
       
   625 
       
   626 #ifdef LOGGING_ENABLED
       
   627         LOGSTRING( "Accept header:" );
       
   628             for( TInt i(0); i < acceptBufPtr.Length(); i += 128 )
       
   629                 {
       
   630                 TPtrC8 logText = acceptBufPtr.Right( acceptBufPtr.Length() - i );
       
   631                 LOGTEXT( logText );
       
   632                 }
       
   633 #endif
       
   634         CleanupStack::PopAndDestroy( acceptBuf );
       
   635         }
       
   636 #ifdef LOGGING_ENABLED
       
   637     else
       
   638         {
       
   639         LOGSTRING( "Accept header already includes PAOS:" );
       
   640         for( TInt i(0); i < accept.Length(); i += 128 )
       
   641             {
       
   642             TPtrC8 logText = accept.Right( accept.Length() - i );
       
   643             LOGTEXT( logText );
       
   644             }
       
   645         }
       
   646 #endif
       
   647 
       
   648     LOGSTRING( "CPnpPaosFilter::AddPaosHeadersL - done" );
       
   649     }
       
   650 
       
   651 TBool CPnpPaosFilter::IsPaosContentTypeL( RHTTPHeaders& aHeaders )
       
   652     {
       
   653     LOGSTRING( "CPnpPaosFilter::IsPaosContentTypeL" );
       
   654 
       
   655     // get the Content-Type string
       
   656     RStringF content = iSessionStringPool.StringF( HTTP::EContentType,
       
   657                                             RHTTPSession::GetTable() );
       
   658 
       
   659     THTTPHdrVal fieldVal;
       
   660     // now retrieve the Content-Type field
       
   661     if( KErrNone == aHeaders.GetField( content, 0, fieldVal ) )
       
   662         {
       
   663         TPtrC8 contentType;
       
   664         // get the field value
       
   665         if( THTTPHdrVal::KStrFVal == fieldVal.Type() )
       
   666             {
       
   667             contentType.Set( fieldVal.StrF().DesC() );
       
   668             LOGSTRING( "ContentType:" );
       
   669             LOGTEXT( contentType );
       
   670             }
       
   671         else if( THTTPHdrVal::KStrVal == fieldVal.Type() )
       
   672             {
       
   673             contentType.Set( fieldVal.Str().DesC() );
       
   674             LOGSTRING( "ContentType:" );
       
   675             LOGTEXT( contentType );
       
   676             }
       
   677         else
       
   678             {
       
   679             return EFalse;
       
   680             }
       
   681 
       
   682         if( contentType.Compare( KPaosContentType ) == 0 )
       
   683             {
       
   684             LOGSTRING("Content type matches");
       
   685 
       
   686             // 3.0 does not handle the resulting html right, it is stored by DL manager.
       
   687             // This means that it does not recognize the incoming text/html data correctly.
       
   688             // So try replacing content type field with text/html, maybe PAOS content type is
       
   689             // cached somewhere even if the transaction has been canceled.
       
   690             LOGSTRING("Resetting Content type to text/html");
       
   691             aHeaders.RemoveField( iSessionStringPool.StringF( HTTP::EContentType , RHTTPSession::GetTable() ) );
       
   692             SetHttpHeaderL( aHeaders, HTTP::EContentType, _L8("text/html") );
       
   693 
       
   694             return ETrue;
       
   695             }
       
   696         }
       
   697     return EFalse;
       
   698     }
       
   699 
       
   700 void CPnpPaosFilter::PaosPostL( RHTTPTransaction& aTransaction )
       
   701     {
       
   702     LOGSTRING( "CPnpPaosFilter::PaosPostL" );
       
   703 
       
   704     RHTTPRequest request = aTransaction.Request();
       
   705 
       
   706     aTransaction.Cancel( THTTPFilterHandle::ECurrentFilter );
       
   707     RHTTPHeaders requestHeaders = request.GetHeaderCollection();
       
   708     request.RemoveBody();
       
   709     // Remove Content-Type header
       
   710     requestHeaders.RemoveField( iSessionStringPool.StringF( HTTP::EContentType, RHTTPSession::GetTable() ) );
       
   711     // Remove Content-Length header
       
   712     requestHeaders.RemoveField( iSessionStringPool.StringF( HTTP::EContentLength, RHTTPSession::GetTable() ) );
       
   713     // Remove Host header
       
   714     requestHeaders.RemoveField( iSessionStringPool.StringF( HTTP::EHost, RHTTPSession::GetTable() ) );
       
   715 
       
   716     // PAOS header
       
   717     THTTPHdrVal paosVer;
       
   718     RStringF paosVerStr = iSessionStringPool.OpenFStringL( KPaosHeader );
       
   719     CleanupClosePushL( paosVerStr );
       
   720     paosVer.SetStrF( paosVerStr );
       
   721     RStringF paosStr = iSessionStringPool.OpenFStringL( KPaosHeaderName );
       
   722     CleanupClosePushL( paosStr );
       
   723     requestHeaders.SetFieldL( paosStr, paosVerStr );
       
   724     CleanupStack::PopAndDestroy(); // paosStr
       
   725     CleanupStack::PopAndDestroy(); // paosVerStr
       
   726 
       
   727     // Content headers
       
   728     SetHttpHeaderL( requestHeaders, HTTP::EContentType, _L8("application/vnd.paos+xml") );
       
   729 
       
   730     request.SetMethod( iSessionStringPool.StringF( HTTP::EPOST, RHTTPSession::GetTable() ) );
       
   731 
       
   732     // Set the URI of the request
       
   733     request.SetURIL( iPaosPostUrl->Uri() );
       
   734 
       
   735     LOGSTRING( "Uri:" );
       
   736     LOGTEXT( iPaosPostUrl->Uri().UriDes() );
       
   737 
       
   738     // Provide Response
       
   739     if( !iPnpPaosXml )
       
   740         {
       
   741         User::Leave( KErrGeneral );
       
   742         }
       
   743     request.SetBody( *iPnpPaosXml );
       
   744 
       
   745     aTransaction.Cancel();
       
   746     aTransaction.SubmitL();
       
   747     LOGSTRING( "CPnpPaosFilter::PaosPostL - done" );
       
   748     }
       
   749 
       
   750 void CPnpPaosFilter::SetHttpHeaderL( RHTTPHeaders& aMessage, const HTTP::TStrings aIndex, const TDesC8& aString )
       
   751     {
       
   752     LOGSTRING( "CPnpPaosFilter::SetHttpHeaderL" );
       
   753     
       
   754     THTTPHdrVal hdrVal;
       
   755     RStringF str = iSessionStringPool.OpenFStringL( aString );
       
   756     CleanupClosePushL( str );
       
   757     hdrVal.SetStrF( str );
       
   758     aMessage.SetFieldL( iSessionStringPool.StringF( aIndex, RHTTPSession::GetTable() ), hdrVal );
       
   759     CleanupStack::PopAndDestroy();
       
   760     
       
   761     LOGSTRING( "CPnpPaosFilter::SetHttpHeaderL - done" );
       
   762     }
       
   763 
       
   764 TInt CPnpPaosFilter::MHFRunError( TInt aError,
       
   765                                  RHTTPTransaction aTransaction,
       
   766                                  const THTTPEvent& aEvent )
       
   767     {
       
   768     LOGSTRING( "CPnpPaosFilter::MHFRunError()" );
       
   769 
       
   770     LOGSTRING3( "error: %d, event: %d", aError, aEvent.iStatus );
       
   771     // If anything left, we've run out of memory or something
       
   772     // similarly catastrophic has gone wrong.
       
   773     // Remove the body to prevent other client from accessing
       
   774     // the contents.
       
   775     aTransaction.Response().RemoveBody();
       
   776     // Set the transaction to failed
       
   777     aTransaction.Fail();
       
   778     // Keep compiler happy
       
   779     (void)aError;
       
   780     (void)aEvent;
       
   781     LOGSTRING( "CPnpPaosFilter::MHFRunError() - done" );
       
   782     return KErrNone;
       
   783     }
       
   784 
       
   785 void CPnpPaosFilter::MHFLoad(RHTTPSession /*aSession*/,
       
   786                                          THTTPFilterHandle /*aHandle*/)
       
   787     {
       
   788     LOGSTRING("CPnpPaosFilter::MHFLoad");
       
   789     iLoadCount++;
       
   790     }
       
   791 
       
   792 void CPnpPaosFilter::MHFUnload(RHTTPSession /*aSession*/,
       
   793                                            THTTPFilterHandle /*aHandle*/)
       
   794     {
       
   795     LOGSTRING("CPnpPaosFilter::MHFUnload");
       
   796     if( --iLoadCount > 0 )
       
   797         {
       
   798         LOGSTRING("CPnpPaosFilter::MHFUnload - done");
       
   799         return;
       
   800         }
       
   801     delete this; // Delete object itself
       
   802     LOGSTRING("CPnpPaosFilter::MHFUnload - done");
       
   803     }
       
   804 
       
   805 TBool CPnpPaosFilter::IsPaosHomeDomainL( const TPtrC8 aHost )
       
   806     {
       
   807     LOGSTRING("CPnpPaosFilter::IsPaosHomeDomainL");
       
   808     // check is the host in trusted domains list
       
   809     for (TInt i=0; i < iTrustedPnpDomains.Count(); i++)
       
   810         {
       
   811         if (aHost.Find(iTrustedPnpDomains[i]) != KErrNotFound )
       
   812             {
       
   813             return ETrue;
       
   814             }
       
   815         }
       
   816     return EFalse;
       
   817     }