upnp/upnpstack/upnphttptransfer/src/httpdownloadworker.cpp
changeset 0 f5a58ecadc66
equal deleted inserted replaced
-1:000000000000 0:f5a58ecadc66
       
     1 /** @file
       
     2 * Copyright (c) 2007 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:  Handles download of one file at a time
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 // System include files
       
    20 #include <sysutil.h>
       
    21 #ifndef __SERIES60_31__
       
    22 #include <driveinfo.h>
       
    23 #endif
       
    24 
       
    25 // User include files
       
    26 #include "httpfile.h"
       
    27 #include "httpdownloadworker.h"
       
    28 #include "httpheader.h"
       
    29 #include "httpworkerobserver.h"
       
    30 #include "upnpcompvariant.hrh"
       
    31 
       
    32 // Constants
       
    33 _LIT8( KModuleName, "HttpTransfer");
       
    34 const TUint KDefaultBufferSize = 64000;
       
    35 const TUint32 KMaxBufferSize   = 0x100000; //1MB
       
    36 
       
    37 
       
    38 // ======== MEMBER FUNCTIONS ========
       
    39 
       
    40 // --------------------------------------------------------------------------
       
    41 // CHttpDownloadWorker::NewL()
       
    42 // (See comments in header file)
       
    43 // --------------------------------------------------------------------------
       
    44 //
       
    45 CHttpDownloadWorker* CHttpDownloadWorker::NewL(
       
    46                                            MHttpTransferObserver& aObserver,
       
    47                                            TUint aIAPId,
       
    48                                            TUint aBufferSize,
       
    49                                            MHttpWorkerObserver& aCallback )
       
    50     {
       
    51     CHttpDownloadWorker* self = CHttpDownloadWorker::NewLC( aObserver,
       
    52                                                             aIAPId,
       
    53                                                             aBufferSize,
       
    54                                                             aCallback );
       
    55     CleanupStack::Pop( self );
       
    56     return self;
       
    57     }
       
    58 
       
    59 // --------------------------------------------------------------------------
       
    60 // CHttpDownloadWorker::NewLC()
       
    61 // (See comments in header file)
       
    62 // --------------------------------------------------------------------------
       
    63 //
       
    64 CHttpDownloadWorker* CHttpDownloadWorker::NewLC(
       
    65                                            MHttpTransferObserver& aObserver,
       
    66                                            TUint aIAPId,
       
    67                                            TUint aBufferSize,
       
    68                                            MHttpWorkerObserver& aCallback )
       
    69     {
       
    70     CHttpDownloadWorker* self = new( ELeave ) CHttpDownloadWorker(
       
    71                                                                aIAPId,
       
    72                                                                aBufferSize,
       
    73                                                                aObserver,
       
    74                                                                aCallback );
       
    75     CleanupStack::PushL( self );
       
    76     self->ConstructL();
       
    77     return self;
       
    78     }
       
    79 
       
    80 // --------------------------------------------------------------------------
       
    81 // CHttpDownloadWorker::CHttpDownloadWorker()
       
    82 // (See comments in header file)
       
    83 // --------------------------------------------------------------------------
       
    84 //
       
    85 CHttpDownloadWorker::CHttpDownloadWorker( TUint /*aIAPId*/,
       
    86                                           TUint aBufferSize,
       
    87                                           MHttpTransferObserver& aObserver,
       
    88                                           MHttpWorkerObserver& aCallback )
       
    89     {
       
    90     iProcessState = EHttpTransactionIdle;
       
    91     iFileSizeFromHeader = 0;
       
    92     iBytesTransferred = 0;
       
    93     iObserver = &aObserver;
       
    94     iCallback = &aCallback;
       
    95 
       
    96     if ( aBufferSize <= 0 )
       
    97         {
       
    98         iBufferSize = KDefaultBufferSize;
       
    99         }
       
   100     else if ( aBufferSize > KMaxBufferSize )
       
   101         {
       
   102         iBufferSize = KMaxBufferSize;
       
   103         }
       
   104     else
       
   105         {
       
   106         iBufferSize = aBufferSize;
       
   107         }
       
   108     }
       
   109 
       
   110 // --------------------------------------------------------------------------
       
   111 // CHttpDownloadWorker::ConstructL()
       
   112 // (See comments in header file)
       
   113 // --------------------------------------------------------------------------
       
   114 //
       
   115 void CHttpDownloadWorker::ConstructL()
       
   116     {
       
   117     CHttpTransferWorker::ConstructL();
       
   118     ConnectL();
       
   119     iSessionTimer = CHttpNotifyTimer::NewL( this );
       
   120     }
       
   121 
       
   122 // --------------------------------------------------------------------------
       
   123 // CHttpDownloadWorker::~CHttpDownloadWorker()
       
   124 // (See comments in header file)
       
   125 // --------------------------------------------------------------------------
       
   126 //
       
   127 CHttpDownloadWorker::~CHttpDownloadWorker()
       
   128     {
       
   129     delete iResponseBody;
       
   130     delete iSessionTimer;
       
   131     }
       
   132 
       
   133 // --------------------------------------------------------------------------
       
   134 // CHttpDownloadWorker::CheckDiskSpaceL()
       
   135 // (See comments in header file)
       
   136 // --------------------------------------------------------------------------
       
   137 //
       
   138 void CHttpDownloadWorker::CheckDiskSpaceL( TInt aSize )
       
   139     {
       
   140     TInt driveNum;
       
   141     TDriveInfo aninfo;
       
   142     if ( iProcessedFile->Path() )
       
   143         {
       
   144         TParse p;
       
   145         p.Set( *(iProcessedFile->Path() ), NULL, NULL );
       
   146         TPtrC pointer = p.Drive();
       
   147         TLex lineParser( pointer.Ptr() );
       
   148         TChar ch = lineParser.Get();
       
   149 
       
   150         //sets the default drive or the fulnd value
       
   151         User::LeaveIfError( iFsSession.CharToDrive( ch, driveNum ) );
       
   152         }
       
   153     else
       
   154         {
       
   155         TDriveInfo driveInfo;
       
   156         User::LeaveIfError( iFile.Drive( driveNum, driveInfo ) );
       
   157         }
       
   158 
       
   159     User::LeaveIfError( iFsSession.Drive( aninfo, driveNum ) );
       
   160 
       
   161     // get the drive status from DriveInfo in order to distinguish memory card
       
   162     // and hard disk from each other in multiple drive environment.
       
   163 #ifndef __SERIES60_31__
       
   164     TUint driveStatus = 0;
       
   165     User::LeaveIfError( DriveInfo::GetDriveStatus(
       
   166         iFsSession, driveNum, driveStatus ) );
       
   167 #endif
       
   168 
       
   169     // The case for default device memory (C-drive).
       
   170     if( aninfo.iType == EMediaNANDFlash )
       
   171         {
       
   172         if( SysUtil::FFSSpaceBelowCriticalLevelL
       
   173                                         ( &iFsSession, aSize ) )
       
   174              {
       
   175              User::Leave( KErrDiskFull );
       
   176              }
       
   177         }
       
   178 #ifndef __SERIES60_31__
       
   179     // Internal FLASH memory
       
   180     // Multiple drive checking rules are applied here
       
   181     // note that in case of S60 3.1 this case is skipped
       
   182     else if( aninfo.iType == EMediaHardDisk &&
       
   183              aninfo.iDriveAtt & KDriveAttRemovable &&
       
   184              driveStatus & DriveInfo::EDriveInternal )
       
   185         {
       
   186         if( SysUtil::MMCSpaceBelowCriticalLevelL( &iFsSession, aSize ) )
       
   187             {
       
   188             User::Leave( KErrDiskFull );
       
   189             }
       
   190         }
       
   191 #endif
       
   192     // Memory card (or practically any other memory type)
       
   193     // This covers also emulator's EMediaRam.
       
   194     else
       
   195         {
       
   196         if( SysUtil::DiskSpaceBelowCriticalLevelL
       
   197                                         ( &iFsSession, aSize, driveNum ) )
       
   198             {
       
   199             User::Leave( KErrDiskFull );
       
   200             }
       
   201         }
       
   202     }
       
   203 
       
   204 // --------------------------------------------------------------------------
       
   205 // CHttpDownloadWorker::WriteTailIntoFileL()
       
   206 // (See comments in header file)
       
   207 // --------------------------------------------------------------------------
       
   208 //
       
   209 void CHttpDownloadWorker::WriteTailIntoFileL()
       
   210     {
       
   211     if( iResponseBody )
       
   212         {
       
   213         if( iResponseBody->Length() > 0 )
       
   214             {
       
   215             CheckDiskSpaceL( iResponseBody->Length() );
       
   216             TPtr8 ptrResponseBody = iResponseBody->Des();
       
   217 #ifndef RD_UPNP_REMOTE_ACCESS
       
   218             TInt size( 0 );
       
   219             iFile.Size( size );
       
   220             if( size >= 0 )
       
   221                 {
       
   222                 //transfer succeed, total size can be set to file size
       
   223                 //it concerns chunked encoding or HTTP1.0 
       
   224                 if ( iFileSizeFromHeader == 0 )
       
   225                     {
       
   226                     iFileSizeFromHeader = size;
       
   227                     }
       
   228                 
       
   229 #endif //RD_UPNP_REMOTE_ACCESS
       
   230                 // Write the data on the disk
       
   231                 User::LeaveIfError( iFile.Write( ptrResponseBody ) );
       
   232                 
       
   233                 delete iResponseBody;
       
   234                 iResponseBody = NULL;
       
   235 
       
   236                 // if the tracking is on send one more progress info
       
   237 #ifdef RD_UPNP_REMOTE_ACCESS
       
   238                 if ( iProcessedFile->TrackingOn() )
       
   239 #else // RD_UPNP_REMOTE_ACCESS
       
   240                 if ( iProcessedFile->TrackingOn()  )
       
   241 #endif // RD_UPNP_REMOTE_ACCESS
       
   242                     {
       
   243                     iObserver->TransferProgress( iProcessedFile->Key(),
       
   244                                                  iBytesTransferred,
       
   245                                                  iFileSizeFromHeader );
       
   246                     }
       
   247 #ifndef RD_UPNP_REMOTE_ACCESS
       
   248                 }
       
   249 #endif //RD_UPNP_REMOTE_ACCESS
       
   250             }
       
   251         }
       
   252     }
       
   253 
       
   254 // --------------------------------------------------------------------------
       
   255 // CHttpDownloadWorker::HandleResponseDataL()
       
   256 // (See comments in header file)
       
   257 // --------------------------------------------------------------------------
       
   258 //
       
   259 void CHttpDownloadWorker::HandleResponseDataL(
       
   260                                               RHTTPTransaction aTransaction )
       
   261     {
       
   262     MHTTPDataSupplier* pRespBody = aTransaction.Response().Body();
       
   263 
       
   264     if( pRespBody )
       
   265         {
       
   266         TPtrC8 dataChunk;
       
   267         pRespBody->GetNextDataPart( dataChunk );
       
   268 
       
   269         iSessionTimer->Cancel();
       
   270         iSessionTimer->AfterSeconds( KSessionTimeout );
       
   271 
       
   272         // increase the progress counter
       
   273         iBytesTransferred += dataChunk.Length();
       
   274 
       
   275         // Allocate memory for the data
       
   276         if( !iResponseBody )
       
   277             {
       
   278             // this is the first call so create the buffer to retain
       
   279             // response data
       
   280             iResponseBody = HBufC8::NewL( iBufferSize );
       
   281             }
       
   282 
       
   283         if ( iResponseBody->Length() + dataChunk.Length() > iBufferSize  )
       
   284             {
       
   285             iResponseBody = iResponseBody->ReAllocL(
       
   286                                                 iResponseBody->Length() +
       
   287                                                 dataChunk.Length() );
       
   288             }
       
   289 
       
   290         // Append the new data to the buffer
       
   291         TPtr8 ptrResponseBody = iResponseBody->Des();
       
   292         ptrResponseBody.Append( dataChunk );
       
   293         pRespBody->ReleaseData();
       
   294         // If buffer is full write data to memory card ( to file )
       
   295         if( iResponseBody->Length() > iBufferSize )
       
   296             {
       
   297 #ifndef RD_UPNP_REMOTE_ACCESS
       
   298             TInt size( 0 );
       
   299             // if the file handle was not valid
       
   300             User::LeaveIfError( iFile.Size( size ) );
       
   301             if( size >= 0 )
       
   302                 {
       
   303 #endif // RD_UPNP_REMOTE_ACCESS
       
   304                 CheckDiskSpaceL( ptrResponseBody.Length() );
       
   305                 User::LeaveIfError( iFile.Write( ptrResponseBody ) );
       
   306                 delete iResponseBody;
       
   307                 iResponseBody = NULL;
       
   308 #ifndef RD_UPNP_REMOTE_ACCESS
       
   309                 }                      
       
   310 #endif // RD_UPNP_REMOTE_ACCESS
       
   311 
       
   312             // Inform observer about the progress if progress tracking is on
       
   313 #ifdef RD_UPNP_REMOTE_ACCESS
       
   314             if ( iProcessedFile->TrackingOn() )
       
   315 #else // RD_UPNP_REMOTE_ACCESS
       
   316             if ( iProcessedFile->TrackingOn()  )
       
   317 #endif // RD_UPNP_REMOTE_ACCESS
       
   318                 {
       
   319                 iObserver->TransferProgress( iProcessedFile->Key(),
       
   320                                              iBytesTransferred,
       
   321                                              iFileSizeFromHeader );
       
   322                 }
       
   323             }
       
   324         }
       
   325 
       
   326     else
       
   327         {
       
   328         aTransaction.Close();
       
   329 
       
   330         // Remove remains of the file from the file system
       
   331         delete iProcessedFile;
       
   332         iProcessedFile = NULL;
       
   333         }
       
   334     }
       
   335 
       
   336 // --------------------------------------------------------------------------
       
   337 // CHttpDownloadWorker::HTTPGetL()
       
   338 // (See comments in header file)
       
   339 // --------------------------------------------------------------------------
       
   340 //
       
   341 void CHttpDownloadWorker::HttpGetL()
       
   342     {
       
   343     // if URI is null -> leave
       
   344     if ( !iProcessedFile->Uri() )
       
   345         {
       
   346         User::Leave( KErrArgument );
       
   347         }
       
   348 
       
   349     TUriParser8 uri;
       
   350     User::LeaveIfError( uri.Parse( *( iProcessedFile->Uri() ) ) );
       
   351 
       
   352     RStringF method;
       
   353     method = iStringPool.StringF( HTTP::EGET, RHTTPSession::GetTable() );
       
   354 
       
   355     iHttpTransaction = iSession.OpenTransactionL( uri, *this, method );
       
   356     RHTTPHeaders hdr = iHttpTransaction.Request().GetHeaderCollection();
       
   357 
       
   358     SetHeaderL( hdr, HTTP::EUserAgent, KModuleName );
       
   359 
       
   360     //Set the property of upnphttptransfer to ENotifyOnDisconnect
       
   361     //Set the property of HTTP Transaction to EEnableDisconnectNotification
       
   362     //The MHFRunL can get the really http error.
       
   363     iHttpTransaction.PropertySet().SetPropertyL(
       
   364         iSession.StringPool().StringF(
       
   365             HTTP::ENotifyOnDisconnect,RHTTPSession::GetTable()),
       
   366             iSession.StringPool().StringF(
       
   367                 HTTP::EEnableDisconnectNotification,
       
   368                 RHTTPSession::GetTable() ));
       
   369 
       
   370     // Sets extra headers
       
   371     RPointerArray<CHttpHeader> headerArray = iProcessedFile->Headers();
       
   372     for ( TInt i = 0; i < headerArray.Count(); i++ )
       
   373         {
       
   374         SetHeaderL( hdr,
       
   375                     headerArray[i]->FieldName(),
       
   376                     headerArray[i]->FieldValue() );
       
   377         }
       
   378 
       
   379     // Now will get events in MHFRunL
       
   380     iHttpTransaction.SubmitL();
       
   381 
       
   382     //set timer
       
   383     iSessionTimer->Cancel();
       
   384     iSessionTimer->AfterSeconds( KSessionTimeout );
       
   385 
       
   386     method.Close();
       
   387 
       
   388     // Change state of the state machine
       
   389     iProcessState = EHttpGetSent;
       
   390     }
       
   391 
       
   392 // --------------------------------------------------------------------------
       
   393 // CHttpDownloadWorker::FinishDownload()
       
   394 // (See comments in header file)
       
   395 // --------------------------------------------------------------------------
       
   396 //
       
   397 void CHttpDownloadWorker::FinishDownload( RHTTPTransaction aTransaction )
       
   398     {
       
   399     // close transaction
       
   400     aTransaction.Close();
       
   401 
       
   402     delete iResponseBody;
       
   403     iResponseBody = NULL;
       
   404     
       
   405     // change state
       
   406     iProcessState = EHttpTransactionIdle;
       
   407     iProcessedFile->CloseFile(); 
       
   408     iFile.Close();
       
   409 
       
   410     // inform observers
       
   411     iObserver->TransferCompleted( iProcessedFile->Key(), KErrNone );
       
   412 
       
   413     delete iProcessedFile;
       
   414     iProcessedFile = NULL;
       
   415     
       
   416     // inform the worker observer
       
   417     iCallback->WorkerCompleted();
       
   418     }
       
   419 
       
   420 // --------------------------------------------------------------------------
       
   421 // CHttpDownloadWorker::CompleteAndNotify()
       
   422 // (See comments in header file)
       
   423 // --------------------------------------------------------------------------
       
   424 //
       
   425 void CHttpDownloadWorker::CompleteAndNotifyL( TInt aError )
       
   426     {
       
   427     iSessionTimer->Cancel();
       
   428     iHttpTransaction.Cancel();
       
   429     iHttpTransaction.Close();
       
   430     iObserver->TransferCompleted( iProcessedFile->Key(), aError );
       
   431 
       
   432     delete iResponseBody;
       
   433     iResponseBody = NULL;
       
   434     iProcessState = EHttpTransactionIdle;
       
   435     iCallback->WorkerCompleted();
       
   436 
       
   437     iFile.Close();
       
   438     iProcessedFile->DeleteFileFromFileSystemL();
       
   439     delete iProcessedFile;
       
   440     iProcessedFile = NULL;
       
   441     }
       
   442 
       
   443 
       
   444 // from base class CHttpTransferWorker
       
   445 
       
   446 // --------------------------------------------------------------------------
       
   447 // CHttpDownloadWorker::CancelTransfer()
       
   448 // (See comments in header file)
       
   449 // --------------------------------------------------------------------------
       
   450 //
       
   451 void CHttpDownloadWorker::CancelTransfer()
       
   452     {
       
   453     iSessionTimer->Cancel();
       
   454     // if transfer has not been started yet
       
   455     if ( iProcessState == EHttpWaitingForStart )
       
   456         {
       
   457         delete iProcessedFile;
       
   458         iProcessedFile = NULL;
       
   459 
       
   460         iProcessState = EHttpTransactionIdle;
       
   461         iCallback->WorkerCompleted();
       
   462         }
       
   463     // if process is finished do nothing
       
   464     else if ( iProcessState != EHttpTransactionIdle )
       
   465         {
       
   466         iHttpTransaction.Cancel();
       
   467         iHttpTransaction.Close();
       
   468 
       
   469         delete iResponseBody;
       
   470         iResponseBody = NULL;
       
   471         iProcessState = EHttpTransactionIdle;
       
   472         iCallback->WorkerCompleted();
       
   473 
       
   474         iFile.Close();
       
   475         TRAP_IGNORE( iProcessedFile->DeleteFileFromFileSystemL() )
       
   476         delete iProcessedFile;
       
   477         iProcessedFile = NULL;
       
   478         }
       
   479     }
       
   480 
       
   481 // --------------------------------------------------------------------------
       
   482 // CHttpDownloadWorker::StartProcessL()
       
   483 // (See comments in header file)
       
   484 // --------------------------------------------------------------------------
       
   485 //
       
   486 void CHttpDownloadWorker::StartProcessL()
       
   487     {
       
   488     CHttpTransferWorker::StartProcessL();
       
   489 
       
   490     iProcessedFile->CreateFileInFileSystemL();
       
   491 
       
   492     // File creation succeeded -> handle available
       
   493     User::LeaveIfError( iFile.Duplicate( iProcessedFile->FileHandle() ) );
       
   494 
       
   495     // Perform HTTP GET
       
   496     HttpGetL();
       
   497     }
       
   498 
       
   499 // --------------------------------------------------------------------------
       
   500 // CHttpDownloadWorker::MHFRunL()
       
   501 // (See comments in header file)
       
   502 // --------------------------------------------------------------------------
       
   503 //
       
   504 void CHttpDownloadWorker::MHFRunL( RHTTPTransaction aTransaction,
       
   505                                    const THTTPEvent& aEvent )
       
   506     {
       
   507     //set timer
       
   508     iSessionTimer->Cancel();
       
   509 
       
   510     // event handler
       
   511     switch (aEvent.iStatus)
       
   512         {
       
   513         // Response headers received
       
   514         case THTTPEvent::EGotResponseHeaders:
       
   515             {
       
   516             // accept all 'Successful' range of codes 2xx
       
   517             TInt status = aTransaction.Response().StatusCode();
       
   518             if ( !( ( status >= HTTPStatus::EOk ) &&
       
   519                     ( status <  HTTPStatus::EMultipleChoices ) ) )
       
   520                 {
       
   521                 // calls MHFRunError
       
   522                 User::Leave( aTransaction.Response().StatusCode() );
       
   523                 }
       
   524 
       
   525             else if ( iProcessState == EHttpGetSent )
       
   526                 {
       
   527                 RHTTPHeaders header =
       
   528                            aTransaction.Response().GetHeaderCollection();
       
   529                 RStringF field;
       
   530                 field = iStringPool.StringF( HTTP::EContentLength,
       
   531                                              RHTTPSession::GetTable() );
       
   532                 THTTPHdrVal value;
       
   533 
       
   534                 // Get value of the content-length field.
       
   535                 // Value is represented in bytes.
       
   536                 if ( header.GetField( field, 0, value ) == KErrNone )
       
   537                     {
       
   538                     // Set the value to filesize
       
   539                     iFileSizeFromHeader = value.Int();
       
   540                     }
       
   541                 else
       
   542                     {
       
   543                     // If the Content-Length is not defined
       
   544                     // in case chunked encoding or HTTP1.0 
       
   545                     // Set the iFileSizeFromHeader to zero
       
   546                     iFileSizeFromHeader = 0;
       
   547                     }
       
   548 
       
   549                 iBytesTransferred = 0;
       
   550 
       
   551                 iProcessState = EHttpGetResponseReceived;
       
   552                 }
       
   553             iSessionTimer->AfterSeconds( KSessionTimeout );
       
   554             break;
       
   555             }
       
   556 
       
   557         // Response body data received
       
   558         // This is only entered when state is EHttpGetResponseReceived
       
   559         //   --> no need to check state
       
   560         case THTTPEvent::EGotResponseBodyData:
       
   561             {
       
   562             // handle body data
       
   563             // Informs the observer as well
       
   564             HandleResponseDataL( aTransaction );
       
   565 
       
   566             break;
       
   567             }
       
   568 
       
   569         // Response completed
       
   570         case THTTPEvent::EResponseComplete:
       
   571             {
       
   572             // Get response was completed
       
   573             if ( iProcessState == EHttpGetResponseReceived )
       
   574                 {
       
   575                 // Write last part of the buffer to file ( if exists )
       
   576                 WriteTailIntoFileL();
       
   577                 }
       
   578 
       
   579             break;
       
   580             }
       
   581 
       
   582         // Transaction succeeded
       
   583         case THTTPEvent::ESucceeded:
       
   584             {
       
   585             if ( iProcessState == EHttpGetResponseReceived )
       
   586                 {
       
   587                 // Finish download
       
   588                 FinishDownload( aTransaction );
       
   589                 }
       
   590 
       
   591             break;
       
   592             }
       
   593 
       
   594         // Transaction failed
       
   595         case THTTPEvent::EFailed:
       
   596             {
       
   597             CompleteAndNotifyL( KErrGeneral );
       
   598             break;
       
   599             }
       
   600 
       
   601         default:
       
   602             {
       
   603             if ( aEvent.iStatus < 0 )
       
   604                 {
       
   605                 CompleteAndNotifyL( aEvent.iStatus );
       
   606                 }
       
   607             else
       
   608                 {
       
   609                 CompleteAndNotifyL( KErrGeneral );
       
   610                 }
       
   611             break;
       
   612             }
       
   613         }
       
   614     }
       
   615 
       
   616 // --------------------------------------------------------------------------
       
   617 // CHttpDownloadWorker::MHFRunError()
       
   618 // (See comments in header file)
       
   619 // --------------------------------------------------------------------------
       
   620 //
       
   621 TInt CHttpDownloadWorker::MHFRunError( TInt aError,
       
   622                                        RHTTPTransaction /*aTransaction*/,
       
   623                                        const THTTPEvent& /*aEvent*/ )
       
   624     {
       
   625     // if the HTTP server responds with HTTP error code the aError variable
       
   626     // contains the code which is above zero, changed to KErrGeneral
       
   627     if ( aError > 0 )
       
   628         {
       
   629         aError = KErrGeneral;
       
   630         }
       
   631 
       
   632     TRAP_IGNORE( CompleteAndNotifyL( aError ) )
       
   633 
       
   634     return KErrNone;
       
   635     }
       
   636 
       
   637 // -----------------------------------------------------------------------------
       
   638 // CHttpDownloadWorker::TimerEventL
       
   639 // Disconnect connection
       
   640 // -----------------------------------------------------------------------------
       
   641 //
       
   642 void CHttpDownloadWorker::TimerEventL( CHttpNotifyTimer* /*aTimer*/ )
       
   643     {
       
   644     CompleteAndNotifyL( KErrTimedOut );
       
   645     }
       
   646 // end of file