bump product version to 5.0.4.1
[LibreOffice.git] / ucb / source / ucp / webdav-neon / DAVResourceAccess.cxx
blobe3d331b95a8240cdd679bdee53080838cd16f0e9
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
30 #include "osl/diagnose.h"
32 #include "com/sun/star/task/XInteractionAbort.hpp"
33 #include "com/sun/star/ucb/XWebDAVCommandEnvironment.hpp"
35 #include "ucbhelper/simpleauthenticationrequest.hxx"
36 #include "comphelper/processfactory.hxx"
37 #include "comphelper/seekableinput.hxx"
39 #include "DAVAuthListenerImpl.hxx"
40 #include "DAVResourceAccess.hxx"
42 using namespace webdav_ucp;
43 using namespace com::sun::star;
48 // DAVAuthListener_Impl Implementation.
54 // virtual
55 int DAVAuthListener_Impl::authenticate(
56 const OUString & inRealm,
57 const OUString & inHostName,
58 OUString & inoutUserName,
59 OUString & outPassWord,
60 bool bCanUseSystemCredentials )
62 if ( m_xEnv.is() )
64 uno::Reference< task::XInteractionHandler > xIH
65 = m_xEnv->getInteractionHandler();
67 if ( xIH.is() )
69 // #102871# - Supply username and password from previous try.
70 // Password container service depends on this!
71 if ( inoutUserName.isEmpty() )
72 inoutUserName = m_aPrevUsername;
74 if ( outPassWord.isEmpty() )
75 outPassWord = m_aPrevPassword;
77 rtl::Reference< ucbhelper::SimpleAuthenticationRequest > xRequest
78 = new ucbhelper::SimpleAuthenticationRequest(
79 m_aURL, inHostName, inRealm, inoutUserName,
80 outPassWord, OUString(),
81 true /*bAllowPersistentStoring*/,
82 bCanUseSystemCredentials );
83 xIH->handle( xRequest.get() );
85 rtl::Reference< ucbhelper::InteractionContinuation > xSelection
86 = xRequest->getSelection();
88 if ( xSelection.is() )
90 // Handler handled the request.
91 uno::Reference< task::XInteractionAbort > xAbort(
92 xSelection.get(), uno::UNO_QUERY );
93 if ( !xAbort.is() )
95 const rtl::Reference<
96 ucbhelper::InteractionSupplyAuthentication > & xSupp
97 = xRequest->getAuthenticationSupplier();
99 bool bUseSystemCredentials = false;
101 if ( bCanUseSystemCredentials )
102 bUseSystemCredentials
103 = xSupp->getUseSystemCredentials();
105 if ( bUseSystemCredentials )
107 // This is the (strange) way to tell neon to use
108 // system credentials.
109 inoutUserName.clear();
110 outPassWord.clear();
112 else
114 inoutUserName = xSupp->getUserName();
115 outPassWord = xSupp->getPassword();
118 // #102871# - Remember username and password.
119 m_aPrevUsername = inoutUserName;
120 m_aPrevPassword = outPassWord;
122 // go on.
123 return 0;
128 // Abort.
129 return -1;
135 // DAVResourceAccess Implementation.
141 DAVResourceAccess::DAVResourceAccess(
142 const uno::Reference< uno::XComponentContext > & rxContext,
143 rtl::Reference< DAVSessionFactory > const & rSessionFactory,
144 const OUString & rURL )
145 : m_aURL( rURL ),
146 m_xSessionFactory( rSessionFactory ),
147 m_xContext( rxContext )
152 DAVResourceAccess::DAVResourceAccess( const DAVResourceAccess & rOther )
153 : m_aURL( rOther.m_aURL ),
154 m_aPath( rOther.m_aPath ),
155 m_aFlags( rOther.m_aFlags ),
156 m_xSession( rOther.m_xSession ),
157 m_xSessionFactory( rOther.m_xSessionFactory ),
158 m_xContext( rOther.m_xContext ),
159 m_aRedirectURIs( rOther.m_aRedirectURIs )
164 DAVResourceAccess & DAVResourceAccess::operator=(
165 const DAVResourceAccess & rOther )
167 m_aURL = rOther.m_aURL;
168 m_aPath = rOther.m_aPath;
169 m_aFlags = rOther.m_aFlags;
170 m_xSession = rOther.m_xSession;
171 m_xSessionFactory = rOther.m_xSessionFactory;
172 m_xContext = rOther.m_xContext;
173 m_aRedirectURIs = rOther.m_aRedirectURIs;
175 return *this;
178 #if 0 // currently not used, but please don't remove code
180 void DAVResourceAccess::OPTIONS(
181 DAVCapabilities & rCapabilities,
182 const uno::Reference< ucb::XCommandEnvironment > & xEnv )
183 throw( DAVException )
185 initialize();
187 bool bRetry;
188 int errorCount = 0;
191 bRetry = false;
194 DAVRequestHeaders aHeaders;
195 getUserRequestHeaders( xEnv,
196 getRequestURI(),
197 OUString( "OPTIONS" ),
198 aHeaders );
200 m_xSession->OPTIONS( getRequestURI(),
201 rCapabilities,
202 DAVRequestEnvironment(
203 getRequestURI(),
204 new DAVAuthListener_Impl( xEnv, m_aURL ),
205 aHeaders, xEnv) );
207 catch ( const DAVException & e )
209 errorCount++;
210 bRetry = handleException( e, errorCount );
211 if ( !bRetry )
212 throw;
215 while ( bRetry );
217 #endif
220 void DAVResourceAccess::PROPFIND(
221 const Depth nDepth,
222 const std::vector< OUString > & rPropertyNames,
223 std::vector< DAVResource > & rResources,
224 const uno::Reference< ucb::XCommandEnvironment > & xEnv )
225 throw( DAVException )
227 initialize();
229 int errorCount = 0;
230 bool bRetry;
233 bRetry = false;
236 DAVRequestHeaders aHeaders;
238 getUserRequestHeaders( xEnv,
239 getRequestURI(),
240 ucb::WebDAVHTTPMethod_PROPFIND,
241 aHeaders );
243 m_xSession->PROPFIND( getRequestURI(),
244 nDepth,
245 rPropertyNames,
246 rResources,
247 DAVRequestEnvironment(
248 getRequestURI(),
249 new DAVAuthListener_Impl( xEnv, m_aURL ),
250 aHeaders, xEnv ) );
252 catch ( const DAVException & e )
254 errorCount++;
255 bRetry = handleException( e, errorCount );
256 if ( !bRetry )
257 throw;
260 while ( bRetry );
264 void DAVResourceAccess::PROPFIND(
265 const Depth nDepth,
266 std::vector< DAVResourceInfo > & rResInfo,
267 const uno::Reference< ucb::XCommandEnvironment > & xEnv )
268 throw( DAVException )
270 initialize();
272 int errorCount = 0;
273 bool bRetry;
276 bRetry = false;
279 DAVRequestHeaders aHeaders;
280 getUserRequestHeaders( xEnv,
281 getRequestURI(),
282 ucb::WebDAVHTTPMethod_PROPFIND,
283 aHeaders );
285 m_xSession->PROPFIND( getRequestURI(),
286 nDepth,
287 rResInfo,
288 DAVRequestEnvironment(
289 getRequestURI(),
290 new DAVAuthListener_Impl( xEnv, m_aURL ),
291 aHeaders, xEnv ) ) ;
293 catch ( const DAVException & e )
295 errorCount++;
296 bRetry = handleException( e, errorCount );
297 if ( !bRetry )
298 throw;
301 while ( bRetry );
305 void DAVResourceAccess::PROPPATCH(
306 const std::vector< ProppatchValue >& rValues,
307 const uno::Reference< ucb::XCommandEnvironment >& xEnv )
308 throw( DAVException )
310 initialize();
312 int errorCount = 0;
313 bool bRetry;
316 bRetry = false;
319 DAVRequestHeaders aHeaders;
320 getUserRequestHeaders( xEnv,
321 getRequestURI(),
322 ucb::WebDAVHTTPMethod_PROPPATCH,
323 aHeaders );
325 m_xSession->PROPPATCH( getRequestURI(),
326 rValues,
327 DAVRequestEnvironment(
328 getRequestURI(),
329 new DAVAuthListener_Impl( xEnv, m_aURL ),
330 aHeaders, xEnv ) );
332 catch ( const DAVException & e )
334 errorCount++;
335 bRetry = handleException( e, errorCount );
336 if ( !bRetry )
337 throw;
340 while ( bRetry );
344 void DAVResourceAccess::HEAD(
345 const std::vector< OUString > & rHeaderNames,
346 DAVResource & rResource,
347 const uno::Reference< ucb::XCommandEnvironment >& xEnv )
348 throw( DAVException )
350 initialize();
352 int errorCount = 0;
353 bool bRetry;
356 bRetry = false;
359 DAVRequestHeaders aHeaders;
360 getUserRequestHeaders( xEnv,
361 getRequestURI(),
362 ucb::WebDAVHTTPMethod_HEAD,
363 aHeaders );
365 m_xSession->HEAD( getRequestURI(),
366 rHeaderNames,
367 rResource,
368 DAVRequestEnvironment(
369 getRequestURI(),
370 new DAVAuthListener_Impl( xEnv, m_aURL ),
371 aHeaders, xEnv ) );
373 catch ( const DAVException & e )
375 errorCount++;
376 bRetry = handleException( e, errorCount );
377 if ( !bRetry )
378 throw;
381 while ( bRetry );
385 uno::Reference< io::XInputStream > DAVResourceAccess::GET(
386 const uno::Reference< ucb::XCommandEnvironment > & xEnv )
387 throw( DAVException )
389 initialize();
391 uno::Reference< io::XInputStream > xStream;
392 int errorCount = 0;
393 bool bRetry;
396 bRetry = false;
399 DAVRequestHeaders aHeaders;
400 getUserRequestHeaders( xEnv,
401 getRequestURI(),
402 ucb::WebDAVHTTPMethod_GET,
403 aHeaders );
405 xStream = m_xSession->GET( getRequestURI(),
406 DAVRequestEnvironment(
407 getRequestURI(),
408 new DAVAuthListener_Impl(
409 xEnv, m_aURL ),
410 aHeaders, xEnv ) );
412 catch ( const DAVException & e )
414 errorCount++;
415 bRetry = handleException( e, errorCount );
416 if ( !bRetry )
417 throw;
420 while ( bRetry );
422 return xStream;
426 void DAVResourceAccess::GET(
427 uno::Reference< io::XOutputStream > & rStream,
428 const uno::Reference< ucb::XCommandEnvironment > & xEnv )
429 throw( DAVException )
431 initialize();
433 int errorCount = 0;
434 bool bRetry;
437 bRetry = false;
440 DAVRequestHeaders aHeaders;
441 getUserRequestHeaders( xEnv,
442 getRequestURI(),
443 ucb::WebDAVHTTPMethod_GET,
444 aHeaders );
446 m_xSession->GET( getRequestURI(),
447 rStream,
448 DAVRequestEnvironment(
449 getRequestURI(),
450 new DAVAuthListener_Impl( xEnv, m_aURL ),
451 aHeaders, xEnv ) );
453 catch ( const DAVException & e )
455 errorCount++;
456 bRetry = handleException( e, errorCount );
457 if ( !bRetry )
458 throw;
461 while ( bRetry );
465 uno::Reference< io::XInputStream > DAVResourceAccess::GET(
466 const std::vector< OUString > & rHeaderNames,
467 DAVResource & rResource,
468 const uno::Reference< ucb::XCommandEnvironment > & xEnv )
469 throw( DAVException )
471 initialize();
473 uno::Reference< io::XInputStream > xStream;
474 int errorCount = 0;
475 bool bRetry;
478 bRetry = false;
481 DAVRequestHeaders aHeaders;
482 getUserRequestHeaders( xEnv,
483 getRequestURI(),
484 ucb::WebDAVHTTPMethod_GET,
485 aHeaders );
487 xStream = m_xSession->GET( getRequestURI(),
488 rHeaderNames,
489 rResource,
490 DAVRequestEnvironment(
491 getRequestURI(),
492 new DAVAuthListener_Impl(
493 xEnv, m_aURL ),
494 aHeaders, xEnv ) );
496 catch ( const DAVException & e )
498 errorCount++;
499 bRetry = handleException( e, errorCount );
500 if ( !bRetry )
501 throw;
504 while ( bRetry );
506 return xStream;
510 void DAVResourceAccess::GET(
511 uno::Reference< io::XOutputStream > & rStream,
512 const std::vector< OUString > & rHeaderNames,
513 DAVResource & rResource,
514 const uno::Reference< ucb::XCommandEnvironment > & xEnv )
515 throw( DAVException )
517 initialize();
519 bool bRetry;
520 int errorCount = 0;
523 bRetry = false;
526 DAVRequestHeaders aHeaders;
527 getUserRequestHeaders( xEnv,
528 getRequestURI(),
529 ucb::WebDAVHTTPMethod_GET,
530 aHeaders );
532 m_xSession->GET( getRequestURI(),
533 rStream,
534 rHeaderNames,
535 rResource,
536 DAVRequestEnvironment(
537 getRequestURI(),
538 new DAVAuthListener_Impl( xEnv, m_aURL ),
539 aHeaders, xEnv ) );
541 catch ( const DAVException & e )
543 errorCount++;
544 bRetry = handleException( e, errorCount );
545 if ( !bRetry )
546 throw;
549 while ( bRetry );
553 void DAVResourceAccess::abort()
554 throw( DAVException )
556 initialize();
557 m_xSession->abort();
561 namespace {
563 void resetInputStream( const uno::Reference< io::XInputStream > & rStream )
564 throw( DAVException )
568 uno::Reference< io::XSeekable > xSeekable(
569 rStream, uno::UNO_QUERY );
570 if ( xSeekable.is() )
572 xSeekable->seek( 0 );
573 return;
576 catch ( lang::IllegalArgumentException const & )
579 catch ( io::IOException const & )
583 throw DAVException( DAVException::DAV_INVALID_ARG );
586 } // namespace
589 void DAVResourceAccess::PUT(
590 const uno::Reference< io::XInputStream > & rStream,
591 const uno::Reference< ucb::XCommandEnvironment > & xEnv )
592 throw (css::uno::RuntimeException, DAVException)
594 initialize();
596 // Make stream seekable, if it not. Needed, if request must be retried.
597 uno::Reference< io::XInputStream > xSeekableStream
598 = comphelper::OSeekableInputWrapper::CheckSeekableCanWrap(
599 rStream, m_xContext );
601 int errorCount = 0;
602 bool bRetry = false;
605 if ( bRetry )
606 resetInputStream( xSeekableStream );
608 bRetry = false;
611 DAVRequestHeaders aHeaders;
612 getUserRequestHeaders( xEnv,
613 getRequestURI(),
614 ucb::WebDAVHTTPMethod_PUT,
615 aHeaders );
617 m_xSession->PUT( getRequestURI(),
618 xSeekableStream,
619 DAVRequestEnvironment(
620 getRequestURI(),
621 new DAVAuthListener_Impl( xEnv, m_aURL ),
622 aHeaders, xEnv ) );
624 catch ( const DAVException & e )
626 errorCount++;
627 bRetry = handleException( e, errorCount );
628 if ( !bRetry )
629 throw;
632 while ( bRetry );
636 uno::Reference< io::XInputStream > DAVResourceAccess::POST(
637 const OUString & rContentType,
638 const OUString & rReferer,
639 const uno::Reference< io::XInputStream > & rInputStream,
640 const uno::Reference< ucb::XCommandEnvironment >& xEnv )
641 throw (css::uno::RuntimeException, DAVException)
643 initialize();
645 // Make stream seekable, if it not. Needed, if request must be retried.
646 uno::Reference< io::XInputStream > xSeekableStream
647 = comphelper::OSeekableInputWrapper::CheckSeekableCanWrap(
648 rInputStream, m_xContext );
650 uno::Reference< io::XInputStream > xStream;
651 int errorCount = 0;
652 bool bRetry = false;
655 if ( bRetry )
657 resetInputStream( xSeekableStream );
658 bRetry = false;
663 DAVRequestHeaders aHeaders;
664 getUserRequestHeaders( xEnv,
665 getRequestURI(),
666 ucb::WebDAVHTTPMethod_POST,
667 aHeaders );
669 xStream = m_xSession->POST( getRequestURI(),
670 rContentType,
671 rReferer,
672 xSeekableStream,
673 DAVRequestEnvironment(
674 getRequestURI(),
675 new DAVAuthListener_Impl(
676 xEnv, m_aURL ),
677 aHeaders, xEnv ) );
679 catch ( const DAVException & e )
681 errorCount++;
682 bRetry = handleException( e, errorCount );
683 if ( !bRetry )
684 throw;
686 if ( e.getError() == DAVException::DAV_HTTP_REDIRECT )
688 // #i74980# - Upon POST redirect, do a GET.
689 return GET( xEnv );
693 while ( bRetry );
695 return xStream;
699 void DAVResourceAccess::POST(
700 const OUString & rContentType,
701 const OUString & rReferer,
702 const uno::Reference< io::XInputStream > & rInputStream,
703 uno::Reference< io::XOutputStream > & rOutputStream,
704 const uno::Reference< ucb::XCommandEnvironment >& xEnv )
705 throw (css::uno::RuntimeException, DAVException)
707 initialize();
709 // Make stream seekable, if it not. Needed, if request must be retried.
710 uno::Reference< io::XInputStream > xSeekableStream
711 = comphelper::OSeekableInputWrapper::CheckSeekableCanWrap(
712 rInputStream, m_xContext );
714 int errorCount = 0;
715 bool bRetry = false;
718 if ( bRetry )
720 resetInputStream( xSeekableStream );
721 bRetry = false;
726 DAVRequestHeaders aHeaders;
727 getUserRequestHeaders( xEnv,
728 getRequestURI(),
729 ucb::WebDAVHTTPMethod_POST,
730 aHeaders );
732 m_xSession->POST( getRequestURI(),
733 rContentType,
734 rReferer,
735 xSeekableStream,
736 rOutputStream,
737 DAVRequestEnvironment(
738 getRequestURI(),
739 new DAVAuthListener_Impl( xEnv, m_aURL ),
740 aHeaders, xEnv ) );
742 catch ( const DAVException & e )
744 errorCount++;
745 bRetry = handleException( e, errorCount );
746 if ( !bRetry )
747 throw;
749 if ( e.getError() == DAVException::DAV_HTTP_REDIRECT )
751 // #i74980# - Upon POST redirect, do a GET.
752 GET( rOutputStream, xEnv );
753 return;
757 while ( bRetry );
761 void DAVResourceAccess::MKCOL(
762 const uno::Reference< ucb::XCommandEnvironment > & xEnv )
763 throw( DAVException )
765 initialize();
767 int errorCount = 0;
768 bool bRetry;
771 bRetry = false;
774 DAVRequestHeaders aHeaders;
775 getUserRequestHeaders( xEnv,
776 getRequestURI(),
777 ucb::WebDAVHTTPMethod_MKCOL,
778 aHeaders );
780 m_xSession->MKCOL( getRequestURI(),
781 DAVRequestEnvironment(
782 getRequestURI(),
783 new DAVAuthListener_Impl( xEnv, m_aURL ),
784 aHeaders, xEnv ) );
786 catch ( const DAVException & e )
788 errorCount++;
789 bRetry = handleException( e, errorCount );
790 if ( !bRetry )
791 throw;
794 while ( bRetry );
798 void DAVResourceAccess::COPY(
799 const OUString & rSourcePath,
800 const OUString & rDestinationURI,
801 bool bOverwrite,
802 const uno::Reference< ucb::XCommandEnvironment > & xEnv )
803 throw( DAVException )
805 initialize();
807 int errorCount = 0;
808 bool bRetry;
811 bRetry = false;
814 DAVRequestHeaders aHeaders;
815 getUserRequestHeaders( xEnv,
816 getRequestURI(),
817 ucb::WebDAVHTTPMethod_COPY,
818 aHeaders );
820 m_xSession->COPY( rSourcePath,
821 rDestinationURI,
822 DAVRequestEnvironment(
823 getRequestURI(),
824 new DAVAuthListener_Impl( xEnv, m_aURL ),
825 aHeaders, xEnv ),
826 bOverwrite );
828 catch ( const DAVException & e )
830 errorCount++;
831 bRetry = handleException( e, errorCount );
832 if ( !bRetry )
833 throw;
836 while ( bRetry );
840 void DAVResourceAccess::MOVE(
841 const OUString & rSourcePath,
842 const OUString & rDestinationURI,
843 bool bOverwrite,
844 const uno::Reference< ucb::XCommandEnvironment > & xEnv )
845 throw( DAVException )
847 initialize();
849 int errorCount = 0;
850 bool bRetry;
853 bRetry = false;
856 DAVRequestHeaders aHeaders;
857 getUserRequestHeaders( xEnv,
858 getRequestURI(),
859 ucb::WebDAVHTTPMethod_MOVE,
860 aHeaders );
862 m_xSession->MOVE( rSourcePath,
863 rDestinationURI,
864 DAVRequestEnvironment(
865 getRequestURI(),
866 new DAVAuthListener_Impl( xEnv, m_aURL ),
867 aHeaders, xEnv ),
868 bOverwrite );
870 catch ( const DAVException & e )
872 errorCount++;
873 bRetry = handleException( e, errorCount );
874 if ( !bRetry )
875 throw;
878 while ( bRetry );
882 void DAVResourceAccess::DESTROY(
883 const uno::Reference< ucb::XCommandEnvironment > & xEnv )
884 throw( DAVException )
886 initialize();
888 int errorCount = 0;
889 bool bRetry;
892 bRetry = false;
895 DAVRequestHeaders aHeaders;
896 getUserRequestHeaders( xEnv,
897 getRequestURI(),
898 ucb::WebDAVHTTPMethod_DELETE,
899 aHeaders );
901 m_xSession->DESTROY( getRequestURI(),
902 DAVRequestEnvironment(
903 getRequestURI(),
904 new DAVAuthListener_Impl( xEnv, m_aURL ),
905 aHeaders, xEnv ) );
907 catch ( const DAVException & e )
909 errorCount++;
910 bRetry = handleException( e, errorCount );
911 if ( !bRetry )
912 throw;
915 while ( bRetry );
919 // set new lock.
920 void DAVResourceAccess::LOCK(
921 ucb::Lock & inLock,
922 const uno::Reference< ucb::XCommandEnvironment > & xEnv )
923 throw ( DAVException )
925 initialize();
927 int errorCount = 0;
928 bool bRetry;
931 bRetry = false;
934 DAVRequestHeaders aHeaders;
935 getUserRequestHeaders( xEnv,
936 getRequestURI(),
937 ucb::WebDAVHTTPMethod_LOCK,
938 aHeaders );
940 m_xSession->LOCK( getRequestURI(),
941 inLock,
942 DAVRequestEnvironment(
943 getRequestURI(),
944 new DAVAuthListener_Impl( xEnv, m_aURL ),
945 aHeaders, xEnv ) );
947 catch ( const DAVException & e )
949 errorCount++;
950 bRetry = handleException( e, errorCount );
951 if ( !bRetry )
952 throw;
955 while ( bRetry );
958 #if 0 // currently not used, but please don't remove code
960 // refresh existing lock.
961 sal_Int64 DAVResourceAccess::LOCK(
962 sal_Int64 nTimeout,
963 const uno::Reference< ucb::XCommandEnvironment > & xEnv )
964 throw ( DAVException )
966 initialize();
968 sal_Int64 nNewTimeout = 0;
969 int errorCount = 0;
970 bool bRetry;
973 bRetry = false;
976 DAVRequestHeaders aHeaders;
977 getUserRequestHeaders( xEnv,
978 getRequestURI(),
979 ucb::WebDAVHTTPMethod_LOCK,
980 aHeaders );
982 nNewTimeout = m_xSession->LOCK( getRequestURI(),
983 nTimeout,
984 DAVRequestEnvironment(
985 getRequestURI(),
986 new DAVAuthListener_Impl(
987 xEnv, m_aURL ),
988 aHeaders, xEnv ) );
990 catch ( const DAVException & e )
992 errorCount++;
993 bRetry = handleException( e, errorCount );
994 if ( !bRetry )
995 throw;
998 while ( bRetry );
1000 return nNewTimeout;
1002 #endif
1005 void DAVResourceAccess::UNLOCK(
1006 const uno::Reference< ucb::XCommandEnvironment > & xEnv )
1007 throw ( DAVException )
1009 initialize();
1011 int errorCount = 0;
1012 bool bRetry;
1015 bRetry = false;
1018 DAVRequestHeaders aHeaders;
1019 getUserRequestHeaders( xEnv,
1020 getRequestURI(),
1021 ucb::WebDAVHTTPMethod_UNLOCK,
1022 aHeaders );
1024 m_xSession->UNLOCK( getRequestURI(),
1025 DAVRequestEnvironment(
1026 getRequestURI(),
1027 new DAVAuthListener_Impl( xEnv, m_aURL ),
1028 aHeaders, xEnv ) );
1030 catch ( const DAVException & e )
1032 errorCount++;
1033 bRetry = handleException( e, errorCount );
1034 if ( !bRetry )
1035 throw;
1038 while ( bRetry );
1042 void DAVResourceAccess::setFlags( const uno::Sequence< beans::NamedValue >& rFlags )
1043 throw ( DAVException )
1045 osl::Guard< osl::Mutex > aGuard( m_aMutex );
1046 m_aFlags = rFlags;
1050 void DAVResourceAccess::setURL( const OUString & rNewURL )
1051 throw( DAVException )
1053 osl::Guard< osl::Mutex > aGuard( m_aMutex );
1054 m_aURL = rNewURL;
1055 m_aPath.clear(); // Next initialize() will create new session.
1059 // init dav session and path
1060 void DAVResourceAccess::initialize()
1061 throw ( DAVException )
1063 osl::Guard< osl::Mutex > aGuard( m_aMutex );
1064 if ( m_aPath.isEmpty() )
1066 NeonUri aURI( m_aURL );
1067 OUString aPath( aURI.GetPath() );
1069 /* #134089# - Check URI */
1070 if ( aPath.isEmpty() )
1071 throw DAVException( DAVException::DAV_INVALID_ARG );
1073 /* #134089# - Check URI */
1074 if ( aURI.GetHost().isEmpty() )
1075 throw DAVException( DAVException::DAV_INVALID_ARG );
1077 if ( !m_xSession.is() || !m_xSession->CanUse( m_aURL, m_aFlags ) )
1079 m_xSession.clear();
1081 // create new webdav session
1082 m_xSession
1083 = m_xSessionFactory->createDAVSession( m_aURL, m_aFlags, m_xContext );
1085 if ( !m_xSession.is() )
1086 return;
1089 // Own URI is needed for redirect cycle detection.
1090 m_aRedirectURIs.push_back( aURI );
1092 // Success.
1093 m_aPath = aPath;
1095 // Not only the path has to be encoded
1096 m_aURL = aURI.GetURI();
1101 const OUString & DAVResourceAccess::getRequestURI() const
1103 OSL_ENSURE( m_xSession.is(),
1104 "DAVResourceAccess::getRequestURI - Not initialized!" );
1106 // In case a proxy is used we have to use the absolute URI for a request.
1107 if ( m_xSession->UsesProxy() )
1108 return m_aURL;
1110 return m_aPath;
1114 // static
1115 void DAVResourceAccess::getUserRequestHeaders(
1116 const uno::Reference< ucb::XCommandEnvironment > & xEnv,
1117 const OUString & rURI,
1118 ucb::WebDAVHTTPMethod eMethod,
1119 DAVRequestHeaders & rRequestHeaders )
1121 if ( xEnv.is() )
1123 uno::Reference< ucb::XWebDAVCommandEnvironment > xDAVEnv(
1124 xEnv, uno::UNO_QUERY );
1126 if ( xDAVEnv.is() )
1128 uno::Sequence< beans::StringPair > aRequestHeaders
1129 = xDAVEnv->getUserRequestHeaders( rURI, eMethod );
1131 for ( sal_Int32 n = 0; n < aRequestHeaders.getLength(); ++n )
1133 rRequestHeaders.push_back(
1134 DAVRequestHeader(
1135 aRequestHeaders[ n ].First,
1136 aRequestHeaders[ n ].Second ) );
1141 // Make sure a User-Agent header is always included, as at least
1142 // en.wikipedia.org:80 forces back 403 "Scripts should use an informative
1143 // User-Agent string with contact information, or they may be IP-blocked
1144 // without notice" otherwise:
1145 for ( DAVRequestHeaders::iterator i(rRequestHeaders.begin());
1146 i != rRequestHeaders.end(); ++i )
1148 if ( i->first.equalsIgnoreAsciiCase( "User-Agent" ) )
1150 return;
1153 rRequestHeaders.push_back(
1154 DAVRequestHeader( "User-Agent", "LibreOffice" ) );
1158 bool DAVResourceAccess::detectRedirectCycle(
1159 const OUString& rRedirectURL )
1160 throw ( DAVException )
1162 osl::Guard< osl::Mutex > aGuard( m_aMutex );
1164 NeonUri aUri( rRedirectURL );
1166 std::vector< NeonUri >::const_iterator it = m_aRedirectURIs.begin();
1167 std::vector< NeonUri >::const_iterator end = m_aRedirectURIs.end();
1169 while ( it != end )
1171 if ( aUri == (*it) )
1172 return true;
1174 ++it;
1177 return false;
1181 void DAVResourceAccess::resetUri()
1183 osl::Guard< osl::Mutex > aGuard( m_aMutex );
1184 if ( !m_aRedirectURIs.empty() )
1186 std::vector< NeonUri >::const_iterator it = m_aRedirectURIs.begin();
1188 NeonUri aUri( (*it) );
1189 m_aRedirectURIs.clear();
1190 setURL ( aUri.GetURI() );
1191 initialize();
1196 bool DAVResourceAccess::handleException( const DAVException & e, int errorCount )
1197 throw ( DAVException )
1199 switch ( e.getError() )
1201 case DAVException::DAV_HTTP_REDIRECT:
1202 if ( !detectRedirectCycle( e.getData() ) )
1204 // set new URL and path.
1205 setURL( e.getData() );
1206 initialize();
1207 return true;
1209 return false;
1210 // #67048# copy & paste images doesn't display.
1211 // if we have a bad connection try again. Up to three times.
1212 case DAVException::DAV_HTTP_ERROR:
1213 // retry up to three times, if not a client-side error.
1214 if ( ( e.getStatus() < 400 || e.getStatus() >= 500 ) &&
1215 errorCount < 3 )
1217 return true;
1219 return false;
1220 // if connection has said retry then retry!
1221 case DAVException::DAV_HTTP_RETRY:
1222 return true;
1223 default:
1224 return false; // Abort
1228 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */