diff -r 000000000000 -r b16258d2340f applayerpluginsandutils/httpprotocolplugins/httpheadercodec/chttpheaderreader.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/applayerpluginsandutils/httpprotocolplugins/httpheadercodec/chttpheaderreader.cpp Tue Feb 02 01:09:52 2010 +0200 @@ -0,0 +1,288 @@ +// Copyright (c) 2002-2009 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: +// + +#include "chttpheaderreader.h" + +#include +#include +#include +#include "CHeaderField.h" + + +CHttpHeaderReader::CHttpHeaderReader(RStringPool aStrPool) + : iStrPool(aStrPool), iStringTable(RHTTPSession::GetTable()) + { + } + +/** Generic Decoding function that splits headers into parts on a character separator */ +void CHttpHeaderReader::DecodeGenericL(RHeaderField& aHeader, const TDesC8& aSeparator) const + { + TPtrC8 rawData; + aHeader.RawDataL(rawData); + TInt remaining = rawData.Length(); + TPtrC8 token; + TInt tokensFound =0; + while (remaining > 0) + { + remaining -= InetProtTextUtils::ExtractNextTokenFromList(rawData, token, aSeparator); + SetNewFStringPartL(aHeader, tokensFound, token); + ++tokensFound; + if(remaining > 0) + { + remaining -= InetProtTextUtils::ExtractNextTokenFromList(rawData, token, aSeparator); + SetNewFStringPartL(aHeader, tokensFound, token); + ++tokensFound; + } + } + } + +// Helper to DoUserAgentL(), etc., which take token lists with arbitrary separators +void CHttpHeaderReader::DecodeTokenListHeaderL(RHeaderField& aHeader, const TDesC8& aSep) const + { + TPtrC8 rawData; + TPtrC8 token; + + aHeader.RawDataL(rawData); + + TUint remaining = rawData.Length(); + TInt tokensFound=0; + while (remaining > 0) + { + remaining -= InetProtTextUtils::ExtractNextTokenFromList(rawData, token, aSep); + InetProtTextUtils::RemoveWhiteSpace(token, InetProtTextUtils::ERemoveBoth); + SetNewFStringPartL(aHeader, tokensFound, token); + tokensFound++; + if(remaining > 0) + { + remaining -= InetProtTextUtils::ExtractNextTokenFromList(rawData, token, aSep); + InetProtTextUtils::RemoveWhiteSpace(token, InetProtTextUtils::ERemoveBoth); + SetNewFStringPartL(aHeader, tokensFound, token); + tokensFound++; + } + } + } + +void CHttpHeaderReader::DecodeGenericNumberL(RHeaderField& aHeader) const + { + TPtrC8 buffer; + aHeader.RawDataL(buffer); + TInt number = KErrNotFound; + + TInt decimalPos = buffer.Locate('.'); + if(decimalPos == 0) + { + // first character is decimal. So, set the value as zero. + SetNewIntegerPartL(aHeader, 0, 0); + } + else + { + // Search for '\n' separator. In the case when a duplicate header has been received, + // only use the fist instance of the valid data. + TInt newLinePos = buffer.Locate('\n'); + if (newLinePos != KErrNotFound) + { + buffer.Set(buffer.Left(newLinePos)); + } + + TInt value = KErrNotFound; + TInt ret = InetProtTextUtils::ConvertDescriptorToInt(buffer, value); + if ( ret > KErrNone ) + { + // Extract an integer. Do not permit terminators other than WS or EOL. + InetProtTextUtils::ExtractIntegerValueL(buffer, number, EFalse); + } + SetNewIntegerPartL(aHeader, 0, number); // part 0, i.e. the first (and only) part + } + } + +CHeaderFieldPart* CHttpHeaderReader::SetNewIntegerPartL(RHeaderField& aHeader, TInt aPartIndex, TInt aValue) const + { + THTTPHdrVal partVal(aValue); + CHeaderFieldPart* part = SetNewPartL(aHeader, aPartIndex, partVal); + return part; + } + +CHeaderFieldPart* CHttpHeaderReader::SetNewDatePartL(RHeaderField& aHeader, TInt aPartIndex, TDateTime& aDate) const + { + THTTPHdrVal partVal(aDate); + CHeaderFieldPart* part = SetNewPartL(aHeader, aPartIndex, partVal); + return part; + } + +CHeaderFieldPart* CHttpHeaderReader::SetNewFStringPartL(RHeaderField& aHeader, TInt aPartIndex, TPtrC8 aValue) const + { + RStringF partStr = iStrPool.OpenFStringL(aValue); + CleanupClosePushL(partStr); + THTTPHdrVal partVal(partStr); + CHeaderFieldPart* part = SetNewPartL(aHeader, aPartIndex, partVal); + CleanupStack::PopAndDestroy(&partStr); + return part; + } +CHeaderFieldPart* CHttpHeaderReader::SetNewStringPartL(RHeaderField& aHeader, TInt aPartIndex, TPtrC8 aValue) const + { + RString partStr = iStrPool.OpenStringL(aValue); + CleanupClosePushL(partStr); + THTTPHdrVal partVal(partStr); + CHeaderFieldPart* part = SetNewPartL(aHeader, aPartIndex, partVal); + CleanupStack::PopAndDestroy(&partStr); + return part; + } + +CHeaderFieldPart* CHttpHeaderReader::SetNewPartL(RHeaderField& aHeader, TInt aPartIndex, THTTPHdrVal& aPartVal) const + { + CHeaderFieldPart* part = CHeaderFieldPart::NewL(aPartVal); + CleanupStack::PushL(part); + aHeader.SetPartL(part, aPartIndex); + CleanupStack::Pop(part); + return part; + } + +void CHttpHeaderReader::SetParamNameAndValueL(CHeaderFieldPart& aHeaderPart, const TDesC8& aParam, TBool aQuotedValueAllowed) const + { + // Extract the name and value of the parameter. + TPtrC8 paramName; + TPtrC8 paramValue; + + TInt equalPos = aParam.Locate('='); + if (equalPos == KErrNotFound) + { + // If there is no value then set an empty parameter + paramName.Set(aParam); + paramValue.Set(KNullDesC8); + } + else + { + paramName.Set(aParam.Left(equalPos)); + InetProtTextUtils::RemoveWhiteSpace(paramName, InetProtTextUtils::ERemoveBoth); + paramValue.Set(aParam.Right(aParam.Length() - (equalPos+1))); + InetProtTextUtils::RemoveWhiteSpace(paramValue, InetProtTextUtils::ERemoveBoth); + } + + TPtrC8 unquotedParamValue; + if (aQuotedValueAllowed && paramValue.Length() > 0 && paramValue[0] == '"') + { + InetProtTextUtils::ExtractQuotedStringL(paramValue, unquotedParamValue); + } + else + { + unquotedParamValue.Set(paramValue); + } + + + SetNewFStringParamL(aHeaderPart, paramName, unquotedParamValue); + } + +CHeaderFieldParam* CHttpHeaderReader::SetNewFStringParamL(CHeaderFieldPart& aHeaderPart, TPtrC8 aParamName, TPtrC8 aParamValue) const + { + RStringF paramNameStr = iStrPool.OpenFStringL(aParamName); + CleanupClosePushL(paramNameStr); + RStringF paramValStr = iStrPool.OpenFStringL(aParamValue); + CleanupClosePushL(paramValStr); + THTTPHdrVal paramVal(paramValStr); + CHeaderFieldParam* param = CHeaderFieldParam::NewL(paramNameStr, paramVal); + CleanupStack::PushL(param); + aHeaderPart.AddParamL(param); + CleanupStack::Pop(param); + CleanupStack::PopAndDestroy(2, ¶mNameStr); // and paramValStr + return param; + } + + +CHeaderFieldParam* CHttpHeaderReader::SetNewStringParamL(CHeaderFieldPart& aHeaderPart, TPtrC8 aParamName, TPtrC8 aParamValue) const + { + RStringF paramNameStr = iStrPool.OpenFStringL(aParamName); + CleanupClosePushL(paramNameStr); + RString paramValStr = iStrPool.OpenStringL(aParamValue); + CleanupClosePushL(paramValStr); + THTTPHdrVal paramVal(paramValStr); + CHeaderFieldParam* param = CHeaderFieldParam::NewL(paramNameStr, paramVal); + CleanupStack::PushL(param); + aHeaderPart.AddParamL(param); + CleanupStack::Pop(param); + CleanupStack::PopAndDestroy(2, ¶mNameStr); // and paramValStr + return param; + } + +CHeaderFieldParam* CHttpHeaderReader::SetNewIntegerParamL(CHeaderFieldPart& aHeaderPart, TPtrC8 aParamName, TPtrC8 aParamValue) const + { + RStringF paramNameStr = iStrPool.OpenFStringL(aParamName); + CleanupClosePushL(paramNameStr); + TInt intParamVal; + InetProtTextUtils::ConvertDescriptorToInt(aParamValue, intParamVal); + THTTPHdrVal paramVal(intParamVal); + CHeaderFieldParam* param = CHeaderFieldParam::NewL(paramNameStr, paramVal); + CleanupStack::PushL(param); + aHeaderPart.AddParamL(param); + CleanupStack::Pop(param); + CleanupStack::PopAndDestroy(¶mNameStr); + return param; + } + +void CHttpHeaderReader::DecodeDateL(RHeaderField& aHeader) const + { + // RFC2616, section 14.18 + // Date = "Date" ":" HTTP-date + // + // An example is + // Date: Tue, 15 Nov 1994 08:12:31 GMT + + TPtrC8 buffer; + aHeader.RawDataL(buffer); + + // Search for '\n' separator. In the case when a duplicate header has been received, + // only use the fist instance of the valid data. + TInt newLinePos = buffer.Locate('\n'); + if (newLinePos != KErrNotFound) + { + buffer.Set(buffer.Left(newLinePos)); + } + + TInternetDate date; + date.SetDateL(buffer); + TDateTime dateTime = date.DateTime(); + SetNewDatePartL(aHeader, 0, dateTime); // part 0, i.e. the first (and only) part + } + + +TInt CHttpHeaderReader::GetParamNameAndValueL(TPtrC8& aBuffer, TPtrC8& aName, TPtrC8& aValue, TInt aErrorCode) const + { + TInt bytesConsumed=0; + + TInt equalsPos = (aBuffer.Locate('=') ); + if (equalsPos==KErrNotFound) + User::Leave(aErrorCode); + + aName.Set(aBuffer.Left(equalsPos)); + InetProtTextUtils::RemoveWhiteSpace(aName, InetProtTextUtils::ERemoveBoth); + + TPtrC8 value(aBuffer.Mid(equalsPos+1)); + InetProtTextUtils::RemoveWhiteSpace(value, InetProtTextUtils::ERemoveBoth); + + // Obtain the parameter value. It is a string which + // may or may not be quoted. + if (value.Length()==0) + User::Leave(aErrorCode); + + if (value[0] == '"') + { + bytesConsumed += InetProtTextUtils::ExtractQuotedStringL(value, aValue); + } + else + { + aValue.Set(value); + } + + return bytesConsumed; + }