Version 4.0.2.1, tag libreoffice-4.0.2.1
[LibreOffice.git] / ucb / source / ucp / webdav / DAVResourceAccess.cxx
blobbbdac2f644fbcfc98b56fda826ec37ba1db45c76
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "osl/diagnose.h"
22 #include "com/sun/star/task/XInteractionAbort.hpp"
23 #include "com/sun/star/ucb/XWebDAVCommandEnvironment.hpp"
25 #include "ucbhelper/simpleauthenticationrequest.hxx"
26 #include "comphelper/seekableinput.hxx"
28 #include "DAVAuthListenerImpl.hxx"
29 #include "DAVResourceAccess.hxx"
31 using namespace http_dav_ucp;
32 using namespace com::sun::star;
34 //=========================================================================
35 //=========================================================================
37 // DAVAuthListener_Impl Implementation.
39 //=========================================================================
40 //=========================================================================
42 //=========================================================================
43 // virtual
44 int DAVAuthListener_Impl::authenticate(
45 const ::rtl::OUString & inRealm,
46 const ::rtl::OUString & inHostName,
47 ::rtl::OUString & inoutUserName,
48 ::rtl::OUString & outPassWord,
49 sal_Bool bCanUseSystemCredentials,
50 sal_Bool bUsePreviousCredentials )
52 if ( m_xEnv.is() )
54 uno::Reference< task::XInteractionHandler > xIH
55 = m_xEnv->getInteractionHandler();
57 if ( xIH.is() )
59 // Providing previously retrieved credentials will cause the password
60 // container to reject these. Thus, the credential input dialog will be shown again.
61 // #102871# - Supply username and password from previous try.
62 // Password container service depends on this!
63 if ( inoutUserName.getLength() == 0 && bUsePreviousCredentials )
64 inoutUserName = m_aPrevUsername;
66 if ( outPassWord.getLength() == 0 && bUsePreviousCredentials )
67 outPassWord = m_aPrevPassword;
69 rtl::Reference< ucbhelper::SimpleAuthenticationRequest > xRequest
70 = new ucbhelper::SimpleAuthenticationRequest(
71 m_aURL, inHostName, inRealm, inoutUserName,
72 outPassWord, ::rtl::OUString(),
73 true /*bAllowPersistentStoring*/,
74 bCanUseSystemCredentials );
75 xIH->handle( xRequest.get() );
77 rtl::Reference< ucbhelper::InteractionContinuation > xSelection
78 = xRequest->getSelection();
80 if ( xSelection.is() )
82 // Handler handled the request.
83 uno::Reference< task::XInteractionAbort > xAbort(
84 xSelection.get(), uno::UNO_QUERY );
85 if ( !xAbort.is() )
87 const rtl::Reference<
88 ucbhelper::InteractionSupplyAuthentication > & xSupp
89 = xRequest->getAuthenticationSupplier();
91 sal_Bool bUseSystemCredentials = sal_False;
93 if ( bCanUseSystemCredentials )
94 bUseSystemCredentials
95 = xSupp->getUseSystemCredentials();
97 if ( bUseSystemCredentials )
99 // This is the (strange) way to tell neon to use
100 // system credentials.
101 inoutUserName = rtl::OUString();
102 outPassWord = rtl::OUString();
104 else
106 inoutUserName = xSupp->getUserName();
107 outPassWord = xSupp->getPassword();
110 // #102871# - Remember username and password.
111 m_aPrevUsername = inoutUserName;
112 m_aPrevPassword = outPassWord;
114 // go on.
115 return 0;
120 // Abort.
121 return -1;
124 //=========================================================================
125 //=========================================================================
127 // DAVResourceAccess Implementation.
129 //=========================================================================
130 //=========================================================================
132 //=========================================================================
133 DAVResourceAccess::DAVResourceAccess(
134 const uno::Reference< lang::XMultiServiceFactory > & rSMgr,
135 rtl::Reference< DAVSessionFactory > const & rSessionFactory,
136 const rtl::OUString & rURL )
137 : m_aURL( rURL ),
138 m_xSessionFactory( rSessionFactory ),
139 m_xSMgr( rSMgr )
143 //=========================================================================
144 DAVResourceAccess::DAVResourceAccess( const DAVResourceAccess & rOther )
145 : m_aURL( rOther.m_aURL ),
146 m_aPath( rOther.m_aPath ),
147 m_xSession( rOther.m_xSession ),
148 m_xSessionFactory( rOther.m_xSessionFactory ),
149 m_xSMgr( rOther.m_xSMgr ),
150 m_aRedirectURIs( rOther.m_aRedirectURIs )
154 //=========================================================================
155 DAVResourceAccess & DAVResourceAccess::operator=(
156 const DAVResourceAccess & rOther )
158 m_aURL = rOther.m_aURL;
159 m_aPath = rOther.m_aPath;
160 m_xSession = rOther.m_xSession;
161 m_xSessionFactory = rOther.m_xSessionFactory;
162 m_xSMgr = rOther.m_xSMgr;
163 m_aRedirectURIs = rOther.m_aRedirectURIs;
165 return *this;
168 //=========================================================================
169 void DAVResourceAccess::PROPFIND(
170 const Depth nDepth,
171 const std::vector< rtl::OUString > & rPropertyNames,
172 std::vector< DAVResource > & rResources,
173 const uno::Reference< ucb::XCommandEnvironment > & xEnv )
174 throw( DAVException )
176 initialize();
178 int errorCount = 0;
179 bool bRetry;
182 bRetry = false;
185 DAVRequestHeaders aHeaders;
187 getUserRequestHeaders( xEnv,
188 getRequestURI(),
189 rtl::OUString::createFromAscii(
190 "PROPFIND" ),
191 aHeaders );
193 m_xSession->PROPFIND( getRequestURI(),
194 nDepth,
195 rPropertyNames,
196 rResources,
197 DAVRequestEnvironment(
198 getRequestURI(),
199 new DAVAuthListener_Impl( xEnv, m_aURL ),
200 aHeaders, xEnv ) );
202 catch ( DAVException & e )
204 errorCount++;
205 bRetry = handleException( e, errorCount );
206 if ( !bRetry )
207 throw;
210 while ( bRetry );
213 //=========================================================================
214 void DAVResourceAccess::PROPFIND(
215 const Depth nDepth,
216 std::vector< DAVResourceInfo > & rResInfo,
217 const uno::Reference< ucb::XCommandEnvironment > & xEnv )
218 throw( DAVException )
220 initialize();
222 int errorCount = 0;
223 bool bRetry;
226 bRetry = false;
229 DAVRequestHeaders aHeaders;
230 getUserRequestHeaders( xEnv,
231 getRequestURI(),
232 rtl::OUString::createFromAscii(
233 "PROPFIND" ),
234 aHeaders );
236 m_xSession->PROPFIND( getRequestURI(),
237 nDepth,
238 rResInfo,
239 DAVRequestEnvironment(
240 getRequestURI(),
241 new DAVAuthListener_Impl( xEnv, m_aURL ),
242 aHeaders, xEnv ) ) ;
244 catch ( DAVException & e )
246 errorCount++;
247 bRetry = handleException( e, errorCount );
248 if ( !bRetry )
249 throw;
252 while ( bRetry );
255 //=========================================================================
256 void DAVResourceAccess::PROPPATCH(
257 const std::vector< ProppatchValue >& rValues,
258 const uno::Reference< ucb::XCommandEnvironment >& xEnv )
259 throw( DAVException )
261 initialize();
263 int errorCount = 0;
264 bool bRetry;
267 bRetry = false;
270 DAVRequestHeaders aHeaders;
271 getUserRequestHeaders( xEnv,
272 getRequestURI(),
273 rtl::OUString::createFromAscii(
274 "PROPPATCH" ),
275 aHeaders );
277 m_xSession->PROPPATCH( getRequestURI(),
278 rValues,
279 DAVRequestEnvironment(
280 getRequestURI(),
281 new DAVAuthListener_Impl( xEnv, m_aURL ),
282 aHeaders, xEnv ) );
284 catch ( DAVException & e )
286 errorCount++;
287 bRetry = handleException( e, errorCount );
288 if ( !bRetry )
289 throw;
292 while ( bRetry );
295 //=========================================================================
296 void DAVResourceAccess::HEAD(
297 const std::vector< rtl::OUString > & rHeaderNames,
298 DAVResource & rResource,
299 const uno::Reference< ucb::XCommandEnvironment >& xEnv )
300 throw( DAVException )
302 initialize();
304 int errorCount = 0;
305 bool bRetry;
308 bRetry = false;
311 DAVRequestHeaders aHeaders;
312 getUserRequestHeaders( xEnv,
313 getRequestURI(),
314 rtl::OUString::createFromAscii( "HEAD" ),
315 aHeaders );
317 m_xSession->HEAD( getRequestURI(),
318 rHeaderNames,
319 rResource,
320 DAVRequestEnvironment(
321 getRequestURI(),
322 new DAVAuthListener_Impl( xEnv, m_aURL ),
323 aHeaders, xEnv ) );
325 catch ( DAVException & e )
327 errorCount++;
328 bRetry = handleException( e, errorCount );
329 if ( !bRetry )
330 throw;
333 while ( bRetry );
336 //=========================================================================
337 uno::Reference< io::XInputStream > DAVResourceAccess::GET(
338 const uno::Reference< ucb::XCommandEnvironment > & xEnv )
339 throw( DAVException )
341 initialize();
343 uno::Reference< io::XInputStream > xStream;
344 int errorCount = 0;
345 bool bRetry;
348 bRetry = false;
351 DAVRequestHeaders aHeaders;
352 getUserRequestHeaders( xEnv,
353 getRequestURI(),
354 rtl::OUString::createFromAscii( "GET" ),
355 aHeaders );
357 xStream = m_xSession->GET( getRequestURI(),
358 DAVRequestEnvironment(
359 getRequestURI(),
360 new DAVAuthListener_Impl(
361 xEnv, m_aURL ),
362 aHeaders, xEnv ) );
364 catch ( DAVException & e )
366 errorCount++;
367 bRetry = handleException( e, errorCount );
368 if ( !bRetry )
369 throw;
372 while ( bRetry );
374 return xStream;
377 //=========================================================================
378 void DAVResourceAccess::GET(
379 uno::Reference< io::XOutputStream > & rStream,
380 const uno::Reference< ucb::XCommandEnvironment > & xEnv )
381 throw( DAVException )
383 initialize();
385 int errorCount = 0;
386 bool bRetry;
389 bRetry = false;
392 DAVRequestHeaders aHeaders;
393 getUserRequestHeaders( xEnv,
394 getRequestURI(),
395 rtl::OUString::createFromAscii( "GET" ),
396 aHeaders );
398 m_xSession->GET( getRequestURI(),
399 rStream,
400 DAVRequestEnvironment(
401 getRequestURI(),
402 new DAVAuthListener_Impl( xEnv, m_aURL ),
403 aHeaders, xEnv ) );
405 catch ( DAVException & e )
407 errorCount++;
408 bRetry = handleException( e, errorCount );
409 if ( !bRetry )
410 throw;
413 while ( bRetry );
416 //=========================================================================
417 uno::Reference< io::XInputStream > DAVResourceAccess::GET(
418 const std::vector< rtl::OUString > & rHeaderNames,
419 DAVResource & rResource,
420 const uno::Reference< ucb::XCommandEnvironment > & xEnv )
421 throw( DAVException )
423 initialize();
425 uno::Reference< io::XInputStream > xStream;
426 int errorCount = 0;
427 bool bRetry;
430 bRetry = false;
433 DAVRequestHeaders aHeaders;
434 getUserRequestHeaders( xEnv,
435 getRequestURI(),
436 rtl::OUString::createFromAscii( "GET" ),
437 aHeaders );
439 xStream = m_xSession->GET( getRequestURI(),
440 rHeaderNames,
441 rResource,
442 DAVRequestEnvironment(
443 getRequestURI(),
444 new DAVAuthListener_Impl(
445 xEnv, m_aURL ),
446 aHeaders, xEnv ) );
448 catch ( DAVException & e )
450 errorCount++;
451 bRetry = handleException( e, errorCount );
452 if ( !bRetry )
453 throw;
456 while ( bRetry );
458 return xStream;
461 //=========================================================================
462 void DAVResourceAccess::GET(
463 uno::Reference< io::XOutputStream > & rStream,
464 const std::vector< rtl::OUString > & rHeaderNames,
465 DAVResource & rResource,
466 const uno::Reference< ucb::XCommandEnvironment > & xEnv )
467 throw( DAVException )
469 initialize();
471 bool bRetry;
472 int errorCount = 0;
475 bRetry = false;
478 DAVRequestHeaders aHeaders;
479 getUserRequestHeaders( xEnv,
480 getRequestURI(),
481 rtl::OUString::createFromAscii( "GET" ),
482 aHeaders );
484 m_xSession->GET( getRequestURI(),
485 rStream,
486 rHeaderNames,
487 rResource,
488 DAVRequestEnvironment(
489 getRequestURI(),
490 new DAVAuthListener_Impl( xEnv, m_aURL ),
491 aHeaders, xEnv ) );
493 catch ( DAVException & e )
495 errorCount++;
496 bRetry = handleException( e, errorCount );
497 if ( !bRetry )
498 throw;
501 while ( bRetry );
504 //=========================================================================
505 void DAVResourceAccess::abort()
506 throw( DAVException )
508 // 17.11.09 (tkr): abort currently disabled caused by issue i106766
509 // initialize();
510 // m_xSession->abort();
511 OSL_TRACE( "Not implemented. -> #i106766#" );
514 //=========================================================================
515 namespace {
517 void resetInputStream( const uno::Reference< io::XInputStream > & rStream )
518 throw( DAVException )
522 uno::Reference< io::XSeekable > xSeekable(
523 rStream, uno::UNO_QUERY );
524 if ( xSeekable.is() )
526 xSeekable->seek( 0 );
527 return;
530 catch ( lang::IllegalArgumentException const & )
533 catch ( io::IOException const & )
537 throw DAVException( DAVException::DAV_INVALID_ARG );
540 } // namespace
542 //=========================================================================
543 void DAVResourceAccess::PUT(
544 const uno::Reference< io::XInputStream > & rStream,
545 const uno::Reference< ucb::XCommandEnvironment > & xEnv )
546 throw( DAVException )
548 initialize();
550 // Make stream seekable, if it not. Needed, if request must be retried.
551 uno::Reference< io::XInputStream > xSeekableStream
552 = comphelper::OSeekableInputWrapper::CheckSeekableCanWrap(
553 rStream, m_xSMgr );
555 int errorCount = 0;
556 bool bRetry = false;
559 if ( bRetry )
560 resetInputStream( xSeekableStream );
562 bRetry = false;
565 DAVRequestHeaders aHeaders;
566 getUserRequestHeaders( xEnv,
567 getRequestURI(),
568 rtl::OUString::createFromAscii( "PUT" ),
569 aHeaders );
571 m_xSession->PUT( getRequestURI(),
572 xSeekableStream,
573 DAVRequestEnvironment(
574 getRequestURI(),
575 new DAVAuthListener_Impl( xEnv, m_aURL ),
576 aHeaders, xEnv ) );
578 catch ( DAVException & e )
580 errorCount++;
581 bRetry = handleException( e, errorCount );
582 if ( !bRetry )
583 throw;
586 while ( bRetry );
589 //=========================================================================
590 uno::Reference< io::XInputStream > DAVResourceAccess::POST(
591 const rtl::OUString & rContentType,
592 const rtl::OUString & rReferer,
593 const uno::Reference< io::XInputStream > & rInputStream,
594 const uno::Reference< ucb::XCommandEnvironment >& xEnv )
595 throw ( DAVException )
597 initialize();
599 // Make stream seekable, if it not. Needed, if request must be retried.
600 uno::Reference< io::XInputStream > xSeekableStream
601 = comphelper::OSeekableInputWrapper::CheckSeekableCanWrap(
602 rInputStream, m_xSMgr );
604 uno::Reference< io::XInputStream > xStream;
605 int errorCount = 0;
606 bool bRetry = false;
609 if ( bRetry )
611 resetInputStream( xSeekableStream );
612 bRetry = false;
617 DAVRequestHeaders aHeaders;
618 getUserRequestHeaders( xEnv,
619 getRequestURI(),
620 rtl::OUString::createFromAscii( "POST" ),
621 aHeaders );
623 xStream = m_xSession->POST( getRequestURI(),
624 rContentType,
625 rReferer,
626 xSeekableStream,
627 DAVRequestEnvironment(
628 getRequestURI(),
629 new DAVAuthListener_Impl(
630 xEnv, m_aURL ),
631 aHeaders, xEnv ) );
633 catch ( DAVException & e )
635 errorCount++;
636 bRetry = handleException( e, errorCount );
637 if ( !bRetry )
638 throw;
640 if ( e.getError() == DAVException::DAV_HTTP_REDIRECT )
642 // #i74980# - Upon POST redirect, do a GET.
643 return GET( xEnv );
647 while ( bRetry );
649 return xStream;
652 //=========================================================================
653 void DAVResourceAccess::POST(
654 const rtl::OUString & rContentType,
655 const rtl::OUString & rReferer,
656 const uno::Reference< io::XInputStream > & rInputStream,
657 uno::Reference< io::XOutputStream > & rOutputStream,
658 const uno::Reference< ucb::XCommandEnvironment >& xEnv )
659 throw ( DAVException )
661 initialize();
663 // Make stream seekable, if it not. Needed, if request must be retried.
664 uno::Reference< io::XInputStream > xSeekableStream
665 = comphelper::OSeekableInputWrapper::CheckSeekableCanWrap(
666 rInputStream, m_xSMgr );
668 int errorCount = 0;
669 bool bRetry = false;
672 if ( bRetry )
674 resetInputStream( xSeekableStream );
675 bRetry = false;
680 DAVRequestHeaders aHeaders;
681 getUserRequestHeaders( xEnv,
682 getRequestURI(),
683 rtl::OUString::createFromAscii( "POST" ),
684 aHeaders );
686 m_xSession->POST( getRequestURI(),
687 rContentType,
688 rReferer,
689 xSeekableStream,
690 rOutputStream,
691 DAVRequestEnvironment(
692 getRequestURI(),
693 new DAVAuthListener_Impl( xEnv, m_aURL ),
694 aHeaders, xEnv ) );
696 catch ( DAVException & e )
698 errorCount++;
699 bRetry = handleException( e, errorCount );
700 if ( !bRetry )
701 throw;
703 if ( e.getError() == DAVException::DAV_HTTP_REDIRECT )
705 // #i74980# - Upon POST redirect, do a GET.
706 GET( rOutputStream, xEnv );
707 return;
711 while ( bRetry );
714 //=========================================================================
715 void DAVResourceAccess::MKCOL(
716 const uno::Reference< ucb::XCommandEnvironment > & xEnv )
717 throw( DAVException )
719 initialize();
721 int errorCount = 0;
722 bool bRetry;
725 bRetry = false;
728 DAVRequestHeaders aHeaders;
729 getUserRequestHeaders( xEnv,
730 getRequestURI(),
731 rtl::OUString::createFromAscii( "MKCOL" ),
732 aHeaders );
734 m_xSession->MKCOL( getRequestURI(),
735 DAVRequestEnvironment(
736 getRequestURI(),
737 new DAVAuthListener_Impl( xEnv, m_aURL ),
738 aHeaders, xEnv ) );
740 catch ( DAVException & e )
742 errorCount++;
743 bRetry = handleException( e, errorCount );
744 if ( !bRetry )
745 throw;
748 while ( bRetry );
751 //=========================================================================
752 void DAVResourceAccess::COPY(
753 const ::rtl::OUString & rSourcePath,
754 const ::rtl::OUString & rDestinationURI,
755 sal_Bool bOverwrite,
756 const uno::Reference< ucb::XCommandEnvironment > & xEnv )
757 throw( DAVException )
759 initialize();
761 int errorCount = 0;
762 bool bRetry;
765 bRetry = false;
768 DAVRequestHeaders aHeaders;
769 getUserRequestHeaders( xEnv,
770 getRequestURI(),
771 rtl::OUString::createFromAscii( "COPY" ),
772 aHeaders );
774 m_xSession->COPY( rSourcePath,
775 rDestinationURI,
776 DAVRequestEnvironment(
777 getRequestURI(),
778 new DAVAuthListener_Impl( xEnv, m_aURL ),
779 aHeaders, xEnv ),
780 bOverwrite );
782 catch ( DAVException & e )
784 errorCount++;
785 bRetry = handleException( e, errorCount );
786 if ( !bRetry )
787 throw;
790 while ( bRetry );
793 //=========================================================================
794 void DAVResourceAccess::MOVE(
795 const ::rtl::OUString & rSourcePath,
796 const ::rtl::OUString & rDestinationURI,
797 sal_Bool bOverwrite,
798 const uno::Reference< ucb::XCommandEnvironment > & xEnv )
799 throw( DAVException )
801 initialize();
803 int errorCount = 0;
804 bool bRetry;
807 bRetry = false;
810 DAVRequestHeaders aHeaders;
811 getUserRequestHeaders( xEnv,
812 getRequestURI(),
813 rtl::OUString::createFromAscii( "MOVE" ),
814 aHeaders );
816 m_xSession->MOVE( rSourcePath,
817 rDestinationURI,
818 DAVRequestEnvironment(
819 getRequestURI(),
820 new DAVAuthListener_Impl( xEnv, m_aURL ),
821 aHeaders, xEnv ),
822 bOverwrite );
824 catch ( DAVException & e )
826 errorCount++;
827 bRetry = handleException( e, errorCount );
828 if ( !bRetry )
829 throw;
832 while ( bRetry );
835 //=========================================================================
836 void DAVResourceAccess::DESTROY(
837 const uno::Reference< ucb::XCommandEnvironment > & xEnv )
838 throw( DAVException )
840 initialize();
842 int errorCount = 0;
843 bool bRetry;
846 bRetry = false;
849 DAVRequestHeaders aHeaders;
850 getUserRequestHeaders( xEnv,
851 getRequestURI(),
852 rtl::OUString::createFromAscii(
853 "DESTROY" ),
854 aHeaders );
856 m_xSession->DESTROY( getRequestURI(),
857 DAVRequestEnvironment(
858 getRequestURI(),
859 new DAVAuthListener_Impl( xEnv, m_aURL ),
860 aHeaders, xEnv ) );
862 catch ( DAVException & e )
864 errorCount++;
865 bRetry = handleException( e, errorCount );
866 if ( !bRetry )
867 throw;
870 while ( bRetry );
873 //=========================================================================
874 // set new lock.
875 void DAVResourceAccess::LOCK(
876 ucb::Lock & inLock,
877 const uno::Reference< ucb::XCommandEnvironment > & xEnv )
878 throw ( DAVException )
880 initialize();
882 int errorCount = 0;
883 bool bRetry;
886 bRetry = false;
889 DAVRequestHeaders aHeaders;
890 getUserRequestHeaders( xEnv,
891 getRequestURI(),
892 rtl::OUString::createFromAscii( "LOCK" ),
893 aHeaders );
895 m_xSession->LOCK( getRequestURI(),
896 inLock,
897 DAVRequestEnvironment(
898 getRequestURI(),
899 new DAVAuthListener_Impl( xEnv, m_aURL ),
900 aHeaders, xEnv ) );
902 catch ( DAVException & e )
904 errorCount++;
905 bRetry = handleException( e, errorCount );
906 if ( !bRetry )
907 throw;
910 while ( bRetry );
913 #if 0 // currently not used, but please don't remove code
914 //=========================================================================
915 // refresh existing lock.
916 sal_Int64 DAVResourceAccess::LOCK(
917 sal_Int64 nTimeout,
918 const uno::Reference< ucb::XCommandEnvironment > & xEnv )
919 throw ( DAVException )
921 initialize();
923 sal_Int64 nNewTimeout = 0;
924 int errorCount = 0;
925 bool bRetry;
928 bRetry = false;
931 DAVRequestHeaders aHeaders;
932 getUserRequestHeaders( xEnv,
933 getRequestURI(),
934 rtl::OUString::createFromAscii( "LOCK" ),
935 aHeaders );
937 nNewTimeout = m_xSession->LOCK( getRequestURI(),
938 nTimeout,
939 DAVRequestEnvironment(
940 getRequestURI(),
941 new DAVAuthListener_Impl(
942 xEnv, m_aURL ),
943 aHeaders, xEnv ) );
945 catch ( DAVException & e )
947 errorCount++;
948 bRetry = handleException( e, errorCount );
949 if ( !bRetry )
950 throw;
953 while ( bRetry );
955 return nNewTimeout;
957 #endif
959 //=========================================================================
960 void DAVResourceAccess::UNLOCK(
961 const uno::Reference< ucb::XCommandEnvironment > & xEnv )
962 throw ( DAVException )
964 initialize();
966 int errorCount = 0;
967 bool bRetry;
970 bRetry = false;
973 DAVRequestHeaders aHeaders;
974 getUserRequestHeaders( xEnv,
975 getRequestURI(),
976 rtl::OUString::createFromAscii( "UNLOCK" ),
977 aHeaders );
979 m_xSession->UNLOCK( getRequestURI(),
980 DAVRequestEnvironment(
981 getRequestURI(),
982 new DAVAuthListener_Impl( xEnv, m_aURL ),
983 aHeaders, xEnv ) );
985 catch ( DAVException & e )
987 errorCount++;
988 bRetry = handleException( e, errorCount );
989 if ( !bRetry )
990 throw;
993 while ( bRetry );
996 //=========================================================================
997 void DAVResourceAccess::setURL( const rtl::OUString & rNewURL )
998 throw( DAVException )
1000 osl::Guard< osl::Mutex > aGuard( m_aMutex );
1001 m_aURL = rNewURL;
1002 m_aPath = rtl::OUString(); // Next initialize() will create new session.
1005 //=========================================================================
1006 // init dav session and path
1007 void DAVResourceAccess::initialize()
1008 throw ( DAVException )
1010 osl::Guard< osl::Mutex > aGuard( m_aMutex );
1011 if ( m_aPath.getLength() == 0 )
1013 SerfUri aURI( m_aURL );
1014 rtl::OUString aPath( aURI.GetPath() );
1016 /* #134089# - Check URI */
1017 if ( !aPath.getLength() )
1018 throw DAVException( DAVException::DAV_INVALID_ARG );
1020 /* #134089# - Check URI */
1021 if ( !aURI.GetHost().getLength() )
1022 throw DAVException( DAVException::DAV_INVALID_ARG );
1024 if ( !m_xSession.is() || !m_xSession->CanUse( m_aURL ) )
1026 m_xSession.clear();
1028 // create new webdav session
1029 m_xSession
1030 = m_xSessionFactory->createDAVSession( m_aURL, m_xSMgr );
1032 if ( !m_xSession.is() )
1033 return;
1036 // Own URI is needed for redirect cycle detection.
1037 m_aRedirectURIs.push_back( aURI );
1039 // Success.
1040 m_aPath = aPath;
1042 // Not only the path has to be encoded
1043 m_aURL = aURI.GetURI();
1047 //=========================================================================
1048 const rtl::OUString & DAVResourceAccess::getRequestURI() const
1050 OSL_ENSURE( m_xSession.is(),
1051 "DAVResourceAccess::getRequestURI - Not initialized!" );
1053 // In case a proxy is used we have to use the absolute URI for a request.
1054 if ( m_xSession->UsesProxy() )
1055 return m_aURL;
1057 return m_aPath;
1060 //=========================================================================
1061 // static
1062 void DAVResourceAccess::getUserRequestHeaders(
1063 const uno::Reference< ucb::XCommandEnvironment > & xEnv,
1064 const rtl::OUString & rURI,
1065 const rtl::OUString & rMethod,
1066 DAVRequestHeaders & rRequestHeaders )
1068 if ( xEnv.is() )
1070 uno::Reference< ucb::XWebDAVCommandEnvironment > xDAVEnv(
1071 xEnv, uno::UNO_QUERY );
1073 if ( xDAVEnv.is() )
1075 uno::Sequence< beans::NamedValue > aRequestHeaders
1076 = xDAVEnv->getUserRequestHeaders( rURI, rMethod );
1078 for ( sal_Int32 n = 0; n < aRequestHeaders.getLength(); ++n )
1080 rtl::OUString aValue;
1081 sal_Bool isString = aRequestHeaders[ n ].Value >>= aValue;
1083 if ( !isString )
1085 OSL_ENSURE( isString,
1086 "DAVResourceAccess::getUserRequestHeaders :"
1087 "Value is not a string! Ignoring..." );
1090 rRequestHeaders.push_back(
1091 DAVRequestHeader( aRequestHeaders[ n ].Name, aValue ) );
1097 //=========================================================================
1098 sal_Bool DAVResourceAccess::detectRedirectCycle(
1099 const rtl::OUString& rRedirectURL )
1100 throw ( DAVException )
1102 osl::Guard< osl::Mutex > aGuard( m_aMutex );
1104 SerfUri aUri( rRedirectURL );
1106 std::vector< SerfUri >::const_iterator it = m_aRedirectURIs.begin();
1107 std::vector< SerfUri >::const_iterator end = m_aRedirectURIs.end();
1109 while ( it != end )
1111 if ( aUri == (*it) )
1112 return sal_True;
1114 ++it;
1117 return sal_False;
1120 //=========================================================================
1121 void DAVResourceAccess::resetUri()
1123 osl::Guard< osl::Mutex > aGuard( m_aMutex );
1124 if ( ! m_aRedirectURIs.empty() )
1126 std::vector< SerfUri >::const_iterator it = m_aRedirectURIs.begin();
1128 SerfUri aUri( (*it) );
1129 m_aRedirectURIs.clear();
1130 setURL ( aUri.GetURI() );
1131 initialize();
1135 //=========================================================================
1136 sal_Bool DAVResourceAccess::handleException( DAVException & e, int errorCount )
1137 throw ( DAVException )
1139 switch ( e.getError() )
1141 case DAVException::DAV_HTTP_REDIRECT:
1142 if ( !detectRedirectCycle( e.getData() ) )
1144 // set new URL and path.
1145 setURL( e.getData() );
1146 initialize();
1147 return sal_True;
1149 return sal_False;
1150 // --> tkr #67048# copy & paste images doesn't display.
1151 // if we have a bad connection try again. Up to three times.
1152 case DAVException::DAV_HTTP_ERROR:
1153 // retry up to three times, if not a client-side error.
1154 if ( ( e.getStatus() < 400 || e.getStatus() >= 500 ||
1155 e.getStatus() == 413 ) &&
1156 errorCount < 3 )
1158 return sal_True;
1160 return sal_False;
1161 // <--
1162 // --> tkr: if connection has said retry then retry!
1163 case DAVException::DAV_HTTP_RETRY:
1164 return sal_True;
1165 // <--
1166 default:
1167 return sal_False; // Abort
1171 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */