|
1 /* |
|
2 ============================================================================ |
|
3 Name : HttpClient.cpp |
|
4 Author : John Kern |
|
5 |
|
6 Copyright (c) 2009 Symbian Foundation Ltd |
|
7 This component and the accompanying materials are made available |
|
8 under the terms of the License "Eclipse Public License v1.0" |
|
9 which accompanies this distribution, and is available |
|
10 at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
11 |
|
12 Initial Contributors: |
|
13 - Symbian Foundation Ltd - initial contribution. |
|
14 |
|
15 Contributors: |
|
16 - John Kern |
|
17 - Symsource |
|
18 |
|
19 Description : Web client |
|
20 ============================================================================ |
|
21 */ |
|
22 |
|
23 #include <activeapdb.h> |
|
24 #include <HttpStringConstants.h> // HTTP |
|
25 |
|
26 #include "HttpClient.h" |
|
27 |
|
28 // HTTP header values |
|
29 _LIT8(KUserAgent, "NPR 1.0"); // Name of the client app. |
|
30 _LIT8(KAccept, "text/*"); // Accept any (but only) text content (errors may not be sent as "text/x-visto-ota-activation"). |
|
31 |
|
32 CHttpClient* CHttpClient::NewL(MHTTPObserver& aObserver) |
|
33 { |
|
34 CHttpClient* self = new (ELeave)CHttpClient(aObserver); |
|
35 CleanupStack::PushL(self); |
|
36 self->ConstructL(); |
|
37 CleanupStack::Pop(); |
|
38 return self; |
|
39 } |
|
40 |
|
41 CHttpClient::CHttpClient(MHTTPObserver& aObserver) |
|
42 :iObserver(aObserver) |
|
43 { |
|
44 } |
|
45 |
|
46 CHttpClient::~CHttpClient() |
|
47 { |
|
48 if (iTransactionActive) |
|
49 { |
|
50 iHttpTransaction.Cancel(); |
|
51 iTransactionActive = EFalse; |
|
52 } |
|
53 |
|
54 iHTTPSession.Close(); |
|
55 iConnection.Close(); |
|
56 iSocketServ.Close(); |
|
57 delete iResponseBuffer; |
|
58 delete iUri; |
|
59 } |
|
60 |
|
61 void CHttpClient::ConstructL() |
|
62 { |
|
63 // Open the Http session |
|
64 iHTTPSession.OpenL(); |
|
65 User::LeaveIfError(iSocketServ.Connect()); |
|
66 User::LeaveIfError(iConnection.Open(iSocketServ)); |
|
67 User::LeaveIfError(iConnection.Start()); |
|
68 } |
|
69 |
|
70 |
|
71 void CHttpClient::SendRequestL(const TDesC& aUri) |
|
72 { |
|
73 if(iUri) |
|
74 { |
|
75 delete iUri; |
|
76 iUri = NULL; |
|
77 } |
|
78 |
|
79 iUri = HBufC8::NewL(aUri.Length()); |
|
80 TPtr8 uriPtr = iUri->Des(); |
|
81 uriPtr.Copy(aUri); |
|
82 |
|
83 TUriParser8 uriParser; |
|
84 User::LeaveIfError(uriParser.Parse(uriPtr)); |
|
85 |
|
86 TBuf8<256> buf; |
|
87 buf.Copy(uriParser.UriDes()); |
|
88 |
|
89 RStringPool strPool = iHTTPSession.StringPool(); |
|
90 iHttpConnInfo = iHTTPSession.ConnectionInfo(); |
|
91 iHttpConnInfo.SetPropertyL(strPool.StringF(HTTP::EHttpSocketServ, RHTTPSession::GetTable() ), THTTPHdrVal(iSocketServ.Handle())); |
|
92 iHttpConnInfo.SetPropertyL(strPool.StringF(HTTP::EHttpSocketConnection, RHTTPSession::GetTable() ),THTTPHdrVal (REINTERPRET_CAST(TInt, &(iConnection)))); |
|
93 |
|
94 if(iTransactionActive) |
|
95 { |
|
96 iHttpTransaction.Cancel(); |
|
97 iHttpTransaction.Close(); |
|
98 iTransactionActive = EFalse; |
|
99 } |
|
100 |
|
101 // Create transaction |
|
102 iHttpTransaction = iHTTPSession.OpenTransactionL( |
|
103 uriParser, |
|
104 *this, |
|
105 iHTTPSession.StringPool().StringF(HTTP::EPOST, RHTTPSession::GetTable())); |
|
106 iTransactionActive = ETrue; |
|
107 |
|
108 |
|
109 // Set transaction headers. |
|
110 RHTTPHeaders headers = iHttpTransaction.Request().GetHeaderCollection(); |
|
111 AddHeaderL(headers, HTTP::EUserAgent, KUserAgent); |
|
112 AddHeaderL(headers, HTTP::EAccept, KAccept); |
|
113 |
|
114 // Delete any previous response. |
|
115 delete iResponseBuffer; |
|
116 iResponseBuffer = NULL; |
|
117 |
|
118 // Set the body. |
|
119 iHttpTransaction.Request().SetBody(*this); |
|
120 |
|
121 // Submit the request |
|
122 iHttpTransaction.SubmitL(); |
|
123 } |
|
124 |
|
125 /** |
|
126 * Add a header to a header set |
|
127 * |
|
128 * @param aHeaders The header set to be modified |
|
129 * @param aHeaderField The name of the header to be added |
|
130 * @param aHeaderValue The value for the header to be added |
|
131 */ |
|
132 void CHttpClient::AddHeaderL(RHTTPHeaders aHeaders, |
|
133 TInt aHeaderField, |
|
134 const TDesC8& aHeaderValue) |
|
135 { |
|
136 RStringPool stringPool = iHTTPSession.StringPool(); // Do not close this session here. |
|
137 RStringF valStr = stringPool.OpenFStringL(aHeaderValue); |
|
138 CleanupClosePushL(valStr); |
|
139 THTTPHdrVal headerVal(valStr); |
|
140 aHeaders.SetFieldL(stringPool.StringF(aHeaderField, RHTTPSession::GetTable()), headerVal); |
|
141 CleanupStack::PopAndDestroy(); // valStr |
|
142 } |
|
143 |
|
144 /** |
|
145 * Add a header to a header set |
|
146 * |
|
147 * @param aHeaders The header set to be modified |
|
148 * @param aHeaderField The name of the header to be added |
|
149 * @param aHeaderValue The value for the header to be added |
|
150 * @param aExtensionValue The extension value for the header |
|
151 */ |
|
152 void CHttpClient::AddHeaderL(RHTTPHeaders aHeaders, |
|
153 TInt aHeaderField, |
|
154 const TDesC8& aHeaderValue, |
|
155 TInt aExtensionField, |
|
156 const TDesC8& aExtensionValue) |
|
157 { |
|
158 RStringPool stringPool = iHTTPSession.StringPool(); // Do not close this session here. |
|
159 RStringF valStr = stringPool.OpenFStringL(aHeaderValue); |
|
160 CleanupClosePushL(valStr); |
|
161 THTTPHdrVal headerVal(valStr); |
|
162 RStringF extensionStr = stringPool.OpenFStringL(aExtensionValue); |
|
163 CleanupClosePushL(extensionStr); |
|
164 THTTPHdrVal extensionVal(extensionStr); |
|
165 aHeaders.SetFieldL( |
|
166 stringPool.StringF(aHeaderField, RHTTPSession::GetTable()), |
|
167 headerVal, |
|
168 stringPool.StringF(aExtensionField, RHTTPSession::GetTable()), |
|
169 extensionVal); |
|
170 CleanupStack::PopAndDestroy(2); // extensionStr, valStr |
|
171 } |
|
172 |
|
173 void CHttpClient::MHFRunL(RHTTPTransaction aTransaction, const THTTPEvent &aEvent) |
|
174 { |
|
175 switch (aEvent.iStatus){ |
|
176 case THTTPEvent::EGotResponseHeaders: |
|
177 { |
|
178 // HTTP response headers have been received. |
|
179 // Pass status information to observer. |
|
180 RHTTPResponse resp = aTransaction.Response(); |
|
181 // Get status code |
|
182 TInt statusCode = resp.StatusCode(); |
|
183 |
|
184 // Get status text |
|
185 RStringF statusStr = resp.StatusText(); |
|
186 HBufC* statusBuf = HBufC::NewLC(statusStr.DesC().Length()); |
|
187 statusBuf->Des().Copy(statusStr.DesC()); |
|
188 |
|
189 // Inform observer |
|
190 iObserver.ResponseStatusL(statusCode, *statusBuf); |
|
191 |
|
192 CleanupStack::PopAndDestroy(statusBuf); |
|
193 break; |
|
194 } |
|
195 case THTTPEvent::EGotResponseBodyData: |
|
196 { |
|
197 // Get text of response body |
|
198 MHTTPDataSupplier* dataSupplier = aTransaction.Response().Body(); |
|
199 TPtrC8 ptr; |
|
200 dataSupplier->GetNextDataPart(ptr); |
|
201 |
|
202 // Append to iResponseBuffer |
|
203 if (!iResponseBuffer) |
|
204 { |
|
205 iResponseBuffer = ptr.AllocL(); |
|
206 } |
|
207 else |
|
208 { |
|
209 iResponseBuffer = iResponseBuffer->ReAllocL(iResponseBuffer->Length() + ptr.Length()); |
|
210 iResponseBuffer->Des().Append(ptr); |
|
211 } |
|
212 |
|
213 // Release the body data |
|
214 dataSupplier->ReleaseData(); |
|
215 break; |
|
216 } |
|
217 case THTTPEvent::EResponseComplete: |
|
218 iObserver.ResponseReceivedL(*iResponseBuffer); |
|
219 break; |
|
220 case THTTPEvent::ESucceeded: |
|
221 case THTTPEvent::EFailed: |
|
222 { |
|
223 aTransaction.Close(); |
|
224 iTransactionActive = EFalse; |
|
225 break; |
|
226 } |
|
227 case THTTPEvent::ERedirectedPermanently: |
|
228 break; |
|
229 case THTTPEvent::ERedirectedTemporarily: |
|
230 break; |
|
231 default: |
|
232 { |
|
233 if (aEvent.iStatus < 0) |
|
234 { |
|
235 aTransaction.Close(); |
|
236 iTransactionActive = EFalse; |
|
237 } |
|
238 break; |
|
239 } |
|
240 } |
|
241 } |
|
242 |
|
243 TInt CHttpClient::MHFRunError(TInt aError, RHTTPTransaction aTransaction, const THTTPEvent& /*aEvent*/) |
|
244 { |
|
245 if(!aError) |
|
246 { |
|
247 aTransaction.Close(); |
|
248 iTransactionActive = EFalse; |
|
249 } |
|
250 return KErrNone; |
|
251 } |
|
252 |
|
253 TBool CHttpClient::GetNextDataPart(TPtrC8& /*aDataPart*/) |
|
254 { |
|
255 // Not implemented for now as assuming that chunked response won't be sent |
|
256 // by the server |
|
257 return ETrue; |
|
258 } |
|
259 |
|
260 void CHttpClient::ReleaseData() |
|
261 { |
|
262 // Not implemented for now as assuming that chunked response won't be sent |
|
263 // by the server |
|
264 } |
|
265 |
|
266 TInt CHttpClient::OverallDataSize() |
|
267 { |
|
268 // Not implemented for now as assuming that chunked response won't be sent |
|
269 // by the server |
|
270 return 0; |
|
271 } |
|
272 |
|
273 TInt CHttpClient::Reset() |
|
274 { |
|
275 // Not implemented for now as assuming that chunked response won't be sent |
|
276 // by the server |
|
277 return KErrNone; |
|
278 } |