|
1 // Copyright (c) 2005-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 <e32base.h> |
|
17 #include <http.h> |
|
18 #include <escapeutils.h> |
|
19 |
|
20 #include "testwebbrowser.h" |
|
21 #include "httpexampleutils.h" |
|
22 |
|
23 |
|
24 const TInt KMaxURISize = 256; |
|
25 const TInt KMaxFilePathLength = 512; |
|
26 const TInt KHttpSchemeLength = 7; |
|
27 |
|
28 _LIT ( KDirPath, "c:\\TestWebBrowser\\"); |
|
29 _LIT ( KDefaultFilePath, "index.html" ); |
|
30 _LIT ( KQuit, "quit" ); |
|
31 _LIT ( KSelectOption, " Select an option \n\n" ); |
|
32 _LIT ( KPossibleSelectionsText, " 1 Download URL \n 2 Set Proxy\n 3 Quit \n" ); |
|
33 _LIT ( KPossibleSelections,"123" ); |
|
34 _LIT ( KEnterUrl, "Enter URL: " ); |
|
35 _LIT ( KEnterProxy, "Enter Proxy Address: " ); |
|
36 |
|
37 // Invalid characters that can appear in a URL. These values must be replaced |
|
38 // with a valid character to generate the full file path. |
|
39 _LIT ( KInvalidChars, "<>:\"|*?"); |
|
40 |
|
41 const TUint KReplaceChar = '_'; |
|
42 |
|
43 void ChangePathSeparator( TDes& aDesPtr, TUint aPathSeperatorFrom, TUint aPathSeperatorTo ) |
|
44 { |
|
45 for( TInt offset = aDesPtr.Length() - 1; offset >= 0; offset-- ) |
|
46 { |
|
47 if ( aDesPtr[offset] == aPathSeperatorFrom ) |
|
48 { |
|
49 aDesPtr[offset] = TUint16( aPathSeperatorTo ); |
|
50 } |
|
51 } |
|
52 } |
|
53 |
|
54 CTestWebBrowser::CTestWebBrowser ( CHttpExampleUtils& aUtils ) |
|
55 : CActive ( EPriorityStandard ), |
|
56 iTestUtils ( aUtils ), |
|
57 iCurrentState ( EMainMenu ) |
|
58 { |
|
59 //Add this active object to the active schedeler |
|
60 CActiveScheduler::Add(this); |
|
61 __ASSERT_DEBUG( !IsActive(),User::Panic(_L("Reader"), KErrCorrupt) ); |
|
62 |
|
63 // Wait for request to be handled. |
|
64 IssueAndCompleteRequest(); |
|
65 } |
|
66 |
|
67 |
|
68 CTestWebBrowser::~CTestWebBrowser () |
|
69 { |
|
70 // Close the HTTP session. |
|
71 iHttpSession.Close(); |
|
72 |
|
73 iTransArray.ResetAndDestroy (); |
|
74 iTransArray.Close (); |
|
75 |
|
76 delete iBaseUri; |
|
77 } |
|
78 |
|
79 CTestWebBrowser* CTestWebBrowser::NewLC ( CHttpExampleUtils& aUtils ) |
|
80 { |
|
81 CTestWebBrowser* me = new (ELeave) CTestWebBrowser ( aUtils ); |
|
82 CleanupStack::PushL ( me ); |
|
83 me->ConstructL (); |
|
84 return me; |
|
85 } |
|
86 |
|
87 void CTestWebBrowser::ConstructL () |
|
88 { |
|
89 // Open a HTTP session. |
|
90 iHttpSession.OpenL (); |
|
91 |
|
92 // Install the callback into the session. |
|
93 InstallAuthenticationL ( iHttpSession ); |
|
94 |
|
95 iBaseUri = HBufC8::NewL ( KMaxURISize ); |
|
96 } |
|
97 |
|
98 CTestWebBrowser* CTestWebBrowser::NewL ( CHttpExampleUtils& aUtils ) |
|
99 { |
|
100 CTestWebBrowser* me = CTestWebBrowser::NewLC ( aUtils ); |
|
101 CleanupStack::Pop ( me ); |
|
102 return me; |
|
103 } |
|
104 |
|
105 /** |
|
106 Set HTTP proxy information for the session. |
|
107 |
|
108 @param aProxyAddr [in] Proxy address to set for the session |
|
109 */ |
|
110 void CTestWebBrowser::SetProxyL ( const TDesC8& aProxyAddr ) |
|
111 { |
|
112 |
|
113 RHTTPConnectionInfo connInfo = iHttpSession.ConnectionInfo(); |
|
114 |
|
115 // Set the proxy usage property. |
|
116 THTTPHdrVal proxyUsage( iHttpSession.StringPool().StringF( HTTP::EUseProxy, RHTTPSession::GetTable() ) ); |
|
117 connInfo.SetPropertyL( iHttpSession.StringPool().StringF( HTTP::EProxyUsage, RHTTPSession::GetTable() ), proxyUsage ); |
|
118 |
|
119 RStringF proxyAddr = iHttpSession.StringPool ().OpenFStringL ( aProxyAddr ); |
|
120 CleanupClosePushL ( proxyAddr ); |
|
121 |
|
122 // Set the proxy address property. |
|
123 THTTPHdrVal proxyAddrHdr( proxyAddr ); |
|
124 connInfo.SetPropertyL( iHttpSession.StringPool().StringF( HTTP::EProxyAddress, RHTTPSession::GetTable() ), proxyAddrHdr ); |
|
125 |
|
126 CleanupStack::PopAndDestroy (); // Pop and destroy proxyAddr |
|
127 return; |
|
128 } |
|
129 |
|
130 /** |
|
131 Get the credentials from the user. |
|
132 |
|
133 @param aURI [in] The URI being requested |
|
134 @param aRealm [out] The realm being requested |
|
135 @param aAuthenticationType [out] The type of authentication. |
|
136 @param aUsername [out] User name |
|
137 @param aPassword [out] Pass word |
|
138 |
|
139 @return TBool ETrue if credentials being returned else EFalse |
|
140 */ |
|
141 TBool CTestWebBrowser::GetCredentialsL( const TUriC8& aURI, |
|
142 RString aRealm, |
|
143 RStringF aAuthenticationType, |
|
144 RString& aUsername, |
|
145 RString& aPassword ) |
|
146 { |
|
147 // Convert to 16 bit to display |
|
148 HBufC* uriDesBuf = HBufC::NewLC( aURI.UriDes().Length() ); |
|
149 TPtr uriDesPtr( uriDesBuf->Des() ); |
|
150 uriDesPtr.Copy( aURI.UriDes() ); |
|
151 |
|
152 HBufC* uriRealmBuf = HBufC::NewLC( aRealm.DesC().Length() ); |
|
153 TPtr uriRealmPtr( uriRealmBuf->Des() ); |
|
154 uriRealmPtr.Copy( aRealm.DesC() ); |
|
155 |
|
156 HBufC* uriAuthenticationType = HBufC::NewLC ( aAuthenticationType.DesC().Length() ); |
|
157 TPtr uriAuthenticationPtr( uriAuthenticationType->Des() ); |
|
158 uriAuthenticationPtr.Copy ( aAuthenticationType.DesC() ); |
|
159 |
|
160 |
|
161 // Prompt user for input |
|
162 iTestUtils.Test().Printf ( _L( "Enter credentials for URL %S, realm %S\n"), &uriDesPtr, &uriRealmPtr ); |
|
163 iTestUtils.Test().Printf ( _L("Using %S authentication\n"), &uriAuthenticationPtr ); |
|
164 CleanupStack::PopAndDestroy ( 3 ); // Pop and destroy uriDesBuf, uriRealmBuf and uriAuthenticationType |
|
165 |
|
166 HBufC* userDetails16 = HBufC::NewLC ( KMaxUserEntrySize ); |
|
167 HBufC8* userDetails8 = HBufC8::NewLC ( KMaxUserEntrySize ); |
|
168 TPtr userDetailsPtr16( userDetails16->Des() ); |
|
169 TPtr8 userDetailsPtr8( userDetails8->Des() ); |
|
170 |
|
171 iTestUtils.GetAnEntry ( _L( "Username (or QUIT to give up): " ), userDetailsPtr16 ); |
|
172 TBool set = EFalse; |
|
173 if ( userDetailsPtr16.CompareF ( KQuit ) ) |
|
174 { |
|
175 userDetailsPtr8.Copy ( userDetailsPtr16 ); |
|
176 aUsername = aRealm.Pool().OpenStringL ( userDetailsPtr8 ); |
|
177 iTestUtils.GetAnEntry( _L( "Password: " ), userDetailsPtr16 ); |
|
178 userDetailsPtr8.Copy ( userDetailsPtr16 ); |
|
179 aPassword = aRealm.Pool().OpenStringL ( userDetailsPtr8 ); |
|
180 set = ETrue; |
|
181 } |
|
182 CleanupStack::PopAndDestroy ( 2 ); // Pop and destroy userDetails16 & userDetails8 |
|
183 return set; |
|
184 } |
|
185 |
|
186 /** |
|
187 Create a new transaction. Generate the full uri from a partial uri. |
|
188 Also, generates the file path where the contents to be saved. Adds the transaction |
|
189 object into array. |
|
190 |
|
191 @param aUri [in] URI to download. |
|
192 @param aParseHtml [in] Parse the downloaded HTML content. Default value: EFalse. ETrue value to parse |
|
193 the HTML content. Typically the value will be set to ETrue only for the main page. |
|
194 */ |
|
195 void CTestWebBrowser::CreateTransactionL ( const TDesC8& aUri, TBool aParseHtml /* = EFalse */ ) |
|
196 { |
|
197 TUriParser8 baseUri; |
|
198 baseUri.Parse ( iBaseUri->Des() ); |
|
199 |
|
200 TUriParser8 refUri; |
|
201 refUri.Parse ( aUri ); |
|
202 |
|
203 // Resolve uri |
|
204 CUri8* uriPtr = CUri8::ResolveL( baseUri, refUri ); |
|
205 CleanupStack::PushL ( uriPtr ); |
|
206 |
|
207 // Generate the file path from the full http uri. |
|
208 HBufC* filePath = GenerateFilePathL ( uriPtr->Uri() ); |
|
209 CleanupStack::PushL ( filePath ); |
|
210 |
|
211 // Create a new HTTP transaction object. |
|
212 CBrowserTransaction* newTrans = CBrowserTransaction::NewL ( iHttpSession, iTestUtils, this, *filePath, aParseHtml ); |
|
213 CleanupStack::PopAndDestroy ( filePath ); |
|
214 CleanupStack::PushL ( newTrans ); |
|
215 iTransArray.AppendL ( newTrans ); |
|
216 |
|
217 // Open and submit the transaction. |
|
218 newTrans->CreateTransactionL ( uriPtr->Uri().UriDes() ); |
|
219 newTrans->StartTransactionL (); |
|
220 |
|
221 CleanupStack::Pop ( newTrans ); |
|
222 CleanupStack::PopAndDestroy ( uriPtr ); |
|
223 return; |
|
224 } |
|
225 |
|
226 /** |
|
227 To create a new transaction. This function is a calllback called from |
|
228 the CHTMLHandler when it finds a new URI to be downloaded. |
|
229 |
|
230 @param aUri [in] URI to download. |
|
231 */ |
|
232 void CTestWebBrowser::OnTransactionCreateL ( const TDesC8& aUri, TBool aParseHtml ) |
|
233 { |
|
234 CreateTransactionL ( aUri, aParseHtml ); |
|
235 return; |
|
236 } |
|
237 |
|
238 /** |
|
239 Delete the transaction. Removes the transaction object from the transaction array |
|
240 |
|
241 @param aTrans [out] Transaction object to close. |
|
242 */ |
|
243 void CTestWebBrowser::OnTransactionClose ( CBrowserTransaction* aTrans ) |
|
244 { |
|
245 // Find the transaction object to be deleted and remove it from the |
|
246 // transaction array. |
|
247 TInt numTrans = iTransArray.Count (); |
|
248 for ( TInt i = 0; i < numTrans; ++i ) |
|
249 { |
|
250 if ( iTransArray[ i ] == aTrans ) |
|
251 { |
|
252 delete aTrans; |
|
253 iTransArray.Remove ( i ); |
|
254 break; |
|
255 } |
|
256 } |
|
257 |
|
258 if ( iTransArray.Count () == 0 ) |
|
259 { |
|
260 // All transactions are completed. |
|
261 iCurrentState = ETransactionCompleted; |
|
262 IssueAndCompleteRequest (); |
|
263 } |
|
264 return; |
|
265 } |
|
266 |
|
267 /** |
|
268 Issues a new request if the active object has no outstanding request. |
|
269 |
|
270 */ |
|
271 void CTestWebBrowser::IssueAndCompleteRequest() |
|
272 { |
|
273 if ( !IsActive() ) |
|
274 { |
|
275 TRequestStatus* status = &iStatus; |
|
276 User::RequestComplete( status, KErrNone ); |
|
277 SetActive(); |
|
278 } |
|
279 } |
|
280 |
|
281 void CTestWebBrowser::RunL () |
|
282 { |
|
283 |
|
284 switch ( iCurrentState ) |
|
285 { |
|
286 case EMainMenu: |
|
287 iTestUtils.Test().Printf ( _L ( "Main menu") ); |
|
288 ExecuteMainMenuL(); |
|
289 break; |
|
290 |
|
291 case EEnterUrl: |
|
292 AcceptUrlL (); |
|
293 break; |
|
294 |
|
295 case ESelectProxy: |
|
296 AcceptProxyL (); |
|
297 break; |
|
298 |
|
299 case EStop: |
|
300 CActiveScheduler::Stop(); |
|
301 break; |
|
302 |
|
303 case EStartTransaction: |
|
304 { |
|
305 CreateTransactionL ( iBaseUri->Des(), ETrue ); |
|
306 } |
|
307 break; |
|
308 |
|
309 case ETransactionStarted: |
|
310 { |
|
311 iTestUtils.Test().Printf ( _L ( "Transaction started. Please wait...") ); |
|
312 } |
|
313 break; |
|
314 |
|
315 case ETransactionCompleted: |
|
316 { |
|
317 OnTransactionCompleted(); |
|
318 } |
|
319 break; |
|
320 |
|
321 default: |
|
322 break; |
|
323 } |
|
324 } |
|
325 |
|
326 void CTestWebBrowser::DoCancel () |
|
327 { |
|
328 // Do nothing... |
|
329 } |
|
330 |
|
331 /** |
|
332 Checks whether a uri is valid or not. Will check whether the uri contains |
|
333 scheme, host and path. |
|
334 |
|
335 @param aUri [in] URI to validate. Only scheme and host presence is validated. |
|
336 |
|
337 @return TBool ETrue if the URI is successfully validated else EFalse. |
|
338 */ |
|
339 TBool CTestWebBrowser::ValidateUri ( const TDesC8& aUri ) |
|
340 { |
|
341 TUriParser8 uriParser; |
|
342 if ( uriParser.Parse ( aUri ) != KErrNone ) |
|
343 { |
|
344 return EFalse; |
|
345 } |
|
346 |
|
347 // check for scheme |
|
348 if ( !uriParser.IsPresent ( EUriScheme ) ) |
|
349 { |
|
350 return EFalse; |
|
351 } |
|
352 |
|
353 // check for host |
|
354 if ( !uriParser.IsPresent ( EUriHost) ) |
|
355 { |
|
356 return EFalse; |
|
357 } |
|
358 return ETrue; |
|
359 } |
|
360 |
|
361 /** |
|
362 Generate the full file path based on the aUri. |
|
363 |
|
364 @param aUri [in] Full URI to generate the full file path. |
|
365 |
|
366 @return HBufC* Holds the full file path. |
|
367 */ |
|
368 HBufC* CTestWebBrowser::GenerateFilePathL ( const TUriC8& aUri ) |
|
369 { |
|
370 |
|
371 HBufC* filePath = HBufC::NewLC ( KMaxFilePathLength ); |
|
372 TPtr filePtr ( filePath->Des() ); |
|
373 |
|
374 // Append the base path |
|
375 filePtr.Append ( KDirPath ); |
|
376 |
|
377 // Get the full uri. |
|
378 HBufC* completeUri = aUri.DisplayFormL(); |
|
379 CleanupStack::PushL ( completeUri ); |
|
380 |
|
381 TPtr ptr = completeUri->Des(); |
|
382 // Chop off the scheme. ( http:// ) |
|
383 ptr.Delete ( 0, KHttpSchemeLength ); |
|
384 |
|
385 // Reverse the slashes. |
|
386 ChangePathSeparator ( ptr, '/', '\\' ); |
|
387 |
|
388 // Replace invalid characters with '_'. Invalid characters: <>:"|* |
|
389 TPtrC ptrInvalidChars ( KInvalidChars ); |
|
390 for ( TInt i = 0; i < KInvalidChars().Length(); ++i ) |
|
391 { |
|
392 ChangePathSeparator ( ptr, ptrInvalidChars[i], KReplaceChar ); |
|
393 } |
|
394 |
|
395 // Append the URI file path. |
|
396 filePtr.Append ( ptr ); |
|
397 CleanupStack::PopAndDestroy ( completeUri ); |
|
398 |
|
399 HBufC* uriTail = aUri.GetFileNameL ( EUriFileNameTail ); |
|
400 CleanupStack::PushL ( uriTail ); |
|
401 |
|
402 TBool fileExtPresent = uriTail->Des().Length() != 0; |
|
403 |
|
404 CleanupStack::PopAndDestroy ( uriTail ); |
|
405 |
|
406 // Append a '\\' at the end of the completeUri if not present. |
|
407 TInt len = filePtr.Length(); |
|
408 |
|
409 if ( ( !fileExtPresent ) && ( len != 0 ) && ( filePtr[ len-1 ] != '\\') ) |
|
410 { |
|
411 filePtr.Append ( '\\' ); |
|
412 } |
|
413 |
|
414 if ( !fileExtPresent ) |
|
415 { |
|
416 // No file name present in the uri. Set the file name as index.html. |
|
417 filePtr.Append ( KDefaultFilePath() ); |
|
418 } |
|
419 |
|
420 CleanupStack::Pop ( filePath ); |
|
421 iTestUtils.LogIt ( _L("File Path: %S"), &filePtr ); |
|
422 return filePath; |
|
423 } |
|
424 |
|
425 void CTestWebBrowser::ExecuteMainMenuL () |
|
426 { |
|
427 iTestUtils.Test().Console()->ClearScreen (); |
|
428 |
|
429 iTestUtils.Test().Printf(KSelectOption); |
|
430 |
|
431 |
|
432 TInt selection = iTestUtils.GetSelection ( KPossibleSelectionsText, KPossibleSelections ); |
|
433 |
|
434 switch ( selection ) |
|
435 { |
|
436 case EDownloadURL: |
|
437 iCurrentState = EEnterUrl; |
|
438 break; |
|
439 |
|
440 case ESetProxy: |
|
441 iCurrentState = ESelectProxy; |
|
442 break; |
|
443 |
|
444 case EQuit: |
|
445 iCurrentState = EStop; |
|
446 break; |
|
447 |
|
448 default: |
|
449 break; |
|
450 } |
|
451 |
|
452 IssueAndCompleteRequest (); |
|
453 } |
|
454 |
|
455 /** |
|
456 Accept the url from the user and validate. |
|
457 */ |
|
458 void CTestWebBrowser::AcceptUrlL () |
|
459 { |
|
460 |
|
461 HBufC* uri = HBufC::NewLC ( KMaxURISize ); |
|
462 TPtr ptr( uri->Des() ); |
|
463 iTestUtils.GetAnEntry ( KEnterUrl, ptr ); |
|
464 if ( iBaseUri->Des().MaxLength() < ptr.Length() ) |
|
465 { |
|
466 iBaseUri = iBaseUri->ReAllocL ( ptr.Length() ); |
|
467 } |
|
468 |
|
469 iBaseUri->Des().Copy ( ptr ); |
|
470 |
|
471 if ( ValidateUri( iBaseUri->Des() ) ) |
|
472 { |
|
473 iCurrentState = EStartTransaction; |
|
474 } |
|
475 else |
|
476 { |
|
477 iTestUtils.Test().Printf ( _L("Invalid entry.") ); |
|
478 iTestUtils.PressAnyKey (); |
|
479 iCurrentState = EMainMenu; |
|
480 } |
|
481 CleanupStack::PopAndDestroy ( uri ); |
|
482 |
|
483 IssueAndCompleteRequest (); |
|
484 } |
|
485 |
|
486 /** |
|
487 Accept proxy information from the user. |
|
488 */ |
|
489 void CTestWebBrowser::AcceptProxyL () |
|
490 { |
|
491 HBufC* proxy16 = HBufC::NewLC ( 128 ) ; |
|
492 TPtr ptr( proxy16->Des() ); |
|
493 iTestUtils.GetAnEntry ( KEnterProxy, ptr ); |
|
494 |
|
495 HBufC8* proxy8 = HBufC8::NewLC ( ptr.Length() ); |
|
496 proxy8->Des().Copy ( ptr ); |
|
497 |
|
498 TRAPD ( err, SetProxyL ( proxy8->Des() ) ); |
|
499 |
|
500 if ( err != KErrNone ) |
|
501 { |
|
502 iTestUtils.Test().Printf ( _L ( "Setting of proxy address failed." ) ); |
|
503 } |
|
504 |
|
505 iCurrentState = EMainMenu; |
|
506 IssueAndCompleteRequest (); |
|
507 } |
|
508 |
|
509 /** |
|
510 Set the state to EMainMenu and issues a request to be processed by the RunL. |
|
511 */ |
|
512 void CTestWebBrowser::OnTransactionCompleted () |
|
513 { |
|
514 iTestUtils.Test().Printf ( _L ("Transaction completed.") ); |
|
515 iTestUtils.PressAnyKey(); |
|
516 iCurrentState = EMainMenu; |
|
517 IssueAndCompleteRequest (); |
|
518 } |
|
519 |
|
520 |