diff -r 000000000000 -r f5a58ecadc66 upnp/upnpstack/dlnawebserver/src/upnphttpbuffer.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/upnp/upnpstack/dlnawebserver/src/upnphttpbuffer.cpp Tue Feb 02 01:12:20 2010 +0200 @@ -0,0 +1,952 @@ +/** @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 +#include "upnphttpbuffer.h" +#include "upnphttpserver.h" +#include "upnpcons.h" +#include "upnphttpsession.h" +#include "upnphttpfileaccess.h" +#include "upnphttpfiletransferreader.h" +#include "upnphttpchunkparser.h" +#define KLogFile _L("DLNAWebServer.txt") +#include "upnpcustomlog.h" +#include "upnpcons.h" +#include "httperr.h" +// CONSTANTS + +const TInt KMaxBufferLength = 10240; + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CUpnpHttpBuffer::NewL +// Two-phased constructor +// ----------------------------------------------------------------------------- +// +CUpnpHttpBuffer* CUpnpHttpBuffer::NewL( CUpnpHttpSession* aSession, TBool aToBeSavedInFile ) + { +LOGS("CUpnpHttpBuffer::NewL(CUpnpHttpSession*, TBool)"); + CUpnpHttpBuffer* self = new (ELeave) CUpnpHttpBuffer( aSession, aToBeSavedInFile ); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + + return self; + } + +// ----------------------------------------------------------------------------- +// CUpnpHttpBuffer::~CUpnpHttpBuffer +// C++ default destructor +// ----------------------------------------------------------------------------- +// +CUpnpHttpBuffer::~CUpnpHttpBuffer() + { +LOGS("CUpnpHttpBuffer::~CUpnpHttpBuffer()"); + + iBuffer.Close(); + delete iChunkParser; + } + +// ----------------------------------------------------------------------------- +// CUpnpHttpBuffer::CUpnpHttpBuffer +// C++ default constructor +// ----------------------------------------------------------------------------- +// +CUpnpHttpBuffer::CUpnpHttpBuffer( CUpnpHttpSession* aSession, TBool aToBeSavedInFile ) + { + iContentLength = -1; + iSession = aSession; + iToFile = aToBeSavedInFile; + iContentLengthCounter = 0; + iErrorCodeCheckedForSaving = EFalse; + iOkToSaveToFile = EFalse; + iFileReadBufferSize = aSession->HttpServer()->FileReadBufferSize(); + } + +// ----------------------------------------------------------------------------- +// CUpnpHttpBuffer::ConstructL +// Two-phased constructor +// ----------------------------------------------------------------------------- +// +void CUpnpHttpBuffer::ConstructL() + { + iBuffer.Create( 0 ); + iChunkParser = CUpnpHttpChunkParser::NewL(); + } + +// ----------------------------------------------------------------------------- +// CUpnpHttpBuffer::AppendHeadersL +// +// ----------------------------------------------------------------------------- +// +TInt CUpnpHttpBuffer::AppendHeadersL( TDesC8& aBuffer, TBool aToBeSavedInFile ) +{ + TInt PosOfDoubleLineFeed ( KErrNotFound ); + + LOGS("CUpnpHttpBuffer::AppendL(TDesC8&)"); + + if ( !IsHeaderReady() ) + { + iToFile = aToBeSavedInFile; + // header not yet ready. Checking if it gets ready with this received buffer + PosOfDoubleLineFeed = aBuffer.FindF( UpnpString::KDoubleLineFeed ); + +//trying to find double linefeed by spliiitng line + + if (iBuffer.Length() > 0) + { + if( !iBuffer.Right(UpnpString::KLineFeedLength).CompareF( UpnpString::KLineFeed) + && !aBuffer.FindF(UpnpString::KLineFeed) ) + { + PosOfDoubleLineFeed = iBuffer.Length() - UpnpString::KLineFeedLength; + } + else if (!iBuffer.Right(UpnpString::KCRLength).CompareF(UpnpString::KCR) + && !aBuffer.FindF(UpnpString::KLFCRLF)) + { + PosOfDoubleLineFeed = iBuffer.Length() - UpnpString::KCRLength; + } + else if (!iBuffer.Right(UpnpString::KCRLFCRLength).CompareF(UpnpString::KCRLFCR) + && !aBuffer.FindF(UpnpString::KLinefeed)) + { + PosOfDoubleLineFeed = iBuffer.Length() - UpnpString::KCRLFCRLength; + } + //if double linefeed there are not found by splitting line + //may be it (all double linefeed) is in ne line + else if ( PosOfDoubleLineFeed != KErrNotFound ) + { + PosOfDoubleLineFeed += iBuffer.Length(); + } + } + + if ( PosOfDoubleLineFeed == KErrNotFound ) + { + // double linefeed not found, so only adding unfinished headers to + // iBuffer + + if (iBuffer.Length() <= KMaxBufferLength ) //10kb + { + iBuffer.ReAllocL( iBuffer.Length() + aBuffer.Length() ); + iBuffer.Append( aBuffer ); + } + + } + else + { + // Double linefeed found. Appending headers and then checking if + // response is OK. + TInt afterDoubleLineFeed = PosOfDoubleLineFeed + UpnpString::KDoubleLineFeedLength - iBuffer.Length(); + iBuffer.ReAllocL(PosOfDoubleLineFeed + UpnpString::KDoubleLineFeedLength); + iBuffer.Append( aBuffer.Left(afterDoubleLineFeed)); + + // is headers checked + if( !iErrorCodeCheckedForSaving ) + { + TInt messageError = MessageErrorCode( iBuffer ); + TPtrC8 method = Method(); + TPtrC8 target = Target(); + + if(method == KHttpPost ) + { + messageError = EHttpOk; + } + + _LIT8( KControl, "/control"); + + if( method.FindC( KHttpPost() ) == 0 && + method.Length() == KHttpPost().Length() + ) + { + TInt lastSlash = target.LocateReverse('/'); + if( lastSlash > KErrNotFound ) + { + target.Set( target.Mid( lastSlash ) ); + } + } + + if ( messageError == EHttpOk || messageError == EHttpPartialContent ) + { + iOkToSaveToFile = ETrue; + } + + // if EXPORTING, then saving to file + else if( method.FindC( KHttpPost() ) == 0 && + method.Length() == KHttpPost().Length() && + target.FindC( KControl ) != 0 ) + { + iOkToSaveToFile = ETrue; + } + else + { + iOkToSaveToFile = EFalse; + CUpnpHttpFileAccess* temp = iSession->FileAccess(); + // Delete only downloaded file if it is not complete. + if( temp && temp->Download() ) + { + temp->DeleteFile(); + // no delete, not owned + temp = NULL; + } + } + // error code checked, no need to check it again. + iErrorCodeCheckedForSaving = ETrue; + } + + return afterDoubleLineFeed; + } + } + + return PosOfDoubleLineFeed; +} + +// ----------------------------------------------------------------------------- +// CUpnpHttpBuffer::AppendL +// This function appends the aBuffer data at the end of this HTTPBuffer. +// ----------------------------------------------------------------------------- +// +TInt CUpnpHttpBuffer::AppendL( TDesC8& aBuffer, TBool aToBeSavedInFile) + { + TInt retVal ( KErrNone ); + + LOGS("CUpnpHttpBuffer::AppendL(TDesC8&)"); + + if ( !IsHeaderReady() ) + { + TInt PosOfDoubleLineFeed = AppendHeadersL( aBuffer, aToBeSavedInFile ); + + if ( PosOfDoubleLineFeed > KErrNotFound ) + { + TInt afterDoubleLineFeed = PosOfDoubleLineFeed + UpnpString::KDoubleLineFeedLength - iBuffer.Length(); + TPtrC8 AppendPointer( aBuffer.Right( aBuffer.Length() - PosOfDoubleLineFeed ) ); + //for file upload, data copied to the file transfer reader + if(iToFile && iOkToSaveToFile + && iSession->FileTransferReader() && iSession->FileTransferReader()->Activated()) + { + if(AppendPointer.Length() > 0) + iSession->FileTransferReader()->AppendL(AppendPointer); + } + else if ( IsChunked() ) + { + iPos = iBuffer.Length(); + retVal = ParseL( AppendPointer ); + } + else + { + iBuffer.ReAllocL( iBuffer.Length() + aBuffer.Length() ); + iBuffer.Append( AppendPointer ); + } + } + } + else + { + if( !iErrorCodeCheckedForSaving ) + { + TInt messageError = MessageErrorCode( iBuffer ); + if ( messageError == EHttpOk || messageError == EHttpPartialContent ) + { + iOkToSaveToFile = ETrue; + } + else + { + iOkToSaveToFile = EFalse; + CUpnpHttpFileAccess* temp = iSession->FileAccess(); + if( temp ) + { + temp->DeleteFile(); + // no delete, not owned + temp = NULL; + } + } + // error code checked, no need to check it again. + iErrorCodeCheckedForSaving = ETrue; + } + + //for file upload, data copied to the file transfer reader + if(iToFile && iOkToSaveToFile && + iSession->FileTransferReader() && iSession->FileTransferReader()->Activated()) + { + if(aBuffer.Length() > 0) + iSession->FileTransferReader()->AppendL(aBuffer); + return retVal; + } + + if ( IsChunked() ) + { + retVal = ParseL( aBuffer ); + } + else + { + iBuffer.ReAllocL( iBuffer.Length() + aBuffer.Length() ); + iBuffer.Append( aBuffer ); + } + } + return retVal; + } + +// ----------------------------------------------------------------------------- +// CUpnpHttpBuffer::ParseL +// Decodes chunked messages. +// ----------------------------------------------------------------------------- +// +TInt CUpnpHttpBuffer::ParseL( TDesC8& aBuffer ) + { + iBuffer.ReAllocL( iBuffer.Length() + aBuffer.Length() ); + iBuffer.Append( aBuffer ); + return Parse( iBuffer, iPos ) < 0 ? KErrHttpUnknownParseState: KErrNone; + } + +// ----------------------------------------------------------------------------- +// CUpnpHttpBuffer::Parse +// Decodes chunked-encoded buffer +// ----------------------------------------------------------------------------- +// +TInt CUpnpHttpBuffer::Parse(TDes8& aBuffer, TInt& aPos) + { + if( aPos >= aBuffer.Length() ) + { + iChunkParser->Reset(); + return KErrNone; + } + return iChunkParser->Parse( aBuffer, aPos ); + } + +// ----------------------------------------------------------------------------- +// CUpnpHttpBuffer::IsReady +// Returns ETrue, if buffer is ready to be converted to HTTPMessage +// else returns EFalse. +// ----------------------------------------------------------------------------- +// +TBool CUpnpHttpBuffer::IsReadyL() + { +LOGS("CUpnpHttpBuffer::IsReady()"); + if ( IsHeaderReady() ) + { + //Assuming here that HTTP GET -requests may not have a body. + //So if a HTTP GET request arrives and it has a CONTENT-TYPE or a + //CONTENT-LENGHT header we may still serve the file + TPtrC8 method = Method(); + if ( method.FindC( KHttpGet() ) == 0 ) + { + return ETrue; + } + if ( HasBody() ) + { + return IsBodyReadyL(); + } + else + { + return ETrue; + } + } + return EFalse; + } + +// ----------------------------------------------------------------------------- +// CUpnpHttpBuffer::IsHeaderReady +// Returns ETrue, if header part of HTTPMessage is ready, else returns EFalse. +// ----------------------------------------------------------------------------- +// +TBool CUpnpHttpBuffer::IsHeaderReady() + { +LOGS("CUpnpHttpBuffer::IsHeaderReady()"); + if ( iBuffer.Find( UpnpString::KDoubleLineFeed() ) > KErrNotFound ) + { + return ETrue; + } + else + { + return EFalse; + } + } + +// ----------------------------------------------------------------------------- +// CUpnpHttpBuffer::IsBodyReadyL +// Returns ETrue, if body part of HTTPMessage is ready, else returns EFalse. +// ----------------------------------------------------------------------------- +// +TBool CUpnpHttpBuffer::IsBodyReadyL() + { +LOGS("CUpnpHttpBuffer::IsBodyReadyL()"); + TInt bodyStart = iBuffer.FindF( UpnpString::KDoubleLineFeed ); + TInt contLength = ContentLengthL(); + if ( IsChunked() ) + { + return ChunkTransferFinished(); + } + else + { + if ( iHasContentType ) + { + TPtrC8 body = iBuffer.Mid( bodyStart + + UpnpString::KDoubleLineFeed().Length() ); + return body.Find( UpnpString::KDoubleLineFeed() ) != KErrNotFound; + } + } + + TPtrC8 tempPtr; + if ( iToFile && iOkToSaveToFile ) + { + if ( iContentLengthCounter >= contLength ) + { + return !(IsChunked() && !ChunkTransferFinished()); + } + else + { + return EFalse; + } + } + else + { + tempPtr.Set( iBuffer.Mid( bodyStart + UpnpString::KDoubleLineFeedLength ) ); + if ( tempPtr.Length() >= contLength ) + { + return !(IsChunked() && !ChunkTransferFinished()); + } + else + { + return EFalse; + } + } + } + +// ----------------------------------------------------------------------------- +// CUpnpHttpBuffer::BytesInBuffer +// Returns the length of entire buffer. +// ----------------------------------------------------------------------------- +// +TInt CUpnpHttpBuffer::BytesInBuffer() + { +LOGS("CUpnpHttpBuffer::BytesInBuffer()"); + return iBuffer.Length(); + } + +// ----------------------------------------------------------------------------- +// CUpnpHttpBuffer::RemoveL +// This function deletes aLength bytes from the beginning of HTTPBuffer. +// ----------------------------------------------------------------------------- +// +void CUpnpHttpBuffer::RemoveL( TInt aLength ) + { +LOGS1("CUpnpHttpBuffer::RemoveL(%i)", aLength); + if ( aLength <= iBuffer.Length() ) + { + iBuffer.Delete( 0, aLength ); + } + } + +// ----------------------------------------------------------------------------- +// CUpnpHttpBuffer::ChunkTransferFinished +// Returns ETrue, if chunk encoded message is finished. +// ----------------------------------------------------------------------------- +// +TBool CUpnpHttpBuffer::ChunkTransferFinished() + { +LOGS("CUpnpHttpBuffer::ChunkTransferFinished()"); + return iChunkParser->IsFinished(); + } + +// ----------------------------------------------------------------------------- +// CUpnpHttpBuffer::HasBody +// Returns ETrue, if message has body, else returns EFalse. +// ----------------------------------------------------------------------------- +// +TBool CUpnpHttpBuffer::HasBody() + { +LOGS("CUpnpHttpBuffer::HasBody()"); + if( IsChunked() ) + { + return ETrue; + } +TInt endOfHeader = iBuffer.Find( UpnpString::KDoubleLineFeed ); +if (endOfHeader>0) + {TPtrC8 tmp = iBuffer.Mid(0, endOfHeader); + if ( tmp.FindC( UpnpHTTP::KContentLength() ) > -1 ) + { + iHasContentType = EFalse; + return ETrue; + } + else if ( tmp.FindC( UpnpHTTP::KContentType() ) > -1) + { + iHasContentType = ETrue; + return ETrue; + } + else + { + iHasContentType = EFalse; + return EFalse; + } + } +else + { + iHasContentType = EFalse; + return EFalse; //no end of the header, not possible to judge if there is a body + } + } + +// ----------------------------------------------------------------------------- +// CUpnpHttpBuffer::IsChunked +// Returns ETrue, if message's header contains "Transfer-encoding: +// Chunked" -header. +// ----------------------------------------------------------------------------- +// +TBool CUpnpHttpBuffer::IsChunked() + { + LOGS("CUpnpHttpBuffer::IsChunked()"); + TInt endOfHeader = iBuffer.Find( UpnpString::KDoubleLineFeed ); + + // to check only first 2k of data or whole portion with all headers + // if they are bigger + TPtrC8 TranferCodingPointer; + if (endOfHeader <= UpnpSSDP::KMaxMessageLength) + TranferCodingPointer.Set( iBuffer.Left( endOfHeader + UpnpString::KLineFeedLength ) ); + else + TranferCodingPointer.Set( iBuffer.Left( UpnpSSDP::KMaxMessageLength ) ); + + TInt TransferEncodingIndex = + TranferCodingPointer.FindC( UpnpHTTP::TransferEncoding ); + + if ( TransferEncodingIndex == KErrNotFound ) + { + return EFalse; + } + else + { + TInt correct = 0; + TInt transferHeaderLength = 0; + correct = TransferEncodingIndex; + transferHeaderLength = UpnpHTTP::TransferEncoding().Length(); + + TPtrC8 tempPtr = iBuffer.Mid( correct + transferHeaderLength, + iBuffer.Length() - correct - transferHeaderLength ); + + TInt LineFeedAfterTransferCoding = tempPtr.FindF( UpnpString::KLineFeed ); + + TPtrC8 codingPtr = tempPtr.Left( LineFeedAfterTransferCoding ); + if ( codingPtr.FindC( UpnpHTTP::Chunked ) != KErrNotFound ) + { + return ETrue; + } + else + { + return EFalse; + } + } + } + +// ----------------------------------------------------------------------------- +// CUpnpHttpBuffer::Headers +// Returns Headers of the first message in the buffer. +// ----------------------------------------------------------------------------- +// +TPtrC8 CUpnpHttpBuffer::Headers() + { +LOGS("CUpnpHttpBuffer::Headers()"); + TInt EndOfHeaders = iBuffer.FindC( UpnpString::KDoubleLineFeed ); + TPtrC8 headers = iBuffer.Left( EndOfHeaders + UpnpString::KDoubleLineFeedLength ); + return headers; + } + + +// ----------------------------------------------------------------------------- +// CUpnpHttpBuffer::L +// Returns the content of buffer. +// ----------------------------------------------------------------------------- +// +TPtrC8 CUpnpHttpBuffer::Content() + { +LOGS("CUpnpHttpBuffer::Content()"); + TInt PosOfContLength = iBuffer.FindC( UpnpHTTP::KHdrContentLength() ); + TInt contLen = 0; + + if ( PosOfContLength > 0 ) + { + TRAPD(error, contLen = ContentLengthL()); + if (error) + { + contLen = 0; + } + } + else if ( iHasContentType ) + { + return TPtrC8( iBuffer ); + } + else if( IsChunked() ) + { + TInt StartOfMessage = iBuffer.FindC( UpnpString::KDoubleLineFeed ); + contLen = iBuffer.Length() - StartOfMessage; + } + /*else + { + TInt StartOfMessage = iBuffer.FindC( UpnpString::KDoubleLineFeed ); + contLen = iBuffer.Des().Length() - StartOfMessage; + }*/ + + TInt endOfHeader = iBuffer.Find( UpnpString::KDoubleLineFeed ); + TInt length = 0; + // Probably not all headers were sent + + if( endOfHeader == KErrNotFound ) + { + length = iBuffer.Length(); + } + else + { + length = endOfHeader + contLen + UpnpString::KDoubleLineFeedLength; + } + + if( length < 0 ) // in case of overflow of length value + { + length = INT_MAX; + } + + TPtrC8 message = iBuffer.Left( length ); + return message; + } + +// ----------------------------------------------------------------------------- +// CUpnpHttpBuffer::ContentLengthL +// Returns the content length of first message in the buffer. +// ----------------------------------------------------------------------------- +// +TInt CUpnpHttpBuffer::ContentLengthL() + { + LOGS("CUpnpHttpBuffer::ContentLengthL()"); + + TInt endOfHeader = iBuffer.Find( UpnpString::KDoubleLineFeed ); + User::LeaveIfError(endOfHeader); + TPtrC8 findptr; + // to check only first 2k of data or whole portion with all headers + // if they are bigger + if (endOfHeader >= UpnpSSDP::KMaxMessageLength) + findptr.Set( iBuffer.Left( endOfHeader + UpnpString::KLineFeedLength ) ); + else + findptr.Set( iBuffer.Left( UpnpSSDP::KMaxMessageLength ) ); + + TInt contentLengthIndex = findptr.FindC( UpnpHTTP::KHdrContentLength() ); + + TInt lengthOfContentLength = UpnpHTTP::KHdrContentLength().Length() + + UpnpString::KColon().Length(); + + if ( contentLengthIndex <= 0 ) + { + return KErrNotFound; + } + + TPtrC8 rest; + rest.Set( findptr ); + rest.Set( rest.Mid( contentLengthIndex + lengthOfContentLength ) ); + + TInt lineEnd = rest.Find( UpnpString::KLineFeed ); + if ( lineEnd < 0 ) + { + return KErrNotFound; + } + + // LWS and spanning headers + TInt indexLWS = 0; + TPtrC8 clRest = rest; + TInt contentLengthValueEnd = lineEnd; + + while( ETrue ) + { + indexLWS = CUpnpHttpMessage::FindLWS( clRest ); + if( indexLWS == lineEnd ) + { + clRest.Set( clRest.Mid( lineEnd + UpnpString::KLineFeed().Length() ) ); + lineEnd = clRest.Find( UpnpString::KLineFeed ); + contentLengthValueEnd += lineEnd + UpnpString::KLineFeed().Length(); + } + else + { + break; + } + } + + TPtrC8 length = rest.Left( contentLengthValueEnd ); + + if( !length.Compare( KNullDesC8() ) ) + return -1; + + // Unfold header + HBufC8* clValueBuf = length.AllocLC(); + TPtr8 ptrCLValue = clValueBuf->Des(); + + // Remove CRLFs + TInt pos; + while( ( pos = ptrCLValue.FindC( UpnpString::KLineFeed() ) ) != KErrNotFound) + { + ptrCLValue.Delete(pos, UpnpString::KLineFeedLength); + } + + // Remove spaces + while( ( pos = ptrCLValue.FindC( UpnpString::KSpace() ) ) != KErrNotFound) + { + ptrCLValue.Delete(pos, 1); + } + + // Remove tabs + while( ( pos = ptrCLValue.FindC( UpnpString::KTab() ) ) != KErrNotFound) + { + ptrCLValue.Delete(pos, 1); + } + + TLex8 lex( ptrCLValue ); + TInt val = 0; + User::LeaveIfError(lex.Val( val )); + + CleanupStack::PopAndDestroy( clValueBuf ); + + iContentLength = val; + + return val; + } + +// ----------------------------------------------------------------------------- +// CUpnpHttpBuffer::UsesConnectionClose +// Returns ETrue, if message's header contains "Connection: close" -header. +// ----------------------------------------------------------------------------- +// +TBool CUpnpHttpBuffer::UsesConnectionClose() + { +LOGS("CUpnpHttpBuffer::UsesConnectionClose()"); + if(IsHeaderReady()) + { + TPtrC8 headers=Headers(); + TInt posOfConn=headers.FindC(UpnpHTTP::KConnection()); + TInt posOfHttp10 = headers.FindC(KHttp10); + + if( posOfConn != KErrNotFound ) + { + TPtrC8 conn=headers.Mid(posOfConn+UpnpHTTP::KConnection().Length() + + UpnpString::KColon().Length()); + + TInt posOfLineFeed=conn.FindC(UpnpString::KLineFeed()); + if(posOfLineFeed != KErrNotFound) + { + conn.Set(conn.Left(posOfLineFeed)); + + while((conn.Left(1)).CompareC(UpnpString::KSpace()) == 0) + { + conn.Set(conn.Mid(1)); // removing spaces in front of value + } + + if(conn.FindC(UpnpHTTP::KClose()) >= 0) + { + return ETrue; + } + else + { + return EFalse; + } + } + else + { + // If rsp = 'HTTP/1.0', we can assume that it contains 'connection:close' header, even if it doesn't! + if( posOfHttp10 != KErrNotFound ) + return ETrue; + return EFalse; + } + } + else + { + // If rsp = 'HTTP/1.0', we can assume that it contains 'connection:close' header, even if it doesn't! + if( posOfHttp10 != KErrNotFound ) + return ETrue; + return EFalse; + } + } + return EFalse; + } + +// ----------------------------------------------------------------------------- +// CUpnpHttpBuffer::MessageErrorCode +// Checks error code of received message. +// ----------------------------------------------------------------------------- +// +TInt CUpnpHttpBuffer::MessageErrorCode( TDesC8& aBuffer ) + { + if( IsHeaderReady() ) + { + TInt posOfNextLine = aBuffer.Find(UpnpString::KLineFeed); + if( posOfNextLine != KErrNotFound ) + { + TPtrC8 spacePtr; + spacePtr.Set( aBuffer ); + + // finding first space + TInt posOfFirstSpace = spacePtr.Find(UpnpString::KSpace); + if ( posOfFirstSpace != KErrNotFound ) + { + spacePtr.Set( spacePtr.Left( posOfFirstSpace ) ); + + } + + // back to basic handling + spacePtr.Set( aBuffer ); + + if( posOfFirstSpace < posOfNextLine && posOfFirstSpace != KErrNotFound ) + { + // if first space is found, it has to be before linefeed + // +1 comes from going over the first space, we are interested + // in what comes after it. + spacePtr.Set( spacePtr.Mid( posOfFirstSpace + 1 ) ); + TInt posOfSecondSpace = spacePtr.Find(UpnpString::KSpace); + if( posOfSecondSpace < posOfNextLine && posOfSecondSpace != KErrNotFound ) + { + // check that length of path is longer than zero. + if( posOfSecondSpace > 0 ) + { + // now setting spacePtr so that we have the error number in spacePrt + spacePtr.Set( spacePtr.Left( posOfSecondSpace ) ); + + // making conversion + TLex8 errorValue( spacePtr ); + TInt messageErrorValue( 0 ); + TInt convError = errorValue.Val( messageErrorValue ); + + // checking that conversion was ok + if( convError == KErrNone ) + { + return messageErrorValue; + } + else + { + return KErrAbort; + } + + } + else + { + // header too short. Invalid message + return KErrAbort; + } + } + else + { + // no second space found. Invalid message. + return KErrAbort; + } + } + else + { + // no space found before linefeed. Invalid message + return KErrAbort; + } + } + else + { + // no linefeed found in headers. Invalid message + return KErrAbort; + } + } + else + { + return KErrAbort; + } + } + +// ----------------------------------------------------------------------------- +// CUpnpHttpBuffer::Method +// returns the method of message +// ----------------------------------------------------------------------------- +// +TPtrC8 CUpnpHttpBuffer::Method() + { + if( IsHeaderReady() ) + { + TPtrC8 ret; + ret.Set( Headers() ); + TInt posOfSpace = ret.Locate(' '); + if( posOfSpace != KErrNotFound ) + { + ret.Set( ret.Left( posOfSpace ) ); + return ret; + } + else + { + return KNullDesC8(); + } + + } + else + { + return KNullDesC8(); + } + } + +// ----------------------------------------------------------------------------- +// CUpnpHttpBuffer::Target +// +// ----------------------------------------------------------------------------- +// +TPtrC8 CUpnpHttpBuffer::Target() + { + if( IsHeaderReady() ) + { + TPtrC8 ret; + ret.Set( Headers() ); + TInt posOfSpace = ret.Locate(' '); + if( posOfSpace != KErrNotFound ) + { + ret.Set( ret.Mid( posOfSpace +1 ) ); + posOfSpace = ret.Locate(' '); + if( posOfSpace != KErrNotFound ) + { + ret.Set( ret.Left( posOfSpace ) ); + return ret; + } + else + { + return KNullDesC8(); + } + } + else + { + return KNullDesC8(); + } + + } + else + { + return KNullDesC8(); + } + } + +// ----------------------------------------------------------------------------- +// CUpnpHttpBuffer::IsToFile +// Returns True if message content is going to be saved in file. +// ----------------------------------------------------------------------------- +// +TBool CUpnpHttpBuffer::IsToFile() + { + return iToFile; + } + +// ----------------------------------------------------------------------------- +// CUpnpHttpBuffer::SetToFile +// Sets if body of message contained in buffer should be saved in file. +// ----------------------------------------------------------------------------- +// +void CUpnpHttpBuffer::SetToFile( TBool aToFile ) + { + iToFile = aToFile; + } + + +// End Of File