1 /* |
|
2 * Copyright (c) 2005-2006 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: PnP Paos filter implementation |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 #include <e32std.h> |
|
20 #include <http.h> |
|
21 #include <apgcli.h> // for RApaLsSession |
|
22 #include <apacmdln.h> // for CApaCommandLine |
|
23 #include <centralrepository.h> // link against centralrepository.lib |
|
24 |
|
25 #include "PnpPaosFilter.h" |
|
26 #include "PnpPaosLogger.h" |
|
27 #include "PnpPaosXml.h" |
|
28 #include "PnpPaosFilterPrivateCRKeys.h" |
|
29 |
|
30 |
|
31 |
|
32 _LIT8( KPaosContentType, "application/vnd.paos+xml" ); |
|
33 _LIT8( KPnpPaosFilterName, "PnpPaosFilter" ); |
|
34 _LIT8( KPaosHeaderName, "PAOS" ); |
|
35 _LIT8( KPaosHeader, "ver=\"urn:liberty:paos:2003-08\"; urn:\"http://pnpms.nokia.com/signkey\"" ); |
|
36 _LIT8( KDummyResponse, "<!-- Dummy -->" ); |
|
37 _LIT8( KHttp, "http://" ); |
|
38 _LIT8( KHttps, "https://" ); |
|
39 |
|
40 CEComFilter* CPnpPaosFilter::InstantiateL( TAny* aSession ) |
|
41 { |
|
42 LOGSTRING("CPnpPaosFilter::InstantiateL()"); |
|
43 // Cast TAny to RHTTPSession |
|
44 RHTTPSession* pSession = static_cast<RHTTPSession*>(aSession); |
|
45 CPnpPaosFilter* filter = CPnpPaosFilter::NewL( pSession ); |
|
46 LOGSTRING("CPnpPaosFilter::InstantiateL() - done"); |
|
47 return filter; |
|
48 } |
|
49 |
|
50 CPnpPaosFilter* CPnpPaosFilter::NewL( RHTTPSession* pSession ) |
|
51 { |
|
52 LOGSTRING("CPnpPaosFilter::NewL()"); |
|
53 CPnpPaosFilter* pNew = new (ELeave) CPnpPaosFilter( pSession); |
|
54 CleanupStack::PushL(pNew); |
|
55 pNew->ConstructL(); |
|
56 CleanupStack::Pop(); |
|
57 LOGSTRING("CPnpPaosFilter::NewL() - done"); |
|
58 return pNew; |
|
59 } |
|
60 |
|
61 CPnpPaosFilter::CPnpPaosFilter( RHTTPSession* pSession ) : |
|
62 iTransactionId(-1), |
|
63 iSession( pSession ), |
|
64 iMakePaosResponse( EFalse ) |
|
65 #ifndef __SERIES60_ |
|
66 ,iHdcPaosPostDone( EFalse ) |
|
67 #endif |
|
68 { |
|
69 LOGSTRING("constructor CPnpPaosFilter()"); |
|
70 } |
|
71 |
|
72 void CPnpPaosFilter::ReadAllowedDomainsL() |
|
73 { |
|
74 LOGSTRING("CPnpPaosFilter::ReadAllowedDomainsL()"); |
|
75 RLibrary library; |
|
76 const TUidType hdcuid( KNullUid, KNullUid, KHdcUtilDllUid ); |
|
77 TInt result = library.Load( KHdcDllFileName, hdcuid ); |
|
78 LOGSTRING2( "Hdc Library load result: %i", result ); |
|
79 // If there is no HDC installed, cannot add allowed HDC domains |
|
80 if( result == KErrNone ) |
|
81 { |
|
82 CleanupClosePushL( library ); |
|
83 LOGSTRING("CPnpPaosFilter::ReadAllowedDomainsL() 2"); |
|
84 // Function at ordinal 1 is NewLC |
|
85 TLibraryFunction entry = library.Lookup(1); |
|
86 // Call the function to create new hdc dll object |
|
87 LOGSTRING("CPnpPaosFilter::ReadAllowedDomainsL() 3"); |
|
88 CHdcToPaosInterface* hdcUtil = ( CHdcToPaosInterface* ) entry(); |
|
89 hdcUtil->TrustedDomainsL( iTrustedHdcDomains ); |
|
90 LOGSTRING("CPnpPaosFilter::ReadAllowedDomainsL() 4"); |
|
91 CleanupStack::PopAndDestroy( hdcUtil ); |
|
92 CleanupStack::PopAndDestroy(); // library.Close() |
|
93 LOGSTRING("CPnpPaosFilter::ReadAllowedDomainsL() 5"); |
|
94 } |
|
95 |
|
96 // PnP trusted domains could be handled as in HDC case, by maintaining |
|
97 // a list of trusted domains as browser bookmarks (changeable only |
|
98 // in a Device Managament session, not by the user) |
|
99 //AllowedDomainsArray pnpDomains = pnpUtil->AllowedDomainsL(); |
|
100 LOGSTRING("CPnpPaosFilter::ReadAllowedDomainsL() - done"); |
|
101 } |
|
102 |
|
103 void CPnpPaosFilter::ReadAllowedPnpDomainsL() |
|
104 { |
|
105 LOGSTRING("CPnpPaosFilter::ReadAllowedPnpDomainsL()"); |
|
106 // Create PnP-MS home domain filter |
|
107 // Read allowed pnp domains from cenrep |
|
108 CRepository* repository = CRepository::NewLC( KCRUidPnpPaosFilter ); |
|
109 |
|
110 TBuf<KMaxURLLength> buffer; |
|
111 TUint32 domainNbr; |
|
112 TrustedDomain domain; |
|
113 for (domainNbr = KPnPPaosFilterHomeDomain1; domainNbr <= KPnPPaosFilterHomeDomainLast; domainNbr++) |
|
114 { |
|
115 User::LeaveIfError( repository->Get( domainNbr, buffer ) ); |
|
116 if(buffer.Length() > 0) |
|
117 { |
|
118 domain.Copy( buffer ); |
|
119 iTrustedPnpDomains.Append( domain ); |
|
120 } |
|
121 } |
|
122 CleanupStack::PopAndDestroy( repository ); |
|
123 LOGSTRING("CPnpPaosFilter::ReadAllowedPnpDomainsL() - done"); |
|
124 } |
|
125 |
|
126 void CPnpPaosFilter::ConstructL() |
|
127 { |
|
128 LOGSTRING("CPnpPaosFilter::ConstructL()"); |
|
129 |
|
130 iSessionStringPool = iSession->StringPool(); |
|
131 iFilterName = iSessionStringPool.OpenFStringL( KPnpPaosFilterName ); |
|
132 TInt err( KErrNone ); |
|
133 TRAP( err, iPnpPaosXml = CPnpPaosXml::NewL() ); |
|
134 LOGSTRING2( "iPnpPaosXml err: %i", err ); |
|
135 |
|
136 TRAP( err, ReadAllowedDomainsL() ); |
|
137 if( err != KErrNone ) |
|
138 { |
|
139 LOGSTRING2( "Could not read allowed domains for HelpDeskConnect PAOS: %i", err ); |
|
140 } |
|
141 |
|
142 TRAP( err, ReadAllowedPnpDomainsL() ); |
|
143 if( err != KErrNone ) |
|
144 { |
|
145 LOGSTRING2( "Could not read allowed domains for PnP PAOS: %i", err ); |
|
146 } |
|
147 |
|
148 |
|
149 LOGSTRING("CPnpPaosFilter::ConstructL() add filters"); |
|
150 |
|
151 // Add the filter to the queue and register for selected incoming and |
|
152 // outgoing events. |
|
153 iSession->FilterCollection().AddFilterL( |
|
154 *this, |
|
155 THTTPEvent::ESubmit, // Transaction event |
|
156 RStringF(), // Any header field |
|
157 KAnyStatusCode, // HTTP status code |
|
158 MHTTPFilter::EClientFilters, // Position in filter chain |
|
159 //MHTTPFilter::EProtocolHandler, // Position in filter chain |
|
160 iFilterName ); // Filter name |
|
161 |
|
162 iSession->FilterCollection().AddFilterL( |
|
163 *this, |
|
164 THTTPEvent::EGotResponseHeaders, |
|
165 RStringF(), |
|
166 200, |
|
167 MHTTPFilter::EClientFilters, // Position in filter chain |
|
168 //MHTTPFilter::EProtocolHandler, // Position in filter chain |
|
169 iFilterName ); |
|
170 |
|
171 iSession->FilterCollection().AddFilterL( |
|
172 *this, |
|
173 THTTPEvent::EGotResponseBodyData, |
|
174 RStringF(), |
|
175 200, |
|
176 MHTTPFilter::EClientFilters, // Position in filter chain |
|
177 //MHTTPFilter::EProtocolHandler, // Position in filter chain |
|
178 iFilterName ); |
|
179 |
|
180 iSession->FilterCollection().AddFilterL( |
|
181 *this, |
|
182 THTTPEvent::EResponseComplete, |
|
183 RStringF(), |
|
184 200, |
|
185 MHTTPFilter::EClientFilters, // Position in filter chain |
|
186 //MHTTPFilter::EProtocolHandler, // Position in filter chain |
|
187 iFilterName ); |
|
188 |
|
189 LOGSTRING("CPnpPaosFilter::ConstructL() - done"); |
|
190 } |
|
191 |
|
192 CPnpPaosFilter::~CPnpPaosFilter() |
|
193 { |
|
194 LOGSTRING("CPnpPaosFilter::~CPnpPaosFilter()"); |
|
195 |
|
196 if( iLoadCount ) |
|
197 { |
|
198 // As we're already in a destructor, MHFUnload must not delete us again |
|
199 iLoadCount = -1; |
|
200 if (iSession) |
|
201 { |
|
202 // Removes all registrations of this filter: |
|
203 iSession->FilterCollection().RemoveFilter( iFilterName ); |
|
204 } |
|
205 } |
|
206 iFilterName.Close(); |
|
207 iTrustedPnpDomains.Close(); |
|
208 |
|
209 delete iPaosPostUrl; |
|
210 delete iPnpPaosXml; |
|
211 |
|
212 // RArray must be closed before destructing |
|
213 iTrustedHdcDomains.Close(); |
|
214 |
|
215 // we do not own iSessionStringPool, we do not close it. |
|
216 // we do not own iSession |
|
217 |
|
218 LOGSTRING("CPnpPaosFilter::~CPnpPaosFilter() - done"); |
|
219 } |
|
220 |
|
221 void CPnpPaosFilter::HostFromUriL( CUri8* aUri ) |
|
222 { |
|
223 LOGSTRING( "Original URI:" ); |
|
224 LOGTEXT( aUri->Uri().UriDes() ); |
|
225 |
|
226 /** The userinfo component specifier */ |
|
227 aUri->RemoveComponentL( EUriUserinfo ); |
|
228 LOGTEXT( aUri->Uri().UriDes() ); |
|
229 /** The path component specifier */ |
|
230 aUri->RemoveComponentL( EUriPath ); |
|
231 LOGTEXT( aUri->Uri().UriDes() ); |
|
232 /** The query component specifier */ |
|
233 aUri->RemoveComponentL( EUriQuery ); |
|
234 LOGTEXT( aUri->Uri().UriDes() ); |
|
235 /** The fragment component specifier */ |
|
236 aUri->RemoveComponentL( EUriFragment ); |
|
237 LOGTEXT( aUri->Uri().UriDes() ); |
|
238 |
|
239 // Only EUriHost (The host component specifier) and |
|
240 // EUriPort (The port component specifier) are left |
|
241 } |
|
242 |
|
243 void CPnpPaosFilter::MHFRunL( RHTTPTransaction aTransaction, |
|
244 const THTTPEvent& aEvent) |
|
245 { |
|
246 LOGSTRING3( "CPnpPaosFilter::MHFRunL( TxnId: %d, event: %d )", aTransaction.Id(), aEvent.iStatus ); |
|
247 switch( aEvent.iStatus ) |
|
248 { |
|
249 case THTTPEvent::ESubmit: |
|
250 { |
|
251 LOGSTRING( "CPnpPaosFilter::MHFRunL:ESubmit"); |
|
252 |
|
253 // Generate as little overhead as possible: |
|
254 |
|
255 // If this is the case maybe PAOS requests should be allowed only from certain URLs... |
|
256 // Now only nokia.com or help-portal.com are allowed URLs |
|
257 CUri8* uri = CUri8::NewLC( aTransaction.Request().URI() ); |
|
258 HostFromUriL( uri ); |
|
259 TPtrC8 host = uri->Uri().UriDes(); |
|
260 |
|
261 // Check if a PAOS query is allowed from the domain |
|
262 |
|
263 if( IsPaosHomeDomainL( host ) ) |
|
264 { |
|
265 LOGSTRING("PnP Mobile Services Allows PAOS-requests from the domain"); |
|
266 RHTTPHeaders headers = aTransaction.Request().GetHeaderCollection(); |
|
267 AddPaosHeadersL( headers ); |
|
268 // From HTTP stack documentation: |
|
269 // It's important to note that a filter object is per-session, and so might be shared by several |
|
270 // transactions. This means that if you have per-transaction state that you need to store, it |
|
271 // must be stored in the transaction's property set. DO NOT STORE ANY PER-TRANSACTION INFORMATION |
|
272 // IN THE FILTER OBJECT. |
|
273 |
|
274 iMakePaosResponse = ETrue; |
|
275 } |
|
276 else |
|
277 { |
|
278 if( host.Size() <= 255) |
|
279 { |
|
280 if( iTrustedHdcDomains.Find( host ) != KErrNotFound ) |
|
281 { |
|
282 LOGSTRING("HelpDeskConnect Allows PAOS-requests from the domain"); |
|
283 RHTTPHeaders headers = aTransaction.Request().GetHeaderCollection(); |
|
284 AddPaosHeadersL( headers ); |
|
285 iMakePaosResponse = ETrue; |
|
286 } |
|
287 else |
|
288 { |
|
289 iMakePaosResponse = EFalse; |
|
290 } |
|
291 } |
|
292 } |
|
293 CleanupStack::PopAndDestroy( uri ); |
|
294 break; |
|
295 } |
|
296 case THTTPEvent::EGotResponseHeaders: |
|
297 { |
|
298 LOGSTRING( "CPnpPaosFilter::MHFRunL:EGotResponseHeaders" ); |
|
299 |
|
300 if( !iMakePaosResponse ) break; |
|
301 |
|
302 RHTTPHeaders headers = aTransaction.Response().GetHeaderCollection(); |
|
303 if( IsPaosContentTypeL( headers ) ) |
|
304 { |
|
305 iTransactionId = aTransaction.Id(); |
|
306 |
|
307 delete iPaosPostUrl; |
|
308 iPaosPostUrl = 0; |
|
309 iPaosPostUrl = CUri8::NewL( aTransaction.Request().URI() ); |
|
310 HostFromUriL( iPaosPostUrl ); |
|
311 } |
|
312 else |
|
313 { |
|
314 iMakePaosResponse = EFalse; |
|
315 } |
|
316 break; |
|
317 } |
|
318 case THTTPEvent::EGotResponseBodyData: |
|
319 { |
|
320 LOGSTRING( "CPnpPaosFilter::MHFRunL:EGotResponseBodyData" ); |
|
321 |
|
322 // Check if we are allowed to make a PAOS response |
|
323 if( iMakePaosResponse && aTransaction.Id() == iTransactionId ) |
|
324 { |
|
325 if( !iPnpPaosXml ) |
|
326 { |
|
327 User::Leave( KErrGeneral ); |
|
328 } |
|
329 TBool lastPart( EFalse ); |
|
330 // Received another body data chunk |
|
331 MHTTPDataSupplier* pBody = aTransaction.Response().Body(); |
|
332 if( pBody ) |
|
333 { |
|
334 lastPart = iPnpPaosXml->CollectResponseBodyL( *pBody ); |
|
335 } |
|
336 |
|
337 // check if more data is expected |
|
338 if( lastPart ) |
|
339 { |
|
340 PostPaosResponseL( aTransaction ); |
|
341 } |
|
342 } |
|
343 #ifndef __SERIES60_ |
|
344 // check if expecting a HDC trigger file |
|
345 else if( iHdcPaosPostDone ) |
|
346 { |
|
347 // Received another body data chunk |
|
348 MHTTPDataSupplier* pBody = aTransaction.Response().Body(); |
|
349 if( pBody ) |
|
350 { |
|
351 iPnpPaosXml->CollectResponseBodyL( *pBody ); |
|
352 } |
|
353 } |
|
354 #endif |
|
355 break; |
|
356 } |
|
357 case THTTPEvent::EResponseComplete: |
|
358 { |
|
359 LOGSTRING( "CPnpPaosFilter::MHFRunL:EResponseComplete" ); |
|
360 |
|
361 #ifndef __SERIES60_ |
|
362 // if( contenttype == trigger ) |
|
363 if( iHdcPaosPostDone ) |
|
364 { |
|
365 HandleHdcTriggerL(); |
|
366 aTransaction.Cancel( THTTPFilterHandle::ECurrentFilter ); |
|
367 } |
|
368 #endif |
|
369 break; |
|
370 } |
|
371 default: |
|
372 { |
|
373 // We ignore other events. We shouldn't receive other events though. |
|
374 break; |
|
375 } |
|
376 } |
|
377 LOGSTRING( "CPnpPaosFilter::MHFRunL - done" ); |
|
378 } |
|
379 |
|
380 |
|
381 void CPnpPaosFilter::PostPaosResponseL( RHTTPTransaction& aTransaction ) |
|
382 { |
|
383 // For some mysterious reason the http transaction has to be cancelled here (EGotResponseBodyData), |
|
384 // otherwise browser will have the PAOS request concatenated with the resulting |
|
385 // html page (or at least the resulting html page shows an extra text "setOfKeys" |
|
386 // so it seems to concatenate at least part of the PAOS request) |
|
387 |
|
388 // Since transaction is cancelled in EGotResponseBodyData event, there is no |
|
389 // point in listening for EResponseComplete event anymore |
|
390 |
|
391 CPnpPaosXml::TPaosStates status( CPnpPaosXml::EPaosStatusUnknown ); |
|
392 |
|
393 TRAPD( err, iPnpPaosXml->ParseL( status ) ); |
|
394 if( err == KErrNone ) |
|
395 { |
|
396 iMakePaosResponse = EFalse; |
|
397 iTransactionId = -1; |
|
398 LOGSTRING( "PAOS post URL:" ); |
|
399 /* |
|
400 "responseConsumerURL attribute, with a URL as its value.This URL SHOULD be relative to the URL that |
|
401 was requested by the user agent (in the HTTP request that resulted in the creation of the SOAP message). If the |
|
402 URL nevertheless is absolute it MUST have http or https as the protocol and SHOULD have a domain that is |
|
403 owned by the same party as the owner of the domain in the URL of the HTTP request." |
|
404 [Liberty Reverse HTTP binding for SOAP Specification] |
|
405 */ |
|
406 const TDesC8& paosPostUrl = iPnpPaosXml->GetPaosPostUrlL(); |
|
407 if( paosPostUrl.Find( KHttp ) != KErrNotFound || paosPostUrl.Find( KHttps ) != KErrNotFound ) |
|
408 { |
|
409 LOGSTRING( "Absolute URL" ); |
|
410 delete iPaosPostUrl; |
|
411 iPaosPostUrl = 0; |
|
412 TUriParser8 uriParser; |
|
413 User::LeaveIfError( uriParser.Parse( paosPostUrl ) ); |
|
414 iPaosPostUrl = CUri8::NewL( uriParser ); |
|
415 } |
|
416 else |
|
417 { |
|
418 LOGSTRING( "Relative URL" ); |
|
419 iPaosPostUrl->SetComponentL( paosPostUrl, EUriPath ); |
|
420 } |
|
421 LOGTEXT( iPaosPostUrl->Uri().UriDes() ); |
|
422 |
|
423 switch( status ) |
|
424 { |
|
425 case CPnpPaosXml::EPaosStatusUnknown: |
|
426 LOGSTRING( "EPaosStatusUnknown" ); |
|
427 // Do nothing, was: User::Leave( KErrArgument ); |
|
428 break; |
|
429 case CPnpPaosXml::EPaosStatusRequestingPnPKeys: |
|
430 { |
|
431 LOGSTRING( "EPaosStatusRequestingPnPKeys" ); |
|
432 CUri8* uri = CUri8::NewLC( aTransaction.Request().URI() ); |
|
433 HostFromUriL( uri ); |
|
434 // Also remove scheme |
|
435 uri->RemoveComponentL( EUriScheme ); |
|
436 LOGTEXT( uri->Uri().UriDes() ); |
|
437 |
|
438 TPtrC8 host = uri->Uri().UriDes(); |
|
439 // check the domain was an allowed domain of PnP-MS home domain filter |
|
440 if( IsPaosHomeDomainL( host ) ) |
|
441 { |
|
442 PaosPostL( aTransaction ); |
|
443 } |
|
444 CleanupStack::PopAndDestroy( uri ); |
|
445 break; |
|
446 } |
|
447 case CPnpPaosXml::EPaosStatusRequestingHdcKeys: |
|
448 { |
|
449 LOGSTRING( "EPaosStatusRequestingHdcKeys" ); |
|
450 CUri8* uri = CUri8::NewLC( aTransaction.Request().URI() ); |
|
451 HostFromUriL( uri ); |
|
452 TPtrC8 host = uri->Uri().UriDes(); |
|
453 |
|
454 TBool isTrusted( EFalse ); |
|
455 for( TInt i(0); i < iTrustedHdcDomains.Count(); i++ ) |
|
456 { |
|
457 HdcTrustedDomain trustedDomain = iTrustedHdcDomains[i]; |
|
458 if( host.Find( trustedDomain ) != KErrNotFound ) |
|
459 isTrusted = ETrue; |
|
460 } |
|
461 // check the domain was an allowed domain of HDC home domain filter |
|
462 if( isTrusted ) |
|
463 { |
|
464 PaosPostL( aTransaction ); |
|
465 #ifndef __SERIES60_ |
|
466 iHdcPaosPostDone = ETrue; |
|
467 #endif |
|
468 } |
|
469 #ifdef _DEBUG |
|
470 else |
|
471 { |
|
472 LOGSTRING("Not an allowed domain!"); |
|
473 LOGTEXT( host ); |
|
474 LOGSTRING("domains:"); |
|
475 for( TInt j(0); j < iTrustedHdcDomains.Count(); j++ ) |
|
476 { |
|
477 LOGTEXT( iTrustedHdcDomains[j] ); |
|
478 } |
|
479 } |
|
480 #endif |
|
481 CleanupStack::PopAndDestroy( uri ); |
|
482 break; |
|
483 } |
|
484 default: |
|
485 { |
|
486 // We ignore other events. We shouldn't receive other events though. |
|
487 break; |
|
488 } |
|
489 } |
|
490 } |
|
491 else |
|
492 { |
|
493 LOGSTRING2( "Error in ParseL: %i", err ); |
|
494 } |
|
495 |
|
496 LOGSTRING("iPnpPaosXml->ResetPaosRequest()"); |
|
497 iPnpPaosXml->ResetPaosRequest(); |
|
498 } |
|
499 |
|
500 #ifndef __SERIES60_ |
|
501 void CPnpPaosFilter::HandleHdcTriggerL() |
|
502 { |
|
503 LOGSTRING("Create file"); |
|
504 iHdcPaosPostDone = EFalse; |
|
505 |
|
506 _LIT( KTempDocumentName, "C:\\Temp\\trigger.trg" ); |
|
507 |
|
508 RFs rfs; |
|
509 User::LeaveIfError( rfs.Connect() ); |
|
510 CleanupClosePushL( rfs ); |
|
511 TInt err = rfs.MkDir( KTempDocumentName ); |
|
512 // The folder may already exist, do not leave in that case |
|
513 if( err != KErrNone && err != KErrAlreadyExists ) |
|
514 { |
|
515 User::Leave( err ); |
|
516 } |
|
517 |
|
518 RFile file; |
|
519 User::LeaveIfError( file.Replace( rfs, KTempDocumentName, EFileWrite ) ); |
|
520 CleanupClosePushL( file ); |
|
521 LOGSTRING("File created"); |
|
522 // A HDC PAOS post was made and we expect the response to be a HDC trigger file |
|
523 const TPtrC8 hdcTriggerData = iPnpPaosXml->ResponseBodyL(); |
|
524 file.Write( hdcTriggerData ); |
|
525 LOGSTRING("File written"); |
|
526 iPnpPaosXml->ResetPaosRequest(); |
|
527 |
|
528 CleanupStack::PopAndDestroy(); // rfs |
|
529 CleanupStack::PopAndDestroy(); // file |
|
530 |
|
531 LOGSTRING("Starting app"); |
|
532 RApaLsSession appArcSession; |
|
533 User::LeaveIfError( appArcSession.Connect() ); |
|
534 CleanupClosePushL( appArcSession ); |
|
535 |
|
536 CApaCommandLine* cmdLine = CApaCommandLine::NewLC(); |
|
537 TApaAppInfo info; |
|
538 const TUid KHdcUid = { 0x1020433F }; |
|
539 User::LeaveIfError( appArcSession.GetAppInfo( info, KHdcUid ) ); |
|
540 #ifdef RD_APPS_TO_EXES |
|
541 cmdLine->SetExecutableNameL( info.iFullName ); |
|
542 #else |
|
543 cmdLine->SetLibraryNameL( info.iFullName ); |
|
544 #endif |
|
545 cmdLine->SetCommandL( EApaCommandOpen ); |
|
546 cmdLine->SetDocumentNameL( KTempDocumentName ); |
|
547 err = appArcSession.StartApp( *cmdLine ); |
|
548 if( err != KErrNone ) |
|
549 { |
|
550 LOGSTRING2( "StartApp err %i", err ); |
|
551 User::Leave( err ); |
|
552 } |
|
553 LOGSTRING("Cancel transaction"); |
|
554 CleanupStack::PopAndDestroy( cmdLine ); |
|
555 CleanupStack::PopAndDestroy(); // appArcSession |
|
556 LOGSTRING("done"); |
|
557 } |
|
558 #endif |
|
559 |
|
560 |
|
561 TBool CPnpPaosFilter::GetNextDataPart( TPtrC8& aDataPart ) |
|
562 { |
|
563 LOGSTRING("CPnpPaosFilter::GetNextDataPart"); |
|
564 aDataPart.Set( KDummyResponse ); |
|
565 return ETrue; |
|
566 } |
|
567 |
|
568 void CPnpPaosFilter::ReleaseData() |
|
569 { |
|
570 LOGSTRING("CPnpPaosFilter::ReleaseData"); |
|
571 } |
|
572 |
|
573 TInt CPnpPaosFilter::OverallDataSize() |
|
574 { |
|
575 LOGSTRING("CPnpPaosFilter::OverallDataSize"); |
|
576 return KDummyResponse().Length(); |
|
577 } |
|
578 |
|
579 TInt CPnpPaosFilter::Reset() |
|
580 { |
|
581 LOGSTRING("CPnpPaosFilter::Reset"); |
|
582 return KErrNone; |
|
583 } |
|
584 |
|
585 void CPnpPaosFilter::AddPaosHeadersL( RHTTPHeaders& requestHeaders ) |
|
586 { |
|
587 LOGSTRING( "CPnpPaosFilter::AddPaosHeadersL" ); |
|
588 |
|
589 // Add PAOS header |
|
590 THTTPHdrVal paosVer; |
|
591 RStringF paosVerStr = iSessionStringPool.OpenFStringL( KPaosHeader ); |
|
592 CleanupClosePushL( paosVerStr ); |
|
593 paosVer.SetStrF( paosVerStr ); |
|
594 RStringF paosStr = iSessionStringPool.OpenFStringL( KPaosHeaderName ); |
|
595 CleanupClosePushL( paosStr ); |
|
596 requestHeaders.SetFieldL( paosStr, paosVerStr ); |
|
597 CleanupStack::PopAndDestroy(); // paosStr.Close() |
|
598 CleanupStack::PopAndDestroy(); // paosVerStr.Close() |
|
599 |
|
600 // Add PAOS content type to accept header |
|
601 THTTPHdrVal acceptHdr; |
|
602 requestHeaders.GetField( |
|
603 iSessionStringPool.StringF( HTTP::EAccept, RHTTPSession::GetTable() ), 0, acceptHdr ); |
|
604 |
|
605 if (acceptHdr.Type() == 0x04) //Worst case scenario, if transaction does not have accept header. |
|
606 { |
|
607 RStringF valStr = iSessionStringPool.OpenFStringL(_L8("*/*")); |
|
608 THTTPHdrVal val(valStr); |
|
609 requestHeaders.SetFieldL(iSessionStringPool.StringF(HTTP::EAccept, RHTTPSession::GetTable() ), val); |
|
610 valStr.Close(); |
|
611 requestHeaders.GetField( |
|
612 iSessionStringPool.StringF( HTTP::EAccept, RHTTPSession::GetTable() ), 0, acceptHdr ); |
|
613 |
|
614 } |
|
615 |
|
616 |
|
617 RStringF acceptStr = acceptHdr.StrF(); |
|
618 TPtrC8 accept = acceptStr.DesC(); |
|
619 if( accept.Find( KPaosContentType ) == KErrNotFound ) |
|
620 { |
|
621 HBufC8* acceptBuf = HBufC8::NewLC( KPaosContentType().Length() ); |
|
622 TPtr8 acceptBufPtr = acceptBuf->Des(); |
|
623 acceptBufPtr.Append( KPaosContentType ); |
|
624 SetHttpHeaderL( requestHeaders, HTTP::EAccept, *acceptBuf ); |
|
625 |
|
626 #ifdef LOGGING_ENABLED |
|
627 LOGSTRING( "Accept header:" ); |
|
628 for( TInt i(0); i < acceptBufPtr.Length(); i += 128 ) |
|
629 { |
|
630 TPtrC8 logText = acceptBufPtr.Right( acceptBufPtr.Length() - i ); |
|
631 LOGTEXT( logText ); |
|
632 } |
|
633 #endif |
|
634 CleanupStack::PopAndDestroy( acceptBuf ); |
|
635 } |
|
636 #ifdef LOGGING_ENABLED |
|
637 else |
|
638 { |
|
639 LOGSTRING( "Accept header already includes PAOS:" ); |
|
640 for( TInt i(0); i < accept.Length(); i += 128 ) |
|
641 { |
|
642 TPtrC8 logText = accept.Right( accept.Length() - i ); |
|
643 LOGTEXT( logText ); |
|
644 } |
|
645 } |
|
646 #endif |
|
647 |
|
648 LOGSTRING( "CPnpPaosFilter::AddPaosHeadersL - done" ); |
|
649 } |
|
650 |
|
651 TBool CPnpPaosFilter::IsPaosContentTypeL( RHTTPHeaders& aHeaders ) |
|
652 { |
|
653 LOGSTRING( "CPnpPaosFilter::IsPaosContentTypeL" ); |
|
654 |
|
655 // get the Content-Type string |
|
656 RStringF content = iSessionStringPool.StringF( HTTP::EContentType, |
|
657 RHTTPSession::GetTable() ); |
|
658 |
|
659 THTTPHdrVal fieldVal; |
|
660 // now retrieve the Content-Type field |
|
661 if( KErrNone == aHeaders.GetField( content, 0, fieldVal ) ) |
|
662 { |
|
663 TPtrC8 contentType; |
|
664 // get the field value |
|
665 if( THTTPHdrVal::KStrFVal == fieldVal.Type() ) |
|
666 { |
|
667 contentType.Set( fieldVal.StrF().DesC() ); |
|
668 LOGSTRING( "ContentType:" ); |
|
669 LOGTEXT( contentType ); |
|
670 } |
|
671 else if( THTTPHdrVal::KStrVal == fieldVal.Type() ) |
|
672 { |
|
673 contentType.Set( fieldVal.Str().DesC() ); |
|
674 LOGSTRING( "ContentType:" ); |
|
675 LOGTEXT( contentType ); |
|
676 } |
|
677 else |
|
678 { |
|
679 return EFalse; |
|
680 } |
|
681 |
|
682 if( contentType.Compare( KPaosContentType ) == 0 ) |
|
683 { |
|
684 LOGSTRING("Content type matches"); |
|
685 |
|
686 // 3.0 does not handle the resulting html right, it is stored by DL manager. |
|
687 // This means that it does not recognize the incoming text/html data correctly. |
|
688 // So try replacing content type field with text/html, maybe PAOS content type is |
|
689 // cached somewhere even if the transaction has been canceled. |
|
690 LOGSTRING("Resetting Content type to text/html"); |
|
691 aHeaders.RemoveField( iSessionStringPool.StringF( HTTP::EContentType , RHTTPSession::GetTable() ) ); |
|
692 SetHttpHeaderL( aHeaders, HTTP::EContentType, _L8("text/html") ); |
|
693 |
|
694 return ETrue; |
|
695 } |
|
696 } |
|
697 return EFalse; |
|
698 } |
|
699 |
|
700 void CPnpPaosFilter::PaosPostL( RHTTPTransaction& aTransaction ) |
|
701 { |
|
702 LOGSTRING( "CPnpPaosFilter::PaosPostL" ); |
|
703 |
|
704 RHTTPRequest request = aTransaction.Request(); |
|
705 |
|
706 aTransaction.Cancel( THTTPFilterHandle::ECurrentFilter ); |
|
707 RHTTPHeaders requestHeaders = request.GetHeaderCollection(); |
|
708 request.RemoveBody(); |
|
709 // Remove Content-Type header |
|
710 requestHeaders.RemoveField( iSessionStringPool.StringF( HTTP::EContentType, RHTTPSession::GetTable() ) ); |
|
711 // Remove Content-Length header |
|
712 requestHeaders.RemoveField( iSessionStringPool.StringF( HTTP::EContentLength, RHTTPSession::GetTable() ) ); |
|
713 // Remove Host header |
|
714 requestHeaders.RemoveField( iSessionStringPool.StringF( HTTP::EHost, RHTTPSession::GetTable() ) ); |
|
715 |
|
716 // PAOS header |
|
717 THTTPHdrVal paosVer; |
|
718 RStringF paosVerStr = iSessionStringPool.OpenFStringL( KPaosHeader ); |
|
719 CleanupClosePushL( paosVerStr ); |
|
720 paosVer.SetStrF( paosVerStr ); |
|
721 RStringF paosStr = iSessionStringPool.OpenFStringL( KPaosHeaderName ); |
|
722 CleanupClosePushL( paosStr ); |
|
723 requestHeaders.SetFieldL( paosStr, paosVerStr ); |
|
724 CleanupStack::PopAndDestroy(); // paosStr |
|
725 CleanupStack::PopAndDestroy(); // paosVerStr |
|
726 |
|
727 // Content headers |
|
728 SetHttpHeaderL( requestHeaders, HTTP::EContentType, _L8("application/vnd.paos+xml") ); |
|
729 |
|
730 request.SetMethod( iSessionStringPool.StringF( HTTP::EPOST, RHTTPSession::GetTable() ) ); |
|
731 |
|
732 // Set the URI of the request |
|
733 request.SetURIL( iPaosPostUrl->Uri() ); |
|
734 |
|
735 LOGSTRING( "Uri:" ); |
|
736 LOGTEXT( iPaosPostUrl->Uri().UriDes() ); |
|
737 |
|
738 // Provide Response |
|
739 if( !iPnpPaosXml ) |
|
740 { |
|
741 User::Leave( KErrGeneral ); |
|
742 } |
|
743 request.SetBody( *iPnpPaosXml ); |
|
744 |
|
745 aTransaction.Cancel(); |
|
746 aTransaction.SubmitL(); |
|
747 LOGSTRING( "CPnpPaosFilter::PaosPostL - done" ); |
|
748 } |
|
749 |
|
750 void CPnpPaosFilter::SetHttpHeaderL( RHTTPHeaders& aMessage, const HTTP::TStrings aIndex, const TDesC8& aString ) |
|
751 { |
|
752 LOGSTRING( "CPnpPaosFilter::SetHttpHeaderL" ); |
|
753 |
|
754 THTTPHdrVal hdrVal; |
|
755 RStringF str = iSessionStringPool.OpenFStringL( aString ); |
|
756 CleanupClosePushL( str ); |
|
757 hdrVal.SetStrF( str ); |
|
758 aMessage.SetFieldL( iSessionStringPool.StringF( aIndex, RHTTPSession::GetTable() ), hdrVal ); |
|
759 CleanupStack::PopAndDestroy(); |
|
760 |
|
761 LOGSTRING( "CPnpPaosFilter::SetHttpHeaderL - done" ); |
|
762 } |
|
763 |
|
764 TInt CPnpPaosFilter::MHFRunError( TInt aError, |
|
765 RHTTPTransaction aTransaction, |
|
766 const THTTPEvent& aEvent ) |
|
767 { |
|
768 LOGSTRING( "CPnpPaosFilter::MHFRunError()" ); |
|
769 |
|
770 LOGSTRING3( "error: %d, event: %d", aError, aEvent.iStatus ); |
|
771 // If anything left, we've run out of memory or something |
|
772 // similarly catastrophic has gone wrong. |
|
773 // Remove the body to prevent other client from accessing |
|
774 // the contents. |
|
775 aTransaction.Response().RemoveBody(); |
|
776 // Set the transaction to failed |
|
777 aTransaction.Fail(); |
|
778 // Keep compiler happy |
|
779 (void)aError; |
|
780 (void)aEvent; |
|
781 LOGSTRING( "CPnpPaosFilter::MHFRunError() - done" ); |
|
782 return KErrNone; |
|
783 } |
|
784 |
|
785 void CPnpPaosFilter::MHFLoad(RHTTPSession /*aSession*/, |
|
786 THTTPFilterHandle /*aHandle*/) |
|
787 { |
|
788 LOGSTRING("CPnpPaosFilter::MHFLoad"); |
|
789 iLoadCount++; |
|
790 } |
|
791 |
|
792 void CPnpPaosFilter::MHFUnload(RHTTPSession /*aSession*/, |
|
793 THTTPFilterHandle /*aHandle*/) |
|
794 { |
|
795 LOGSTRING("CPnpPaosFilter::MHFUnload"); |
|
796 if( --iLoadCount > 0 ) |
|
797 { |
|
798 LOGSTRING("CPnpPaosFilter::MHFUnload - done"); |
|
799 return; |
|
800 } |
|
801 delete this; // Delete object itself |
|
802 LOGSTRING("CPnpPaosFilter::MHFUnload - done"); |
|
803 } |
|
804 |
|
805 TBool CPnpPaosFilter::IsPaosHomeDomainL( const TPtrC8 aHost ) |
|
806 { |
|
807 LOGSTRING("CPnpPaosFilter::IsPaosHomeDomainL"); |
|
808 // check is the host in trusted domains list |
|
809 for (TInt i=0; i < iTrustedPnpDomains.Count(); i++) |
|
810 { |
|
811 if (aHost.Find(iTrustedPnpDomains[i]) != KErrNotFound ) |
|
812 { |
|
813 return ETrue; |
|
814 } |
|
815 } |
|
816 return EFalse; |
|
817 } |
|