|
1 // Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // |
|
15 |
|
16 #include "chttpheaderreader.h" |
|
17 |
|
18 #include <inetprottextutils.h> |
|
19 #include <tinternetdate.h> |
|
20 #include <http/rhttpsession.h> |
|
21 #include "CHeaderField.h" |
|
22 |
|
23 |
|
24 CHttpHeaderReader::CHttpHeaderReader(RStringPool aStrPool) |
|
25 : iStrPool(aStrPool), iStringTable(RHTTPSession::GetTable()) |
|
26 { |
|
27 } |
|
28 |
|
29 /** Generic Decoding function that splits headers into parts on a character separator */ |
|
30 void CHttpHeaderReader::DecodeGenericL(RHeaderField& aHeader, const TDesC8& aSeparator) const |
|
31 { |
|
32 TPtrC8 rawData; |
|
33 aHeader.RawDataL(rawData); |
|
34 TInt remaining = rawData.Length(); |
|
35 TPtrC8 token; |
|
36 TInt tokensFound =0; |
|
37 while (remaining > 0) |
|
38 { |
|
39 remaining -= InetProtTextUtils::ExtractNextTokenFromList(rawData, token, aSeparator); |
|
40 SetNewFStringPartL(aHeader, tokensFound, token); |
|
41 ++tokensFound; |
|
42 if(remaining > 0) |
|
43 { |
|
44 remaining -= InetProtTextUtils::ExtractNextTokenFromList(rawData, token, aSeparator); |
|
45 SetNewFStringPartL(aHeader, tokensFound, token); |
|
46 ++tokensFound; |
|
47 } |
|
48 } |
|
49 } |
|
50 |
|
51 // Helper to DoUserAgentL(), etc., which take token lists with arbitrary separators |
|
52 void CHttpHeaderReader::DecodeTokenListHeaderL(RHeaderField& aHeader, const TDesC8& aSep) const |
|
53 { |
|
54 TPtrC8 rawData; |
|
55 TPtrC8 token; |
|
56 |
|
57 aHeader.RawDataL(rawData); |
|
58 |
|
59 TUint remaining = rawData.Length(); |
|
60 TInt tokensFound=0; |
|
61 while (remaining > 0) |
|
62 { |
|
63 remaining -= InetProtTextUtils::ExtractNextTokenFromList(rawData, token, aSep); |
|
64 InetProtTextUtils::RemoveWhiteSpace(token, InetProtTextUtils::ERemoveBoth); |
|
65 SetNewFStringPartL(aHeader, tokensFound, token); |
|
66 tokensFound++; |
|
67 if(remaining > 0) |
|
68 { |
|
69 remaining -= InetProtTextUtils::ExtractNextTokenFromList(rawData, token, aSep); |
|
70 InetProtTextUtils::RemoveWhiteSpace(token, InetProtTextUtils::ERemoveBoth); |
|
71 SetNewFStringPartL(aHeader, tokensFound, token); |
|
72 tokensFound++; |
|
73 } |
|
74 } |
|
75 } |
|
76 |
|
77 void CHttpHeaderReader::DecodeGenericNumberL(RHeaderField& aHeader) const |
|
78 { |
|
79 TPtrC8 buffer; |
|
80 aHeader.RawDataL(buffer); |
|
81 TInt number = KErrNotFound; |
|
82 |
|
83 TInt decimalPos = buffer.Locate('.'); |
|
84 if(decimalPos == 0) |
|
85 { |
|
86 // first character is decimal. So, set the value as zero. |
|
87 SetNewIntegerPartL(aHeader, 0, 0); |
|
88 } |
|
89 else |
|
90 { |
|
91 // Search for '\n' separator. In the case when a duplicate header has been received, |
|
92 // only use the fist instance of the valid data. |
|
93 TInt newLinePos = buffer.Locate('\n'); |
|
94 if (newLinePos != KErrNotFound) |
|
95 { |
|
96 buffer.Set(buffer.Left(newLinePos)); |
|
97 } |
|
98 |
|
99 TInt value = KErrNotFound; |
|
100 TInt ret = InetProtTextUtils::ConvertDescriptorToInt(buffer, value); |
|
101 if ( ret > KErrNone ) |
|
102 { |
|
103 // Extract an integer. Do not permit terminators other than WS or EOL. |
|
104 InetProtTextUtils::ExtractIntegerValueL(buffer, number, EFalse); |
|
105 } |
|
106 SetNewIntegerPartL(aHeader, 0, number); // part 0, i.e. the first (and only) part |
|
107 } |
|
108 } |
|
109 |
|
110 CHeaderFieldPart* CHttpHeaderReader::SetNewIntegerPartL(RHeaderField& aHeader, TInt aPartIndex, TInt aValue) const |
|
111 { |
|
112 THTTPHdrVal partVal(aValue); |
|
113 CHeaderFieldPart* part = SetNewPartL(aHeader, aPartIndex, partVal); |
|
114 return part; |
|
115 } |
|
116 |
|
117 CHeaderFieldPart* CHttpHeaderReader::SetNewDatePartL(RHeaderField& aHeader, TInt aPartIndex, TDateTime& aDate) const |
|
118 { |
|
119 THTTPHdrVal partVal(aDate); |
|
120 CHeaderFieldPart* part = SetNewPartL(aHeader, aPartIndex, partVal); |
|
121 return part; |
|
122 } |
|
123 |
|
124 CHeaderFieldPart* CHttpHeaderReader::SetNewFStringPartL(RHeaderField& aHeader, TInt aPartIndex, TPtrC8 aValue) const |
|
125 { |
|
126 RStringF partStr = iStrPool.OpenFStringL(aValue); |
|
127 CleanupClosePushL(partStr); |
|
128 THTTPHdrVal partVal(partStr); |
|
129 CHeaderFieldPart* part = SetNewPartL(aHeader, aPartIndex, partVal); |
|
130 CleanupStack::PopAndDestroy(&partStr); |
|
131 return part; |
|
132 } |
|
133 CHeaderFieldPart* CHttpHeaderReader::SetNewStringPartL(RHeaderField& aHeader, TInt aPartIndex, TPtrC8 aValue) const |
|
134 { |
|
135 RString partStr = iStrPool.OpenStringL(aValue); |
|
136 CleanupClosePushL(partStr); |
|
137 THTTPHdrVal partVal(partStr); |
|
138 CHeaderFieldPart* part = SetNewPartL(aHeader, aPartIndex, partVal); |
|
139 CleanupStack::PopAndDestroy(&partStr); |
|
140 return part; |
|
141 } |
|
142 |
|
143 CHeaderFieldPart* CHttpHeaderReader::SetNewPartL(RHeaderField& aHeader, TInt aPartIndex, THTTPHdrVal& aPartVal) const |
|
144 { |
|
145 CHeaderFieldPart* part = CHeaderFieldPart::NewL(aPartVal); |
|
146 CleanupStack::PushL(part); |
|
147 aHeader.SetPartL(part, aPartIndex); |
|
148 CleanupStack::Pop(part); |
|
149 return part; |
|
150 } |
|
151 |
|
152 void CHttpHeaderReader::SetParamNameAndValueL(CHeaderFieldPart& aHeaderPart, const TDesC8& aParam, TBool aQuotedValueAllowed) const |
|
153 { |
|
154 // Extract the name and value of the parameter. |
|
155 TPtrC8 paramName; |
|
156 TPtrC8 paramValue; |
|
157 |
|
158 TInt equalPos = aParam.Locate('='); |
|
159 if (equalPos == KErrNotFound) |
|
160 { |
|
161 // If there is no value then set an empty parameter |
|
162 paramName.Set(aParam); |
|
163 paramValue.Set(KNullDesC8); |
|
164 } |
|
165 else |
|
166 { |
|
167 paramName.Set(aParam.Left(equalPos)); |
|
168 InetProtTextUtils::RemoveWhiteSpace(paramName, InetProtTextUtils::ERemoveBoth); |
|
169 paramValue.Set(aParam.Right(aParam.Length() - (equalPos+1))); |
|
170 InetProtTextUtils::RemoveWhiteSpace(paramValue, InetProtTextUtils::ERemoveBoth); |
|
171 } |
|
172 |
|
173 TPtrC8 unquotedParamValue; |
|
174 if (aQuotedValueAllowed && paramValue.Length() > 0 && paramValue[0] == '"') |
|
175 { |
|
176 InetProtTextUtils::ExtractQuotedStringL(paramValue, unquotedParamValue); |
|
177 } |
|
178 else |
|
179 { |
|
180 unquotedParamValue.Set(paramValue); |
|
181 } |
|
182 |
|
183 |
|
184 SetNewFStringParamL(aHeaderPart, paramName, unquotedParamValue); |
|
185 } |
|
186 |
|
187 CHeaderFieldParam* CHttpHeaderReader::SetNewFStringParamL(CHeaderFieldPart& aHeaderPart, TPtrC8 aParamName, TPtrC8 aParamValue) const |
|
188 { |
|
189 RStringF paramNameStr = iStrPool.OpenFStringL(aParamName); |
|
190 CleanupClosePushL(paramNameStr); |
|
191 RStringF paramValStr = iStrPool.OpenFStringL(aParamValue); |
|
192 CleanupClosePushL(paramValStr); |
|
193 THTTPHdrVal paramVal(paramValStr); |
|
194 CHeaderFieldParam* param = CHeaderFieldParam::NewL(paramNameStr, paramVal); |
|
195 CleanupStack::PushL(param); |
|
196 aHeaderPart.AddParamL(param); |
|
197 CleanupStack::Pop(param); |
|
198 CleanupStack::PopAndDestroy(2, ¶mNameStr); // and paramValStr |
|
199 return param; |
|
200 } |
|
201 |
|
202 |
|
203 CHeaderFieldParam* CHttpHeaderReader::SetNewStringParamL(CHeaderFieldPart& aHeaderPart, TPtrC8 aParamName, TPtrC8 aParamValue) const |
|
204 { |
|
205 RStringF paramNameStr = iStrPool.OpenFStringL(aParamName); |
|
206 CleanupClosePushL(paramNameStr); |
|
207 RString paramValStr = iStrPool.OpenStringL(aParamValue); |
|
208 CleanupClosePushL(paramValStr); |
|
209 THTTPHdrVal paramVal(paramValStr); |
|
210 CHeaderFieldParam* param = CHeaderFieldParam::NewL(paramNameStr, paramVal); |
|
211 CleanupStack::PushL(param); |
|
212 aHeaderPart.AddParamL(param); |
|
213 CleanupStack::Pop(param); |
|
214 CleanupStack::PopAndDestroy(2, ¶mNameStr); // and paramValStr |
|
215 return param; |
|
216 } |
|
217 |
|
218 CHeaderFieldParam* CHttpHeaderReader::SetNewIntegerParamL(CHeaderFieldPart& aHeaderPart, TPtrC8 aParamName, TPtrC8 aParamValue) const |
|
219 { |
|
220 RStringF paramNameStr = iStrPool.OpenFStringL(aParamName); |
|
221 CleanupClosePushL(paramNameStr); |
|
222 TInt intParamVal; |
|
223 InetProtTextUtils::ConvertDescriptorToInt(aParamValue, intParamVal); |
|
224 THTTPHdrVal paramVal(intParamVal); |
|
225 CHeaderFieldParam* param = CHeaderFieldParam::NewL(paramNameStr, paramVal); |
|
226 CleanupStack::PushL(param); |
|
227 aHeaderPart.AddParamL(param); |
|
228 CleanupStack::Pop(param); |
|
229 CleanupStack::PopAndDestroy(¶mNameStr); |
|
230 return param; |
|
231 } |
|
232 |
|
233 void CHttpHeaderReader::DecodeDateL(RHeaderField& aHeader) const |
|
234 { |
|
235 // RFC2616, section 14.18 |
|
236 // Date = "Date" ":" HTTP-date |
|
237 // |
|
238 // An example is |
|
239 // Date: Tue, 15 Nov 1994 08:12:31 GMT |
|
240 |
|
241 TPtrC8 buffer; |
|
242 aHeader.RawDataL(buffer); |
|
243 |
|
244 // Search for '\n' separator. In the case when a duplicate header has been received, |
|
245 // only use the fist instance of the valid data. |
|
246 TInt newLinePos = buffer.Locate('\n'); |
|
247 if (newLinePos != KErrNotFound) |
|
248 { |
|
249 buffer.Set(buffer.Left(newLinePos)); |
|
250 } |
|
251 |
|
252 TInternetDate date; |
|
253 date.SetDateL(buffer); |
|
254 TDateTime dateTime = date.DateTime(); |
|
255 SetNewDatePartL(aHeader, 0, dateTime); // part 0, i.e. the first (and only) part |
|
256 } |
|
257 |
|
258 |
|
259 TInt CHttpHeaderReader::GetParamNameAndValueL(TPtrC8& aBuffer, TPtrC8& aName, TPtrC8& aValue, TInt aErrorCode) const |
|
260 { |
|
261 TInt bytesConsumed=0; |
|
262 |
|
263 TInt equalsPos = (aBuffer.Locate('=') ); |
|
264 if (equalsPos==KErrNotFound) |
|
265 User::Leave(aErrorCode); |
|
266 |
|
267 aName.Set(aBuffer.Left(equalsPos)); |
|
268 InetProtTextUtils::RemoveWhiteSpace(aName, InetProtTextUtils::ERemoveBoth); |
|
269 |
|
270 TPtrC8 value(aBuffer.Mid(equalsPos+1)); |
|
271 InetProtTextUtils::RemoveWhiteSpace(value, InetProtTextUtils::ERemoveBoth); |
|
272 |
|
273 // Obtain the parameter value. It is a string which |
|
274 // may or may not be quoted. |
|
275 if (value.Length()==0) |
|
276 User::Leave(aErrorCode); |
|
277 |
|
278 if (value[0] == '"') |
|
279 { |
|
280 bytesConsumed += InetProtTextUtils::ExtractQuotedStringL(value, aValue); |
|
281 } |
|
282 else |
|
283 { |
|
284 aValue.Set(value); |
|
285 } |
|
286 |
|
287 return bytesConsumed; |
|
288 } |