diff options
author | Giuseppe Castagno <giuseppe.castagno@acca-esse.eu> | 2016-09-25 17:48:27 +0200 |
---|---|---|
committer | Giuseppe Castagno <giuseppe.castagno@acca-esse.eu> | 2016-10-05 12:10:40 +0000 |
commit | f423a9d695814b1babf5f2c3f42821190adc7e53 (patch) | |
tree | 032e399a327914ec4d5c9dff234757a1bfba80c4 /ucb | |
parent | 7cf9028d3b735c5a1929897e556357b5d18573a2 (diff) |
tdf#102499 (3): Change caching model for HTTP response status code
Instead of caching only a single status flag, now both the HTTP
response status code and the message accompanying it are cached.
Change-Id: If7352f6b0cb7c7dab6af3cede96647308baa5ce2
Reviewed-on: https://gerrit.libreoffice.org/29538
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Giuseppe Castagno <giuseppe.castagno@acca-esse.eu>
Diffstat (limited to 'ucb')
-rw-r--r-- | ucb/qa/cppunit/webdav/webdav_options.cxx | 84 | ||||
-rw-r--r-- | ucb/source/ucp/webdav-neon/DAVTypes.cxx | 30 | ||||
-rw-r--r-- | ucb/source/ucp/webdav-neon/DAVTypes.hxx | 38 | ||||
-rw-r--r-- | ucb/source/ucp/webdav-neon/NeonSession.cxx | 3 | ||||
-rw-r--r-- | ucb/source/ucp/webdav-neon/webdavcontent.cxx | 241 |
5 files changed, 214 insertions, 182 deletions
diff --git a/ucb/qa/cppunit/webdav/webdav_options.cxx b/ucb/qa/cppunit/webdav/webdav_options.cxx index 371873354743..0dad7f8d155b 100644 --- a/ucb/qa/cppunit/webdav/webdav_options.cxx +++ b/ucb/qa/cppunit/webdav/webdav_options.cxx @@ -55,7 +55,6 @@ namespace { // check if the class is at reset state // using accessors - CPPUNIT_ASSERT_EQUAL( false, aDavType.isResourceFound() ); CPPUNIT_ASSERT_EQUAL( false, aDavType.isClass1() ); CPPUNIT_ASSERT_EQUAL( false, aDavType.isClass2() ); CPPUNIT_ASSERT_EQUAL( false, aDavType.isClass3() ); @@ -66,6 +65,8 @@ namespace CPPUNIT_ASSERT_EQUAL( true, aDavType.getURL().isEmpty() ); CPPUNIT_ASSERT_EQUAL( true, aDavType.getRedirectedURL().isEmpty() ); CPPUNIT_ASSERT_EQUAL( sal_uInt32( 0 ), aDavType.getStaleTime() ); + CPPUNIT_ASSERT_EQUAL( sal_uInt16( 0 ), aDavType.getHttpResponseStatusCode() ); + CPPUNIT_ASSERT_EQUAL( true, aDavType.getHttpResponseStatusText().isEmpty() ); } void webdav_opts_test::DAVTypesTest() @@ -73,22 +74,8 @@ namespace //our DAVOptions webdav_ucp::DAVOptions aDavOpt; DAVTypesCheckInit( aDavOpt ); - aDavOpt.setResourceFound(); - //recheck... - CPPUNIT_ASSERT_EQUAL( true, aDavOpt.isResourceFound() ); - CPPUNIT_ASSERT_EQUAL( false, aDavOpt.isClass1() ); - CPPUNIT_ASSERT_EQUAL( false, aDavOpt.isClass2() ); - CPPUNIT_ASSERT_EQUAL( false, aDavOpt.isClass3() ); - CPPUNIT_ASSERT_EQUAL( true, aDavOpt.isHeadAllowed() ); - CPPUNIT_ASSERT_EQUAL( false, aDavOpt.isLockAllowed() ); - CPPUNIT_ASSERT_EQUAL( true, aDavOpt.getAllowedMethods().isEmpty() ); - CPPUNIT_ASSERT_EQUAL( sal_uInt32( 0 ), aDavOpt.getStaleTime() ); - CPPUNIT_ASSERT_EQUAL( true, aDavOpt.getURL().isEmpty() ); - CPPUNIT_ASSERT_EQUAL( true, aDavOpt.getRedirectedURL().isEmpty() ); - aDavOpt.setResourceFound( false ); aDavOpt.setClass1(); - CPPUNIT_ASSERT_EQUAL( false, aDavOpt.isResourceFound() ); CPPUNIT_ASSERT_EQUAL( true, aDavOpt.isClass1() ); CPPUNIT_ASSERT_EQUAL( false, aDavOpt.isClass2() ); CPPUNIT_ASSERT_EQUAL( false, aDavOpt.isClass3() ); @@ -98,10 +85,11 @@ namespace CPPUNIT_ASSERT_EQUAL( sal_uInt32( 0 ), aDavOpt.getStaleTime() ); CPPUNIT_ASSERT_EQUAL( true, aDavOpt.getURL().isEmpty() ); CPPUNIT_ASSERT_EQUAL( true, aDavOpt.getRedirectedURL().isEmpty() ); + CPPUNIT_ASSERT_EQUAL( sal_uInt16( 0 ), aDavOpt.getHttpResponseStatusCode() ); + CPPUNIT_ASSERT_EQUAL( true, aDavOpt.getHttpResponseStatusText().isEmpty() ); aDavOpt.setClass1( false ); aDavOpt.setClass2(); - CPPUNIT_ASSERT_EQUAL( false, aDavOpt.isResourceFound() ); CPPUNIT_ASSERT_EQUAL( false, aDavOpt.isClass1() ); CPPUNIT_ASSERT_EQUAL( true, aDavOpt.isClass2() ); CPPUNIT_ASSERT_EQUAL( false, aDavOpt.isClass3() ); @@ -111,10 +99,11 @@ namespace CPPUNIT_ASSERT_EQUAL( sal_uInt32( 0 ), aDavOpt.getStaleTime() ); CPPUNIT_ASSERT_EQUAL( true, aDavOpt.getURL().isEmpty() ); CPPUNIT_ASSERT_EQUAL( true, aDavOpt.getRedirectedURL().isEmpty() ); + CPPUNIT_ASSERT_EQUAL( sal_uInt16( 0 ), aDavOpt.getHttpResponseStatusCode() ); + CPPUNIT_ASSERT_EQUAL( true, aDavOpt.getHttpResponseStatusText().isEmpty() ); aDavOpt.setClass2( false ); aDavOpt.setClass3(); - CPPUNIT_ASSERT_EQUAL( false, aDavOpt.isResourceFound() ); CPPUNIT_ASSERT_EQUAL( false, aDavOpt.isClass1() ); CPPUNIT_ASSERT_EQUAL( false, aDavOpt.isClass2() ); CPPUNIT_ASSERT_EQUAL( true, aDavOpt.isClass3() ); @@ -124,10 +113,11 @@ namespace CPPUNIT_ASSERT_EQUAL( sal_uInt32( 0 ), aDavOpt.getStaleTime() ); CPPUNIT_ASSERT_EQUAL( true, aDavOpt.getURL().isEmpty() ); CPPUNIT_ASSERT_EQUAL( true, aDavOpt.getRedirectedURL().isEmpty() ); + CPPUNIT_ASSERT_EQUAL( sal_uInt16( 0 ), aDavOpt.getHttpResponseStatusCode() ); + CPPUNIT_ASSERT_EQUAL( true, aDavOpt.getHttpResponseStatusText().isEmpty() ); aDavOpt.setClass3( false ); - CPPUNIT_ASSERT_EQUAL( false, aDavOpt.isResourceFound() ); CPPUNIT_ASSERT_EQUAL( false, aDavOpt.isClass1() ); CPPUNIT_ASSERT_EQUAL( false, aDavOpt.isClass2() ); CPPUNIT_ASSERT_EQUAL( false, aDavOpt.isClass3() ); @@ -137,13 +127,14 @@ namespace CPPUNIT_ASSERT_EQUAL( sal_uInt32( 0 ), aDavOpt.getStaleTime() ); CPPUNIT_ASSERT_EQUAL( true, aDavOpt.getURL().isEmpty() ); CPPUNIT_ASSERT_EQUAL( true, aDavOpt.getRedirectedURL().isEmpty() ); + CPPUNIT_ASSERT_EQUAL( sal_uInt16( 0 ), aDavOpt.getHttpResponseStatusCode() ); + CPPUNIT_ASSERT_EQUAL( true, aDavOpt.getHttpResponseStatusText().isEmpty() ); DAVTypesCheckInit( aDavOpt ); //example of allowed method for a Web resource OUString aAllowedMethods = "POST,OPTIONS,GET,HEAD,TRACE"; aDavOpt.setAllowedMethods( aAllowedMethods ); // now check... - CPPUNIT_ASSERT_EQUAL( false, aDavOpt.isResourceFound() ); CPPUNIT_ASSERT_EQUAL( false, aDavOpt.isClass1() ); CPPUNIT_ASSERT_EQUAL( false, aDavOpt.isClass2() ); CPPUNIT_ASSERT_EQUAL( false, aDavOpt.isClass3() ); @@ -153,12 +144,13 @@ namespace CPPUNIT_ASSERT_EQUAL( sal_uInt32( 0 ), aDavOpt.getStaleTime() ); CPPUNIT_ASSERT_EQUAL( true, aDavOpt.getURL().isEmpty() ); CPPUNIT_ASSERT_EQUAL( true, aDavOpt.getRedirectedURL().isEmpty() ); + CPPUNIT_ASSERT_EQUAL( sal_uInt16( 0 ), aDavOpt.getHttpResponseStatusCode() ); + CPPUNIT_ASSERT_EQUAL( true, aDavOpt.getHttpResponseStatusText().isEmpty() ); //example of allowed method for a WebDAV resource supporting LOCK aAllowedMethods = "OPTIONS,GET,HEAD,POST,DELETE,TRACE,PROPFIND,PROPPATCH,COPY,MOVE,PUT,LOCK,UNLOCK"; aDavOpt.setAllowedMethods( aAllowedMethods ); // now check... - CPPUNIT_ASSERT_EQUAL( false, aDavOpt.isResourceFound() ); CPPUNIT_ASSERT_EQUAL( false, aDavOpt.isClass1() ); CPPUNIT_ASSERT_EQUAL( false, aDavOpt.isClass2() ); CPPUNIT_ASSERT_EQUAL( false, aDavOpt.isClass3() ); @@ -168,11 +160,12 @@ namespace CPPUNIT_ASSERT_EQUAL( sal_uInt32( 0 ), aDavOpt.getStaleTime() ); CPPUNIT_ASSERT_EQUAL( true, aDavOpt.getURL().isEmpty() ); CPPUNIT_ASSERT_EQUAL( true, aDavOpt.getRedirectedURL().isEmpty() ); + CPPUNIT_ASSERT_EQUAL( sal_uInt16( 0 ), aDavOpt.getHttpResponseStatusCode() ); + CPPUNIT_ASSERT_EQUAL( true, aDavOpt.getHttpResponseStatusText().isEmpty() ); aAllowedMethods.clear(); aDavOpt.setAllowedMethods( aAllowedMethods ); aDavOpt.setStaleTime( 12345678 ); - CPPUNIT_ASSERT_EQUAL( false, aDavOpt.isResourceFound() ); CPPUNIT_ASSERT_EQUAL( false, aDavOpt.isClass1() ); CPPUNIT_ASSERT_EQUAL( false, aDavOpt.isClass2() ); CPPUNIT_ASSERT_EQUAL( false, aDavOpt.isClass3() ); @@ -182,12 +175,31 @@ namespace CPPUNIT_ASSERT_EQUAL( sal_uInt32( 12345678 ), aDavOpt.getStaleTime() ); CPPUNIT_ASSERT_EQUAL( true, aDavOpt.getURL().isEmpty() ); CPPUNIT_ASSERT_EQUAL( true, aDavOpt.getRedirectedURL().isEmpty() ); + CPPUNIT_ASSERT_EQUAL( sal_uInt16( 0 ), aDavOpt.getHttpResponseStatusCode() ); + CPPUNIT_ASSERT_EQUAL( true, aDavOpt.getHttpResponseStatusText().isEmpty() ); aDavOpt.setStaleTime( 0 ); + OUString aHTTPResponseStatusText = "522 Origin Connection Time-out"; + aDavOpt.setHttpResponseStatusCode( 522 ); + aDavOpt.setHttpResponseStatusText( aHTTPResponseStatusText ); + CPPUNIT_ASSERT_EQUAL( false, aDavOpt.isClass1() ); + CPPUNIT_ASSERT_EQUAL( false, aDavOpt.isClass2() ); + CPPUNIT_ASSERT_EQUAL( false, aDavOpt.isClass3() ); + CPPUNIT_ASSERT_EQUAL( true, aDavOpt.getAllowedMethods().isEmpty() ); + CPPUNIT_ASSERT_EQUAL( false, aDavOpt.isLockAllowed() ); + CPPUNIT_ASSERT_EQUAL( true , aDavOpt.getURL().isEmpty() ); + CPPUNIT_ASSERT_EQUAL( true, aDavOpt.getRedirectedURL().isEmpty() ); + CPPUNIT_ASSERT_EQUAL( sal_uInt32( 0 ), aDavOpt.getStaleTime() ); + CPPUNIT_ASSERT_EQUAL( sal_uInt16( 522 ), aDavOpt.getHttpResponseStatusCode() ); + CPPUNIT_ASSERT_EQUAL( aHTTPResponseStatusText, aDavOpt.getHttpResponseStatusText() ); + + aDavOpt.setHttpResponseStatusCode( 0 ); + aHTTPResponseStatusText.clear(); + aDavOpt.setHttpResponseStatusText( aHTTPResponseStatusText ); + OUString aURL = "http://a%20fake%20url/to%20test"; aDavOpt.setURL( aURL ); - CPPUNIT_ASSERT_EQUAL( false, aDavOpt.isResourceFound() ); CPPUNIT_ASSERT_EQUAL( false, aDavOpt.isClass1() ); CPPUNIT_ASSERT_EQUAL( false, aDavOpt.isClass2() ); CPPUNIT_ASSERT_EQUAL( false, aDavOpt.isClass3() ); @@ -197,12 +209,13 @@ namespace CPPUNIT_ASSERT_EQUAL( sal_uInt32( 0 ), aDavOpt.getStaleTime() ); CPPUNIT_ASSERT_EQUAL( aURL, aDavOpt.getURL() ); CPPUNIT_ASSERT_EQUAL( true, aDavOpt.getRedirectedURL().isEmpty() ); + CPPUNIT_ASSERT_EQUAL( sal_uInt16( 0 ), aDavOpt.getHttpResponseStatusCode() ); + CPPUNIT_ASSERT_EQUAL( true, aDavOpt.getHttpResponseStatusText().isEmpty() ); aURL.clear(); aDavOpt.setURL( aURL ); aURL = "http://a%20fake%20url/to%20test/another-url"; aDavOpt.setRedirectedURL( aURL ); - CPPUNIT_ASSERT_EQUAL( false, aDavOpt.isResourceFound() ); CPPUNIT_ASSERT_EQUAL( false, aDavOpt.isClass1() ); CPPUNIT_ASSERT_EQUAL( false, aDavOpt.isClass2() ); CPPUNIT_ASSERT_EQUAL( false, aDavOpt.isClass3() ); @@ -212,11 +225,13 @@ namespace CPPUNIT_ASSERT_EQUAL( sal_uInt32( 0 ), aDavOpt.getStaleTime() ); CPPUNIT_ASSERT_EQUAL( true, aDavOpt.getURL().isEmpty() ); CPPUNIT_ASSERT_EQUAL( aURL, aDavOpt.getRedirectedURL() ); + CPPUNIT_ASSERT_EQUAL( sal_uInt16( 0 ), aDavOpt.getHttpResponseStatusCode() ); + CPPUNIT_ASSERT_EQUAL( true, aDavOpt.getHttpResponseStatusText().isEmpty() ); //check the init() function aAllowedMethods = "OPTIONS,GET,HEAD,POST,DELETE,TRACE,PROPFIND,PROPPATCH,COPY,MOVE,PUT,LOCK,UNLOCK"; aURL = "http://a%20fake%20url/to%20test/another-url"; - aDavOpt.setResourceFound(); + aHTTPResponseStatusText = "404 Not Found"; aDavOpt.setClass1(); aDavOpt.setClass2(); aDavOpt.setClass3(); @@ -226,6 +241,8 @@ namespace aDavOpt.setStaleTime( 1234567 ); aDavOpt.setURL( aURL ); aDavOpt.setRedirectedURL( aURL ); + aDavOpt.setHttpResponseStatusCode( 404 ); + aDavOpt.setHttpResponseStatusText( aHTTPResponseStatusText ); aDavOpt.init(); DAVTypesCheckInit( aDavOpt ); @@ -258,14 +275,14 @@ namespace aDavOpt.setLocked( false ); CPPUNIT_ASSERT_EQUAL( true , aDavOpt == aDavOptTarget ); - aDavOpt.setResourceFound(); + aDavOpt.setStaleTime( 1234567 ); CPPUNIT_ASSERT_EQUAL( false , aDavOpt == aDavOptTarget ); - aDavOpt.setResourceFound( false ); + aDavOpt.setStaleTime( 0 ); CPPUNIT_ASSERT_EQUAL( true , aDavOpt == aDavOptTarget ); - aDavOpt.setStaleTime( 1234567 ); + aDavOpt.setHttpResponseStatusCode( 404 ); CPPUNIT_ASSERT_EQUAL( false , aDavOpt == aDavOptTarget ); - aDavOpt.setStaleTime( 0 ); + aDavOpt.setHttpResponseStatusCode( 0 ); CPPUNIT_ASSERT_EQUAL( true , aDavOpt == aDavOptTarget ); aDavOpt.setAllowedMethods( aAllowedMethods ); @@ -276,6 +293,16 @@ namespace aDavOpt.setURL( aURL ); CPPUNIT_ASSERT_EQUAL( false , aDavOpt == aDavOptTarget ); + aURL.clear(); + aDavOpt.setURL( aURL ); + CPPUNIT_ASSERT_EQUAL( true , aDavOpt == aDavOptTarget ); + + aDavOpt.setHttpResponseStatusText( aHTTPResponseStatusText ); + CPPUNIT_ASSERT_EQUAL( false , aDavOpt == aDavOptTarget ); + aHTTPResponseStatusText.clear(); + aDavOpt.setHttpResponseStatusText( aHTTPResponseStatusText ); + CPPUNIT_ASSERT_EQUAL( true , aDavOpt == aDavOptTarget ); + } void webdav_opts_test::DAVOptsCacheTests() @@ -292,7 +319,6 @@ namespace OUString aRedirectedURL = "http://a%20fake%20url/to%20test/another-url/redirected"; aDavOpt.setURL( aURL ); aDavOpt.setRedirectedURL( aRedirectedURL ); - aDavOpt.setResourceFound(); aDavOpt.setClass1(); aDavOpt.setClass2(); aDavOpt.setClass3(); diff --git a/ucb/source/ucp/webdav-neon/DAVTypes.cxx b/ucb/source/ucp/webdav-neon/DAVTypes.cxx index bd723e53249f..3e48752a82ab 100644 --- a/ucb/source/ucp/webdav-neon/DAVTypes.cxx +++ b/ucb/source/ucp/webdav-neon/DAVTypes.cxx @@ -20,7 +20,6 @@ using namespace com::sun::star; // DAVOptions implementation DAVOptions::DAVOptions() : - m_isResourceFound( false ), m_isClass1( false ), m_isClass2( false ), m_isClass3( false ), @@ -29,13 +28,14 @@ DAVOptions::DAVOptions() : m_aAllowedMethods(), m_nStaleTime( 0 ), m_sURL(), - m_sRedirectedURL() + m_sRedirectedURL(), + m_nHttpResponseStatusCode( 0 ), + m_sHttpResponseStatusText() { } DAVOptions::DAVOptions( const DAVOptions & rOther ) : - m_isResourceFound( rOther.m_isResourceFound ), m_isClass1( rOther.m_isClass1 ), m_isClass2( rOther.m_isClass2 ), m_isClass3( rOther.m_isClass3 ), @@ -44,7 +44,9 @@ DAVOptions::DAVOptions( const DAVOptions & rOther ) : m_aAllowedMethods( rOther.m_aAllowedMethods ), m_nStaleTime( rOther.m_nStaleTime ), m_sURL( rOther.m_sURL ), - m_sRedirectedURL( rOther.m_sRedirectedURL) + m_sRedirectedURL( rOther.m_sRedirectedURL), + m_nHttpResponseStatusCode( rOther.m_nHttpResponseStatusCode ), + m_sHttpResponseStatusText( rOther.m_sHttpResponseStatusText ) { } @@ -57,7 +59,6 @@ DAVOptions::~DAVOptions() bool DAVOptions::operator==( const DAVOptions& rOpts ) const { return - m_isResourceFound == rOpts.m_isResourceFound && m_isClass1 == rOpts.m_isClass1 && m_isClass2 == rOpts.m_isClass2 && m_isClass3 == rOpts.m_isClass3 && @@ -66,7 +67,9 @@ bool DAVOptions::operator==( const DAVOptions& rOpts ) const m_aAllowedMethods == rOpts.m_aAllowedMethods && m_nStaleTime == rOpts.m_nStaleTime && m_sURL == rOpts.m_sURL && - m_sRedirectedURL == rOpts.m_sRedirectedURL; + m_sRedirectedURL == rOpts.m_sRedirectedURL && + m_nHttpResponseStatusCode == rOpts.m_nHttpResponseStatusCode && + m_sHttpResponseStatusText == rOpts.m_sHttpResponseStatusText; } @@ -129,7 +132,6 @@ void DAVOptionsCache::removeDAVOptions( const OUString & rURL ) void DAVOptionsCache::addDAVOptions( DAVOptions & rDAVOptions, const sal_uInt32 nLifeTime ) { osl::MutexGuard aGuard( m_aMutex ); - OUString aURL( rDAVOptions.getURL() ); OUString aEncodedUrl( ucb_impl::urihelper::encodeURI( NeonUri::unescape( aURL ) ) ); @@ -147,8 +149,7 @@ void DAVOptionsCache::addDAVOptions( DAVOptions & rDAVOptions, const sal_uInt32 m_aTheCache[ aEncodedUrl ] = rDAVOptions; } - -bool DAVOptionsCache::isResourceFound( const OUString & rURL ) +sal_uInt16 DAVOptionsCache::getHttpResponseStatusCode( const OUString & rURL, OUString & rHttpResponseStatusText ) { osl::MutexGuard aGuard( m_aMutex ); OUString aEncodedUrl( ucb_impl::urihelper::encodeURI( NeonUri::unescape( rURL ) ) ); @@ -164,16 +165,13 @@ bool DAVOptionsCache::isResourceFound( const OUString & rURL ) if( (*it).second.getStaleTime() < t1.Seconds ) { m_aTheCache.erase( it ); - return true; // to force again OPTIONS method + return 0; } - // check if the resource was present on server - return (*it).second.isResourceFound(); + rHttpResponseStatusText = (*it).second.getHttpResponseStatusText(); + return (*it).second.getHttpResponseStatusCode(); } - // this value is needed because some web server don't implement - // OPTIONS method, so the resource is considered found, - // until detected otherwise - return true; + return 0; } bool DAVOptionsCache::isHeadAllowed( const OUString & rURL ) diff --git a/ucb/source/ucp/webdav-neon/DAVTypes.hxx b/ucb/source/ucp/webdav-neon/DAVTypes.hxx index 5721619b6360..89f94a737a63 100644 --- a/ucb/source/ucp/webdav-neon/DAVTypes.hxx +++ b/ucb/source/ucp/webdav-neon/DAVTypes.hxx @@ -77,16 +77,14 @@ namespace webdav_ucp class DAVOptions { private: - bool m_isResourceFound; // true if the resource was found, else false bool m_isClass1; bool m_isClass2; bool m_isClass3; - // for server that do not implement it + /// for server that do not implement it bool m_isHeadAllowed; - // Internally used to maintain locked stated of the resource, only - // if it's a Class 2 resource + /// Internally used to maintain the locked state of the resource, only if it's a Class 2 resource bool m_isLocked; - // contains the methods allowed on this resource + /// contains the methods allowed on this resource OUString m_aAllowedMethods; /// target time when this capability becomes stale @@ -94,6 +92,11 @@ namespace webdav_ucp OUString m_sURL; OUString m_sRedirectedURL; + /// The cached HTT response status code. It's 0 if the code was dealt with and there is no need to cache it + sal_uInt16 m_nHttpResponseStatusCode; + /// The cached string with the server returned HTTP reponse status code string, corresponds to m_nHttpResponseStatusCode. + OUString m_sHttpResponseStatusText; + public: DAVOptions(); @@ -101,9 +104,6 @@ namespace webdav_ucp virtual ~DAVOptions(); - bool isResourceFound() { return m_isResourceFound; }; - void setResourceFound( bool ResourceFound = true ) { m_isResourceFound = ResourceFound; }; - bool isClass1() { return m_isClass1; }; void setClass1( bool Class1 = true ) { m_isClass1 = Class1; }; @@ -116,7 +116,7 @@ namespace webdav_ucp bool isHeadAllowed() { return m_isHeadAllowed; }; void setHeadAllowed( bool HeadAllowed = true ) { m_isHeadAllowed = HeadAllowed; }; - sal_uInt32 getStaleTime() const { return m_nStaleTime ; }; + sal_uInt32 getStaleTime() { return m_nStaleTime ; }; void setStaleTime( const sal_uInt32 nStaleTime ) { m_nStaleTime = nStaleTime; }; const OUString & getURL() { return m_sURL; }; @@ -132,8 +132,13 @@ namespace webdav_ucp void setLocked( bool locked = true ) { m_isLocked = locked; } ; bool isLocked() { return m_isLocked; }; + sal_uInt16 getHttpResponseStatusCode() { return m_nHttpResponseStatusCode; }; + void setHttpResponseStatusCode( const sal_uInt16 nHttpResponseStatusCode ) { m_nHttpResponseStatusCode = nHttpResponseStatusCode; }; + + const OUString & getHttpResponseStatusText() { return m_sHttpResponseStatusText; }; + void setHttpResponseStatusText( const OUString & rHttpResponseStatusText ) { m_sHttpResponseStatusText = rHttpResponseStatusText; }; + void init() { - m_isResourceFound = false; m_isClass1 = false; m_isClass2 = false; m_isClass3 = false; @@ -143,6 +148,8 @@ namespace webdav_ucp m_nStaleTime = 0; m_sURL.clear(); m_sRedirectedURL.clear(); + m_nHttpResponseStatusCode = 0; + m_sHttpResponseStatusText.clear(); }; bool operator==( const DAVOptions& rOpts ) const; @@ -167,20 +174,19 @@ namespace webdav_ucp void removeDAVOptions( const OUString & rURL ); void addDAVOptions( DAVOptions & rDAVOptions, const sal_uInt32 nLifeTime ); - /** Check if the DAV options cached value was found - by the last OPTIONS method call. + /** return the cached value of HTTP response status code If the cached value is found stale, it is removed. - @param OUString + @param (in) OUString the resource URL - @return bool - true if resource was found or if the Web resource DAV options + @return int + the cached are not present (meaning the resource should be checked for presence anyway) false if resource was not found */ - bool isResourceFound( const OUString & rURL ); + sal_uInt16 getHttpResponseStatusCode( const OUString & rURL, OUString & rHttpResponseStatusText ); bool isHeadAllowed( const OUString & rURL ); diff --git a/ucb/source/ucp/webdav-neon/NeonSession.cxx b/ucb/source/ucp/webdav-neon/NeonSession.cxx index f337c4f00ef4..99835a5c8ebf 100644 --- a/ucb/source/ucp/webdav-neon/NeonSession.cxx +++ b/ucb/source/ucp/webdav-neon/NeonSession.cxx @@ -940,7 +940,6 @@ void NeonSession::OPTIONS( const OUString & inPath, } } } - rOptions.setResourceFound(); // if applicable, check for lock state: if( rOptions.isClass2() || rOptions.isClass3() ) { @@ -1841,7 +1840,7 @@ void NeonSession::HandleError( int nError, sal_uInt16 code = makeStatusCode( aText ); - SAL_WARN( "ucb.ucp.webdav", "Neon returned NE_ERROR, http response status code was: '" << aText << "'" ); + SAL_WARN( "ucb.ucp.webdav", "Neon returned NE_ERROR, http response status code was: " << code << " '" << aText << "'" ); if ( code == SC_LOCKED ) { if ( m_aNeonLockStore.findByUri( diff --git a/ucb/source/ucp/webdav-neon/webdavcontent.cxx b/ucb/source/ucp/webdav-neon/webdavcontent.cxx index 1b14721b4ee8..7cf9ee1399a4 100644 --- a/ucb/source/ucp/webdav-neon/webdavcontent.cxx +++ b/ucb/source/ucp/webdav-neon/webdavcontent.cxx @@ -1579,15 +1579,29 @@ uno::Reference< sdbc::XRow > Content::getPropertyValues( if ( !aHeaderNames.empty() ) { + DAVOptions aDAVOptions; + OUString aTargetURL = xResAccess->getURL(); + // retrieve the cached options if any + aStaticDAVOptionsCache.getDAVOptions( aTargetURL, aDAVOptions ); try { DAVResource resource; // clean cached value of PROPFIND property names // PROPPATCH can change them - removeCachedPropertyNames( xResAccess->getURL() ); + removeCachedPropertyNames( aTargetURL ); // test if HEAD allowed, if not, throw, will be catched immediately - if ( !aStaticDAVOptionsCache.isHeadAllowed( xResAccess->getURL() ) ) + if ( !aDAVOptions.isHeadAllowed() ) throw DAVException( DAVException::DAV_HTTP_ERROR, "405 Not Implemented", 405 ); + // if HEAD is enabled on this site + // check if there is a relevant HTTP response status code cached + if ( aDAVOptions.getHttpResponseStatusCode() != SC_NONE ) + { + // throws exception as if there was a server error, a DAV exception + throw DAVException( DAVException::DAV_HTTP_ERROR, + aDAVOptions.getHttpResponseStatusText(), + aDAVOptions.getHttpResponseStatusCode() ); + // Unreachable + } xResAccess->HEAD( aHeaderNames, resource, xEnv ); m_bDidGetOrHead = true; @@ -1616,31 +1630,38 @@ uno::Reference< sdbc::XRow > Content::getPropertyValues( bool bError = true; DAVException aLastException = e; - // According to the spec. the origin server SHOULD return - // * 405 (Method Not Allowed): - // the method is known but not allowed for the requested resource - // * 501 (Not Implemented): - // the method is unrecognized or not implemented - // TODO SC_NOT_FOUND is only for google-code server - if ( aLastException.getStatus() == SC_NOT_IMPLEMENTED || - aLastException.getStatus() == SC_METHOD_NOT_ALLOWED || - aLastException.getStatus() == SC_NOT_FOUND ) + if ( e.getError() == DAVException::DAV_HTTP_ERROR ) { - SAL_WARN( "ucb.ucp.webdav", "HEAD not implemented: fall back to a partial GET" ); - lcl_sendPartialGETRequest( bError, - aLastException, - aMissingProps, - aHeaderNames, - xResAccess, - xProps, - xEnv ); - m_bDidGetOrHead = !bError; + // According to the spec. the origin server SHOULD return + // * 405 (Method Not Allowed): + // the method is known but not allowed for the requested resource + // * 501 (Not Implemented): + // the method is unrecognized or not implemented + // * 404 (SC_NOT_FOUND) + // is for google-code server and for MS IIS 10.0 Web server + // when only GET is enabled + if ( aLastException.getStatus() == SC_NOT_IMPLEMENTED || + aLastException.getStatus() == SC_METHOD_NOT_ALLOWED || + aLastException.getStatus() == SC_NOT_FOUND ) + { + SAL_WARN( "ucb.ucp.webdav", "HEAD probably not implemented: fall back to a partial GET" ); + lcl_sendPartialGETRequest( bError, + aLastException, + aMissingProps, + aHeaderNames, + xResAccess, + xProps, + xEnv ); + m_bDidGetOrHead = !bError; + } } if ( bError ) { if ( !shouldAccessNetworkAfterException( aLastException ) ) { + // remove the cached OPTIONS and errors + aStaticDAVOptionsCache.removeDAVOptions( aTargetURL ); cancelCommandExecution( aLastException, xEnv ); // unreachable } @@ -2280,14 +2301,14 @@ uno::Any Content::open( xResAccess.reset( new DAVResourceAccess( *m_xResAccess.get() ) ); } - xResAccess->setFlags( rArg.OpeningFlags ); // fill inputsream sync; return if all data present DAVResource aResource; std::vector< OUString > aHeaders; - removeCachedPropertyNames( xResAccess->getURL() ); + aTargetURL = xResAccess->getURL(); + removeCachedPropertyNames( aTargetURL ); // check if the resource was present on the server // first update it, if necessary // if the open is called directly, without the default open sequence, @@ -2297,67 +2318,36 @@ uno::Any Content::open( DAVOptions aDAVOptions; getResourceOptions( xEnv, aDAVOptions, xResAccess ); - if( aDAVOptions.isResourceFound() ) + if ( aDAVOptions.getHttpResponseStatusCode() != SC_NONE ) { - uno::Reference< io::XInputStream > xIn - = xResAccess->GET( aHeaders, aResource, xEnv ); - m_bDidGetOrHead = true; - - { - osl::MutexGuard aGuard( m_aMutex ); + // throws exception as if there was a server error, a DAV exception + throw DAVException( DAVException::DAV_HTTP_ERROR, + aDAVOptions.getHttpResponseStatusText(), + aDAVOptions.getHttpResponseStatusCode() ); + } + uno::Reference< io::XInputStream > xIn + = xResAccess->GET( aHeaders, aResource, xEnv ); + m_bDidGetOrHead = true; - // cache headers. - if ( !m_xCachedProps.get()) - m_xCachedProps.reset( - new CachableContentProperties( ContentProperties( aResource ) ) ); - else - m_xCachedProps->addProperties( - aResource.properties ); + { + osl::MutexGuard aGuard( m_aMutex ); - m_xResAccess.reset( - new DAVResourceAccess( *xResAccess.get() ) ); - } + // cache headers. + if ( !m_xCachedProps.get()) + m_xCachedProps.reset( + new CachableContentProperties( ContentProperties( aResource ) ) ); + else + m_xCachedProps->addProperties( + aResource.properties ); - xDataSink->setInputStream( xIn ); + m_xResAccess.reset( + new DAVResourceAccess( *xResAccess.get() ) ); } - else - { - // return exception as if the resource was not found - uno::Sequence< uno::Any > aArgs( 1 ); - aArgs[ 0 ] <<= beans::PropertyValue( - OUString("Uri"), -1, - uno::makeAny(aTargetURL), - beans::PropertyState_DIRECT_VALUE); - ucbhelper::cancelCommandExecution( - uno::makeAny( - ucb::InteractiveAugmentedIOException( - OUString("Not found!"), - static_cast< cppu::OWeakObject * >( this ), - task::InteractionClassification_ERROR, - ucb::IOErrorCode_NOT_EXISTING, - aArgs ) ), - xEnv ); - // Unreachable - } + xDataSink->setInputStream( xIn ); } catch ( DAVException const & e ) { - // check if error is SC_NOT_FOUND - // if URL resource not found, set the corresponding resource - // element in option cache and update the cache lifetime accordingly - if( e.getStatus() == SC_NOT_FOUND ) - { - DAVOptions aDAVOptions; - if( aStaticDAVOptionsCache.getDAVOptions( aTargetURL, aDAVOptions ) ) - { - // get redirected url - aDAVOptions.setResourceFound( false ); - aStaticDAVOptionsCache.addDAVOptions( aDAVOptions, - m_nOptsCacheLifeNotFound ); - } - } - cancelCommandExecution( e, xEnv ); // Unreachable } @@ -3907,8 +3897,9 @@ Content::ResourceType Content::getResourceType( DAVOptions aDAVOptionsInner; if( aStaticDAVOptionsCache.getDAVOptions( rURL, aDAVOptionsInner ) ) { - // get redirected url - aDAVOptionsInner.setResourceFound( false ); + // TODO? get redirected url + aDAVOptionsInner.setHttpResponseStatusCode( e.getStatus() ); + aDAVOptionsInner.setHttpResponseStatusText( e.getData() ); aStaticDAVOptionsCache.addDAVOptions( aDAVOptionsInner, m_nOptsCacheLifeNotFound ); } @@ -3927,7 +3918,7 @@ Content::ResourceType Content::getResourceType( { rResAccess->resetUri(); - if ( aDAVOptions.isResourceFound() ) + if ( aDAVOptions.getHttpResponseStatusCode() != SC_NOT_FOUND ) { eResourceType = NON_DAV; } @@ -4049,7 +4040,6 @@ void Content::getResourceOptions( case SC_FORBIDDEN: { SAL_WARN( "ucb.ucp.webdav","OPTIONS - SC_FORBIDDEN for URL <" << m_xIdentifier->getContentIdentifier() << ">" ); - rDAVOptions.setResourceFound(); // it may exists, will be checked by HEAD or GET method, surely it's not DAV // cache it, so OPTIONS won't be called again, this URL does not support it aStaticDAVOptionsCache.addDAVOptions( rDAVOptions, m_nOptsCacheLifeNotImpl ); @@ -4058,7 +4048,6 @@ void Content::getResourceOptions( case SC_BAD_REQUEST: { SAL_WARN( "ucb.ucp.webdav","OPTIONS - SC_BAD_REQUEST for URL <" << m_xIdentifier->getContentIdentifier() << ">" ); - rDAVOptions.setResourceFound(); // it may exists, will be checked by HEAD or GET method, surely it's not DAV // cache it, so OPTIONS won't be called again, this URL does not support it aStaticDAVOptionsCache.addDAVOptions( rDAVOptions, m_nOptsCacheLifeNotImpl ); @@ -4070,7 +4059,6 @@ void Content::getResourceOptions( // OPTIONS method must be implemented in DAV // resource is NON_DAV, or not advertising it SAL_WARN( "ucb.ucp.webdav","OPTIONS - SC_NOT_IMPLEMENTED or SC_METHOD_NOT_ALLOWED for URL <" << m_xIdentifier->getContentIdentifier() << ">" ); - rDAVOptions.setResourceFound(); // means it exists, but it's not DAV // cache it, so OPTIONS won't be called again, this URL does not support it aStaticDAVOptionsCache.addDAVOptions( rDAVOptions, m_nOptsCacheLifeNotImpl ); @@ -4085,7 +4073,6 @@ void Content::getResourceOptions( if( isResourceAvailable( xEnv, rResAccess, rDAVOptions ) ) { nLifeTime = m_nOptsCacheLifeNotImpl; - rDAVOptions.setResourceFound(); // means it exists, but it's not DAV } aStaticDAVOptionsCache.addDAVOptions( rDAVOptions, nLifeTime ); @@ -4093,12 +4080,15 @@ void Content::getResourceOptions( } break; default: - SAL_WARN( "ucb.ucp.webdav", "OPTIONS - DAV_HTTP_ERROR, HTTP error: " << e.getError() << " for URL <" << m_xIdentifier->getContentIdentifier() << ">" ); - rDAVOptions.setResourceFound(); // it may exists, will be checked by HEAD or GET method, surely it's not DAV + { + SAL_WARN( "ucb.ucp.webdav", "OPTIONS - DAV_HTTP_ERROR, for URL <" << m_xIdentifier->getContentIdentifier() << ">, HTTP error: "<< e.getStatus() ); + rDAVOptions.setHttpResponseStatusCode( e.getStatus() ); + rDAVOptions.setHttpResponseStatusText( e.getData() ); // cache it, so OPTIONS won't be called again, this URL does not support it aStaticDAVOptionsCache.addDAVOptions( rDAVOptions, m_nOptsCacheLifeNotImpl ); - break; + } + break; } } break; @@ -4106,15 +4096,14 @@ void Content::getResourceOptions( // number of redirections, consider the resource type as UNKNOWN // possibly a normal web site, not DAV case DAVException::DAV_HTTP_REDIRECT: - default: // leave the resource type as UNKNOWN, for now - // it means this will be managed as a standard http site + default: + { SAL_WARN( "ucb.ucp.webdav","OPTIONS - General DAVException (or max DAV_HTTP_REDIRECT reached) for URL <" << m_xIdentifier->getContentIdentifier() << ">, DAV ExceptionCode: " - << e.getError() << ", HTTP error: "<<e.getStatus() ); - rDAVOptions.setResourceFound(); // it may exists, will be checked by HEAD or GET method, surely it's not DAV - // cache it, so OPTIONS won't be called again, this URL does not support it + << e.getError() << ", HTTP error: "<< e.getStatus() ); aStaticDAVOptionsCache.addDAVOptions( rDAVOptions, m_nOptsCacheLifeNotImpl ); - break; + } + break; } } } @@ -4135,49 +4124,63 @@ bool Content::isResourceAvailable( const css::uno::Reference< css::ucb::XCommand // try using a simple HEAD command // if HEAD is successfull, set element found, rResAccess->HEAD( aHeaderNames, aResource, xEnv ); + rDAVOptions.setHttpResponseStatusCode( 0 ); + OUString aNoText; + rDAVOptions.setHttpResponseStatusText( aNoText ); return true; } catch ( DAVException const & e ) { - if ( e.getStatus() == SC_NOT_IMPLEMENTED || - e.getStatus() == SC_METHOD_NOT_ALLOWED || - e.getStatus() == SC_NOT_FOUND ) + if ( e.getError() == DAVException::DAV_HTTP_ERROR ) { - SAL_WARN( "ucb.ucp.webdav", "HEAD not implemented: fall back to a partial GET" ); - // set in cached OPTIONS "HEAD not implemented" - // so it won't be used again on this resource - rDAVOptions.setHeadAllowed( false ); - try + if ( e.getStatus() == SC_NOT_IMPLEMENTED || + e.getStatus() == SC_METHOD_NOT_ALLOWED || + e.getStatus() == SC_NOT_FOUND ) { - // do a GET with a payload of 0, the server does not - // support HEAD (or has HEAD disabled) - DAVRequestHeaders aPartialGet; - aPartialGet.push_back( - DAVRequestHeader( - OUString( "Range" ), - OUString( "bytes=0-0" ))); - - rResAccess->GET0( aPartialGet, - aHeaderNames, - aResource, - xEnv ); - return true; + SAL_WARN( "ucb.ucp.webdav", "HEAD probably not implemented: fall back to a partial GET" ); + // set in cached OPTIONS "HEAD not implemented" + // so it won't be used again on this resource + rDAVOptions.setHeadAllowed( false ); + try + { + // do a GET with a payload of 0, the server does not + // support HEAD (or has HEAD disabled) + DAVRequestHeaders aPartialGet; + aPartialGet.push_back( + DAVRequestHeader( + OUString( "Range" ), + OUString( "bytes=0-0" ))); + + rResAccess->GET0( aPartialGet, + aHeaderNames, + aResource, + xEnv ); + return true; + } + catch ( DAVException const & ex ) + { + if ( ex.getError() == DAVException::DAV_HTTP_ERROR ) + { + rDAVOptions.setHttpResponseStatusCode( ex.getStatus() ); + rDAVOptions.setHttpResponseStatusText( ex.getData() ); + } + } } - catch (...) + else { - return false; + rDAVOptions.setHttpResponseStatusCode( e.getStatus() ); + rDAVOptions.setHttpResponseStatusText( e.getData() ); } } - else - return false; + return false; } catch ( ... ) { - // some error... so set as not found - // retry errors are taken care of - // in rResAccess function method. - return false; } + // set SC_NOT_IMPLEMENTED since at a minimum GET must be implemented in a basic Web server + rDAVOptions.setHttpResponseStatusCode( SC_NOT_IMPLEMENTED ); + OUString HttpResponseStatusText; + rDAVOptions.setHttpResponseStatusText( HttpResponseStatusText ); return false; } |