diff options
author | Giuseppe Castagno <giuseppe.castagno@acca-esse.eu> | 2016-10-03 16:20:43 +0200 |
---|---|---|
committer | Giuseppe Castagno <giuseppe.castagno@acca-esse.eu> | 2016-10-03 17:41:26 +0000 |
commit | f7697a633cd56003fcb1d86bee7eb658020af506 (patch) | |
tree | 9cba8842b71b3311c818383a1b91bd52161ce0ff /ucb/source | |
parent | e8667a596d2c899ab73a03f3c8f824c9f0dbd72e (diff) |
tdf#101094 (36): Fix behaviour of GET in fetching Headers only
Implement a better way to GET only headers, as HEAD method
substitute.
Wrote a new version of GET, specifically for 'no payload' service
because sometimes neon was returning an internal error about:
'Compressed response was truncated' but without a specific error
state.
Change-Id: I84a3e5635193c3f68d335eba7af41b05980f4192
Reviewed-on: https://gerrit.libreoffice.org/29502
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Giuseppe Castagno <giuseppe.castagno@acca-esse.eu>
Diffstat (limited to 'ucb/source')
-rw-r--r-- | ucb/source/ucp/webdav-neon/DAVResourceAccess.cxx | 21 | ||||
-rw-r--r-- | ucb/source/ucp/webdav-neon/DAVResourceAccess.hxx | 13 | ||||
-rw-r--r-- | ucb/source/ucp/webdav-neon/DAVSession.hxx | 8 | ||||
-rw-r--r-- | ucb/source/ucp/webdav-neon/NeonSession.cxx | 61 | ||||
-rw-r--r-- | ucb/source/ucp/webdav-neon/NeonSession.hxx | 14 | ||||
-rw-r--r-- | ucb/source/ucp/webdav-neon/webdavcontent.cxx | 15 |
6 files changed, 106 insertions, 26 deletions
diff --git a/ucb/source/ucp/webdav-neon/DAVResourceAccess.cxx b/ucb/source/ucp/webdav-neon/DAVResourceAccess.cxx index 3f685919a055..db488b0c15fd 100644 --- a/ucb/source/ucp/webdav-neon/DAVResourceAccess.cxx +++ b/ucb/source/ucp/webdav-neon/DAVResourceAccess.cxx @@ -497,7 +497,8 @@ uno::Reference< io::XInputStream > DAVResourceAccess::GET( } -uno::Reference< io::XInputStream > DAVResourceAccess::GET( +// used as HEAD substitute when HEAD is not implemented on server +void DAVResourceAccess::GET0( DAVRequestHeaders &rRequestHeaders, const std::vector< OUString > & rHeaderNames, DAVResource & rResource, @@ -519,14 +520,14 @@ uno::Reference< io::XInputStream > DAVResourceAccess::GET( ucb::WebDAVHTTPMethod_GET, rRequestHeaders ); - xStream = m_xSession->GET( getRequestURI(), - rHeaderNames, - rResource, - DAVRequestEnvironment( - getRequestURI(), - new DAVAuthListener_Impl( - xEnv, m_aURL ), - rRequestHeaders, xEnv ) ); + m_xSession->GET0( getRequestURI(), + rHeaderNames, + rResource, + DAVRequestEnvironment( + getRequestURI(), + new DAVAuthListener_Impl( + xEnv, m_aURL ), + rRequestHeaders, xEnv ) ); } catch ( const DAVException & e ) { @@ -537,8 +538,6 @@ uno::Reference< io::XInputStream > DAVResourceAccess::GET( } } while ( bRetry ); - - return xStream; } diff --git a/ucb/source/ucp/webdav-neon/DAVResourceAccess.hxx b/ucb/source/ucp/webdav-neon/DAVResourceAccess.hxx index aed404ff1932..47f0bd0d5a50 100644 --- a/ucb/source/ucp/webdav-neon/DAVResourceAccess.hxx +++ b/ucb/source/ucp/webdav-neon/DAVResourceAccess.hxx @@ -134,12 +134,13 @@ public: const css::uno::Reference< css::ucb::XCommandEnvironment > & xEnv ) throw ( DAVException ); - css::uno::Reference< css::io::XInputStream > - GET( DAVRequestHeaders & rRequestHeaders, - const std::vector< rtl::OUString > & rHeaderNames, // empty == 'all' - DAVResource & rResource, - const css::uno::Reference< css::ucb::XCommandEnvironment > & xEnv ) - throw ( DAVException ); + // used as HEAD substitute when HEAD is not implemented on server + void + GET0( DAVRequestHeaders & rRequestHeaders, + const std::vector< rtl::OUString > & rHeaderNames, // empty == 'all' + DAVResource & rResource, + const css::uno::Reference< css::ucb::XCommandEnvironment > & xEnv ) + throw ( DAVException ); void GET( css::uno::Reference< css::io::XOutputStream > & rStream, diff --git a/ucb/source/ucp/webdav-neon/DAVSession.hxx b/ucb/source/ucp/webdav-neon/DAVSession.hxx index e6b7a1ae3f16..b251a7809545 100644 --- a/ucb/source/ucp/webdav-neon/DAVSession.hxx +++ b/ucb/source/ucp/webdav-neon/DAVSession.hxx @@ -123,6 +123,14 @@ public: const DAVRequestEnvironment & rEnv ) throw( std::exception ) = 0; + // used as HEAD substitute when HEAD is not implemented on server + virtual void + GET0( const OUString & inPath, + const std::vector< OUString > & inHeaderNames, + DAVResource & ioResource, + const DAVRequestEnvironment & rEnv ) + throw( std::exception ) = 0; + virtual void GET( const OUString & inPath, css::uno::Reference< css::io::XOutputStream >& o, diff --git a/ucb/source/ucp/webdav-neon/NeonSession.cxx b/ucb/source/ucp/webdav-neon/NeonSession.cxx index 8519cb3b7ec9..f337c4f00ef4 100644 --- a/ucb/source/ucp/webdav-neon/NeonSession.cxx +++ b/ucb/source/ucp/webdav-neon/NeonSession.cxx @@ -1256,6 +1256,31 @@ NeonSession::GET( const OUString & inPath, return uno::Reference< io::XInputStream >( xInputStream.get() ); } +void NeonSession::GET0( const OUString & inPath, + const std::vector< OUString > & inHeaderNames, + DAVResource & ioResource, + const DAVRequestEnvironment & rEnv ) + throw ( std::exception ) +{ + osl::Guard< osl::Mutex > theGuard( m_aMutex ); + SAL_INFO( "ucb.ucp.webdav", "GET - relative URL <" << inPath << ">" ); + + Init( rEnv ); + + ioResource.uri = inPath; + ioResource.properties.clear(); + + rtl::Reference< NeonInputStream > xInputStream( new NeonInputStream ); + NeonRequestContext aCtx( xInputStream, inHeaderNames, ioResource ); + int theRetVal = GET0( m_pHttpSession, + OUStringToOString( + inPath, RTL_TEXTENCODING_UTF8 ).getStr(), + true, + &aCtx ); + + HandleError( theRetVal, inPath, rEnv ); +} + void NeonSession::GET( const OUString & inPath, uno::Reference< io::XOutputStream > & ioOutputStream, const std::vector< OUString > & inHeaderNames, @@ -2005,6 +2030,42 @@ int NeonSession::GET( ne_session * sess, return ret; } +int NeonSession::GET0( ne_session * sess, + const char * uri, + bool getheaders, + void * userdata ) +{ + //struct get_context ctx; + ne_request * req = ne_request_create( sess, "GET", uri ); + int ret; + + { + osl::Guard< osl::Mutex > theGlobalGuard( aGlobalNeonMutex ); + ret = ne_request_dispatch( req ); + } + + if ( getheaders ) + { + void *cursor = nullptr; + const char *name, *value; + while ( ( cursor = ne_response_header_iterate( + req, cursor, &name, &value ) ) != nullptr ) + { + char buffer[8192]; + + SAL_INFO( "ucb.ucp.webdav", "GET - received header: " << name << ": " << value ); + ne_snprintf(buffer, sizeof buffer, "%s: %s", name, value); + runResponseHeaderHandler(userdata, buffer); + } + } + + if ( ret == NE_OK && ne_get_status( req )->klass != 2 ) + ret = NE_ERROR; + + ne_request_destroy( req ); + return ret; +} + int NeonSession::PUT( ne_session * sess, const char * uri, const char * buffer, diff --git a/ucb/source/ucp/webdav-neon/NeonSession.hxx b/ucb/source/ucp/webdav-neon/NeonSession.hxx index 62652c6b07bf..25d23c18e613 100644 --- a/ucb/source/ucp/webdav-neon/NeonSession.hxx +++ b/ucb/source/ucp/webdav-neon/NeonSession.hxx @@ -141,6 +141,13 @@ public: throw ( std::exception ) override; virtual void + GET0( const OUString & inPath, + const std::vector< OUString > & inHeaderNames, + DAVResource & ioResource, + const DAVRequestEnvironment & rEnv ) + throw( std::exception ) override; + + virtual void GET( const OUString & inPath, css::uno::Reference< css::io::XOutputStream > & ioOutputStream, const std::vector< OUString > & inHeaderNames, @@ -251,6 +258,13 @@ private: bool getheaders, void * userdata ); + // low level GET implementation, used by public GET implementations + // used as a HEAD substitute when head is not available + static int GET0( ne_session * sess, + const char * uri, + bool getheaders, + void * userdata ); + // Buffer-based PUT implementation. Neon only has file descriptor- // based API. static int PUT( ne_session * sess, diff --git a/ucb/source/ucp/webdav-neon/webdavcontent.cxx b/ucb/source/ucp/webdav-neon/webdavcontent.cxx index 8f0a83c80c6f..1b14721b4ee8 100644 --- a/ucb/source/ucp/webdav-neon/webdavcontent.cxx +++ b/ucb/source/ucp/webdav-neon/webdavcontent.cxx @@ -129,10 +129,7 @@ namespace } try { - uno::Reference< io::XInputStream > xIn = xResAccess->GET( aPartialGet, - aHeaderNames, - aResource, - xEnv ); + xResAccess->GET0( aPartialGet, aHeaderNames, aResource, xEnv ); bError = false; if ( bIsRequestSize ) @@ -1590,7 +1587,7 @@ uno::Reference< sdbc::XRow > Content::getPropertyValues( removeCachedPropertyNames( xResAccess->getURL() ); // test if HEAD allowed, if not, throw, will be catched immediately if ( !aStaticDAVOptionsCache.isHeadAllowed( xResAccess->getURL() ) ) - throw DAVException( DAVException::DAV_HTTP_ERROR, "405 Not Implemented" ); + throw DAVException( DAVException::DAV_HTTP_ERROR, "405 Not Implemented", 405 ); xResAccess->HEAD( aHeaderNames, resource, xEnv ); m_bDidGetOrHead = true; @@ -4160,10 +4157,10 @@ bool Content::isResourceAvailable( const css::uno::Reference< css::ucb::XCommand OUString( "Range" ), OUString( "bytes=0-0" ))); - rResAccess->GET( aPartialGet, - aHeaderNames, - aResource, - xEnv ); + rResAccess->GET0( aPartialGet, + aHeaderNames, + aResource, + xEnv ); return true; } catch (...) |