|
1 // HttpClient.cpp |
|
2 |
|
3 |
|
4 #include <e32base.h> |
|
5 #include <http/rhttpheaders.h> |
|
6 #include <http.h> |
|
7 #include <commdb.h> |
|
8 #include <eikenv.h> |
|
9 #include <es_sock.h> |
|
10 #include <bautils.h> |
|
11 #include <CommDbConnPref.h> |
|
12 #include "debug.h" |
|
13 #include "constants.h" |
|
14 #include "HttpClient.h" |
|
15 #include "connectionengine.h" |
|
16 #include "settingsengine.h" |
|
17 |
|
18 const TInt KTempBufferSize = 100; |
|
19 |
|
20 CHttpClient::~CHttpClient() |
|
21 { |
|
22 if (iHandler) |
|
23 { |
|
24 iHandler->CloseSaveFile(); |
|
25 delete iHandler; |
|
26 } |
|
27 |
|
28 iSession.Close(); |
|
29 } |
|
30 |
|
31 CHttpClient* CHttpClient::NewL(CPodcastModel& aPodcastModel, MHttpClientObserver& aObserver) |
|
32 { |
|
33 CHttpClient* me = NewLC(aPodcastModel, aObserver); |
|
34 CleanupStack::Pop(me); |
|
35 return me; |
|
36 } |
|
37 |
|
38 CHttpClient::CHttpClient(CPodcastModel& aPodcastModel, MHttpClientObserver& aObserver) : iPodcastModel(aPodcastModel), iObserver(aObserver) |
|
39 { |
|
40 iResumeEnabled = EFalse; |
|
41 } |
|
42 |
|
43 CHttpClient* CHttpClient::NewLC(CPodcastModel& aPodcastModel, MHttpClientObserver& aObserver) |
|
44 { |
|
45 CHttpClient* me = new (ELeave) CHttpClient(aPodcastModel, aObserver); |
|
46 CleanupStack::PushL(me); |
|
47 me->ConstructL(); |
|
48 return me; |
|
49 } |
|
50 |
|
51 void CHttpClient::ConstructL() |
|
52 { |
|
53 iPodcastModel.ConnectionEngine().AddObserver(this); |
|
54 } |
|
55 |
|
56 void CHttpClient::SetHeaderL(RHTTPHeaders aHeaders, TInt aHdrField, const TDesC8& aHdrValue) |
|
57 { |
|
58 RStringF valStr = iSession.StringPool().OpenFStringL(aHdrValue); |
|
59 THTTPHdrVal val(valStr); |
|
60 aHeaders.SetFieldL(iSession.StringPool().StringF(aHdrField, RHTTPSession::GetTable()), val); |
|
61 valStr.Close(); |
|
62 } |
|
63 |
|
64 TBool CHttpClient::IsActive() |
|
65 { |
|
66 return iIsActive; |
|
67 } |
|
68 |
|
69 void CHttpClient::SetResumeEnabled(TBool aEnabled) |
|
70 { |
|
71 iResumeEnabled = aEnabled; |
|
72 } |
|
73 |
|
74 |
|
75 void CHttpClient::ConnectHttpSessionL() |
|
76 { |
|
77 DP("ConnectHttpSessionL START"); |
|
78 CConnectionEngine::TConnectionState connState = iPodcastModel.ConnectionEngine().ConnectionState(); |
|
79 if(connState == CConnectionEngine::EConnected) |
|
80 { |
|
81 DP("ConnectionState == CConnectionEngine::EConnected"); |
|
82 // Session already connected, call connect complete directly but return status since URLs or so might be faulty |
|
83 ConnectCompleteL(KErrNone); |
|
84 return; |
|
85 } |
|
86 |
|
87 if(connState == CConnectionEngine::ENotConnected) |
|
88 { |
|
89 DP1("SpecificIAP() == %d",iPodcastModel.SettingsEngine().SpecificIAP()); |
|
90 |
|
91 if(iPodcastModel.SettingsEngine().SpecificIAP() == -1) |
|
92 { |
|
93 iPodcastModel.ConnectionEngine().StartL(CConnectionEngine::EUserSelectConnection); |
|
94 } |
|
95 else if ( iPodcastModel.SettingsEngine().SpecificIAP() == 0 ) |
|
96 { |
|
97 iPodcastModel.ConnectionEngine().StartL(CConnectionEngine::EDefaultConnection); |
|
98 } |
|
99 else if( (iPodcastModel.SettingsEngine().SpecificIAP()&KUseIAPFlag)) |
|
100 { |
|
101 iPodcastModel.ConnectionEngine().StartL(CConnectionEngine::EIAPConnection); |
|
102 } |
|
103 else |
|
104 { |
|
105 iPodcastModel.ConnectionEngine().StartL(CConnectionEngine::EMobilityConnection); |
|
106 } |
|
107 } |
|
108 DP("ConnectHttpSessionL END"); |
|
109 } |
|
110 |
|
111 void CHttpClient::ConnectCompleteL(TInt aErrorCode) |
|
112 { |
|
113 if(iWaitingForGet) |
|
114 { |
|
115 iWaitingForGet = EFalse; |
|
116 if( aErrorCode == KErrNone) |
|
117 { |
|
118 RHTTPConnectionInfo connInfo = iSession.ConnectionInfo(); |
|
119 RStringPool pool = iSession.StringPool(); |
|
120 // Attach to socket server |
|
121 connInfo.SetPropertyL(pool.StringF(HTTP::EHttpSocketServ, RHTTPSession::GetTable()), THTTPHdrVal(iPodcastModel.ConnectionEngine().SockServ().Handle())); |
|
122 // Attach to connection |
|
123 TInt connPtr = REINTERPRET_CAST(TInt, &iPodcastModel.ConnectionEngine().Connection()); |
|
124 connInfo.SetPropertyL(pool.StringF(HTTP::EHttpSocketConnection, RHTTPSession::GetTable()), THTTPHdrVal(connPtr)); |
|
125 |
|
126 |
|
127 iPodcastModel.SetProxyUsageIfNeededL(iSession); |
|
128 DoGetAfterConnectL(); |
|
129 } |
|
130 else |
|
131 { |
|
132 ClientRequestCompleteL(KErrCouldNotConnect); |
|
133 iSession.Close(); |
|
134 } |
|
135 } |
|
136 } |
|
137 |
|
138 void CHttpClient::Disconnected() |
|
139 { |
|
140 iIsActive = EFalse; |
|
141 iSession.Close(); |
|
142 } |
|
143 |
|
144 void CHttpClient::DoGetAfterConnectL() |
|
145 { |
|
146 // since nothing should be downloading now. Delete the handler |
|
147 if (iHandler) |
|
148 { |
|
149 delete iHandler; |
|
150 iHandler = NULL; |
|
151 } |
|
152 |
|
153 iHandler = CHttpEventHandler::NewL(this, iObserver, iPodcastModel.FsSession()); |
|
154 iHandler->SetSilent(iSilentGet); |
|
155 |
|
156 TEntry entry; |
|
157 TBuf8<KTempBufferSize> rangeText; |
|
158 |
|
159 if (iResumeEnabled && iPodcastModel.FsSession().Entry(iCurrentFileName, entry) == KErrNone) { |
|
160 DP1("Found file, with size=%d", entry.iSize); |
|
161 // file exists, so we should probably resume |
|
162 rangeText.Format(_L8("bytes=%d-"), entry.iSize-KByteOverlap); |
|
163 iHandler->SetSaveFileName(iCurrentFileName, ETrue); |
|
164 } else { |
|
165 // otherwise just make sure the directory exists |
|
166 BaflUtils::EnsurePathExistsL(iPodcastModel.FsSession(),iCurrentFileName); |
|
167 iHandler->SetSaveFileName(iCurrentFileName); |
|
168 } |
|
169 |
|
170 RStringPool strP = iSession.StringPool(); |
|
171 RStringF method; |
|
172 method = strP.StringF(HTTP::EGET, RHTTPSession::GetTable()); |
|
173 |
|
174 iTrans = iSession.OpenTransactionL(iUriParser, *iHandler, method); |
|
175 RHTTPHeaders hdr = iTrans.Request().GetHeaderCollection(); |
|
176 // Add headers appropriate to all methods |
|
177 SetHeaderL(hdr, HTTP::EUserAgent, KUserAgent); |
|
178 SetHeaderL(hdr, HTTP::EAccept, KAccept); |
|
179 TBuf<KTempBufferSize> range16; |
|
180 range16.Copy(rangeText); |
|
181 DP1("range text: %S", &range16); |
|
182 if (rangeText.Length() > 0) { |
|
183 SetHeaderL(hdr, HTTP::ERange, rangeText); |
|
184 } |
|
185 iTransactionCount++; |
|
186 // submit the transaction |
|
187 iTrans.SubmitL(); |
|
188 iIsActive = ETrue; |
|
189 DP("CHttpClient::Get END"); |
|
190 } |
|
191 |
|
192 TBool CHttpClient::GetL(const TDesC& aUrl, const TDesC& aFileName, TBool aSilent) { |
|
193 DP("CHttpClient::Get START"); |
|
194 DP2("Getting '%S' to '%S'", &aUrl, &aFileName); |
|
195 __ASSERT_DEBUG((iIsActive==EFalse), User::Panic(_L("Already active"), -2)); |
|
196 iCurrentURL.Copy(aUrl); |
|
197 |
|
198 TInt urlError = iUriParser.Parse(iCurrentURL); |
|
199 |
|
200 if(urlError != KErrNone ||!iUriParser.IsSchemeValid()) |
|
201 { |
|
202 iCurrentURL = KNullDesC8; |
|
203 iSession.Close(); |
|
204 iObserver.CompleteL(this, KErrHttpInvalidUri); |
|
205 return EFalse; |
|
206 } |
|
207 |
|
208 iSilentGet = aSilent; |
|
209 iCurrentFileName.Copy(aFileName); |
|
210 iWaitingForGet = ETrue; |
|
211 |
|
212 if (iTransactionCount == 0) |
|
213 { |
|
214 DP("CHttpClient::GetL\t*** Opening HTTP session ***"); |
|
215 iSession.Close(); |
|
216 iSession.OpenL(); |
|
217 ConnectHttpSessionL(); |
|
218 } |
|
219 else |
|
220 { |
|
221 DoGetAfterConnectL(); |
|
222 } |
|
223 return ETrue; |
|
224 } |
|
225 |
|
226 void CHttpClient::Stop() |
|
227 { |
|
228 iIsActive = EFalse; |
|
229 if(iHandler != NULL) |
|
230 { |
|
231 // cancel the ongoing transaction |
|
232 iTrans.Cancel(); |
|
233 iTransactionCount = 0; |
|
234 |
|
235 // make sure that we save the file |
|
236 iHandler->CloseSaveFile(); |
|
237 |
|
238 // we could now delete the handler since a new will be created |
|
239 delete iHandler; |
|
240 iHandler = NULL; |
|
241 |
|
242 // close the session |
|
243 DP("CHttpClient::Stop\t*** Closing HTTP session ***"); |
|
244 iSession.Close(); |
|
245 } |
|
246 |
|
247 TRAP_IGNORE(iObserver.CompleteL(this, KErrDisconnected)); |
|
248 |
|
249 } |
|
250 |
|
251 void CHttpClient::ClientRequestCompleteL(TInt aErrorCode) { |
|
252 iIsActive = EFalse; |
|
253 iObserver.CompleteL(this, aErrorCode); |
|
254 DP("CHttpClient::ClientRequestCompleteL"); |
|
255 if(iTransactionCount>0) |
|
256 { |
|
257 iTransactionCount--; |
|
258 |
|
259 if(iTransactionCount == 0) |
|
260 { |
|
261 DP("CHttpClient::ClientRequestCompleteL\t*** Closing HTTP session ***"); |
|
262 delete iHandler; |
|
263 iHandler = NULL; |
|
264 iSession.Close(); |
|
265 } |
|
266 } |
|
267 } |