TInt CWspHeaderReader::DecodeGenericParamTokenL(TWspPrimitiveDecoder& aDecoder, const TStringTable& aStrTable,
											THTTPHdrVal& aParamValue, RStringF& aParamDesValue) const
	{
	TInt err = 0;
	switch( aDecoder.VarType() )
		{
		case TWspPrimitiveDecoder::EString:
			{
			TPtrC8 fieldNameString;
			err = aDecoder.String(fieldNameString);
			User::LeaveIfError(err);
			aParamDesValue = iStrPool.OpenFStringL(fieldNameString);
			aParamValue.SetStrF(aParamDesValue);
			} break;
		case TWspPrimitiveDecoder::E7BitVal:
			{
			TUint8 fieldNameToken = 0;
			err = aDecoder.Val7Bit(fieldNameToken);
			User::LeaveIfError(err);
			aParamDesValue = iStrPool.StringF(fieldNameToken, aStrTable);
			aParamValue.SetStrF(aParamDesValue);
			} break;
		default:
			User::Leave(KErrCorrupt);
			break;
		}
	return err;
	}
void CHttpClientFilter::EnsureContentLengthL(RHTTPTransaction aTransaction)
	{
	RHTTPRequest request = aTransaction.Request();

	if( request.HasBody() )
		{
		THTTPHdrVal hdrVal;
		RStringF teName = iStringPool.StringF(HTTP::ETransferEncoding, iStringTable);

		// Get rid of Content-Length header if present
		// NOTE - cannot use a local variable for the Content-Length as causes a 
		// compiler bug in thumb builds - grand! : (
		RHTTPHeaders headers = request.GetHeaderCollection();
		headers.RemoveField(iStringPool.StringF(HTTP::EContentLength, iStringTable)); 
		
		TInt bodySize = request.Body()->OverallDataSize();
		if( bodySize != KErrNotFound )
			{
			// Size is known - set the ContentLength header.
			headers.SetFieldL(iStringPool.StringF(HTTP::EContentLength, iStringTable), THTTPHdrVal(bodySize));
			}
		else if( headers.GetField(teName, 0, hdrVal) == KErrNotFound )
			{
			// Size is unknown and there's been no Encoding indicated by the 
			// client - set the 'TransferEncoding: chunked'
			hdrVal.SetStrF(iStringPool.StringF(HTTP::EChunked, iStringTable));
			headers.SetFieldL(teName, hdrVal);
			}
		}
	}
void CHttpClientFilter::EnsureContentTypePresentL(RHTTPTransaction aTransaction)
	{
	// From RFC 2616 Section 7.2.1 - 
	//
	// Any HTTP/1.1 message containing an entity-body SHOULD include a Content-Type
	// header field defining the media type of that body. If and only if the 
	// media type is not given by a Content-Type field, the recipient MAY attempt
	// to guess the media type via inspection of its content and/or the name 
	// extension(s) of the URI used to identify the resource. If the media type
	// remains unknown, the recipient SHOULD treat it as type "application/octet-stream".

	RHTTPHeaders headers = aTransaction.Response().GetHeaderCollection();
	THTTPHdrVal contentType;
	RStringF contentTypeString = iStringPool.StringF(HTTP::EContentType, iStringTable);
	if( headers.GetField(contentTypeString, 0, contentType) == KErrNotFound )
		{
		// There is no Content-Type header - add it with a value of 
		// "application/octet-stream".
		contentType.SetStrF(iStringPool.StringF(HTTP::EApplicationOctetStream, iStringTable));
		headers.SetFieldL(contentTypeString, contentType);
		}
	}
void CWspHeaderReader::DecodeWellKnownParamTokenL(TWspPrimitiveDecoder& aDecoder, TInt& aBytesRead,
												  TPtrC8& aRawParamBlock, CHeaderFieldPart& aHeaderFieldPart) const
	{
	TInt err = 0;
	TUint32 parameterToken = 0;
	aBytesRead = aDecoder.Integer(parameterToken);
	THTTPHdrVal paramValue;
	RStringF paramDesValue;
	CleanupClosePushL(paramDesValue);
	RStringF paramName = iStrPool.StringF(parameterToken, WSPParam::Table);
	switch( parameterToken )
		{
		case WSPParam::EQ:
			{
			// Decode Q value
			TUint32 qIntValue = 0;
			err = aDecoder.UintVar(qIntValue);
			User::LeaveIfError(err);
			aBytesRead += err;
			TReal q;
			TInt numDecimals = 0;
			TBuf8<KMaxNumQDigits> qDesC;
			if( qIntValue > 100 )
				{
				// Value is -100 and then divide by 1000
				qIntValue -= 100;
				q = ((TReal)(qIntValue/1000.));
				numDecimals = 3;
				}
			else
				{
				// Value is -1 and then divide by 100
				--qIntValue;
				if( qIntValue%10 ==0 )
					numDecimals = 1;
				else
					numDecimals = 2;
				q = ((TReal)(qIntValue/100.));
				}
			TRealFormat realFt(KMaxNumQDigits,numDecimals); // set max width and 3 decimal places
			// always use a decimal separator rather than the one supplied 
			// by the current locale
			realFt.iPoint = TChar('.'); 
			qDesC.Num(q, realFt);
			paramDesValue = iStrPool.OpenFStringL(qDesC);
			paramValue.SetStrF(paramDesValue);
			} break;
		case WSPParam::ECharset:
			{
			if( aRawParamBlock[aBytesRead] == 128 )
				{
				paramDesValue = iStrPool.StringF(WSPStdConstants::EAny, WSPStdConstants::Table);
				paramValue.SetStrF(paramDesValue);
				// Need to call Integer to update offset in WSP Decoder
				TUint8 updateDecoder =  0;
				err = aDecoder.Val7Bit(updateDecoder);
				User::LeaveIfError(err);
				aBytesRead += err;
				}
			else
				{
				switch( aDecoder.VarType() )
					{
					case TWspPrimitiveDecoder::E7BitVal:
					case TWspPrimitiveDecoder::ELengthVal:
						{
						TUint32 value = 0;
						err = aDecoder.Integer(value);
						User::LeaveIfError(err);
						aBytesRead += err;
						GetCharacterSetFromValueL(value, paramDesValue);
						paramValue.SetStrF(paramDesValue);
						} break;
					default:
						User::Leave(KErrCorrupt);
						break;
					}
				}
			} break;
		case WSPParam::ELevel:
			{
			// This is a version value
			err = aDecoder.VersionL(iStrPool,paramDesValue);
			User::LeaveIfError(err);
			aBytesRead += err;
			paramValue.SetStrF(paramDesValue);
			} break;
		case WSPParam::EType:
		case WSPParam::ESize:
		case WSPParam::EPadding:
		case WSPParam::ESEC:
		case WSPParam::EMaxAge:
			{
			TUint32 integerValue = 0;
			err = aDecoder.Integer(integerValue);
			User::LeaveIfError(err);
			aBytesRead += err;
			paramValue.SetInt(integerValue);
			} break;
		case WSPParam::ECreationDate:
		case WSPParam::EModificationDate:
		case WSPParam::EReadDate:
			{
			TDateTime dateTime(1970, EJanuary, 0, 0, 0, 0, 0);
			err = aDecoder.Date(dateTime);
			User::LeaveIfError(err);
			aBytesRead += err;
			paramValue.SetDateTime(dateTime);
			}
		case WSPParam::ENameDep:
		case WSPParam::EFilenameDep:
		case WSPParam::EStartDep:
		case WSPParam::EStartInfoDep:
		case WSPParam::ECommentDep:
		case WSPParam::EDomainDep:
		case WSPParam::EPathDep:
			{
			TPtrC8 textString;
			err = aDecoder.String(textString);
			User::LeaveIfError(err);
			aBytesRead += err;
			paramDesValue = iStrPool.OpenFStringL(textString);
			paramValue.SetStrF(paramDesValue);
			} break;
		case WSPParam::EMAC:
		case WSPParam::EName:
		case WSPParam::EFilename:
		case WSPParam::EStart:
		case WSPParam::EStartInfo:
		case WSPParam::EComment:
		case WSPParam::EDomain:
		case WSPParam::EPath:
			{
			// Check if the string has <no-value> ie <octet 0>
			if( aRawParamBlock[aBytesRead] == 0 )
				{
				paramDesValue = iStrPool.OpenFStringL(KNullDesC8());
				paramValue.SetStrF(paramDesValue);
				// Need to call Integer to update offset in WSP Decoder
				TUint32 updateDecoder =  0;
				err = aDecoder.Integer(updateDecoder);
				User::LeaveIfError(err);
				}
			else
				{
				TPtrC8 textString;
				err = aDecoder.String(textString);
				User::LeaveIfError(err);
				paramDesValue = iStrPool.OpenFStringL(textString);
				paramValue.SetStrF(paramDesValue);
				}
			aBytesRead += err;
			} break;
		case WSPParam::EDifferences:
			{
			aBytesRead += DecodeGenericParamTokenL(aDecoder, iStrTable, paramValue, paramDesValue);
			} break;
		case WSPParam::EContentTypeType:
			{
			aBytesRead += DecodeGenericParamTokenL(aDecoder, WSPContentTypes::Table, paramValue, paramDesValue);
			} break;
		case WSPParam::ESecure:
			{
			// <octet 0> no-value
			paramDesValue = iStrPool.OpenFStringL(KNullDesC8());
			paramValue.SetStrF(paramDesValue);
			// Need to call Integer to update offset in WSP Decoder
			TUint32 updateDecoder =  0;
			err = aDecoder.Integer(updateDecoder);
			User::LeaveIfError(err);
			aBytesRead += err;
			} break;
		default:
			User::Leave(KErrCorrupt);
			break;
		}

	// Add the parameter name and value
	TPtrC8 paramDes(paramName.DesC());
	SetNewParamL(aHeaderFieldPart, paramDes, paramValue);
	CleanupStack::PopAndDestroy(&paramDesValue);
	}