|
1 // Copyright (c) 2007-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 // Contains implementation of CHttpEboClientStep class |
|
15 // @internalAll |
|
16 // |
|
17 // |
|
18 |
|
19 // User Include |
|
20 #include "testhttpeboclientstep.h" |
|
21 |
|
22 // Standard headers used by default |
|
23 _LIT8(KUserAgent, "TestHttpEboClient"); |
|
24 _LIT8(KAccept, "*/*"); |
|
25 |
|
26 /** |
|
27 Constructor: Sets the test step name. |
|
28 @internalTechnology |
|
29 @test |
|
30 */ |
|
31 CHttpEboClientStep::CHttpEboClientStep() |
|
32 { |
|
33 |
|
34 //Call base class method to set human readable name for test step |
|
35 SetTestStepName(KTestHttpEboClientStep); |
|
36 } |
|
37 |
|
38 |
|
39 /** |
|
40 Destructor |
|
41 @internalTechnology |
|
42 @test |
|
43 */ |
|
44 CHttpEboClientStep::~CHttpEboClientStep() |
|
45 { |
|
46 } |
|
47 |
|
48 |
|
49 /** |
|
50 Sets the proxy and HttpDataOptimiser implemetation to session |
|
51 based on the patameter values in ini file and calls InvokeHttpMethodL() |
|
52 @internalTechnology |
|
53 @test |
|
54 @param None |
|
55 @return None |
|
56 */ |
|
57 void CHttpEboClientStep::StartClientL() |
|
58 { |
|
59 TPtrC uri; |
|
60 TPtrC proxyPtr; |
|
61 TBool proxyUsage; |
|
62 TPtrC resbodyFilename; |
|
63 TBool sessHttpOptUsage; |
|
64 if (!GetStringFromConfig(ConfigSection(), KIniUri, uri) || |
|
65 !GetStringFromConfig(ConfigSection(), KIniFileName, resbodyFilename) || |
|
66 !GetBoolFromConfig(ConfigSection(), KIniSessProxyUsage, proxyUsage) |
|
67 ) |
|
68 { |
|
69 ERR_PRINTF4(_L("Problem in reading values from ini. \ |
|
70 \nExpected fields are: \n%S\n%S\n%S\n" |
|
71 ),&KIniUri, &KIniFileName, &KIniSessProxyUsage |
|
72 ); |
|
73 SetTestStepResult(EFail); |
|
74 return; |
|
75 } |
|
76 iOutputFilename.Set(resbodyFilename); |
|
77 if (proxyUsage) |
|
78 if(!GetStringFromConfig(ConfigSection(), KIniSessProxy, proxyPtr) |
|
79 ) |
|
80 { |
|
81 ERR_PRINTF2(_L("Problem in reading values from ini. \ |
|
82 \nExpected field is: \n%S\n" |
|
83 ),&KIniSessProxy |
|
84 ); |
|
85 SetTestStepResult(EFail); |
|
86 return; |
|
87 } |
|
88 RStringPool strP = iSess.StringPool(); |
|
89 RStringF method; |
|
90 //setting proxy to session |
|
91 if(proxyUsage) |
|
92 { |
|
93 iSess.ConnectionInfo().SetPropertyL(iSess.StringPool().StringF(HTTP::EProxyUsage,RHTTPSession::GetTable()), iSess.StringPool().StringF(HTTP::EUseProxy,RHTTPSession::GetTable())); |
|
94 TBuf8<256> prox8; |
|
95 prox8.Copy(proxyPtr); |
|
96 RStringF proxy = iSess.StringPool().OpenFStringL(prox8); |
|
97 CleanupClosePushL(proxy); |
|
98 iSess.ConnectionInfo().SetPropertyL(iSess.StringPool().StringF(HTTP::EProxyAddress,RHTTPSession::GetTable()), proxy); |
|
99 CleanupStack::PopAndDestroy(&proxy); |
|
100 } |
|
101 // Setting HttpDataOptimiser to session |
|
102 if (!GetBoolFromConfig(ConfigSection(), KIniSessHttpOptUsage, sessHttpOptUsage)) |
|
103 { |
|
104 ERR_PRINTF2(_L("Problem in reading values from ini. \ |
|
105 \nExpected fields are: \n%S\n" |
|
106 ),&KIniSessHttpOptUsage |
|
107 ); |
|
108 SetTestStepResult(EFail); |
|
109 return; |
|
110 } |
|
111 if (sessHttpOptUsage) |
|
112 iSess.SetupHttpDataOptimiser(*this); |
|
113 |
|
114 // method |
|
115 method = strP.StringF(HTTP::EGET,RHTTPSession::GetTable()); |
|
116 TBuf8<256> url8; |
|
117 url8.Copy(uri); |
|
118 TRAPD(err,InvokeHttpMethodL(url8, method)); |
|
119 if (err != KErrNone) |
|
120 { |
|
121 ERR_PRINTF2(_L("Teststep Failed: Leave occured in CTestHttpBaseStep::InvokeHttpMethodL: %D\n" |
|
122 ),err |
|
123 ); |
|
124 SetTestStepResult(EFail); |
|
125 } |
|
126 method.Close(); |
|
127 } |
|
128 |
|
129 |
|
130 /** |
|
131 Invoke the http method |
|
132 This actually creates the transaction, sets the headers and HttpDataOptimiser implemetation to transaction |
|
133 and then starts the transaction |
|
134 @internalTechnology |
|
135 @test |
|
136 @param aUri Requested uri |
|
137 @param aMethod Requested method |
|
138 @return None |
|
139 */ |
|
140 void CHttpEboClientStep::InvokeHttpMethodL(const TDesC8& aUri, RStringF aMethod) |
|
141 { |
|
142 |
|
143 TBool tranProxyUsage; |
|
144 TBool tranHttpOptUsage; |
|
145 TPtrC tranProxy; |
|
146 TUriParser8 uri; |
|
147 uri.Parse( aUri ); |
|
148 |
|
149 // Opening a transaction |
|
150 iTrans = iSess.OpenTransactionL(uri, *this, aMethod); |
|
151 RHTTPHeaders hdr = iTrans.Request().GetHeaderCollection(); |
|
152 // Add headers appropriate to all methods |
|
153 SetHeaderL(hdr, HTTP::EUserAgent, KUserAgent); |
|
154 SetHeaderL(hdr, HTTP::EAccept, KAccept); |
|
155 |
|
156 if (!GetBoolFromConfig(ConfigSection(), KIniTranProxyUsage, tranProxyUsage)) |
|
157 { |
|
158 ERR_PRINTF2(_L("Problem in reading values from ini. \ |
|
159 \nExpected fields are: \n%S\n" |
|
160 ),&KIniTranProxyUsage |
|
161 ); |
|
162 SetTestStepResult(EFail); |
|
163 return; |
|
164 } |
|
165 if (tranProxyUsage) |
|
166 if (!GetStringFromConfig(ConfigSection(), KIniTranProxy, tranProxy)) |
|
167 { |
|
168 ERR_PRINTF2(_L("Problem in reading values from ini. \ |
|
169 \nExpected field is: \n%S\n" |
|
170 ),&KIniTranProxy |
|
171 ); |
|
172 SetTestStepResult(EFail); |
|
173 return; |
|
174 } |
|
175 //setting transaction proxy |
|
176 RHTTPTransactionPropertySet transactionProperties = iTrans.PropertySet(); |
|
177 RStringPool strP = iSess.StringPool(); |
|
178 if (tranProxyUsage) |
|
179 { |
|
180 TBuf8<256> tranProx8; |
|
181 tranProx8.Copy(tranProxy); |
|
182 RStringF proxyAddr = strP.OpenFStringL(tranProx8); |
|
183 CleanupClosePushL(proxyAddr); |
|
184 THTTPHdrVal proxyUsage(strP.StringF(HTTP::EUseProxy, RHTTPSession::GetTable())); |
|
185 transactionProperties.SetPropertyL(strP.StringF(HTTP::EProxyUsage,RHTTPSession::GetTable()), proxyUsage); |
|
186 transactionProperties.SetPropertyL(strP.StringF(HTTP::EProxyAddress,RHTTPSession::GetTable()), proxyAddr); |
|
187 CleanupStack::PopAndDestroy(1,&proxyAddr); |
|
188 } |
|
189 |
|
190 // Setting HttpDataOptimiser for transaction. |
|
191 if (!GetBoolFromConfig(ConfigSection(), KIniTranHttpOptUsage, tranHttpOptUsage)) |
|
192 { |
|
193 ERR_PRINTF2(_L("Problem in reading values from ini. \ |
|
194 \nExpected fields are: \n%S\n" |
|
195 ),&KIniTranHttpOptUsage |
|
196 ); |
|
197 SetTestStepResult(EFail); |
|
198 return; |
|
199 } |
|
200 if (tranHttpOptUsage) |
|
201 iTrans.SetupHttpDataOptimiser(*this); |
|
202 // submit the transaction |
|
203 iTrans.SubmitL(); |
|
204 // Start the scheduler, once the transaction completes or is cancelled on an error the scheduler will be |
|
205 // stopped in the event handler |
|
206 CActiveScheduler::Start(); |
|
207 } |
|
208 |
|
209 |
|
210 /** |
|
211 This is the implementation of interface method MHttpDataOptimiser::MHFRunL |
|
212 If there is a reponse body it will be copied to a file. |
|
213 Just printing the fired events to the log file. |
|
214 @internalTechnology |
|
215 @test |
|
216 @param aTransaction Transaction which is being processed currently |
|
217 @param THTTPEvent Event for which it is called |
|
218 @return None |
|
219 */ |
|
220 void CHttpEboClientStep::MHFRunL(RHTTPTransaction aTransaction, const THTTPEvent& aEvent) |
|
221 { |
|
222 switch (aEvent.iStatus) |
|
223 { |
|
224 case THTTPEvent::EGotResponseHeaders: |
|
225 { |
|
226 // HTTP response headers have been received. We can determine now if there is |
|
227 // going to be a response body to save. |
|
228 RHTTPResponse resp = aTransaction.Response(); |
|
229 TInt status = resp.StatusCode(); |
|
230 RStringF statusStr = resp.StatusText(); |
|
231 TBuf<32> statusStr16; |
|
232 statusStr16.Copy(statusStr.DesC()); |
|
233 INFO_PRINTF3(_L("Status: %D (%S)\n"),status, &statusStr16); |
|
234 // Determine if the body will be saved to disk |
|
235 iSavingResponseBody = EFalse; |
|
236 if (resp.HasBody() && (status >= 200) && (status < 300) && (status != 204)) |
|
237 { |
|
238 TInt dataSize = resp.Body()->OverallDataSize(); |
|
239 if (dataSize >= 0) |
|
240 INFO_PRINTF2(_L("Response body size is %d\n"), dataSize); |
|
241 else |
|
242 INFO_PRINTF1(_L("Response body size is unknown\n")); |
|
243 |
|
244 // Save response to file in disk. |
|
245 iSavingResponseBody = ETrue; |
|
246 } |
|
247 |
|
248 if (iSavingResponseBody) // If we're saving, then open a file handle for the new file |
|
249 { |
|
250 // Check it exists and open a file handle |
|
251 TInt valid = iFileServ.IsValidName(iOutputFilename); |
|
252 if (!valid) |
|
253 { |
|
254 ERR_PRINTF1(_L("The specified filename is not valid!.\n")); |
|
255 iSavingResponseBody = EFalse; |
|
256 } |
|
257 else |
|
258 { |
|
259 TInt err = iRespBodyFile.Replace(iFileServ, |
|
260 iOutputFilename, |
|
261 EFileWrite|EFileShareExclusive); |
|
262 if (err) |
|
263 { |
|
264 iSavingResponseBody = EFalse; |
|
265 User::Leave(err); |
|
266 } |
|
267 } |
|
268 } |
|
269 |
|
270 } break; |
|
271 case THTTPEvent::EGotResponseBodyData: |
|
272 { |
|
273 // Get the body data supplier |
|
274 iRespBody = aTransaction.Response().Body(); |
|
275 |
|
276 // Append to the output file if we're saving responses |
|
277 if (iSavingResponseBody) |
|
278 { |
|
279 INFO_PRINTF1(_L("Saving response body...\n")); |
|
280 TPtrC8 bodyData; |
|
281 TBool lastChunk = iRespBody->GetNextDataPart(bodyData); |
|
282 iRespBodyFile.Write(bodyData); |
|
283 if (lastChunk) |
|
284 iRespBodyFile.Close(); |
|
285 } |
|
286 |
|
287 // Done with that bit of body data |
|
288 iRespBody->ReleaseData(); |
|
289 } break; |
|
290 case THTTPEvent::EResponseComplete: |
|
291 { |
|
292 // The transaction's response is complete |
|
293 INFO_PRINTF1(_L("\nTransaction Complete\n")); |
|
294 } break; |
|
295 case KErrHttpOptimiserFailsTrans: |
|
296 { |
|
297 INFO_PRINTF1(_L("Cancelling/Failing Transaction\n")); |
|
298 aTransaction.Fail(THTTPFilterHandle::EProtocolHandler); |
|
299 //CActiveScheduler::Stop(); |
|
300 } break; |
|
301 case THTTPEvent::ESucceeded: |
|
302 { |
|
303 INFO_PRINTF1(_L("Transaction Successful\n")); |
|
304 aTransaction.Close(); |
|
305 CActiveScheduler::Stop(); |
|
306 } break; |
|
307 case THTTPEvent::EFailed: |
|
308 { |
|
309 INFO_PRINTF1(_L("Transaction Failed\n")); |
|
310 aTransaction.Close(); |
|
311 CActiveScheduler::Stop(); |
|
312 } break; |
|
313 case THTTPEvent::ERedirectedPermanently: |
|
314 { |
|
315 INFO_PRINTF1(_L("Permanent Redirection\n")); |
|
316 } break; |
|
317 case THTTPEvent::ERedirectedTemporarily: |
|
318 { |
|
319 INFO_PRINTF1(_L("Temporary Redirection\n")); |
|
320 } break; |
|
321 case THTTPEvent::ERedirectRequiresConfirmation: |
|
322 { |
|
323 // 301(Moved Permanently), 302(Found) or 307(Temporary Redirect) status is received |
|
324 // from a transaction and hence ERedirectRequiresConfirmation is sent by filter |
|
325 // client has opted to close the transaction |
|
326 INFO_PRINTF1(_L("Redirect requires confirmation\n")); |
|
327 aTransaction.Close(); |
|
328 CActiveScheduler::Stop(); |
|
329 } break; |
|
330 default: |
|
331 { |
|
332 INFO_PRINTF2(_L("<unrecognised event: %D>\n"), aEvent.iStatus); |
|
333 // close off the transaction if it's an error |
|
334 if (aEvent.iStatus < 0) |
|
335 { |
|
336 aTransaction.Close(); |
|
337 CActiveScheduler::Stop(); |
|
338 } |
|
339 } break; |
|
340 } |
|
341 } |
|
342 |
|
343 |
|
344 /** |
|
345 This is the implementation of interface method MHttpDataOptimiser::MHFRunError |
|
346 @internalTechnology |
|
347 @test |
|
348 @param aError Error which has been raised. |
|
349 @param aTransaction Transaction which is being processed currently |
|
350 @param THTTPEvent Event which it is being handled currently. |
|
351 @return None |
|
352 */ |
|
353 TInt CHttpEboClientStep::MHFRunError(TInt aError, RHTTPTransaction /*aTransaction*/, const THTTPEvent& /*aEvent*/) |
|
354 { |
|
355 INFO_PRINTF2(_L("MHFRunError fired with error code %D\n"), aError); |
|
356 return KErrNone; |
|
357 } |
|
358 |
|
359 |
|
360 /** |
|
361 It enocodes the request data. |
|
362 @internalTechnology |
|
363 @test |
|
364 @param aHttpData Actual request. |
|
365 @param aEncodedData Encoded request. |
|
366 @return None |
|
367 */ |
|
368 void CHttpEboClientStep::EncodeL (const TDesC8& /*aHttpData*/, HBufC8* &aEncodedData) |
|
369 { |
|
370 |
|
371 INFO_PRINTF1(_L("######## CHttpEboClientStep::EncodeL ########\n")); |
|
372 TBool isEncoded; |
|
373 if (!GetBoolFromConfig(ConfigSection(), KIniIsEncoded, isEncoded)) |
|
374 { |
|
375 ERR_PRINTF2(_L("Problem in reading values from ini. \ |
|
376 \nExpected fields are: \n%S\n" |
|
377 ),&KIniIsEncoded |
|
378 ); |
|
379 SetTestStepResult(EFail); |
|
380 return; |
|
381 } |
|
382 // Checking whether enocoding is needed. |
|
383 if (isEncoded) |
|
384 { |
|
385 // Encoding: Changing the request data to http://www.google.co.uk/ |
|
386 _LIT8(KTestRequest, "GET http://www.google.co.uk/ HTTP/1.1\r\nHost: www.google.co.uk\r\nAccept: */*\r\nUser-Agent: TestHttpEboClient\r\n\r\n"); |
|
387 const TDesC8& encodedReq(KTestRequest); |
|
388 TRAPD(err, |
|
389 { |
|
390 aEncodedData = encodedReq.AllocLC(); |
|
391 CleanupStack::Pop(); |
|
392 }); |
|
393 if (err != KErrNone) |
|
394 { |
|
395 ERR_PRINTF2(_L("Test step failed: Leave occured while encoding the request: %D\n"), err); |
|
396 SetTestStepResult(EFail); |
|
397 } |
|
398 else |
|
399 { |
|
400 INFO_PRINTF1(_L("Encoded/Changed the request\n")); |
|
401 } |
|
402 } |
|
403 else |
|
404 INFO_PRINTF1(_L("Not encoding the request [passing NULL]\n")); |
|
405 } |
|
406 |
|
407 |
|
408 /** |
|
409 It decodes the responsing data before parsing. |
|
410 @internalTechnology |
|
411 @test |
|
412 @param aHttpData Actual response. |
|
413 @param aEncodedData Decoded response. |
|
414 @return None |
|
415 */ |
|
416 void CHttpEboClientStep::DecodeL (const TDesC8& aData, HBufC8*& aHttpData, TBool& aTransFail) |
|
417 { |
|
418 INFO_PRINTF1(_L("######## CHttpEboClientStep::DecodeL ########\n")); |
|
419 TBool isDecoded; |
|
420 TBool failTransaction; |
|
421 if (!GetBoolFromConfig(ConfigSection(), KIniIsDecoded, isDecoded)) |
|
422 { |
|
423 ERR_PRINTF2(_L("Problem in reading values from ini. \ |
|
424 \nExpected fields are: \n%S\n" |
|
425 ),&KIniIsDecoded |
|
426 ); |
|
427 SetTestStepResult(EFail); |
|
428 return; |
|
429 } |
|
430 // Checking whether decoding is needed. |
|
431 if (isDecoded) |
|
432 { |
|
433 TRAPD(err, |
|
434 { |
|
435 // Copying same actual response to decoded response |
|
436 aHttpData = aData.AllocLC(); |
|
437 CleanupStack::Pop(); |
|
438 }); |
|
439 if (err != KErrNone) |
|
440 { |
|
441 ERR_PRINTF2(_L("Test step failed: Leave occured while decoding the response: %D\n"), err); |
|
442 SetTestStepResult(EFail); |
|
443 } |
|
444 else |
|
445 { |
|
446 INFO_PRINTF1(_L("Sent the actual response as a decoded response\n")); |
|
447 } |
|
448 } |
|
449 else |
|
450 INFO_PRINTF1(_L("Not decoding the response [passing NULL]\n")); |
|
451 |
|
452 if(!GetBoolFromConfig(ConfigSection(), KIniFailTransaction, failTransaction)) |
|
453 { |
|
454 ERR_PRINTF2(_L("Problem in reading values from ini. \ |
|
455 \nExpected fields are: \n%S\n" |
|
456 ),&KIniFailTransaction |
|
457 ); |
|
458 SetTestStepResult(EFail); |
|
459 return; |
|
460 } |
|
461 // Checking to fail the transaction. |
|
462 if (failTransaction) |
|
463 { |
|
464 aTransFail = ETrue; |
|
465 INFO_PRINTF1(_L("CHttpEboClientStep::DecodeL returing ETrue(intend to fail the transaction)\n")); |
|
466 } |
|
467 else |
|
468 { |
|
469 aTransFail = EFalse; |
|
470 INFO_PRINTF1(_L("CHttpEboClientStep::DecodeL returing EFalse(not failing the transaction)\n")); |
|
471 } |
|
472 } |
|
473 |