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.
55 int DAVAuthListener_Impl::authenticate(
56 const OUString
& inRealm
,
57 const OUString
& inHostName
,
58 OUString
& inoutUserName
,
59 OUString
& outPassWord
,
60 bool bCanUseSystemCredentials
)
64 uno::Reference
< task::XInteractionHandler
> xIH
65 = m_xEnv
->getInteractionHandler();
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
);
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();
114 inoutUserName
= xSupp
->getUserName();
115 outPassWord
= xSupp
->getPassword();
118 // #102871# - Remember username and password.
119 m_aPrevUsername
= inoutUserName
;
120 m_aPrevPassword
= outPassWord
;
135 // DAVResourceAccess Implementation.
141 DAVResourceAccess::DAVResourceAccess(
142 const uno::Reference
< uno::XComponentContext
> & rxContext
,
143 rtl::Reference
< DAVSessionFactory
> const & rSessionFactory
,
144 const OUString
& 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
;
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
)
194 DAVRequestHeaders aHeaders
;
195 getUserRequestHeaders( xEnv
,
197 OUString( "OPTIONS" ),
200 m_xSession
->OPTIONS( getRequestURI(),
202 DAVRequestEnvironment(
204 new DAVAuthListener_Impl( xEnv
, m_aURL
),
207 catch ( const DAVException
& e
)
210 bRetry
= handleException( e
, errorCount
);
220 void DAVResourceAccess::PROPFIND(
222 const std::vector
< OUString
> & rPropertyNames
,
223 std::vector
< DAVResource
> & rResources
,
224 const uno::Reference
< ucb::XCommandEnvironment
> & xEnv
)
225 throw( DAVException
)
236 DAVRequestHeaders aHeaders
;
238 getUserRequestHeaders( xEnv
,
240 ucb::WebDAVHTTPMethod_PROPFIND
,
243 m_xSession
->PROPFIND( getRequestURI(),
247 DAVRequestEnvironment(
249 new DAVAuthListener_Impl( xEnv
, m_aURL
),
252 catch ( const DAVException
& e
)
255 bRetry
= handleException( e
, errorCount
);
264 void DAVResourceAccess::PROPFIND(
266 std::vector
< DAVResourceInfo
> & rResInfo
,
267 const uno::Reference
< ucb::XCommandEnvironment
> & xEnv
)
268 throw( DAVException
)
279 DAVRequestHeaders aHeaders
;
280 getUserRequestHeaders( xEnv
,
282 ucb::WebDAVHTTPMethod_PROPFIND
,
285 m_xSession
->PROPFIND( getRequestURI(),
288 DAVRequestEnvironment(
290 new DAVAuthListener_Impl( xEnv
, m_aURL
),
293 catch ( const DAVException
& e
)
296 bRetry
= handleException( e
, errorCount
);
305 void DAVResourceAccess::PROPPATCH(
306 const std::vector
< ProppatchValue
>& rValues
,
307 const uno::Reference
< ucb::XCommandEnvironment
>& xEnv
)
308 throw( DAVException
)
319 DAVRequestHeaders aHeaders
;
320 getUserRequestHeaders( xEnv
,
322 ucb::WebDAVHTTPMethod_PROPPATCH
,
325 m_xSession
->PROPPATCH( getRequestURI(),
327 DAVRequestEnvironment(
329 new DAVAuthListener_Impl( xEnv
, m_aURL
),
332 catch ( const DAVException
& e
)
335 bRetry
= handleException( e
, errorCount
);
344 void DAVResourceAccess::HEAD(
345 const std::vector
< OUString
> & rHeaderNames
,
346 DAVResource
& rResource
,
347 const uno::Reference
< ucb::XCommandEnvironment
>& xEnv
)
348 throw( DAVException
)
359 DAVRequestHeaders aHeaders
;
360 getUserRequestHeaders( xEnv
,
362 ucb::WebDAVHTTPMethod_HEAD
,
365 m_xSession
->HEAD( getRequestURI(),
368 DAVRequestEnvironment(
370 new DAVAuthListener_Impl( xEnv
, m_aURL
),
373 catch ( const DAVException
& e
)
376 bRetry
= handleException( e
, errorCount
);
385 uno::Reference
< io::XInputStream
> DAVResourceAccess::GET(
386 const uno::Reference
< ucb::XCommandEnvironment
> & xEnv
)
387 throw( DAVException
)
391 uno::Reference
< io::XInputStream
> xStream
;
399 DAVRequestHeaders aHeaders
;
400 getUserRequestHeaders( xEnv
,
402 ucb::WebDAVHTTPMethod_GET
,
405 xStream
= m_xSession
->GET( getRequestURI(),
406 DAVRequestEnvironment(
408 new DAVAuthListener_Impl(
412 catch ( const DAVException
& e
)
415 bRetry
= handleException( e
, errorCount
);
426 void DAVResourceAccess::GET(
427 uno::Reference
< io::XOutputStream
> & rStream
,
428 const uno::Reference
< ucb::XCommandEnvironment
> & xEnv
)
429 throw( DAVException
)
440 DAVRequestHeaders aHeaders
;
441 getUserRequestHeaders( xEnv
,
443 ucb::WebDAVHTTPMethod_GET
,
446 m_xSession
->GET( getRequestURI(),
448 DAVRequestEnvironment(
450 new DAVAuthListener_Impl( xEnv
, m_aURL
),
453 catch ( const DAVException
& e
)
456 bRetry
= handleException( e
, errorCount
);
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
)
473 uno::Reference
< io::XInputStream
> xStream
;
481 DAVRequestHeaders aHeaders
;
482 getUserRequestHeaders( xEnv
,
484 ucb::WebDAVHTTPMethod_GET
,
487 xStream
= m_xSession
->GET( getRequestURI(),
490 DAVRequestEnvironment(
492 new DAVAuthListener_Impl(
496 catch ( const DAVException
& e
)
499 bRetry
= handleException( e
, errorCount
);
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
)
526 DAVRequestHeaders aHeaders
;
527 getUserRequestHeaders( xEnv
,
529 ucb::WebDAVHTTPMethod_GET
,
532 m_xSession
->GET( getRequestURI(),
536 DAVRequestEnvironment(
538 new DAVAuthListener_Impl( xEnv
, m_aURL
),
541 catch ( const DAVException
& e
)
544 bRetry
= handleException( e
, errorCount
);
553 void DAVResourceAccess::abort()
554 throw( DAVException
)
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 );
576 catch ( lang::IllegalArgumentException
const & )
579 catch ( io::IOException
const & )
583 throw DAVException( DAVException::DAV_INVALID_ARG
);
589 void DAVResourceAccess::PUT(
590 const uno::Reference
< io::XInputStream
> & rStream
,
591 const uno::Reference
< ucb::XCommandEnvironment
> & xEnv
)
592 throw (css::uno::RuntimeException
, DAVException
)
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
);
606 resetInputStream( xSeekableStream
);
611 DAVRequestHeaders aHeaders
;
612 getUserRequestHeaders( xEnv
,
614 ucb::WebDAVHTTPMethod_PUT
,
617 m_xSession
->PUT( getRequestURI(),
619 DAVRequestEnvironment(
621 new DAVAuthListener_Impl( xEnv
, m_aURL
),
624 catch ( const DAVException
& e
)
627 bRetry
= handleException( e
, errorCount
);
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
)
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
;
657 resetInputStream( xSeekableStream
);
663 DAVRequestHeaders aHeaders
;
664 getUserRequestHeaders( xEnv
,
666 ucb::WebDAVHTTPMethod_POST
,
669 xStream
= m_xSession
->POST( getRequestURI(),
673 DAVRequestEnvironment(
675 new DAVAuthListener_Impl(
679 catch ( const DAVException
& e
)
682 bRetry
= handleException( e
, errorCount
);
686 if ( e
.getError() == DAVException::DAV_HTTP_REDIRECT
)
688 // #i74980# - Upon POST redirect, do a GET.
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
)
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
);
720 resetInputStream( xSeekableStream
);
726 DAVRequestHeaders aHeaders
;
727 getUserRequestHeaders( xEnv
,
729 ucb::WebDAVHTTPMethod_POST
,
732 m_xSession
->POST( getRequestURI(),
737 DAVRequestEnvironment(
739 new DAVAuthListener_Impl( xEnv
, m_aURL
),
742 catch ( const DAVException
& e
)
745 bRetry
= handleException( e
, errorCount
);
749 if ( e
.getError() == DAVException::DAV_HTTP_REDIRECT
)
751 // #i74980# - Upon POST redirect, do a GET.
752 GET( rOutputStream
, xEnv
);
761 void DAVResourceAccess::MKCOL(
762 const uno::Reference
< ucb::XCommandEnvironment
> & xEnv
)
763 throw( DAVException
)
774 DAVRequestHeaders aHeaders
;
775 getUserRequestHeaders( xEnv
,
777 ucb::WebDAVHTTPMethod_MKCOL
,
780 m_xSession
->MKCOL( getRequestURI(),
781 DAVRequestEnvironment(
783 new DAVAuthListener_Impl( xEnv
, m_aURL
),
786 catch ( const DAVException
& e
)
789 bRetry
= handleException( e
, errorCount
);
798 void DAVResourceAccess::COPY(
799 const OUString
& rSourcePath
,
800 const OUString
& rDestinationURI
,
802 const uno::Reference
< ucb::XCommandEnvironment
> & xEnv
)
803 throw( DAVException
)
814 DAVRequestHeaders aHeaders
;
815 getUserRequestHeaders( xEnv
,
817 ucb::WebDAVHTTPMethod_COPY
,
820 m_xSession
->COPY( rSourcePath
,
822 DAVRequestEnvironment(
824 new DAVAuthListener_Impl( xEnv
, m_aURL
),
828 catch ( const DAVException
& e
)
831 bRetry
= handleException( e
, errorCount
);
840 void DAVResourceAccess::MOVE(
841 const OUString
& rSourcePath
,
842 const OUString
& rDestinationURI
,
844 const uno::Reference
< ucb::XCommandEnvironment
> & xEnv
)
845 throw( DAVException
)
856 DAVRequestHeaders aHeaders
;
857 getUserRequestHeaders( xEnv
,
859 ucb::WebDAVHTTPMethod_MOVE
,
862 m_xSession
->MOVE( rSourcePath
,
864 DAVRequestEnvironment(
866 new DAVAuthListener_Impl( xEnv
, m_aURL
),
870 catch ( const DAVException
& e
)
873 bRetry
= handleException( e
, errorCount
);
882 void DAVResourceAccess::DESTROY(
883 const uno::Reference
< ucb::XCommandEnvironment
> & xEnv
)
884 throw( DAVException
)
895 DAVRequestHeaders aHeaders
;
896 getUserRequestHeaders( xEnv
,
898 ucb::WebDAVHTTPMethod_DELETE
,
901 m_xSession
->DESTROY( getRequestURI(),
902 DAVRequestEnvironment(
904 new DAVAuthListener_Impl( xEnv
, m_aURL
),
907 catch ( const DAVException
& e
)
910 bRetry
= handleException( e
, errorCount
);
920 void DAVResourceAccess::LOCK(
922 const uno::Reference
< ucb::XCommandEnvironment
> & xEnv
)
923 throw ( DAVException
)
934 DAVRequestHeaders aHeaders
;
935 getUserRequestHeaders( xEnv
,
937 ucb::WebDAVHTTPMethod_LOCK
,
940 m_xSession
->LOCK( getRequestURI(),
942 DAVRequestEnvironment(
944 new DAVAuthListener_Impl( xEnv
, m_aURL
),
947 catch ( const DAVException
& e
)
950 bRetry
= handleException( e
, errorCount
);
958 #if 0 // currently not used, but please don't remove code
960 // refresh existing lock.
961 sal_Int64
DAVResourceAccess::LOCK(
963 const uno::Reference
< ucb::XCommandEnvironment
> & xEnv
)
964 throw ( DAVException
)
968 sal_Int64 nNewTimeout
= 0;
976 DAVRequestHeaders aHeaders
;
977 getUserRequestHeaders( xEnv
,
979 ucb::WebDAVHTTPMethod_LOCK
,
982 nNewTimeout
= m_xSession
->LOCK( getRequestURI(),
984 DAVRequestEnvironment(
986 new DAVAuthListener_Impl(
990 catch ( const DAVException
& e
)
993 bRetry
= handleException( e
, errorCount
);
1005 void DAVResourceAccess::UNLOCK(
1006 const uno::Reference
< ucb::XCommandEnvironment
> & xEnv
)
1007 throw ( DAVException
)
1018 DAVRequestHeaders aHeaders
;
1019 getUserRequestHeaders( xEnv
,
1021 ucb::WebDAVHTTPMethod_UNLOCK
,
1024 m_xSession
->UNLOCK( getRequestURI(),
1025 DAVRequestEnvironment(
1027 new DAVAuthListener_Impl( xEnv
, m_aURL
),
1030 catch ( const DAVException
& e
)
1033 bRetry
= handleException( e
, errorCount
);
1042 void DAVResourceAccess::setFlags( const uno::Sequence
< beans::NamedValue
>& rFlags
)
1043 throw ( DAVException
)
1045 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
1050 void DAVResourceAccess::setURL( const OUString
& rNewURL
)
1051 throw( DAVException
)
1053 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
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
) )
1081 // create new webdav session
1083 = m_xSessionFactory
->createDAVSession( m_aURL
, m_aFlags
, m_xContext
);
1085 if ( !m_xSession
.is() )
1089 // Own URI is needed for redirect cycle detection.
1090 m_aRedirectURIs
.push_back( aURI
);
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() )
1115 void DAVResourceAccess::getUserRequestHeaders(
1116 const uno::Reference
< ucb::XCommandEnvironment
> & xEnv
,
1117 const OUString
& rURI
,
1118 ucb::WebDAVHTTPMethod eMethod
,
1119 DAVRequestHeaders
& rRequestHeaders
)
1123 uno::Reference
< ucb::XWebDAVCommandEnvironment
> xDAVEnv(
1124 xEnv
, uno::UNO_QUERY
);
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(
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" ) )
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();
1171 if ( aUri
== (*it
) )
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() );
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() );
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 ) &&
1220 // if connection has said retry then retry!
1221 case DAVException::DAV_HTTP_RETRY
:
1224 return false; // Abort
1228 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */