Bump for 3.6-28
[LibreOffice.git] / ucb / source / ucp / webdav / DAVResourceAccess.cxx
blob890f94ba03cfb60d20d133f2c4f08fb885d5dc53
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/seekableinput.hxx"
38 #include "DAVAuthListenerImpl.hxx"
39 #include "DAVResourceAccess.hxx"
41 using namespace webdav_ucp;
42 using namespace com::sun::star;
44 //=========================================================================
45 //=========================================================================
47 // DAVAuthListener_Impl Implementation.
49 //=========================================================================
50 //=========================================================================
52 //=========================================================================
53 // virtual
54 int DAVAuthListener_Impl::authenticate(
55 const ::rtl::OUString & inRealm,
56 const ::rtl::OUString & inHostName,
57 ::rtl::OUString & inoutUserName,
58 ::rtl::OUString & outPassWord,
59 sal_Bool bCanUseSystemCredentials )
61 if ( m_xEnv.is() )
63 uno::Reference< task::XInteractionHandler > xIH
64 = m_xEnv->getInteractionHandler();
66 if ( xIH.is() )
68 // #102871# - Supply username and password from previous try.
69 // Password container service depends on this!
70 if ( inoutUserName.isEmpty() )
71 inoutUserName = m_aPrevUsername;
73 if ( outPassWord.isEmpty() )
74 outPassWord = m_aPrevPassword;
76 rtl::Reference< ucbhelper::SimpleAuthenticationRequest > xRequest
77 = new ucbhelper::SimpleAuthenticationRequest(
78 m_aURL, inHostName, inRealm, inoutUserName,
79 outPassWord, ::rtl::OUString(),
80 true /*bAllowPersistentStoring*/,
81 bCanUseSystemCredentials );
82 xIH->handle( xRequest.get() );
84 rtl::Reference< ucbhelper::InteractionContinuation > xSelection
85 = xRequest->getSelection();
87 if ( xSelection.is() )
89 // Handler handled the request.
90 uno::Reference< task::XInteractionAbort > xAbort(
91 xSelection.get(), uno::UNO_QUERY );
92 if ( !xAbort.is() )
94 const rtl::Reference<
95 ucbhelper::InteractionSupplyAuthentication > & xSupp
96 = xRequest->getAuthenticationSupplier();
98 sal_Bool bUseSystemCredentials = sal_False;
100 if ( bCanUseSystemCredentials )
101 bUseSystemCredentials
102 = xSupp->getUseSystemCredentials();
104 if ( bUseSystemCredentials )
106 // This is the (strange) way to tell neon to use
107 // system credentials.
108 inoutUserName = rtl::OUString();
109 outPassWord = rtl::OUString();
111 else
113 inoutUserName = xSupp->getUserName();
114 outPassWord = xSupp->getPassword();
117 // #102871# - Remember username and password.
118 m_aPrevUsername = inoutUserName;
119 m_aPrevPassword = outPassWord;
121 // go on.
122 return 0;
127 // Abort.
128 return -1;
131 //=========================================================================
132 //=========================================================================
134 // DAVResourceAccess Implementation.
136 //=========================================================================
137 //=========================================================================
139 //=========================================================================
140 DAVResourceAccess::DAVResourceAccess(
141 const uno::Reference< lang::XMultiServiceFactory > & rSMgr,
142 rtl::Reference< DAVSessionFactory > const & rSessionFactory,
143 const rtl::OUString & rURL )
144 : m_aURL( rURL ),
145 m_xSessionFactory( rSessionFactory ),
146 m_xSMgr( rSMgr )
150 //=========================================================================
151 DAVResourceAccess::DAVResourceAccess( const DAVResourceAccess & rOther )
152 : m_aURL( rOther.m_aURL ),
153 m_aPath( rOther.m_aPath ),
154 m_aFlags( rOther.m_aFlags ),
155 m_xSession( rOther.m_xSession ),
156 m_xSessionFactory( rOther.m_xSessionFactory ),
157 m_xSMgr( rOther.m_xSMgr ),
158 m_aRedirectURIs( rOther.m_aRedirectURIs )
162 //=========================================================================
163 DAVResourceAccess & DAVResourceAccess::operator=(
164 const DAVResourceAccess & rOther )
166 m_aURL = rOther.m_aURL;
167 m_aPath = rOther.m_aPath;
168 m_aFlags = rOther.m_aFlags;
169 m_xSession = rOther.m_xSession;
170 m_xSessionFactory = rOther.m_xSessionFactory;
171 m_xSMgr = rOther.m_xSMgr;
172 m_aRedirectURIs = rOther.m_aRedirectURIs;
174 return *this;
177 #if 0 // currently not used, but please don't remove code
178 //=========================================================================
179 void DAVResourceAccess::OPTIONS(
180 DAVCapabilities & rCapabilities,
181 const uno::Reference< ucb::XCommandEnvironment > & xEnv )
182 throw( DAVException )
184 initialize();
186 bool bRetry;
187 int errorCount = 0;
190 bRetry = false;
193 DAVRequestHeaders aHeaders;
194 getUserRequestHeaders( xEnv,
195 getRequestURI(),
196 rtl::OUString( "OPTIONS" ),
197 aHeaders );
199 m_xSession->OPTIONS( getRequestURI(),
200 rCapabilities,
201 DAVRequestEnvironment(
202 getRequestURI(),
203 new DAVAuthListener_Impl( xEnv, m_aURL ),
204 aHeaders, xEnv) );
206 catch ( const DAVException & e )
208 errorCount++;
209 bRetry = handleException( e, errorCount );
210 if ( !bRetry )
211 throw;
214 while ( bRetry );
216 #endif
218 //=========================================================================
219 void DAVResourceAccess::PROPFIND(
220 const Depth nDepth,
221 const std::vector< rtl::OUString > & rPropertyNames,
222 std::vector< DAVResource > & rResources,
223 const uno::Reference< ucb::XCommandEnvironment > & xEnv )
224 throw( DAVException )
226 initialize();
228 int errorCount = 0;
229 bool bRetry;
232 bRetry = false;
235 DAVRequestHeaders aHeaders;
237 getUserRequestHeaders( xEnv,
238 getRequestURI(),
239 rtl::OUString( "PROPFIND" ),
240 aHeaders );
242 m_xSession->PROPFIND( getRequestURI(),
243 nDepth,
244 rPropertyNames,
245 rResources,
246 DAVRequestEnvironment(
247 getRequestURI(),
248 new DAVAuthListener_Impl( xEnv, m_aURL ),
249 aHeaders, xEnv ) );
251 catch ( const DAVException & e )
253 errorCount++;
254 bRetry = handleException( e, errorCount );
255 if ( !bRetry )
256 throw;
259 while ( bRetry );
262 //=========================================================================
263 void DAVResourceAccess::PROPFIND(
264 const Depth nDepth,
265 std::vector< DAVResourceInfo > & rResInfo,
266 const uno::Reference< ucb::XCommandEnvironment > & xEnv )
267 throw( DAVException )
269 initialize();
271 int errorCount = 0;
272 bool bRetry;
275 bRetry = false;
278 DAVRequestHeaders aHeaders;
279 getUserRequestHeaders( xEnv,
280 getRequestURI(),
281 rtl::OUString( "PROPFIND" ),
282 aHeaders );
284 m_xSession->PROPFIND( getRequestURI(),
285 nDepth,
286 rResInfo,
287 DAVRequestEnvironment(
288 getRequestURI(),
289 new DAVAuthListener_Impl( xEnv, m_aURL ),
290 aHeaders, xEnv ) ) ;
292 catch ( const DAVException & e )
294 errorCount++;
295 bRetry = handleException( e, errorCount );
296 if ( !bRetry )
297 throw;
300 while ( bRetry );
303 //=========================================================================
304 void DAVResourceAccess::PROPPATCH(
305 const std::vector< ProppatchValue >& rValues,
306 const uno::Reference< ucb::XCommandEnvironment >& xEnv )
307 throw( DAVException )
309 initialize();
311 int errorCount = 0;
312 bool bRetry;
315 bRetry = false;
318 DAVRequestHeaders aHeaders;
319 getUserRequestHeaders( xEnv,
320 getRequestURI(),
321 rtl::OUString( "PROPPATCH" ),
322 aHeaders );
324 m_xSession->PROPPATCH( getRequestURI(),
325 rValues,
326 DAVRequestEnvironment(
327 getRequestURI(),
328 new DAVAuthListener_Impl( xEnv, m_aURL ),
329 aHeaders, xEnv ) );
331 catch ( const DAVException & e )
333 errorCount++;
334 bRetry = handleException( e, errorCount );
335 if ( !bRetry )
336 throw;
339 while ( bRetry );
342 //=========================================================================
343 void DAVResourceAccess::HEAD(
344 const std::vector< rtl::OUString > & rHeaderNames,
345 DAVResource & rResource,
346 const uno::Reference< ucb::XCommandEnvironment >& xEnv )
347 throw( DAVException )
349 initialize();
351 int errorCount = 0;
352 bool bRetry;
355 bRetry = false;
358 DAVRequestHeaders aHeaders;
359 getUserRequestHeaders( xEnv,
360 getRequestURI(),
361 rtl::OUString("HEAD"),
362 aHeaders );
364 m_xSession->HEAD( getRequestURI(),
365 rHeaderNames,
366 rResource,
367 DAVRequestEnvironment(
368 getRequestURI(),
369 new DAVAuthListener_Impl( xEnv, m_aURL ),
370 aHeaders, xEnv ) );
372 catch ( const DAVException & e )
374 errorCount++;
375 bRetry = handleException( e, errorCount );
376 if ( !bRetry )
377 throw;
380 while ( bRetry );
383 //=========================================================================
384 uno::Reference< io::XInputStream > DAVResourceAccess::GET(
385 const uno::Reference< ucb::XCommandEnvironment > & xEnv )
386 throw( DAVException )
388 initialize();
390 uno::Reference< io::XInputStream > xStream;
391 int errorCount = 0;
392 bool bRetry;
395 bRetry = false;
398 DAVRequestHeaders aHeaders;
399 getUserRequestHeaders( xEnv,
400 getRequestURI(),
401 rtl::OUString("GET"),
402 aHeaders );
404 xStream = m_xSession->GET( getRequestURI(),
405 DAVRequestEnvironment(
406 getRequestURI(),
407 new DAVAuthListener_Impl(
408 xEnv, m_aURL ),
409 aHeaders, xEnv ) );
411 catch ( const DAVException & e )
413 errorCount++;
414 bRetry = handleException( e, errorCount );
415 if ( !bRetry )
416 throw;
419 while ( bRetry );
421 return xStream;
424 //=========================================================================
425 void DAVResourceAccess::GET(
426 uno::Reference< io::XOutputStream > & rStream,
427 const uno::Reference< ucb::XCommandEnvironment > & xEnv )
428 throw( DAVException )
430 initialize();
432 int errorCount = 0;
433 bool bRetry;
436 bRetry = false;
439 DAVRequestHeaders aHeaders;
440 getUserRequestHeaders( xEnv,
441 getRequestURI(),
442 rtl::OUString("GET"),
443 aHeaders );
445 m_xSession->GET( getRequestURI(),
446 rStream,
447 DAVRequestEnvironment(
448 getRequestURI(),
449 new DAVAuthListener_Impl( xEnv, m_aURL ),
450 aHeaders, xEnv ) );
452 catch ( const DAVException & e )
454 errorCount++;
455 bRetry = handleException( e, errorCount );
456 if ( !bRetry )
457 throw;
460 while ( bRetry );
463 //=========================================================================
464 uno::Reference< io::XInputStream > DAVResourceAccess::GET(
465 const std::vector< rtl::OUString > & rHeaderNames,
466 DAVResource & rResource,
467 const uno::Reference< ucb::XCommandEnvironment > & xEnv )
468 throw( DAVException )
470 initialize();
472 uno::Reference< io::XInputStream > xStream;
473 int errorCount = 0;
474 bool bRetry;
477 bRetry = false;
480 DAVRequestHeaders aHeaders;
481 getUserRequestHeaders( xEnv,
482 getRequestURI(),
483 rtl::OUString("GET"),
484 aHeaders );
486 xStream = m_xSession->GET( getRequestURI(),
487 rHeaderNames,
488 rResource,
489 DAVRequestEnvironment(
490 getRequestURI(),
491 new DAVAuthListener_Impl(
492 xEnv, m_aURL ),
493 aHeaders, xEnv ) );
495 catch ( const DAVException & e )
497 errorCount++;
498 bRetry = handleException( e, errorCount );
499 if ( !bRetry )
500 throw;
503 while ( bRetry );
505 return xStream;
508 //=========================================================================
509 void DAVResourceAccess::GET(
510 uno::Reference< io::XOutputStream > & rStream,
511 const std::vector< rtl::OUString > & rHeaderNames,
512 DAVResource & rResource,
513 const uno::Reference< ucb::XCommandEnvironment > & xEnv )
514 throw( DAVException )
516 initialize();
518 bool bRetry;
519 int errorCount = 0;
522 bRetry = false;
525 DAVRequestHeaders aHeaders;
526 getUserRequestHeaders( xEnv,
527 getRequestURI(),
528 rtl::OUString("GET"),
529 aHeaders );
531 m_xSession->GET( getRequestURI(),
532 rStream,
533 rHeaderNames,
534 rResource,
535 DAVRequestEnvironment(
536 getRequestURI(),
537 new DAVAuthListener_Impl( xEnv, m_aURL ),
538 aHeaders, xEnv ) );
540 catch ( const DAVException & e )
542 errorCount++;
543 bRetry = handleException( e, errorCount );
544 if ( !bRetry )
545 throw;
548 while ( bRetry );
551 //=========================================================================
552 void DAVResourceAccess::abort()
553 throw( DAVException )
555 // 17.11.09 (tkr): abort currently disabled caused by issue i106766
556 // initialize();
557 // m_xSession->abort();
558 OSL_TRACE( "Not implemented. -> #i106766#" );
561 //=========================================================================
562 namespace {
564 void resetInputStream( const uno::Reference< io::XInputStream > & rStream )
565 throw( DAVException )
569 uno::Reference< io::XSeekable > xSeekable(
570 rStream, uno::UNO_QUERY );
571 if ( xSeekable.is() )
573 xSeekable->seek( 0 );
574 return;
577 catch ( lang::IllegalArgumentException const & )
580 catch ( io::IOException const & )
584 throw DAVException( DAVException::DAV_INVALID_ARG );
587 } // namespace
589 //=========================================================================
590 void DAVResourceAccess::PUT(
591 const uno::Reference< io::XInputStream > & rStream,
592 const uno::Reference< ucb::XCommandEnvironment > & xEnv )
593 throw( DAVException )
595 initialize();
597 // Make stream seekable, if it not. Needed, if request must be retried.
598 uno::Reference< io::XInputStream > xSeekableStream
599 = comphelper::OSeekableInputWrapper::CheckSeekableCanWrap(
600 rStream, m_xSMgr );
602 int errorCount = 0;
603 bool bRetry = false;
606 if ( bRetry )
607 resetInputStream( xSeekableStream );
609 bRetry = false;
612 DAVRequestHeaders aHeaders;
613 getUserRequestHeaders( xEnv,
614 getRequestURI(),
615 rtl::OUString("PUT"),
616 aHeaders );
618 m_xSession->PUT( getRequestURI(),
619 xSeekableStream,
620 DAVRequestEnvironment(
621 getRequestURI(),
622 new DAVAuthListener_Impl( xEnv, m_aURL ),
623 aHeaders, xEnv ) );
625 catch ( const DAVException & e )
627 errorCount++;
628 bRetry = handleException( e, errorCount );
629 if ( !bRetry )
630 throw;
633 while ( bRetry );
636 //=========================================================================
637 uno::Reference< io::XInputStream > DAVResourceAccess::POST(
638 const rtl::OUString & rContentType,
639 const rtl::OUString & rReferer,
640 const uno::Reference< io::XInputStream > & rInputStream,
641 const uno::Reference< ucb::XCommandEnvironment >& xEnv )
642 throw ( DAVException )
644 initialize();
646 // Make stream seekable, if it not. Needed, if request must be retried.
647 uno::Reference< io::XInputStream > xSeekableStream
648 = comphelper::OSeekableInputWrapper::CheckSeekableCanWrap(
649 rInputStream, m_xSMgr );
651 uno::Reference< io::XInputStream > xStream;
652 int errorCount = 0;
653 bool bRetry = false;
656 if ( bRetry )
658 resetInputStream( xSeekableStream );
659 bRetry = false;
664 DAVRequestHeaders aHeaders;
665 getUserRequestHeaders( xEnv,
666 getRequestURI(),
667 rtl::OUString("POST"),
668 aHeaders );
670 xStream = m_xSession->POST( getRequestURI(),
671 rContentType,
672 rReferer,
673 xSeekableStream,
674 DAVRequestEnvironment(
675 getRequestURI(),
676 new DAVAuthListener_Impl(
677 xEnv, m_aURL ),
678 aHeaders, xEnv ) );
680 catch ( const DAVException & e )
682 errorCount++;
683 bRetry = handleException( e, errorCount );
684 if ( !bRetry )
685 throw;
687 if ( e.getError() == DAVException::DAV_HTTP_REDIRECT )
689 // #i74980# - Upon POST redirect, do a GET.
690 return GET( xEnv );
694 while ( bRetry );
696 return xStream;
699 //=========================================================================
700 void DAVResourceAccess::POST(
701 const rtl::OUString & rContentType,
702 const rtl::OUString & rReferer,
703 const uno::Reference< io::XInputStream > & rInputStream,
704 uno::Reference< io::XOutputStream > & rOutputStream,
705 const uno::Reference< ucb::XCommandEnvironment >& xEnv )
706 throw ( DAVException )
708 initialize();
710 // Make stream seekable, if it not. Needed, if request must be retried.
711 uno::Reference< io::XInputStream > xSeekableStream
712 = comphelper::OSeekableInputWrapper::CheckSeekableCanWrap(
713 rInputStream, m_xSMgr );
715 int errorCount = 0;
716 bool bRetry = false;
719 if ( bRetry )
721 resetInputStream( xSeekableStream );
722 bRetry = false;
727 DAVRequestHeaders aHeaders;
728 getUserRequestHeaders( xEnv,
729 getRequestURI(),
730 rtl::OUString("POST"),
731 aHeaders );
733 m_xSession->POST( getRequestURI(),
734 rContentType,
735 rReferer,
736 xSeekableStream,
737 rOutputStream,
738 DAVRequestEnvironment(
739 getRequestURI(),
740 new DAVAuthListener_Impl( xEnv, m_aURL ),
741 aHeaders, xEnv ) );
743 catch ( const DAVException & e )
745 errorCount++;
746 bRetry = handleException( e, errorCount );
747 if ( !bRetry )
748 throw;
750 if ( e.getError() == DAVException::DAV_HTTP_REDIRECT )
752 // #i74980# - Upon POST redirect, do a GET.
753 GET( rOutputStream, xEnv );
754 return;
758 while ( bRetry );
761 //=========================================================================
762 void DAVResourceAccess::MKCOL(
763 const uno::Reference< ucb::XCommandEnvironment > & xEnv )
764 throw( DAVException )
766 initialize();
768 int errorCount = 0;
769 bool bRetry;
772 bRetry = false;
775 DAVRequestHeaders aHeaders;
776 getUserRequestHeaders( xEnv,
777 getRequestURI(),
778 rtl::OUString("MKCOL"),
779 aHeaders );
781 m_xSession->MKCOL( getRequestURI(),
782 DAVRequestEnvironment(
783 getRequestURI(),
784 new DAVAuthListener_Impl( xEnv, m_aURL ),
785 aHeaders, xEnv ) );
787 catch ( const DAVException & e )
789 errorCount++;
790 bRetry = handleException( e, errorCount );
791 if ( !bRetry )
792 throw;
795 while ( bRetry );
798 //=========================================================================
799 void DAVResourceAccess::COPY(
800 const ::rtl::OUString & rSourcePath,
801 const ::rtl::OUString & rDestinationURI,
802 sal_Bool bOverwrite,
803 const uno::Reference< ucb::XCommandEnvironment > & xEnv )
804 throw( DAVException )
806 initialize();
808 int errorCount = 0;
809 bool bRetry;
812 bRetry = false;
815 DAVRequestHeaders aHeaders;
816 getUserRequestHeaders( xEnv,
817 getRequestURI(),
818 rtl::OUString("COPY"),
819 aHeaders );
821 m_xSession->COPY( rSourcePath,
822 rDestinationURI,
823 DAVRequestEnvironment(
824 getRequestURI(),
825 new DAVAuthListener_Impl( xEnv, m_aURL ),
826 aHeaders, xEnv ),
827 bOverwrite );
829 catch ( const DAVException & e )
831 errorCount++;
832 bRetry = handleException( e, errorCount );
833 if ( !bRetry )
834 throw;
837 while ( bRetry );
840 //=========================================================================
841 void DAVResourceAccess::MOVE(
842 const ::rtl::OUString & rSourcePath,
843 const ::rtl::OUString & rDestinationURI,
844 sal_Bool bOverwrite,
845 const uno::Reference< ucb::XCommandEnvironment > & xEnv )
846 throw( DAVException )
848 initialize();
850 int errorCount = 0;
851 bool bRetry;
854 bRetry = false;
857 DAVRequestHeaders aHeaders;
858 getUserRequestHeaders( xEnv,
859 getRequestURI(),
860 rtl::OUString("MOVE"),
861 aHeaders );
863 m_xSession->MOVE( rSourcePath,
864 rDestinationURI,
865 DAVRequestEnvironment(
866 getRequestURI(),
867 new DAVAuthListener_Impl( xEnv, m_aURL ),
868 aHeaders, xEnv ),
869 bOverwrite );
871 catch ( const DAVException & e )
873 errorCount++;
874 bRetry = handleException( e, errorCount );
875 if ( !bRetry )
876 throw;
879 while ( bRetry );
882 //=========================================================================
883 void DAVResourceAccess::DESTROY(
884 const uno::Reference< ucb::XCommandEnvironment > & xEnv )
885 throw( DAVException )
887 initialize();
889 int errorCount = 0;
890 bool bRetry;
893 bRetry = false;
896 DAVRequestHeaders aHeaders;
897 getUserRequestHeaders( xEnv,
898 getRequestURI(),
899 rtl::OUString( "DESTROY" ),
900 aHeaders );
902 m_xSession->DESTROY( getRequestURI(),
903 DAVRequestEnvironment(
904 getRequestURI(),
905 new DAVAuthListener_Impl( xEnv, m_aURL ),
906 aHeaders, xEnv ) );
908 catch ( const DAVException & e )
910 errorCount++;
911 bRetry = handleException( e, errorCount );
912 if ( !bRetry )
913 throw;
916 while ( bRetry );
919 //=========================================================================
920 // set new lock.
921 void DAVResourceAccess::LOCK(
922 ucb::Lock & inLock,
923 const uno::Reference< ucb::XCommandEnvironment > & xEnv )
924 throw ( DAVException )
926 initialize();
928 int errorCount = 0;
929 bool bRetry;
932 bRetry = false;
935 DAVRequestHeaders aHeaders;
936 getUserRequestHeaders( xEnv,
937 getRequestURI(),
938 rtl::OUString("LOCK"),
939 aHeaders );
941 m_xSession->LOCK( getRequestURI(),
942 inLock,
943 DAVRequestEnvironment(
944 getRequestURI(),
945 new DAVAuthListener_Impl( xEnv, m_aURL ),
946 aHeaders, xEnv ) );
948 catch ( const DAVException & e )
950 errorCount++;
951 bRetry = handleException( e, errorCount );
952 if ( !bRetry )
953 throw;
956 while ( bRetry );
959 #if 0 // currently not used, but please don't remove code
960 //=========================================================================
961 // refresh existing lock.
962 sal_Int64 DAVResourceAccess::LOCK(
963 sal_Int64 nTimeout,
964 const uno::Reference< ucb::XCommandEnvironment > & xEnv )
965 throw ( DAVException )
967 initialize();
969 sal_Int64 nNewTimeout = 0;
970 int errorCount = 0;
971 bool bRetry;
974 bRetry = false;
977 DAVRequestHeaders aHeaders;
978 getUserRequestHeaders( xEnv,
979 getRequestURI(),
980 rtl::OUString("LOCK"),
981 aHeaders );
983 nNewTimeout = m_xSession->LOCK( getRequestURI(),
984 nTimeout,
985 DAVRequestEnvironment(
986 getRequestURI(),
987 new DAVAuthListener_Impl(
988 xEnv, m_aURL ),
989 aHeaders, xEnv ) );
991 catch ( const DAVException & e )
993 errorCount++;
994 bRetry = handleException( e, errorCount );
995 if ( !bRetry )
996 throw;
999 while ( bRetry );
1001 return nNewTimeout;
1003 #endif
1005 //=========================================================================
1006 void DAVResourceAccess::UNLOCK(
1007 const uno::Reference< ucb::XCommandEnvironment > & xEnv )
1008 throw ( DAVException )
1010 initialize();
1012 int errorCount = 0;
1013 bool bRetry;
1016 bRetry = false;
1019 DAVRequestHeaders aHeaders;
1020 getUserRequestHeaders( xEnv,
1021 getRequestURI(),
1022 rtl::OUString("UNLOCK"),
1023 aHeaders );
1025 m_xSession->UNLOCK( getRequestURI(),
1026 DAVRequestEnvironment(
1027 getRequestURI(),
1028 new DAVAuthListener_Impl( xEnv, m_aURL ),
1029 aHeaders, xEnv ) );
1031 catch ( const DAVException & e )
1033 errorCount++;
1034 bRetry = handleException( e, errorCount );
1035 if ( !bRetry )
1036 throw;
1039 while ( bRetry );
1042 //=========================================================================
1043 void DAVResourceAccess::setFlags( const uno::Sequence< beans::NamedValue >& rFlags )
1044 throw ( DAVException )
1046 osl::Guard< osl::Mutex > aGuard( m_aMutex );
1047 m_aFlags = rFlags;
1050 //=========================================================================
1051 void DAVResourceAccess::setURL( const rtl::OUString & rNewURL )
1052 throw( DAVException )
1054 osl::Guard< osl::Mutex > aGuard( m_aMutex );
1055 m_aURL = rNewURL;
1056 m_aPath = rtl::OUString(); // Next initialize() will create new session.
1059 //=========================================================================
1060 // init dav session and path
1061 void DAVResourceAccess::initialize()
1062 throw ( DAVException )
1064 osl::Guard< osl::Mutex > aGuard( m_aMutex );
1065 if ( m_aPath.isEmpty() )
1067 NeonUri aURI( m_aURL );
1068 rtl::OUString aPath( aURI.GetPath() );
1070 /* #134089# - Check URI */
1071 if ( aPath.isEmpty() )
1072 throw DAVException( DAVException::DAV_INVALID_ARG );
1074 /* #134089# - Check URI */
1075 if ( aURI.GetHost().isEmpty() )
1076 throw DAVException( DAVException::DAV_INVALID_ARG );
1078 if ( !m_xSession.is() || !m_xSession->CanUse( m_aURL, m_aFlags ) )
1080 m_xSession.clear();
1082 // create new webdav session
1083 m_xSession
1084 = m_xSessionFactory->createDAVSession( m_aURL, m_aFlags, m_xSMgr );
1086 if ( !m_xSession.is() )
1087 return;
1090 // Own URI is needed for redirect cycle detection.
1091 m_aRedirectURIs.push_back( aURI );
1093 // Success.
1094 m_aPath = aPath;
1096 // Not only the path has to be encoded
1097 m_aURL = aURI.GetURI();
1101 //=========================================================================
1102 const rtl::OUString & DAVResourceAccess::getRequestURI() const
1104 OSL_ENSURE( m_xSession.is(),
1105 "DAVResourceAccess::getRequestURI - Not initialized!" );
1107 // In case a proxy is used we have to use the absolute URI for a request.
1108 if ( m_xSession->UsesProxy() )
1109 return m_aURL;
1111 return m_aPath;
1114 //=========================================================================
1115 // static
1116 void DAVResourceAccess::getUserRequestHeaders(
1117 const uno::Reference< ucb::XCommandEnvironment > & xEnv,
1118 const rtl::OUString & rURI,
1119 const rtl::OUString & rMethod,
1120 DAVRequestHeaders & rRequestHeaders )
1122 if ( xEnv.is() )
1124 uno::Reference< ucb::XWebDAVCommandEnvironment > xDAVEnv(
1125 xEnv, uno::UNO_QUERY );
1127 if ( xDAVEnv.is() )
1129 uno::Sequence< beans::NamedValue > aRequestHeaders
1130 = xDAVEnv->getUserRequestHeaders( rURI, rMethod );
1132 for ( sal_Int32 n = 0; n < aRequestHeaders.getLength(); ++n )
1134 rtl::OUString aValue;
1135 sal_Bool isString = aRequestHeaders[ n ].Value >>= aValue;
1137 if ( !isString )
1139 OSL_ENSURE( isString,
1140 "DAVResourceAccess::getUserRequestHeaders :"
1141 "Value is not a string! Ignoring..." );
1144 rRequestHeaders.push_back(
1145 DAVRequestHeader( aRequestHeaders[ n ].Name, aValue ) );
1150 // Make sure a User-Agent header is always included, as at least
1151 // en.wikipedia.org:80 forces back 403 "Scripts should use an informative
1152 // User-Agent string with contact information, or they may be IP-blocked
1153 // without notice" otherwise:
1154 for ( DAVRequestHeaders::iterator i(rRequestHeaders.begin());
1155 i != rRequestHeaders.end(); ++i )
1157 if ( i->first.equalsIgnoreAsciiCase( "User-Agent" ) )
1159 return;
1162 rRequestHeaders.push_back(
1163 DAVRequestHeader( "User-Agent", "LibreOffice" ) );
1166 //=========================================================================
1167 sal_Bool DAVResourceAccess::detectRedirectCycle(
1168 const rtl::OUString& rRedirectURL )
1169 throw ( DAVException )
1171 osl::Guard< osl::Mutex > aGuard( m_aMutex );
1173 NeonUri aUri( rRedirectURL );
1175 std::vector< NeonUri >::const_iterator it = m_aRedirectURIs.begin();
1176 std::vector< NeonUri >::const_iterator end = m_aRedirectURIs.end();
1178 while ( it != end )
1180 if ( aUri == (*it) )
1181 return sal_True;
1183 ++it;
1186 return sal_False;
1189 //=========================================================================
1190 void DAVResourceAccess::resetUri()
1192 osl::Guard< osl::Mutex > aGuard( m_aMutex );
1193 if ( !m_aRedirectURIs.empty() )
1195 std::vector< NeonUri >::const_iterator it = m_aRedirectURIs.begin();
1197 NeonUri aUri( (*it) );
1198 m_aRedirectURIs.clear();
1199 setURL ( aUri.GetURI() );
1200 initialize();
1204 //=========================================================================
1205 sal_Bool DAVResourceAccess::handleException( const DAVException & e, int errorCount )
1206 throw ( DAVException )
1208 switch ( e.getError() )
1210 case DAVException::DAV_HTTP_REDIRECT:
1211 if ( !detectRedirectCycle( e.getData() ) )
1213 // set new URL and path.
1214 setURL( e.getData() );
1215 initialize();
1216 return sal_True;
1218 return sal_False;
1219 // #67048# copy & paste images doesn't display.
1220 // if we have a bad connection try again. Up to three times.
1221 case DAVException::DAV_HTTP_ERROR:
1222 // retry up to three times, if not a client-side error.
1223 if ( ( e.getStatus() < 400 || e.getStatus() >= 500 ) &&
1224 errorCount < 3 )
1226 return sal_True;
1228 return sal_False;
1229 // if connection has said retry then retry!
1230 case DAVException::DAV_HTTP_RETRY:
1231 return sal_True;
1232 default:
1233 return sal_False; // Abort
1237 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */