|
1 /* |
|
2 * Copyright (c) 2002-2004 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: Handle WebDAV transactions |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 // INCLUDE FILES |
|
20 //#include <HttpStringConstants.h> |
|
21 #include <http/rhttpheaders.h> |
|
22 #include <httperr.h> |
|
23 #include <es_sock.h> |
|
24 |
|
25 #include "rsfwremoteaccess.h" |
|
26 #include "rsfwdavtransaction.h" |
|
27 #include "rsfwdavsession.h" |
|
28 #include "rsfwdavfileinfo.h" |
|
29 #include "mdebug.h" |
|
30 |
|
31 // ============================ MEMBER FUNCTIONS ============================== |
|
32 // Destructor |
|
33 CRsfwDavTransaction::~CRsfwDavTransaction() |
|
34 { |
|
35 DEBUGSTRING(("WebDAV transaction %d in destructor ...", Id())); |
|
36 iHttpTransaction.Close(); |
|
37 iBodyFile.Close(); |
|
38 delete iRequestBodyBuffer; |
|
39 delete iPropFindPath; |
|
40 delete iResponseBuffer; |
|
41 DEBUGSTRING(("... done")); |
|
42 } |
|
43 |
|
44 // ---------------------------------------------------------------------------- |
|
45 // CRsfwDavTransaction:::NewL |
|
46 // Two-phased constructor. |
|
47 // ---------------------------------------------------------------------------- |
|
48 // |
|
49 CRsfwDavTransaction* CRsfwDavTransaction::NewL(CRsfwDavSession* aWebDavSession, |
|
50 TWebDavOp aWebDavOp, |
|
51 const TUriC8& aUri, |
|
52 RStringF aMethod, |
|
53 TUint aTransactionId) |
|
54 { |
|
55 CRsfwDavTransaction* self = new (ELeave) CRsfwDavTransaction; |
|
56 CleanupStack::PushL(self); |
|
57 self->ConstructL(aWebDavSession, |
|
58 aWebDavOp, |
|
59 aUri, |
|
60 aMethod, |
|
61 aTransactionId); |
|
62 CleanupStack::Pop(self); |
|
63 return self; |
|
64 } |
|
65 |
|
66 // ---------------------------------------------------------------------------- |
|
67 // CRsfwDavTransaction::ConstructL |
|
68 // Symbian 2nd phase constructor can leave. |
|
69 // ---------------------------------------------------------------------------- |
|
70 // |
|
71 void CRsfwDavTransaction::ConstructL(CRsfwDavSession* aWebDavSession, |
|
72 TWebDavOp aWebDavOp, |
|
73 const TUriC8& aUri, |
|
74 RStringF aMethod, |
|
75 TInt aTransactionId) |
|
76 { |
|
77 iWebDavSession = aWebDavSession; |
|
78 iTransactionId = aTransactionId; |
|
79 // Borrow the file server from the parent |
|
80 iFs = iWebDavSession->FileServerSession(); |
|
81 iWebDavOp = aWebDavOp; |
|
82 // User may cancel the IAP selection |
|
83 iStatus = KErrCancel; |
|
84 iHttpTransaction = iWebDavSession->HttpSession().OpenTransactionL(aUri, |
|
85 *this, |
|
86 aMethod); |
|
87 // Set body supplier as me |
|
88 switch (aWebDavOp) |
|
89 { |
|
90 case EWebDavOpPut: |
|
91 case EWebDavOpPropFindSingle: |
|
92 case EWebDavOpPropFindMulti: |
|
93 case EWebDavOpLock: |
|
94 iHttpTransaction.Request().SetBody(*this); |
|
95 break; |
|
96 |
|
97 default: |
|
98 break; |
|
99 } |
|
100 } |
|
101 |
|
102 // ---------------------------------------------------------------------------- |
|
103 // CRsfwDavTransaction::SetBodyDataL |
|
104 // ---------------------------------------------------------------------------- |
|
105 // |
|
106 void CRsfwDavTransaction::SetBodyData(HBufC8* aRequestBodyBuffer) |
|
107 { |
|
108 iRequestBodyBuffer = aRequestBodyBuffer; |
|
109 } |
|
110 |
|
111 // ---------------------------------------------------------------------------- |
|
112 // CRsfwDavTransaction::SetBodyFileL |
|
113 // ---------------------------------------------------------------------------- |
|
114 // |
|
115 void CRsfwDavTransaction::SetBodyFileL(const TDesC& aPath, |
|
116 TInt aOffset, |
|
117 TInt* aLength, |
|
118 TUint aFlags) |
|
119 { |
|
120 iBodyFilePath = aPath; |
|
121 iBodyFileOffset = aOffset; |
|
122 iBodyFileFlags = aFlags; |
|
123 |
|
124 iParsedBodyFilePath.Set(iBodyFilePath, NULL, NULL); |
|
125 DEBUGBUFFER((iParsedBodyFilePath.FullName())); |
|
126 if (iWebDavOp == EWebDavOpPut) |
|
127 { |
|
128 if (iBodyFilePath.Length()) |
|
129 { |
|
130 |
|
131 // Check it exists and open a file handle |
|
132 if (!iFs.IsValidName(iBodyFilePath)) |
|
133 { |
|
134 User::Leave(KErrPathNotFound); |
|
135 } |
|
136 TInt err = iBodyFile.Open(iFs, |
|
137 iParsedBodyFilePath.FullName(), |
|
138 EFileRead | EFileShareAny); |
|
139 if (err != KErrNone) |
|
140 { |
|
141 DEBUGSTRING(("Cannot set body file (err=%d)", err)); |
|
142 User::Leave(err); |
|
143 } |
|
144 if ((*aLength) > 0) // partial PUT |
|
145 { |
|
146 iOverallDataSize = *aLength; |
|
147 } |
|
148 else |
|
149 { |
|
150 User::LeaveIfError(iBodyFile.Size(iOverallDataSize)); |
|
151 iOverallDataSize -= iBodyFileOffset; |
|
152 } |
|
153 iRequestBodyBuffer = HBufC8::NewL(KDefaultSubmitSize); |
|
154 } |
|
155 } |
|
156 else |
|
157 { |
|
158 // EWebDavOpGet |
|
159 iClientsLength = aLength; |
|
160 if (iClientsLength) |
|
161 { |
|
162 *iClientsLength = 0; |
|
163 } |
|
164 // store pointer to client's length variable and set it to zero |
|
165 // we will later reset it based on the content-length header |
|
166 |
|
167 if (!iFs.IsValidName(iBodyFilePath)) |
|
168 { |
|
169 User::Leave(KErrPathNotFound); |
|
170 } |
|
171 } |
|
172 } |
|
173 |
|
174 // ---------------------------------------------------------------------------- |
|
175 // CRsfwDavTransaction::SetDavFileInfoL |
|
176 // ---------------------------------------------------------------------------- |
|
177 // |
|
178 void CRsfwDavTransaction::SetDavFileInfoL(CRsfwDavFileInfo** aDavFileInfo, |
|
179 const TDesC& aPath) |
|
180 { |
|
181 if (aDavFileInfo) |
|
182 { |
|
183 iDavFileInfo = CRsfwDavFileInfo::NewL(); |
|
184 iDavFileInfo->SetNameL(aPath); |
|
185 *aDavFileInfo = iDavFileInfo; |
|
186 } |
|
187 } |
|
188 |
|
189 // ---------------------------------------------------------------------------- |
|
190 // CRsfwDavTransaction::SetPropFindDirEntryArray |
|
191 // ---------------------------------------------------------------------------- |
|
192 // |
|
193 void CRsfwDavTransaction::SetPropFindDirEntryArray( |
|
194 RPointerArray<CRsfwDirEnt>& aDirEnts) |
|
195 { |
|
196 // We do not get the ownership |
|
197 iDirEnts = &aDirEnts; |
|
198 } |
|
199 |
|
200 // ---------------------------------------------------------------------------- |
|
201 // CRsfwDavTransaction::SetPropfindPath |
|
202 // ---------------------------------------------------------------------------- |
|
203 void CRsfwDavTransaction::SetPropFindPath(HBufC* aPropFindPath) |
|
204 { |
|
205 // We get the ownership |
|
206 iPropFindPath = aPropFindPath; |
|
207 } |
|
208 |
|
209 // ---------------------------------------------------------------------------- |
|
210 // CRsfwDavTransaction::Submit |
|
211 // ---------------------------------------------------------------------------- |
|
212 // |
|
213 void CRsfwDavTransaction::SubmitL() |
|
214 { |
|
215 DEBUGSTRING(("submitting WebDav operation %d, id=%d ...", |
|
216 iWebDavOp, |
|
217 Id())); |
|
218 TRAPD(err, iHttpTransaction.SubmitL()); |
|
219 if (err != KErrNone) |
|
220 { |
|
221 DEBUGSTRING(("WebDav transaction %d left with err %d!", |
|
222 Id(), |
|
223 err)); |
|
224 // Release resources |
|
225 Cleanup(); |
|
226 User::Leave(err); |
|
227 } |
|
228 } |
|
229 |
|
230 // ---------------------------------------------------------------------------- |
|
231 // CRsfwDavTransaction::Cancel |
|
232 // ---------------------------------------------------------------------------- |
|
233 // |
|
234 void CRsfwDavTransaction::Cancel() |
|
235 { |
|
236 DEBUGSTRING(("Canceling WebDav transaction %d ...", Id())); |
|
237 iHttpTransaction.Cancel(); |
|
238 // Cancel XML parsing, if ongoing |
|
239 iWebDavSession->CancelParsing(iWebDavOp); |
|
240 |
|
241 // We don't receive any callback from the HTTP stack, |
|
242 // as we have not registered a filter to get ECancel event, |
|
243 // so we have to initiate the cleanup process ourselves... |
|
244 iStatus = KErrCancel; |
|
245 TransactionError(); |
|
246 } |
|
247 |
|
248 // ------------------------------------------------------------------ |
|
249 // From MHTTPTransactionCallback |
|
250 // ------------------------------------------------------------------ |
|
251 |
|
252 // ---------------------------------------------------------------------------- |
|
253 // CRsfwDavTransaction::MHFRunL |
|
254 // Called when an action takes place on the transaction. |
|
255 // ---------------------------------------------------------------------------- |
|
256 // |
|
257 void CRsfwDavTransaction::MHFRunL(RHTTPTransaction aTransaction, |
|
258 const THTTPEvent& aEvent) |
|
259 { |
|
260 DEBUGSTRING(("MHFRunL() transaction %d (http id = %d) status: %d", |
|
261 iTransactionId, |
|
262 aTransaction.Id(), |
|
263 aEvent.iStatus)); |
|
264 |
|
265 TBool done = EFalse; |
|
266 TBool ok = EFalse; |
|
267 switch (aEvent.iStatus) |
|
268 { |
|
269 case THTTPEvent::EGotResponseHeaders: // process the headers |
|
270 { |
|
271 // HTTP response headers have been received. |
|
272 // We can determine now if there is |
|
273 // going to be a response body to save. |
|
274 RHTTPResponse response = aTransaction.Response(); |
|
275 iStatus = response.StatusCode(); |
|
276 DEBUGSTRING(("MHFRunL() THTTPEvent::EGotResponseHeaders, status %d", |
|
277 iStatus)); |
|
278 |
|
279 if (iWebDavOp == EWebDavOpOptions) |
|
280 { |
|
281 // Get a pointer to the session owned by WebDavSession |
|
282 RHTTPSession session = aTransaction.Session(); |
|
283 RHTTPHeaders hdr = response.GetHeaderCollection(); |
|
284 |
|
285 // Get DAV:- header, |
|
286 // which should be DAV: 1 if WebDAV v. 1 supported |
|
287 // or DAV: 1, 2 if also WebDAV v. 2 is supported |
|
288 TBuf8<KMaxDavVersionValue> davBuffer; |
|
289 _LIT8(KDav, "DAV"); |
|
290 davBuffer.Append(KDav); |
|
291 RStringF davString = |
|
292 session.StringPool().OpenFStringL(davBuffer); |
|
293 THTTPHdrVal val; |
|
294 TInt r = hdr.GetField(davString, 0, val); |
|
295 davString.Close(); |
|
296 |
|
297 if (r == KErrNone) |
|
298 { |
|
299 RStringF valStr; |
|
300 valStr = val.StrF(); |
|
301 TPtrC8 davTag = valStr.DesC(); |
|
302 DEBUGSTRING8(("DAV: DAV=%S", &davTag)); |
|
303 TLex8 lex(davTag); |
|
304 // Skip over non-numeric chars as long as the list continues... |
|
305 TChar theChar; |
|
306 TInt supportedLevel = -1; |
|
307 while (lex.Peek()) |
|
308 { |
|
309 theChar = lex.Get(); |
|
310 if (theChar.IsDigit()) |
|
311 { |
|
312 supportedLevel = theChar.GetNumericValue(); |
|
313 } |
|
314 } |
|
315 if (supportedLevel == -1) |
|
316 { |
|
317 // DAV not supported... |
|
318 User::Leave(KErrNotSupported); |
|
319 } |
|
320 iWebDavSession->SetWebDavSupportClass(supportedLevel); |
|
321 } |
|
322 else |
|
323 { |
|
324 DEBUGSTRING(("DAV=<empty>")); |
|
325 if (iStatus == HTTPStatus::EUnauthorized) |
|
326 { |
|
327 User::Leave(KErrAccessDenied); |
|
328 } |
|
329 else |
|
330 { |
|
331 if (iStatus == HTTPStatus::EOk) |
|
332 { |
|
333 // everything seemed to be ok, |
|
334 // but no DAV: header |
|
335 User::Leave(KErrNotSupported); |
|
336 } |
|
337 else |
|
338 { |
|
339 User::Leave(iStatus); |
|
340 } |
|
341 } |
|
342 } |
|
343 } |
|
344 // Get the content length and create iResponseBuffer, |
|
345 // where the body will be stored. |
|
346 // However, if we are copying file from the server, |
|
347 // the body (file) will just be stored into |
|
348 // the container file, no memory buffer is needed |
|
349 if (response.HasBody() && |
|
350 // iStatus must be in 'Successful' range of HTTP codes 2xx |
|
351 (iStatus >= 200) && |
|
352 (iStatus < 300) && |
|
353 (iStatus != HTTPStatus::ENoContent)) |
|
354 { |
|
355 DEBUGSTRING(("MHFRunL() response has a body...")); |
|
356 MHTTPDataSupplier* responseBody = response.Body(); |
|
357 switch (iWebDavOp) |
|
358 { |
|
359 case EWebDavOpGet: |
|
360 { |
|
361 // Prepare to dump the body to container file |
|
362 TInt err; |
|
363 if (iStatus == HTTPStatus::EPartialContent) |
|
364 { |
|
365 err = iBodyFile.Open(iFs, |
|
366 iParsedBodyFilePath.FullName(), |
|
367 EFileWrite | EFileShareAny); |
|
368 if (err == KErrNone) |
|
369 { |
|
370 if (!(iBodyFileFlags & |
|
371 KRemoteAccessOptionGetToStartOfFile)) |
|
372 { |
|
373 TInt pos = iBodyFileOffset; |
|
374 DEBUGSTRING(("Get: partial content received, seek to %d", pos)); |
|
375 iBodyFile.Seek(ESeekStart, pos); |
|
376 if (pos != iBodyFileOffset) |
|
377 { |
|
378 // Should never happen |
|
379 DEBUGSTRING(("Get: seek to %d failed (pos=%d)", |
|
380 iBodyFileOffset, |
|
381 pos)); |
|
382 User::Leave(KErrArgument); |
|
383 } |
|
384 } |
|
385 } |
|
386 else |
|
387 { |
|
388 DEBUGSTRING(("Get: partial content received, will overwrite the cache file, err=%d", err)); |
|
389 User::LeaveIfError( |
|
390 iBodyFile.Replace( |
|
391 iFs, |
|
392 iParsedBodyFilePath.FullName(), |
|
393 EFileWrite | EFileShareAny)); |
|
394 } |
|
395 } |
|
396 else // overwrite... |
|
397 { |
|
398 DEBUGSTRING(("Get: full content received")); |
|
399 User::LeaveIfError( |
|
400 iBodyFile.Replace( |
|
401 iFs, |
|
402 iParsedBodyFilePath.FullName(), |
|
403 EFileStream | EFileWrite | EFileShareAny)); |
|
404 } |
|
405 |
|
406 // larger memory buffer |
|
407 TInt dataSize = responseBody->OverallDataSize(); |
|
408 DEBUGSTRING(("MHFRunL() creating a response buffer, size=%d", |
|
409 dataSize)); |
|
410 if (dataSize <= KDefaultFileBufferSize) // 40k |
|
411 { |
|
412 iResponseBuffer = HBufC8::NewL(dataSize); |
|
413 } |
|
414 else |
|
415 { |
|
416 iResponseBuffer = HBufC8::NewL(KDefaultFileBufferSize); |
|
417 } |
|
418 |
|
419 } |
|
420 break; |
|
421 |
|
422 case EWebDavOpPropFindSingle: |
|
423 case EWebDavOpPropFindMulti: |
|
424 case EWebDavOpLock: |
|
425 case EWebDavOpRefreshLock: |
|
426 { |
|
427 if (iWebDavOp == EWebDavOpPropFindMulti) |
|
428 { |
|
429 PropFindResponseBeginL(KDavResourceTypeCollection); |
|
430 } |
|
431 else if (iWebDavOp == EWebDavOpPropFindSingle) |
|
432 { |
|
433 PropFindResponseBeginL(KDavResourceTypeOther); |
|
434 } |
|
435 else |
|
436 { |
|
437 LockQueryResponseBegin(); |
|
438 } |
|
439 } |
|
440 break; |
|
441 |
|
442 default: |
|
443 { |
|
444 // We are not interested in any body |
|
445 iDiscardBody = ETrue; |
|
446 } |
|
447 break; |
|
448 } |
|
449 } |
|
450 else |
|
451 { |
|
452 DEBUGSTRING(("MHFRunL() response does not have a body...")); |
|
453 iDiscardBody = ETrue; |
|
454 } |
|
455 } |
|
456 break; |
|
457 |
|
458 case THTTPEvent::EGotResponseBodyData: |
|
459 { |
|
460 DEBUGSTRING(("MHFRunL() THTTPEvent::EGotResponseBodyData")); |
|
461 // Get the body data supplier |
|
462 TBool allDone; |
|
463 |
|
464 MHTTPDataSupplier* responseBody = aTransaction.Response().Body(); |
|
465 ASSERT(responseBody); |
|
466 |
|
467 // Some (more) body data has been received (in the HTTP response) |
|
468 TPtrC8 bodyData; |
|
469 allDone = responseBody->GetNextDataPart(bodyData); |
|
470 DEBUGSTRING(("MHFRunL() body size = %d (all=%d)", |
|
471 bodyData.Length(), |
|
472 allDone)); |
|
473 |
|
474 if (!iDiscardBody) |
|
475 { |
|
476 switch (iWebDavOp) |
|
477 { |
|
478 case EWebDavOpPropFindSingle: |
|
479 case EWebDavOpPropFindMulti: |
|
480 { |
|
481 ParsePropFindResponseL(bodyData); |
|
482 if (allDone) |
|
483 { |
|
484 PropFindResponseEndL(); |
|
485 } |
|
486 } |
|
487 break; |
|
488 case EWebDavOpLock: |
|
489 case EWebDavOpRefreshLock: |
|
490 { |
|
491 ParseLockResponseL(bodyData); |
|
492 if (allDone) |
|
493 { |
|
494 LockResponseEndL(); |
|
495 } |
|
496 } |
|
497 break; |
|
498 case EWebDavOpGet: |
|
499 { |
|
500 // set client's length variable |
|
501 // based on the amount of data fetched |
|
502 if (iClientsLength) |
|
503 { |
|
504 *iClientsLength += bodyData.Length(); |
|
505 } |
|
506 |
|
507 TPtr8 responseBodyPtr = iResponseBuffer->Des(); |
|
508 if ((responseBodyPtr.Length() + bodyData.Length()) <= |
|
509 KDefaultFileBufferSize) |
|
510 { |
|
511 responseBodyPtr.Append(bodyData); |
|
512 } |
|
513 else |
|
514 { |
|
515 DEBUGSTRING(("Get: writing to cache file: %d bytes", |
|
516 responseBodyPtr.Length())); |
|
517 User::LeaveIfError(iBodyFile.Write(responseBodyPtr)); |
|
518 // Reset buffer with new data |
|
519 responseBodyPtr.Copy(bodyData); |
|
520 } |
|
521 |
|
522 if (allDone) // this was the last chunk |
|
523 { |
|
524 DEBUGSTRING(("Get: writing to cache file %d bytes and closing", |
|
525 responseBodyPtr.Length())); |
|
526 User::LeaveIfError(iBodyFile.Write(responseBodyPtr)); |
|
527 iBodyFile.Close(); |
|
528 } |
|
529 } |
|
530 break; |
|
531 |
|
532 default: |
|
533 break; |
|
534 } |
|
535 } |
|
536 |
|
537 // Done with that bit of body data |
|
538 responseBody->ReleaseData(); |
|
539 } |
|
540 break; |
|
541 |
|
542 case THTTPEvent::EResponseComplete: |
|
543 { |
|
544 // The transaction's response is complete |
|
545 DEBUGSTRING(("Transaction Complete")); |
|
546 } |
|
547 break; |
|
548 |
|
549 case THTTPEvent::ESucceeded: |
|
550 { |
|
551 DEBUGSTRING(("Transaction Successful")); |
|
552 // We need to process the iStatus for the different cases |
|
553 switch (iWebDavOp) |
|
554 { |
|
555 case EWebDavOpPropFindMulti: |
|
556 case EWebDavOpPropFindSingle: |
|
557 if (iStatus == RsfwDavStatus::EMultiStatus) |
|
558 { |
|
559 iStatus = KErrNone; |
|
560 ok = ETrue; |
|
561 } |
|
562 break; |
|
563 // Other states which need processing of reponses |
|
564 case EWebDavOpDelete: |
|
565 { |
|
566 // DELETE contains the status of the response in a XML document |
|
567 // STATUS tag which should be parsed to produce an error |
|
568 // condition for this working is that we get back a |
|
569 // status from the server of 204: No Content |
|
570 if ((iStatus == HTTPStatus::ENoContent || |
|
571 iStatus == HTTPStatus::EOk)) |
|
572 { |
|
573 ok = ETrue; |
|
574 } |
|
575 |
|
576 // Note that if the server reported an error they usually |
|
577 // return 207 multistatus with an xml body |
|
578 // containing the status of the DELETE |
|
579 // should parse the body here |
|
580 } |
|
581 break; |
|
582 |
|
583 case EWebDavOpMove: |
|
584 case EWebDavOpMkCol: |
|
585 case EWebDavOpPut: |
|
586 if ((iStatus == HTTPStatus::EOk) || |
|
587 (iStatus == HTTPStatus::ECreated) || |
|
588 (iStatus == HTTPStatus::ENoContent)) |
|
589 { |
|
590 // 200, 201 or 204 would be the expected response |
|
591 // that everything went well |
|
592 DEBUGSTRING(("Move/MkCol/Put: status ok")); |
|
593 ok = ETrue; |
|
594 } |
|
595 else |
|
596 { |
|
597 // 207 responses contains a status tag in xml data |
|
598 // 409 would indicate there was a conflict |
|
599 DEBUGSTRING(("Move/MkCol/Put: bad status!")); |
|
600 } |
|
601 break; |
|
602 |
|
603 case EWebDavOpGet: |
|
604 if ((iStatus == HTTPStatus::EOk) || |
|
605 (iStatus == HTTPStatus::EPartialContent)) |
|
606 { |
|
607 ok = ETrue; |
|
608 } |
|
609 break; |
|
610 |
|
611 case EWebDavOpOptions: |
|
612 if (iStatus == 200) |
|
613 { |
|
614 ok = ETrue; |
|
615 } |
|
616 break; |
|
617 |
|
618 case EWebDavOpLock: |
|
619 case EWebDavOpRefreshLock: |
|
620 { |
|
621 if ((iStatus == HTTPStatus::ECreated) || |
|
622 (iStatus == HTTPStatus::EOk)) |
|
623 { |
|
624 ok = ETrue; |
|
625 } |
|
626 } |
|
627 break; |
|
628 |
|
629 case EWebDavOpUnlock: |
|
630 ok = ETrue; |
|
631 break; |
|
632 |
|
633 default: |
|
634 break; |
|
635 } |
|
636 |
|
637 done = ETrue; |
|
638 } |
|
639 break; |
|
640 |
|
641 case THTTPEvent::EFailed: |
|
642 { |
|
643 switch (iWebDavOp) |
|
644 { |
|
645 case EWebDavOpOptions: |
|
646 iStatus = KErrAccessDenied; |
|
647 break; |
|
648 |
|
649 default: |
|
650 break; |
|
651 } |
|
652 |
|
653 DEBUGSTRING(("Transaction failed")); |
|
654 done = ETrue; |
|
655 } |
|
656 break; |
|
657 |
|
658 case THTTPEvent::ERedirectedPermanently: |
|
659 case KErrHttpRedirectNoLocationField: |
|
660 { |
|
661 DEBUGSTRING(("Permanent Redirection")); |
|
662 iStatus = HTTPStatus::EMovedPermanently; |
|
663 done = ETrue; |
|
664 } |
|
665 break; |
|
666 |
|
667 case THTTPEvent::ERedirectedTemporarily: |
|
668 { |
|
669 DEBUGSTRING(("Temporary Redirection")); |
|
670 iStatus = HTTPStatus::ETemporaryRedirect; |
|
671 done = ETrue; |
|
672 } |
|
673 break; |
|
674 |
|
675 case THTTPEvent::ERedirectRequiresConfirmation: |
|
676 iStatus = HTTPStatus::EMovedPermanently; |
|
677 DEBUGSTRING(("Requires Confirmation")); |
|
678 // we don't want to resend the request with the new url |
|
679 // let's just close the request |
|
680 iHttpTransaction.Close(); |
|
681 done = ETrue; |
|
682 break; |
|
683 |
|
684 case THTTPEvent::EUnrecoverableError: |
|
685 DEBUGSTRING(("Unrecoverable error")); |
|
686 // Go on - we will end up to EFailed later |
|
687 break; |
|
688 |
|
689 case THTTPEvent::ETooMuchRequestData: |
|
690 DEBUGSTRING(("Too much request data")); |
|
691 break; |
|
692 // ESock errors: |
|
693 case KErrConnectionTerminated: |
|
694 DEBUGSTRING(("Connection Terminated")); |
|
695 iStatus = KErrCommsLineFail; |
|
696 break; |
|
697 default: |
|
698 { |
|
699 // Check the httperr.h header for the meaning of the different fields |
|
700 DEBUGSTRING(("unrecognized event: %d", aEvent.iStatus)); |
|
701 iStatus = aEvent.iStatus; |
|
702 // Close off the transaction if it's an error |
|
703 if (iStatus < 0) |
|
704 { |
|
705 done = ETrue; |
|
706 } |
|
707 } |
|
708 break; |
|
709 } |
|
710 |
|
711 if (done) |
|
712 { |
|
713 if (ok) |
|
714 { |
|
715 TransactionCompleteL(); |
|
716 } |
|
717 else |
|
718 { |
|
719 TransactionError(); |
|
720 } |
|
721 } |
|
722 } |
|
723 |
|
724 // ---------------------------------------------------------------------------- |
|
725 // CRsfwDavTransaction::MHFRunError |
|
726 // ---------------------------------------------------------------------------- |
|
727 // |
|
728 TInt CRsfwDavTransaction::MHFRunError(TInt aError, |
|
729 RHTTPTransaction /* aTransaction*/ , |
|
730 const THTTPEvent& /* aEvent */) |
|
731 { |
|
732 DEBUGSTRING(("MHFRunError() http transaction fired with error %d", |
|
733 aError)); |
|
734 |
|
735 iStatus = aError; |
|
736 TransactionError(); |
|
737 return KErrNone; |
|
738 } |
|
739 |
|
740 // ------------------------------------------------------------------ |
|
741 // From MHTTPDataSupplier |
|
742 // ------------------------------------------------------------------ |
|
743 |
|
744 // ---------------------------------------------------------------------------- |
|
745 // CRsfwDavTransaction::GetNextDataPart |
|
746 // return ETrue if all data has been sent, EFalse otherwise |
|
747 // ---------------------------------------------------------------------------- |
|
748 // |
|
749 TBool CRsfwDavTransaction::GetNextDataPart(TPtrC8& aDataPart) |
|
750 { |
|
751 DEBUGSTRING(("GetNextDataPart() (iMoreToCome = EFalse)")); |
|
752 // Read from the request body file |
|
753 iMoreToCome = EFalse; |
|
754 |
|
755 // we cannot supply more data if the condition is true |
|
756 if ((!iRequestBodyBuffer) || |
|
757 (iOverallDataSize == 0 && iWebDavOp == EWebDavOpPut)) |
|
758 { |
|
759 DEBUGSTRING(("All data supplied")); |
|
760 return !iMoreToCome; |
|
761 } |
|
762 |
|
763 switch (iWebDavOp) |
|
764 { |
|
765 case EWebDavOpOptions: |
|
766 case EWebDavOpPropFindSingle: |
|
767 case EWebDavOpPropFindMulti: |
|
768 case EWebDavOpLock: |
|
769 { |
|
770 // Called when the request body is being filled |
|
771 aDataPart.Set(*iRequestBodyBuffer); |
|
772 } |
|
773 break; |
|
774 |
|
775 case EWebDavOpPut: |
|
776 { |
|
777 DEBUGSTRING(("Put: GetNextDataPart()")); |
|
778 if (iSendDataCount == 0) |
|
779 { |
|
780 // first run |
|
781 DEBUGSTRING(("first run")); |
|
782 TInt pos = iBodyFileOffset; |
|
783 iBodyFile.Seek(ESeekStart, pos); |
|
784 } |
|
785 else |
|
786 { |
|
787 DEBUGSTRING(("%d bytes of data have been sent", iSendDataCount)); |
|
788 } |
|
789 |
|
790 // We read data that will be given to the stack next time, |
|
791 // or we will find out that there is no more data... |
|
792 TInt readLength; |
|
793 if ((iOverallDataSize - iSendDataCount) >= KDefaultSubmitSize) |
|
794 { |
|
795 readLength = KDefaultSubmitSize; |
|
796 } |
|
797 else |
|
798 { |
|
799 readLength = iOverallDataSize - iSendDataCount; |
|
800 } |
|
801 |
|
802 |
|
803 TPtr8 requestBodyBufferPtr = iRequestBodyBuffer->Des(); |
|
804 TInt err = iBodyFile.Read(requestBodyBufferPtr, readLength); |
|
805 iSendDataCount = iSendDataCount + iRequestBodyBuffer->Length(); |
|
806 if (err == KErrNone) |
|
807 { |
|
808 DEBUGSTRING(("passing %d bytes of data to the HTTP stack", iRequestBodyBuffer->Length())); |
|
809 if ((iSendDataCount < iOverallDataSize) && iRequestBodyBuffer->Length() > 0) |
|
810 { |
|
811 DEBUGSTRING(("Put: More data to come (iMoreToCome = ETrue)")); |
|
812 iMoreToCome = ETrue; |
|
813 } |
|
814 else |
|
815 { |
|
816 DEBUGSTRING(("Put: all data has been exhausted")); |
|
817 iMoreToCome = EFalse; |
|
818 } |
|
819 } |
|
820 else |
|
821 { |
|
822 DEBUGSTRING(("Put: failed to read the local file (err=%d)", |
|
823 err)); |
|
824 iMoreToCome = EFalse; |
|
825 } |
|
826 aDataPart.Set(*iRequestBodyBuffer); |
|
827 |
|
828 break; |
|
829 } |
|
830 |
|
831 default: |
|
832 break; |
|
833 } |
|
834 |
|
835 return !iMoreToCome; |
|
836 } |
|
837 |
|
838 // ---------------------------------------------------------------------------- |
|
839 // CRsfwDavTransaction::ReleaseData |
|
840 // ---------------------------------------------------------------------------- |
|
841 // |
|
842 void CRsfwDavTransaction::ReleaseData() |
|
843 { |
|
844 if (iMoreToCome) |
|
845 { |
|
846 TRAP_IGNORE(iHttpTransaction.NotifyNewRequestBodyPartL()); |
|
847 } |
|
848 else |
|
849 { |
|
850 DEBUGSTRING(("Releasing request body buffer")); |
|
851 delete iRequestBodyBuffer; |
|
852 iRequestBodyBuffer = NULL; |
|
853 } |
|
854 } |
|
855 |
|
856 // ---------------------------------------------------------------------------- |
|
857 // CRsfwDavTransaction::OverallDataSize |
|
858 // ---------------------------------------------------------------------------- |
|
859 // |
|
860 TInt CRsfwDavTransaction::OverallDataSize() |
|
861 { |
|
862 TInt ods; |
|
863 switch (iWebDavOp) |
|
864 { |
|
865 case EWebDavOpPut: |
|
866 DEBUGSTRING(("Put: OverallDataSize returned %d", |
|
867 iOverallDataSize)); |
|
868 // the size of the file to be copied |
|
869 ods = iOverallDataSize; |
|
870 break; |
|
871 |
|
872 default: |
|
873 if (!iRequestBodyBuffer) |
|
874 { |
|
875 ods = 0; |
|
876 } |
|
877 else |
|
878 { |
|
879 ods = iRequestBodyBuffer->Length(); |
|
880 } |
|
881 |
|
882 break; |
|
883 } |
|
884 return ods; |
|
885 } |
|
886 |
|
887 // ---------------------------------------------------------------------------- |
|
888 // CRsfwDavTransaction::Reset |
|
889 // ---------------------------------------------------------------------------- |
|
890 // |
|
891 TInt CRsfwDavTransaction::Reset() |
|
892 { |
|
893 DEBUGSTRING(("Reset data suplier")); |
|
894 switch (iWebDavOp) |
|
895 { |
|
896 case EWebDavOpPut: |
|
897 iSendDataCount = 0; |
|
898 break; |
|
899 |
|
900 default: |
|
901 break; |
|
902 } |
|
903 return KErrNone; |
|
904 } |
|
905 |
|
906 // ---------------------------------------------------------------------------- |
|
907 // CRsfwDavTransaction::TransactionComplete |
|
908 // ---------------------------------------------------------------------------- |
|
909 // |
|
910 void CRsfwDavTransaction::TransactionCompleteL() |
|
911 { |
|
912 iStatus = KErrNone; |
|
913 if (iWebDavOp == EWebDavOpOptions) |
|
914 { |
|
915 iWebDavSession->SetConnected(ETrue); |
|
916 } |
|
917 iWebDavOp = EWebDavOpNone; |
|
918 iWebDavSession->WebDavTransactionCompleteL(this); |
|
919 // Must not do anything with this transaction object |
|
920 // after calling the completion callback because this will be destroyed |
|
921 } |
|
922 |
|
923 // ---------------------------------------------------------------------------- |
|
924 // CRsfwDavTransaction::TransactionError |
|
925 // ---------------------------------------------------------------------------- |
|
926 // |
|
927 void CRsfwDavTransaction::TransactionError() |
|
928 { |
|
929 Cleanup(); |
|
930 iWebDavOp = EWebDavOpNone; |
|
931 iWebDavSession->WebDavTransactionError(this); |
|
932 // Must not do anything with this transaction object |
|
933 // after calling the error callback because this will be destroyed |
|
934 } |
|
935 |
|
936 // ---------------------------------------------------------------------------- |
|
937 // CRsfwDavTransaction::Cleanup |
|
938 // ---------------------------------------------------------------------------- |
|
939 // |
|
940 void CRsfwDavTransaction::Cleanup() |
|
941 { |
|
942 // Cleanup (e.g., after a failed transaction). |
|
943 // Only release resources that may block further transactions |
|
944 // before this transaction has been destroyed. |
|
945 switch (iWebDavOp) |
|
946 { |
|
947 case EWebDavOpGet: |
|
948 case EWebDavOpPut: |
|
949 iBodyFile.Close(); |
|
950 break; |
|
951 |
|
952 default: |
|
953 break; |
|
954 } |
|
955 } |
|
956 |
|
957 // ---------------------------------------------------------------------------- |
|
958 // CRsfwDavTransaction::PropFindResponseBeginL |
|
959 // ---------------------------------------------------------------------------- |
|
960 // |
|
961 void CRsfwDavTransaction::PropFindResponseBeginL(TInt aDepth) |
|
962 { |
|
963 iWebDavSession->SetPropFindParametersL(iDirEnts, |
|
964 *iPropFindPath, |
|
965 aDepth); |
|
966 } |
|
967 |
|
968 // ---------------------------------------------------------------------------- |
|
969 // CRsfwDavTransaction::LockQueryResponseBeginL |
|
970 // ---------------------------------------------------------------------------- |
|
971 // |
|
972 void CRsfwDavTransaction::LockQueryResponseBegin() |
|
973 { |
|
974 iWebDavSession->SetLockQueryParameters(iDavFileInfo); |
|
975 } |
|
976 |
|
977 // ---------------------------------------------------------------------------- |
|
978 // CRsfwDavTransaction::PropFindResponseEndL |
|
979 // ---------------------------------------------------------------------------- |
|
980 // |
|
981 void CRsfwDavTransaction::PropFindResponseEndL() |
|
982 { |
|
983 iWebDavSession->PropFindResponseEndL(); |
|
984 } |
|
985 |
|
986 // ---------------------------------------------------------------------------- |
|
987 // CRsfwDavTransaction::LockResponseEndL |
|
988 // ---------------------------------------------------------------------------- |
|
989 // |
|
990 void CRsfwDavTransaction::LockResponseEndL() |
|
991 { |
|
992 iWebDavSession->LockResponseEndL(); |
|
993 } |
|
994 |
|
995 // ---------------------------------------------------------------------------- |
|
996 // CRsfwDavTransaction::ParsePropFindResponseL |
|
997 // ---------------------------------------------------------------------------- |
|
998 // |
|
999 void CRsfwDavTransaction::ParsePropFindResponseL(const TDesC8& aResponse) |
|
1000 { |
|
1001 iWebDavSession->ParsePropFindResponseL(aResponse); |
|
1002 } |
|
1003 |
|
1004 // ---------------------------------------------------------------------------- |
|
1005 // CRsfwDavTransaction::ParseLockResponseL |
|
1006 // ---------------------------------------------------------------------------- |
|
1007 // |
|
1008 void CRsfwDavTransaction::ParseLockResponseL(const TDesC8& aResponse) |
|
1009 { |
|
1010 iWebDavSession->ParseLockResponseL(aResponse); |
|
1011 } |
|
1012 |
|
1013 // End of File |