|
1 /* |
|
2 * Copyright (c) 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: HTTP class for HTTP::HEAD testing |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 |
|
20 #include <implementationproxy.h> |
|
21 #include <uri8.h> |
|
22 |
|
23 #include "ictshttphandler.h" |
|
24 #include "ictsengine.h" |
|
25 #include "am_debug.h" |
|
26 |
|
27 // CONSTANTS |
|
28 _LIT8( KHeaderName, "X-Nokia-WLAN-Connectivity-Test" ); |
|
29 _LIT8( KHeaderValue, "true" ); |
|
30 _LIT8( KHttpPrefix, "http://" ); |
|
31 |
|
32 const TInt KMovedPermanently = 301; |
|
33 const TInt KFound = 302; |
|
34 const TInt KSeeOther = 303; |
|
35 const TInt KTemporaryRedirect = 307; |
|
36 // ======== MEMBER FUNCTIONS ======== |
|
37 |
|
38 |
|
39 // --------------------------------------------------------------------------- |
|
40 // CIctsHttpHandler::CIctsHttpHandler |
|
41 // C++ default constructor can NOT contain any code, that |
|
42 // might leave. |
|
43 // --------------------------------------------------------------------------- |
|
44 // |
|
45 CIctsHttpHandler::CIctsHttpHandler( CIctsEngine& aOwner, |
|
46 TInt aHttpResponseTime ) : |
|
47 CTimer( EPriorityLow ), iOwner( aOwner ), |
|
48 iHttpResponseTime( aHttpResponseTime ), iAttachDone( EFalse ) |
|
49 { |
|
50 CActiveScheduler::Add( this ); |
|
51 } |
|
52 |
|
53 |
|
54 // --------------------------------------------------------------------------- |
|
55 // CIctsHttpHandler::ConstructL |
|
56 // --------------------------------------------------------------------------- |
|
57 // |
|
58 void CIctsHttpHandler::ConstructL() |
|
59 { |
|
60 DEBUG("CIctsHttpHandler::ConstructL()"); |
|
61 // Open channel to Socket Server |
|
62 User::LeaveIfError( iSocketServ.Connect() ); |
|
63 // Open connection |
|
64 User::LeaveIfError( iConnection.Open(iSocketServ) ); |
|
65 |
|
66 CTimer::ConstructL(); |
|
67 |
|
68 } |
|
69 |
|
70 |
|
71 // --------------------------------------------------------------------------- |
|
72 // CIctsHttpHandler::NewL |
|
73 // --------------------------------------------------------------------------- |
|
74 // |
|
75 CIctsHttpHandler* CIctsHttpHandler::NewL( CIctsEngine& aOwner, |
|
76 TInt aHttpResponseTime ) |
|
77 { |
|
78 DEBUG("CIctsHttpHandler::NewL()"); |
|
79 CIctsHttpHandler* self = new( ELeave ) CIctsHttpHandler( aOwner, aHttpResponseTime ); |
|
80 CleanupStack::PushL( self ); |
|
81 self->ConstructL(); |
|
82 CleanupStack::Pop( self ); |
|
83 return self; |
|
84 } |
|
85 |
|
86 // --------------------------------------------------------------------------- |
|
87 // CIctsHttpHandler::~CIctsHttpHandler |
|
88 // --------------------------------------------------------------------------- |
|
89 // |
|
90 CIctsHttpHandler::~CIctsHttpHandler() |
|
91 { |
|
92 DEBUG("CIctsHttpHandler::~CIctsHttpHandler()"); |
|
93 iHttpSession.Close(); |
|
94 CTimer::Cancel(); |
|
95 iConnection.Close(); |
|
96 iSocketServ.Close(); |
|
97 DEBUG("CIctsHttpHandler::~CIctsHttpHandler() Done"); |
|
98 } |
|
99 |
|
100 |
|
101 // --------------------------------------------------------------------------- |
|
102 // CIctsHttpHandler::SetHttpConnectionInfoL |
|
103 // --------------------------------------------------------------------------- |
|
104 // |
|
105 void CIctsHttpHandler::SetHttpConnectionInfoL( RConnection& aConnection, |
|
106 RSocketServ& aSocketServ) |
|
107 { |
|
108 DEBUG("CIctsHttpHandler::SetHttpConnectionInfoL"); |
|
109 TInt result; |
|
110 TBuf<16> serviceType; |
|
111 TUint32 serviceId; |
|
112 TBuf<100> query; |
|
113 TUint connCount; |
|
114 |
|
115 iHttpSession.Close(); |
|
116 iHttpSession.OpenL(); |
|
117 |
|
118 RStringPool strPool = iHttpSession.StringPool(); |
|
119 |
|
120 // Remove first session properties just in case. |
|
121 RHTTPConnectionInfo connInfo = iHttpSession.ConnectionInfo(); |
|
122 |
|
123 // Clear RConnection and Socket Server instances |
|
124 connInfo.RemoveProperty(strPool.StringF(HTTP::EHttpSocketServ,RHTTPSession::GetTable())); |
|
125 connInfo.RemoveProperty(strPool.StringF(HTTP::EHttpSocketConnection,RHTTPSession::GetTable())); |
|
126 |
|
127 // Clear the proxy settings |
|
128 THTTPHdrVal proxyUsage(strPool.StringF(HTTP::EUseProxy,RHTTPSession::GetTable())); |
|
129 connInfo.RemoveProperty(strPool.StringF(HTTP::EProxyUsage,RHTTPSession::GetTable())); |
|
130 connInfo.RemoveProperty(strPool.StringF(HTTP::EProxyAddress,RHTTPSession::GetTable())); |
|
131 |
|
132 // RConnection has been started, set proxy (if defined) and RConnection and |
|
133 // Socket Server session properties. |
|
134 |
|
135 // Proxy |
|
136 result = aConnection.EnumerateConnections(connCount); |
|
137 User::LeaveIfError(result); |
|
138 |
|
139 // Get service and service type for this connection |
|
140 // |
|
141 _LIT(string, "%s\\%s"); |
|
142 query.Format(string, IAP, IAP_SERVICE); |
|
143 result = aConnection.GetIntSetting(query, serviceId); |
|
144 |
|
145 query.Format(string, IAP, IAP_SERVICE_TYPE); |
|
146 result = aConnection.GetDesSetting(query, serviceType); |
|
147 User::LeaveIfError(result); |
|
148 |
|
149 |
|
150 // RConnection and Socket Server |
|
151 // Now bind the HTTP session with the socket server connection |
|
152 connInfo.SetPropertyL ( |
|
153 strPool.StringF(HTTP::EHttpSocketServ, RHTTPSession::GetTable()), |
|
154 THTTPHdrVal (aSocketServ.Handle()) ); |
|
155 |
|
156 TInt connPtr1 = reinterpret_cast<TInt>(&aConnection); |
|
157 connInfo.SetPropertyL ( |
|
158 strPool.StringF(HTTP::EHttpSocketConnection, |
|
159 RHTTPSession::GetTable() ), THTTPHdrVal (connPtr1) ); |
|
160 |
|
161 } |
|
162 |
|
163 // --------------------------------------------------------------------------- |
|
164 // CIctsHttpHandler::SendHttpRequestL |
|
165 // --------------------------------------------------------------------------- |
|
166 // |
|
167 TInt CIctsHttpHandler::SendHttpRequestL( TDesC8& aIPAddress, |
|
168 TUint32 aIapID, |
|
169 TUint32 aNetworkId ) |
|
170 { |
|
171 |
|
172 DEBUG("CIctsHttpHandler::SendHttpRequestL"); |
|
173 |
|
174 // Cancel possibly outstanding request for polling reasons. |
|
175 CTimer::Cancel(); |
|
176 |
|
177 TConnectionInfo info; |
|
178 TPckg< TConnectionInfo > pckgInfo( info ); |
|
179 info.iIapId = aIapID; |
|
180 info.iNetId = aNetworkId; |
|
181 |
|
182 TInt err( KErrNone ); |
|
183 |
|
184 if ( !iAttachDone ) |
|
185 { |
|
186 err = iConnection.Attach( pckgInfo, RConnection::EAttachTypeMonitor); |
|
187 DEBUG1("CIctsHttpHandler::SendHttpRequestL attach: %d", err); |
|
188 } |
|
189 |
|
190 if ( KErrNone == err ) |
|
191 { |
|
192 iAttachDone = ETrue; |
|
193 SetHttpConnectionInfoL( iConnection, iSocketServ ); |
|
194 |
|
195 // Remove redirect filter |
|
196 RStringPool stringPool = iHttpSession.StringPool(); |
|
197 RStringF filterName = stringPool.StringF(HTTP::ERedirect, RHTTPSession::GetTable()); |
|
198 iHttpSession.FilterCollection().RemoveFilter(filterName); |
|
199 |
|
200 RStringPool strPool = iHttpSession.StringPool(); |
|
201 RStringF method = strPool.StringF(HTTP::EHEAD,RHTTPSession::GetTable()); |
|
202 |
|
203 TBuf8<KMaxIpLength> ip; |
|
204 |
|
205 TBool httpExists = CheckHttp( aIPAddress ); |
|
206 if ( !httpExists ) |
|
207 { |
|
208 ip.Copy( KHttpPrefix ); |
|
209 } |
|
210 ip.Append( aIPAddress ); |
|
211 |
|
212 // Parse string to URI |
|
213 TUriParser8 uri; |
|
214 uri.Parse(ip); |
|
215 iHttpTransaction = iHttpSession.OpenTransactionL(uri, *this, method); |
|
216 RHTTPHeaders hdr = iHttpTransaction.Request().GetHeaderCollection(); |
|
217 |
|
218 RStringF headerStrName = strPool.OpenFStringL( KHeaderName() ); |
|
219 CleanupClosePushL( headerStrName ); |
|
220 |
|
221 RStringF headerStrValue = strPool.OpenFStringL( KHeaderValue() ); |
|
222 CleanupClosePushL( headerStrValue ); |
|
223 |
|
224 THTTPHdrVal headerValue( headerStrValue ); |
|
225 hdr.SetFieldL( headerStrName, headerValue ); |
|
226 |
|
227 CleanupStack::PopAndDestroy( &headerStrValue ); |
|
228 CleanupStack::PopAndDestroy( &headerStrName ); |
|
229 |
|
230 iHttpTransaction.SubmitL(); |
|
231 DEBUG("CIctsHttpHandler::SendHttpGetL SubmitL() done"); |
|
232 CTimer::After( iHttpResponseTime ); |
|
233 } |
|
234 |
|
235 return err; |
|
236 } |
|
237 |
|
238 // --------------------------------------------------------------------------- |
|
239 // CIctsHttpHandler::CancelHttpRequestL |
|
240 // --------------------------------------------------------------------------- |
|
241 // |
|
242 void CIctsHttpHandler::CancelHttpRequestL() |
|
243 { |
|
244 DEBUG("CIctsHttpHandler::CancelHttpRequestL()"); |
|
245 CTimer::Cancel(); |
|
246 iHttpTransaction.Cancel(); |
|
247 } |
|
248 |
|
249 // --------------------------------------------------------------------------- |
|
250 // CIctsHttpHandler::RunL |
|
251 // --------------------------------------------------------------------------- |
|
252 // |
|
253 void CIctsHttpHandler::RunL() |
|
254 { |
|
255 DEBUG("CIctsHttpHandler::RunL()"); |
|
256 iHttpSession.Close(); |
|
257 iString = KNullDesC; |
|
258 iOwner.HttpEventL( ETimeout, iString ); |
|
259 } |
|
260 |
|
261 |
|
262 // --------------------------------------------------------------------------- |
|
263 // CIctsHttpHandler::MHFRunL |
|
264 // |
|
265 // Inherited from MHTTPTransactionCallback |
|
266 // Called by framework to pass transaction events. |
|
267 // --------------------------------------------------------------------------- |
|
268 // |
|
269 void CIctsHttpHandler::MHFRunL(RHTTPTransaction aTransaction, |
|
270 const THTTPEvent& aEvent) |
|
271 { |
|
272 DEBUG("CIctsHttpHandler::MHFRunL"); |
|
273 |
|
274 switch (aEvent.iStatus) |
|
275 { |
|
276 |
|
277 case THTTPEvent::EGotResponseHeaders: |
|
278 { |
|
279 DEBUG("CIctsHttpHandler::THTTPEvent::EGotResponseHeaders"); |
|
280 } |
|
281 break; |
|
282 |
|
283 case THTTPEvent::EGotResponseBodyData: |
|
284 { |
|
285 DEBUG("CIctsHttpHandler::THTTPEvent::EGotResponseBodyData"); |
|
286 } |
|
287 break; |
|
288 |
|
289 case THTTPEvent::EResponseComplete: |
|
290 { |
|
291 DEBUG("CIctsHttpHandler::THTTPEvent::EResponseComplete"); |
|
292 } |
|
293 break; |
|
294 |
|
295 case THTTPEvent::ESucceeded: |
|
296 { |
|
297 DEBUG("CIctsHttpHandler::THTTPEvent::ESucceeded"); |
|
298 CTimer::Cancel(); |
|
299 // Indicates that transaction succeeded. |
|
300 // Transaction can be closed now. It's not needed anymore. |
|
301 aTransaction.Close(); |
|
302 iHttpSession.Close(); |
|
303 iOwner.HttpEventL( EConnectionOk, iString ); |
|
304 iString = KNullDesC; |
|
305 } |
|
306 break; |
|
307 |
|
308 case THTTPEvent::EFailed: |
|
309 { |
|
310 CTimer::Cancel(); |
|
311 DEBUG("CIctsHttpHandler::THTTPEvent::EFailed"); |
|
312 |
|
313 RHTTPResponse resp = aTransaction.Response(); |
|
314 TInt status = resp.StatusCode(); |
|
315 |
|
316 // Check if redirect was cause of EFailed |
|
317 if( status == KMovedPermanently || status == KFound || |
|
318 status == KSeeOther || status == KTemporaryRedirect ) |
|
319 { |
|
320 |
|
321 // Inform the hotspot server that authentication is needed |
|
322 RHTTPHeaders hdr =aTransaction.Response().GetHeaderCollection(); |
|
323 RStringPool strP = aTransaction.Session().StringPool(); |
|
324 RStringF location = strP.StringF(HTTP::ELocation,RHTTPSession::GetTable()); |
|
325 |
|
326 //parse the headers and look for location header |
|
327 THTTPHdrVal hVal; |
|
328 if(hdr.GetField(location,0,hVal)== KErrNone) |
|
329 { |
|
330 DEBUG("CIctsHttpHandler::THTTPEvent::GetField"); |
|
331 // Location header is present |
|
332 RStringF fieldValStr = strP.StringF(hVal.StrF()); |
|
333 const TDesC8& fieldValDesC = fieldValStr.DesC(); |
|
334 iString.Copy(fieldValDesC); |
|
335 aTransaction.Close(); |
|
336 iHttpSession.Close(); |
|
337 iOwner.HttpEventL( EHttpAuthenticationNeeded, iString ); |
|
338 } |
|
339 else |
|
340 { |
|
341 // No location header. Can't use authentication -> redirect. |
|
342 aTransaction.Close(); |
|
343 iHttpSession.Close(); |
|
344 iOwner.HttpEventL( EConnectionNotOk, iString ); |
|
345 } |
|
346 } |
|
347 else |
|
348 { |
|
349 // Failed for other reason than redirect |
|
350 aTransaction.Close(); |
|
351 iHttpSession.Close(); |
|
352 iOwner.HttpEventL( EConnectionNotOk, iString ); |
|
353 } |
|
354 |
|
355 iString = KNullDesC; |
|
356 } |
|
357 break; |
|
358 |
|
359 case THTTPEvent::ERedirectedPermanently: |
|
360 { |
|
361 // Nothing here |
|
362 DEBUG("CIctsHttpHandler::THTTPEvent::ERedirectedPermanently"); |
|
363 } |
|
364 break; |
|
365 |
|
366 case THTTPEvent::ERedirectedTemporarily: |
|
367 { |
|
368 // Nothing here |
|
369 DEBUG("CIctsHttpHandler::THTTPEvent::ERedirectedTemporarily"); |
|
370 } |
|
371 break; |
|
372 |
|
373 default: |
|
374 { |
|
375 DEBUG1( "CIctsHttpHandler::MHFRunL::default iStatus: %d", aEvent.iStatus ); |
|
376 CTimer::Cancel(); |
|
377 aTransaction.Close(); |
|
378 iHttpSession.Close(); |
|
379 // close the transaction if it's an error |
|
380 if ( aEvent.iStatus < 0 ) |
|
381 { |
|
382 _LIT(string, "Unknown error"); |
|
383 iString = string; |
|
384 iOwner.HttpEventL( EConnectionNotOk, iString ); |
|
385 } |
|
386 else |
|
387 { |
|
388 _LIT(string, "Default"); |
|
389 iString = string; |
|
390 iOwner.HttpEventL( EConnectionNotOk, iString ); |
|
391 } |
|
392 } |
|
393 break; |
|
394 } |
|
395 } |
|
396 |
|
397 // --------------------------------------------------------------------------- |
|
398 // CIctsHttpHandler::MHFRunError |
|
399 // |
|
400 // Inherited from MHTTPTransactionCallback |
|
401 // Called by framework to pass transaction error. |
|
402 // --------------------------------------------------------------------------- |
|
403 // |
|
404 TInt CIctsHttpHandler::MHFRunError( TInt /*aError*/, |
|
405 RHTTPTransaction /*aTransaction*/, |
|
406 const THTTPEvent& /*aEvent*/) |
|
407 { |
|
408 DEBUG("CIctsHttpHandler::MHFRunError"); |
|
409 return KErrNone; |
|
410 } |
|
411 |
|
412 // ---------------------------------------------------------------------------- |
|
413 // CIctsHttpHandler::CheckHttp |
|
414 // ---------------------------------------------------------------------------- |
|
415 TBool CIctsHttpHandler::CheckHttp( TDesC8& aIPAddress ) |
|
416 { |
|
417 // The "http://" prefix is expected to be at the beginning of the URI. |
|
418 return ( 0 == aIPAddress.Find( KHttpPrefix ) ); |
|
419 } |
|
420 |
|
421 // End of File |