diff -r 000000000000 -r f5a58ecadc66 upnp/upnpstack/dlnawebserver/src/upnphttpfileaccess.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/upnp/upnpstack/dlnawebserver/src/upnphttpfileaccess.cpp Tue Feb 02 01:12:20 2010 +0200 @@ -0,0 +1,570 @@ +/** @file +* Copyright (c) 2005-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: Declares HttpServer class. + * +*/ + + +// INCLUDE FILES +#include "upnphttpsession.h" +#include "upnphttpfileaccess.h" +#include "upnpcommonupnplits.h" +#include "upnpfileutils.h" +#include "upnpcons.h" +#define KLogFile _L("DLNAWebServer.txt") +#include "upnpcustomlog.h" + +#include + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CUpnpHttpFileAccess::NewL +// Two-phased constructor +// ----------------------------------------------------------------------------- +// +CUpnpHttpFileAccess* CUpnpHttpFileAccess::NewL( CUpnpHttpSession* aSession, + const TDesC8& aHeaderBuffer, const TDesC16& aFilename, TInt aFileSize ) + { + LOGSH( aHandle, "CUpnpHttpFileAccess::NewL" ); + CUpnpHttpFileAccess* self = new (ELeave) CUpnpHttpFileAccess( + aFileSize ); + CleanupStack::PushL( self ); + self->ConstructL( aSession, aHeaderBuffer, aFilename ); + CleanupStack::Pop( self ); + + return self; + } + +// ----------------------------------------------------------------------------- +// CUpnpHttpFileAccess::NewL +// C++ default constructor, called when saving download +// ----------------------------------------------------------------------------- +// +CUpnpHttpFileAccess* CUpnpHttpFileAccess::NewL( CUpnpHttpSession* aSession, + const TDesC16& aFilename ) + { + LOG_FUNC_NAME; + CUpnpHttpFileAccess* self = new (ELeave) CUpnpHttpFileAccess(); + CleanupStack::PushL( self ); + self->ConstructL( aSession, aFilename ); + CleanupStack::Pop( self ); + + return self; + } + +// ----------------------------------------------------------------------------- +// CUpnpHttpFileAccess::~CUpnpHttpBuffer +// C++ default destructor +// ----------------------------------------------------------------------------- +// +CUpnpHttpFileAccess::~CUpnpHttpFileAccess() + { + LOGS1( "%i, CUpnpHttpFileAccess::~CUpnpHttpFileAccess", this ); + if ( iIsDownload ) + { + if ( !iIsDeleted ) + { + iFile.Close( ); + if ( (iTotalSizeOfDownload - iBytesWritten )!= 0 + || ( !iIsChunkCompleted && iIsChunked ) ) + iFsSession.Delete( *iFileToServe ); + } + + } + if ( iOpen ) + { + iTargetFile.Close( ); + } + + iFsSession.Close( ); + + delete iHeaderBuffer; + + delete iFileToServe; + delete iOpenedFile; + } + +// ----------------------------------------------------------------------------- +// CUpnpHttpFileAccess::CUpnpHttpFileAccess +// C++ default constructor +// ----------------------------------------------------------------------------- +// +CUpnpHttpFileAccess::CUpnpHttpFileAccess( TInt aFileSize ) + { + LOGS1H( aHandle, "%i, CUpnpHttpFileAccess::CUpnpHttpFileAccess", this ); + SetPosOfFile( 0 ); + SetEndPosOfFile( KErrNotFound ); + SetPosOfHeader( 0 ); + iSizeOfFile = aFileSize; + iHeadersSent = EFalse; + iTotalSizeOfDownload = KErrNotFound; + iIsDownload = EFalse; + iIsDeleted = EFalse; + } + +// ----------------------------------------------------------------------------- +// CUpnpHttpFileAccess::CUpnpHttpFileAccess +// C++ default constructor, called when saving download +// ----------------------------------------------------------------------------- +// +CUpnpHttpFileAccess::CUpnpHttpFileAccess() + { + LOGS1H( aHandle, "%i, CUpnpHttpFileAccess::CUpnpHttpFileAccess", this ); + SetPosOfFile( 0 ); + SetEndPosOfFile( KErrNotFound ); + iHeadersSent = ETrue; + iTotalSizeOfDownload = KErrNotFound; + iSizeOfFile = KErrNotFound; + iIsDownload = ETrue; + iBytesWritten = 0; + iIsDeleted = EFalse; + } + +// ----------------------------------------------------------------------------- +// CUpnpHttpFileAccess::CUpnpHttpFileAccess +// Two-phased constructor, called when saving download +// ----------------------------------------------------------------------------- +// + + +void CUpnpHttpFileAccess::ConstructL( CUpnpHttpSession* aSession, + const TDesC16& aFilename ) + { + LOGS1( + "%i, CUpnpHttpFileAccess::ConstructL(CUpnpHttpSession*, TDesC16&)", + this ); + + User::LeaveIfError(iFsSession.Connect()); + iFileToServe = aFilename.AllocL(); + + TInt error = 0; + iPosInFile = 0; + iHeaderLength = 0; + iSession = aSession; + if (iSession->OverwriteExisting() && !iSession->SaveAtOffset()) + { + error = iFile.Replace(iFsSession, *iFileToServe, EFileWrite + | EFileShareAny); + User::LeaveIfError(error); + } + else if (iSession->OverwriteExisting() && iSession->SaveAtOffset()) + { + error = iFile.Open(iFsSession, *iFileToServe, EFileWrite + | EFileShareAny); + if (error != KErrNotFound) + { + TInt size = 0; + error = iFile.Size(size); + if (size >= (iSession->Offset())) + { + iPosInFile = iSession->Offset(); + } + else + { + iFile.Close(); + error = iFile.Replace(iFsSession, *iFileToServe, EFileWrite + | EFileShareAny); + User::LeaveIfError(error); + } + } + else + { + error = iFile.Create(iFsSession, *iFileToServe, EFileWrite + | EFileShareAny); + User::LeaveIfError(error); + } + } + else + { + error = iFile.Open(iFsSession, *iFileToServe, EFileWrite + | EFileShareAny); + if (error == KErrNotFound) + { + error = iFile.Create(iFsSession, *iFileToServe, EFileWrite + | EFileShareAny); + User::LeaveIfError(error); + } + } + } + +// ----------------------------------------------------------------------------- +// CUpnpHttpFileAccess::ConstructL +// Two-phased constructor, called when serving file +// ----------------------------------------------------------------------------- +// +void CUpnpHttpFileAccess::ConstructL( CUpnpHttpSession* aSession, + const TDesC8& aHeaderBuffer, const TDesC16& aFilename ) + { + LOGS1H( + iHandle, + "%i, CUpnpHttpFileAccess::ConstructL(CUpnpHttpSession*, TDesC8&, TDesC16&)", + this ); + iHeaderBuffer = HBufC8::NewL( aHeaderBuffer.Length( ) ); + iHeaderBuffer->Des().Zero( ); + iHeaderBuffer->Des().Append( aHeaderBuffer ); + + iFileToServe = HBufC16::NewL( aFilename.Length( ) ); + iFileToServe->Des().Zero( ); + iFileToServe->Des().Append( aFilename ); + + iHeaderLength = aHeaderBuffer.Length( ); + User::LeaveIfError( iFsSession.Connect( ) ); + iSession = aSession; + iOpenedFile = KNullDesC().AllocL( ); + } + +// ----------------------------------------------------------------------------- +// CUpnpHttpFileAccess::SetPosOfFile +// +// ----------------------------------------------------------------------------- +// +void CUpnpHttpFileAccess::SetPosOfFile( TUint aNewPos ) + { + iPosInFile = aNewPos; + } + +// ----------------------------------------------------------------------------- +// CUpnpHttpFileAccess::PosOfFile +// +// ----------------------------------------------------------------------------- +// +TUint CUpnpHttpFileAccess::PosOfFile() + { + return iPosInFile; + } + +// ----------------------------------------------------------------------------- +// CUpnpHttpFileAccess::SetPosOfFile +// +// ----------------------------------------------------------------------------- +// +void CUpnpHttpFileAccess::SetEndPosOfFile( TInt aNewEndPos ) + { + iEndPosOfFile = aNewEndPos; + } + +// ----------------------------------------------------------------------------- +// CUpnpHttpFileAccess::PosOfFile +// +// ----------------------------------------------------------------------------- +// +TInt CUpnpHttpFileAccess::EndPosOfFile() + { + return iEndPosOfFile; + } +// ----------------------------------------------------------------------------- +// CUpnpHttpFileAccess::GetHeaders +// +// ----------------------------------------------------------------------------- +// +const TDesC8& CUpnpHttpFileAccess::GetHeaders() + { + return (iHeaderBuffer) ? *iHeaderBuffer : KNullDesC8( ); + } + +// ----------------------------------------------------------------------------- +// CUpnpHttpFileAccess::SetPosOfHeader +// +// ----------------------------------------------------------------------------- +// +void CUpnpHttpFileAccess::SetPosOfHeader( TUint aNewPos ) + { + iPosToReadHeader = aNewPos; + } + +// ----------------------------------------------------------------------------- +// CUpnpHttpFileAccess::SetTotalSize +// +// ----------------------------------------------------------------------------- +// +void CUpnpHttpFileAccess::SetTotalSize( TInt aSizeToSet ) + { + iTotalSizeOfDownload = aSizeToSet; + } + +// ----------------------------------------------------------------------------- +// CUpnpHttpFileAccess::SaveL +// +// ----------------------------------------------------------------------------- +// +TInt CUpnpHttpFileAccess::SaveL( TDesC8& aBuffer ) + { + LOGS1( "%i, CUpnpHttpFileAccess::SaveL()", this ); + if ( iIsDeleted ) + { + LOGS( "file closed" ); + return KErrGeneral; + } + LOGS( "file not closed" ); + TInt toWrite = (EncodingMode( )|| (TransferTotal( ) == KErrNotFound ) ) + ? aBuffer.Length( ) : (TransferTotal( )- iBytesWritten); + + if ( aBuffer.Size( ) < toWrite ) + { + toWrite = aBuffer.Size( ); + } + + if ( UpnpFileUtil::CheckDiskSpaceShortL( iFileToServe->Des( ), toWrite, + iFsSession ) ) + { + DeleteFile( ); + return EHttpInsufficientStorage; + } + + TInt error = KErrNone; + + // At first time iPosInFile == 0 or range offset, see ConstructL, and the next time + // saving will continue at stopped point. + + error = iFile.Write( iPosInFile, aBuffer.Right( toWrite ) ); + if ( error != KErrNone ) + { + return error; + } + iPosInFile += toWrite; + iBytesWritten += toWrite; + return KErrNone; + + } + +// ----------------------------------------------------------------------------- +// CUpnpHttpFileAccess::TransferredBytes +// +// ----------------------------------------------------------------------------- +// +TInt CUpnpHttpFileAccess::TransferredBytes() + { + LOGS1( "%i, CUpnpHttpFileAccess::TransferredBytes()", this); + TInt sent = 0; + if ( !iHeadersSent ) + { + sent = iPosToReadHeader; + } + else + { + sent = PosOfFile(); + } + return sent; + } + +// ----------------------------------------------------------------------------- +// CUpnpHttpFileAccess::TransferTotal +// +// ----------------------------------------------------------------------------- +// +TInt CUpnpHttpFileAccess::TransferTotal() + { + LOGS1( "%i, CUpnpHttpFileAccess::TransferTotal()", this); + if ( iTotalSizeOfDownload == KErrNotFound ) + { + return iSizeOfFile; + } + else + { + return iTotalSizeOfDownload; + } + } + +// ----------------------------------------------------------------------------- +// CUpnpHttpFileAccess::FileToServe +// +// ----------------------------------------------------------------------------- +// +TDesC16& CUpnpHttpFileAccess::FileToServe() + { + return *iFileToServe; + } + +// ----------------------------------------------------------------------------- +// CUpnpHttpFileAccess::GetL +// +// ----------------------------------------------------------------------------- +// +TBool CUpnpHttpFileAccess::GetL( TPtr8& aPointer, TInt aBytesToSend ) + { + LOGS1H( aHandle, "%i, CUpnpHttpFileAccess::GetL", this ); + if ( iFileToServe->Compare( *iOpenedFile ) ) // ignore if the same file + { + if ( iOpen ) + { + iTargetFile.Close( ); + } + iOpen = EFalse; + } + + if ( !iOpen ) + { + User::LeaveIfError( iTargetFile.Open( iFsSession, *iFileToServe, + EFileRead|EFileShareReadersOnly ) ); + HBufC* tmp = iFileToServe->AllocL( ); + delete iOpenedFile; + iOpenedFile = tmp; + iOpen = ETrue; + } + + User::LeaveIfError( iTargetFile.Seek( ESeekStart, iPosInFile ) ); + + TInt BytesToRead = aBytesToSend; + + // Get min value from iEndPosInFile and buffer length + // iEndPosInFile + - iPosInFile 1 because indicated byte should also be included + if ( EndPosOfFile( ) != KErrNotFound ) + BytesToRead = (EndPosOfFile( ) - iPosInFile + 1) < BytesToRead + ? (EndPosOfFile( ) - iPosInFile + 1) : BytesToRead; + + LOGS1( "BytesToRead: %d", BytesToRead ); + + User::LeaveIfError( iTargetFile.Read( aPointer, BytesToRead ) ); + iPosInFile = iPosInFile + aPointer.Length( ); + + return IsEndOfFile(); + } +// ----------------------------------------------------------------------------- +//CUpnpHttpFileAccess::DeleteServedFile +// +// ----------------------------------------------------------------------------- +// +void CUpnpHttpFileAccess::DeleteFile() + { + LOGS1( "%i, CUpnpHttpFileAccess::DeleteFile()", this ); + if ( !iIsDeleted ) + { + iFile.Close( ); + iFsSession.Delete( *iFileToServe ); + iIsDeleted = ETrue; + } + + } + +// ----------------------------------------------------------------------------- +// CUpnpHttpFileAccess::Download +// +// ----------------------------------------------------------------------------- +// +TBool CUpnpHttpFileAccess::Download() + { + return iIsDownload; + } + +// ----------------------------------------------------------------------------- +// CUpnpHttpFileAccess::FileExist +// +// ----------------------------------------------------------------------------- +// +TBool CUpnpHttpFileAccess::FileExist() + { + return !iIsDeleted; + } + +// ----------------------------------------------------------------------------- +// CUpnpHttpFileAccess::BytesWritten +// +// ----------------------------------------------------------------------------- +// +TBool CUpnpHttpFileAccess::BytesWritten() + { + return (iIsDownload ? iBytesWritten : 0); + } + +// ----------------------------------------------------------------------------- +// CUpnpHttpFileAccess::SetEncodingMode(TBool aIsChunked) +// +// ----------------------------------------------------------------------------- +// +void CUpnpHttpFileAccess::SetEncodingMode( TBool aIsChunked ) + { + iIsChunked = aIsChunked; + } + +// ----------------------------------------------------------------------------- +// CUpnpHttpFileAccess::EncodingMode() +// +// ----------------------------------------------------------------------------- +// +TBool CUpnpHttpFileAccess::EncodingMode() + { + return iIsChunked; + } + +// ----------------------------------------------------------------------------- +// CUpnpHttpFileAccess::SetTransferTotal(aLength) +// +// ----------------------------------------------------------------------------- +// +void CUpnpHttpFileAccess::SetTransferTotal( TInt aLength ) + { + iTotalSizeOfDownload = aLength; + } + +// ----------------------------------------------------------------------------- +// CUpnpHttpFileAccess::HeadersSent +// +// ----------------------------------------------------------------------------- +// +void CUpnpHttpFileAccess::SetHeadersSent() + { + delete iHeaderBuffer; + iHeaderBuffer = NULL; + iPosToReadHeader = NULL; + iHeadersSent = ETrue; + } + +// ----------------------------------------------------------------------------- +// CUpnpHttpFileAccess::HeadersSent() +// +// ----------------------------------------------------------------------------- +// +TBool CUpnpHttpFileAccess::HeadersSent() + { + return iHeadersSent; + } + +// ----------------------------------------------------------------------------- +// CUpnpHttpFileAccess::SetChunkComplete( TBool aCompleted ) +// +// ----------------------------------------------------------------------------- +// +void CUpnpHttpFileAccess::SetChunkCompleted( TBool aCompleted ) + { + iIsChunkCompleted = aCompleted; + } + +// ----------------------------------------------------------------------------- +// CUpnpHttpFileAccess::IsEndOfFile +// +// ----------------------------------------------------------------------------- +// +TBool CUpnpHttpFileAccess::IsEndOfFile() + { + TInt limit = iSizeOfFile; + if ( EndPosOfFile() != KErrNotFound ) + { + limit = ( EndPosOfFile() + 1 ) < iSizeOfFile ? ( EndPosOfFile() + 1 ) : iSizeOfFile; + } + + if ( iPosInFile >= limit ) + { + iTargetFile.Close(); + iOpen = EFalse; + return ETrue; + } + else + { + return EFalse; + } + } + +// End Of File +