Modified: openoffice/branches/AOO410/main/ucb/source/ucp/webdav/SerfPutReqProcImpl.cxx URL: http://svn.apache.org/viewvc/openoffice/branches/AOO410/main/ucb/source/ucp/webdav/SerfPutReqProcImpl.cxx?rev=1705201&r1=1705200&r2=1705201&view=diff ============================================================================== --- openoffice/branches/AOO410/main/ucb/source/ucp/webdav/SerfPutReqProcImpl.cxx (original) +++ openoffice/branches/AOO410/main/ucb/source/ucp/webdav/SerfPutReqProcImpl.cxx Thu Sep 24 23:52:34 2015 @@ -34,9 +34,11 @@ namespace http_dav_ucp SerfPutReqProcImpl::SerfPutReqProcImpl( const char* inPath, const DAVRequestHeaders& inRequestHeaders, const char* inData, + const char* inLockToken, apr_size_t inDataLen ) : SerfRequestProcessorImpl( inPath, inRequestHeaders ) , mpData( inData ) + , mpLockToken( inLockToken) , mnDataLen( inDataLen ) { } @@ -57,7 +59,7 @@ serf_bucket_t * SerfPutReqProcImpl::crea } // create serf request - serf_bucket_t *req_bkt = serf_request_bucket_request_create( inSerfRequest, + serf_bucket_t *req_bkt = serf_request_bucket_request_create( inSerfRequest, "PUT", getPathStr(), body_bkt, @@ -68,11 +70,16 @@ serf_bucket_t * SerfPutReqProcImpl::crea serf_bucket_t* hdrs_bkt = serf_bucket_request_get_headers( req_bkt ); // general header fields provided by caller setRequestHeaders( hdrs_bkt ); + if(mpLockToken) + { + // request specific header field + serf_bucket_headers_set( hdrs_bkt, "if", mpLockToken ); + } return req_bkt; } -void SerfPutReqProcImpl::processChunkOfResponseData( const char* /*data*/, +void SerfPutReqProcImpl::processChunkOfResponseData( const char* /*data*/, apr_size_t /*len*/ ) { // nothing to do;
Modified: openoffice/branches/AOO410/main/ucb/source/ucp/webdav/SerfPutReqProcImpl.hxx URL: http://svn.apache.org/viewvc/openoffice/branches/AOO410/main/ucb/source/ucp/webdav/SerfPutReqProcImpl.hxx?rev=1705201&r1=1705200&r2=1705201&view=diff ============================================================================== --- openoffice/branches/AOO410/main/ucb/source/ucp/webdav/SerfPutReqProcImpl.hxx (original) +++ openoffice/branches/AOO410/main/ucb/source/ucp/webdav/SerfPutReqProcImpl.hxx Thu Sep 24 23:52:34 2015 @@ -33,6 +33,7 @@ public: SerfPutReqProcImpl( const char* inPath, const DAVRequestHeaders& inRequestHeaders, const char* inData, + const char* inLockToken, apr_size_t inDataLen ); @@ -50,6 +51,7 @@ protected: private: const char* mpData; + const char* mpLockToken; apr_size_t mnDataLen; }; Modified: openoffice/branches/AOO410/main/ucb/source/ucp/webdav/SerfRequestProcessor.cxx URL: http://svn.apache.org/viewvc/openoffice/branches/AOO410/main/ucb/source/ucp/webdav/SerfRequestProcessor.cxx?rev=1705201&r1=1705200&r2=1705201&view=diff ============================================================================== --- openoffice/branches/AOO410/main/ucb/source/ucp/webdav/SerfRequestProcessor.cxx (original) +++ openoffice/branches/AOO410/main/ucb/source/ucp/webdav/SerfRequestProcessor.cxx Thu Sep 24 23:52:34 2015 @@ -30,6 +30,9 @@ #include <apr_strings.h> +//to examine returned http code +#include "DAVException.hxx" + namespace http_dav_ucp { @@ -111,11 +114,19 @@ bool SerfRequestProcessor::processPropFi // PROPPATCH bool SerfRequestProcessor::processPropPatch( const std::vector< ProppatchValue > & inProperties, + const com::sun::star::ucb::Lock inLock, apr_status_t& outSerfStatus ) { + char * inLockToken = static_cast<char*>(0); + if(inLock.LockTokens.getLength() > 0) + { + inLockToken = apr_psprintf( mrSerfSession.getAprPool(), "(<%s>)", + rtl::OUStringToOString(inLock.LockTokens[0], RTL_TEXTENCODING_UTF8 ).getStr() ); + } mpProcImpl = createPropPatchReqProcImpl( mPathStr, mrSerfSession.getRequestEnvironment().m_aRequestHeaders, - inProperties ); + inProperties, + inLockToken ); outSerfStatus = runProcessor(); return outSerfStatus == APR_SUCCESS; @@ -194,11 +205,19 @@ bool SerfRequestProcessor::processHead( // PUT bool SerfRequestProcessor::processPut( const char* inData, apr_size_t inDataLen, + const com::sun::star::ucb::Lock inLock, apr_status_t& outSerfStatus ) { + char * inLockToken = static_cast<char*>(0); + if(inLock.LockTokens.getLength() > 0) + { + inLockToken = apr_psprintf( mrSerfSession.getAprPool(), "(<%s>)", + rtl::OUStringToOString(inLock.LockTokens[0], RTL_TEXTENCODING_UTF8 ).getStr() ); + } mpProcImpl = createPutReqProcImpl( mPathStr, mrSerfSession.getRequestEnvironment().m_aRequestHeaders, inData, + inLockToken, inDataLen ); outSerfStatus = runProcessor(); @@ -210,6 +229,7 @@ bool SerfRequestProcessor::processPost( apr_size_t inDataLen, const rtl::OUString & inContentType, const rtl::OUString & inReferer, + const com::sun::star::ucb::Lock inLock, const com::sun::star::uno::Reference< SerfInputStream >& xioInStrm, apr_status_t& outSerfStatus ) { @@ -217,10 +237,17 @@ bool SerfRequestProcessor::processPost( rtl::OUStringToOString( inContentType, RTL_TEXTENCODING_UTF8 ).getStr() ); mReferer = apr_pstrdup( mrSerfSession.getAprPool(), rtl::OUStringToOString( inReferer, RTL_TEXTENCODING_UTF8 ).getStr() ); + char * inLockToken = static_cast<char*>(0); + if(inLock.LockTokens.getLength() > 0) + { + inLockToken = apr_psprintf( mrSerfSession.getAprPool(), "(<%s>)", + rtl::OUStringToOString(inLock.LockTokens[0], RTL_TEXTENCODING_UTF8 ).getStr() ); + } mpProcImpl = createPostReqProcImpl( mPathStr, mrSerfSession.getRequestEnvironment().m_aRequestHeaders, inData, inDataLen, + inLockToken, mContentType, mReferer, xioInStrm ); @@ -234,6 +261,7 @@ bool SerfRequestProcessor::processPost( apr_size_t inDataLen, const rtl::OUString & inContentType, const rtl::OUString & inReferer, + const com::sun::star::ucb::Lock inLock, const com::sun::star::uno::Reference< com::sun::star::io::XOutputStream >& xioOutStrm, apr_status_t& outSerfStatus ) { @@ -241,10 +269,17 @@ bool SerfRequestProcessor::processPost( rtl::OUStringToOString( inContentType, RTL_TEXTENCODING_UTF8 ).getStr() ); mReferer = apr_pstrdup( mrSerfSession.getAprPool(), rtl::OUStringToOString( inReferer, RTL_TEXTENCODING_UTF8 ).getStr() ); + char * inLockToken = static_cast<char*>(0); + if(inLock.LockTokens.getLength() > 0) + { + inLockToken = apr_psprintf( mrSerfSession.getAprPool(), "(<%s>)", + rtl::OUStringToOString(inLock.LockTokens[0], RTL_TEXTENCODING_UTF8 ).getStr() ); + } mpProcImpl = createPostReqProcImpl( mPathStr, mrSerfSession.getRequestEnvironment().m_aRequestHeaders, inData, inDataLen, + inLockToken, mContentType, mReferer, xioOutStrm ); @@ -254,20 +289,36 @@ bool SerfRequestProcessor::processPost( } // DELETE -bool SerfRequestProcessor::processDelete( apr_status_t& outSerfStatus ) +bool SerfRequestProcessor::processDelete( const com::sun::star::ucb::Lock inLock, + apr_status_t& outSerfStatus ) { + char * inLockToken = static_cast<char*>(0); + if(inLock.LockTokens.getLength() > 0) + { + inLockToken = apr_psprintf( mrSerfSession.getAprPool(), "(<%s>)", + rtl::OUStringToOString(inLock.LockTokens[0], RTL_TEXTENCODING_UTF8 ).getStr() ); + } mpProcImpl = createDeleteReqProcImpl( mPathStr, - mrSerfSession.getRequestEnvironment().m_aRequestHeaders ); + mrSerfSession.getRequestEnvironment().m_aRequestHeaders, + inLockToken ); outSerfStatus = runProcessor(); return outSerfStatus == APR_SUCCESS; } // MKCOL -bool SerfRequestProcessor::processMkCol( apr_status_t& outSerfStatus ) +bool SerfRequestProcessor::processMkCol( const com::sun::star::ucb::Lock inLock, + apr_status_t& outSerfStatus ) { + char * inLockToken = static_cast<char*>(0); + if(inLock.LockTokens.getLength() > 0) + { + inLockToken = apr_psprintf( mrSerfSession.getAprPool(), "(<%s>)", + rtl::OUStringToOString(inLock.LockTokens[0], RTL_TEXTENCODING_UTF8 ).getStr() ); + } mpProcImpl = createMkColReqProcImpl( mPathStr, - mrSerfSession.getRequestEnvironment().m_aRequestHeaders ); + mrSerfSession.getRequestEnvironment().m_aRequestHeaders, + inLockToken ); outSerfStatus = runProcessor(); return outSerfStatus == APR_SUCCESS; @@ -276,14 +327,22 @@ bool SerfRequestProcessor::processMkCol( // COPY bool SerfRequestProcessor::processCopy( const rtl::OUString & inDestinationPath, const bool inOverwrite, + const com::sun::star::ucb::Lock inLock, apr_status_t& outSerfStatus ) { mDestPathStr = apr_pstrdup( mrSerfSession.getAprPool(), rtl::OUStringToOString( inDestinationPath, RTL_TEXTENCODING_UTF8 ).getStr() ); + char * inLockToken = static_cast<char*>(0); + if(inLock.LockTokens.getLength() > 0) + { + inLockToken = apr_psprintf( mrSerfSession.getAprPool(), "(<%s>)", + rtl::OUStringToOString(inLock.LockTokens[0], RTL_TEXTENCODING_UTF8 ).getStr() ); + } mpProcImpl = createCopyReqProcImpl( mPathStr, mrSerfSession.getRequestEnvironment().m_aRequestHeaders, mDestPathStr, - inOverwrite ); + inOverwrite, + inLockToken ); outSerfStatus = runProcessor(); return outSerfStatus == APR_SUCCESS; @@ -292,14 +351,95 @@ bool SerfRequestProcessor::processCopy( // MOVE bool SerfRequestProcessor::processMove( const rtl::OUString & inDestinationPath, const bool inOverwrite, + const com::sun::star::ucb::Lock inLock, apr_status_t& outSerfStatus ) { mDestPathStr = apr_pstrdup( mrSerfSession.getAprPool(), rtl::OUStringToOString( inDestinationPath, RTL_TEXTENCODING_UTF8 ).getStr() ); + char * inLockToken = static_cast<char*>(0); + if(inLock.LockTokens.getLength() > 0) + { + inLockToken = apr_psprintf( mrSerfSession.getAprPool(), "(<%s>)", + rtl::OUStringToOString(inLock.LockTokens[0], RTL_TEXTENCODING_UTF8 ).getStr() ); + } mpProcImpl = createMoveReqProcImpl( mPathStr, mrSerfSession.getRequestEnvironment().m_aRequestHeaders, mDestPathStr, - inOverwrite ); + inOverwrite, + inLockToken ); + outSerfStatus = runProcessor(); + + return outSerfStatus == APR_SUCCESS; +} + +//LOCK creating a new lock +bool SerfRequestProcessor::processLock( const rtl::OUString & inDestinationPath, + const com::sun::star::ucb::Lock& inLock, + DAVPropertyValue & outLock, + apr_status_t& outSerfStatus ) +{ + mDestPathStr = apr_pstrdup( mrSerfSession.getAprPool(), + rtl::OUStringToOString( inDestinationPath, RTL_TEXTENCODING_UTF8 ).getStr() ); + char * Timeout; + if(inLock.Timeout == -1) + Timeout = apr_psprintf( mrSerfSession.getAprPool(), "Infinite" ); + else + Timeout = apr_psprintf( mrSerfSession.getAprPool(), "Second-%ld", inLock.Timeout ); + + mpProcImpl = createLockReqProcImpl( mPathStr, + mrSerfSession.getRequestEnvironment().m_aRequestHeaders, + inLock, + Timeout, + outLock); + outSerfStatus = runProcessor(); + + return outSerfStatus == APR_SUCCESS; +} + +//LOCK refresh an existing lock +bool SerfRequestProcessor::processLockRefresh( const rtl::OUString & inDestinationPath, + const com::sun::star::ucb::Lock& inLock, + DAVPropertyValue & outLock, + apr_status_t& outSerfStatus ) +{ + mDestPathStr = apr_pstrdup( mrSerfSession.getAprPool(), + rtl::OUStringToOString( inDestinationPath, RTL_TEXTENCODING_UTF8 ).getStr() ); + char * Timeout; + if(inLock.Timeout == -1) + Timeout = apr_psprintf( mrSerfSession.getAprPool(), "Infinite" ); + else + Timeout = apr_psprintf( mrSerfSession.getAprPool(), "Second-%ld", inLock.Timeout ); + + char * inLockToken = apr_psprintf( mrSerfSession.getAprPool(), "(<%s>)", + rtl::OUStringToOString(inLock.LockTokens[0], RTL_TEXTENCODING_UTF8 ).getStr() ); + + mpProcImpl = createLockRefreshProcImpl( mPathStr, + mrSerfSession.getRequestEnvironment().m_aRequestHeaders, + inLock, + inLockToken, + Timeout, + outLock); + outSerfStatus = runProcessor(); + + return outSerfStatus == APR_SUCCESS; +} + +//ULOCK unlock an existing lock +bool SerfRequestProcessor::processUnlock( const rtl::OUString & inDestinationPath, + const com::sun::star::ucb::Lock& inLock, + apr_status_t& outSerfStatus ) +{ + mDestPathStr = apr_pstrdup( mrSerfSession.getAprPool(), + rtl::OUStringToOString( inDestinationPath, RTL_TEXTENCODING_UTF8 ).getStr() ); + + char * aToken = apr_psprintf( mrSerfSession.getAprPool(), "<%s>", + rtl::OUStringToOString(inLock.LockTokens[0], RTL_TEXTENCODING_UTF8 ).getStr() ); + + mpProcImpl = createUnlockProcImpl( mPathStr, + mrSerfSession.getRequestEnvironment().m_aRequestHeaders, + inLock, + aToken ); + outSerfStatus = runProcessor(); return outSerfStatus == APR_SUCCESS; @@ -316,7 +456,8 @@ apr_status_t SerfRequestProcessor::runPr } // create serf request - serf_connection_request_create( mrSerfSession.getSerfConnection(), + OSL_ASSERT(mrSerfSession.getSerfConnection() != NULL); + serf_connection_request_create( mrSerfSession.getSerfConnection(), Serf_SetupRequest, this ); @@ -327,15 +468,19 @@ apr_status_t SerfRequestProcessor::runPr apr_pool_t* pAprPool = mrSerfSession.getAprPool(); while ( true ) { - status = serf_context_run( pSerfContext, - SERF_DURATION_FOREVER, + status = serf_context_run( pSerfContext, + SERF_DURATION_FOREVER, pAprPool ); if ( APR_STATUS_IS_TIMEUP( status ) ) { continue; } - if ( status != APR_SUCCESS ) + if ( status != APR_SUCCESS ) { +#if OSL_DEBUG_LEVEL > 0 + char buff[512]; + OSL_TRACE("SerfRequestProcessor::runProcessor, status != APR_SUCCESS: %d (%s)",status, apr_strerror(status, buff, 512)); +#endif break; } if ( mbProcessingDone ) @@ -356,6 +501,7 @@ void SerfRequestProcessor::postprocessPr return; } + OSL_TRACE("SerfRequestProcessor::postprocessProcessor:%d",__LINE__); switch ( inStatus ) { case APR_EGENERAL: @@ -379,8 +525,8 @@ void SerfRequestProcessor::postprocessPr } else { - mpDAVException = new DAVException( DAVException::DAV_HTTP_ERROR, - mHTTPStatusCodeText, + mpDAVException = new DAVException( DAVException::DAV_HTTP_ERROR, + mHTTPStatusCodeText, mnHTTPStatusCode ); } break; @@ -388,12 +534,17 @@ void SerfRequestProcessor::postprocessPr case SC_MOVED_TEMPORARILY: case SC_SEE_OTHER: case SC_TEMPORARY_REDIRECT: - mpDAVException = new DAVException( DAVException::DAV_HTTP_REDIRECT, + mpDAVException = new DAVException( DAVException::DAV_HTTP_REDIRECT, mRedirectLocation ); break; + case SC_LOCKED: + mpDAVException = new DAVException( DAVException::DAV_LOCKED, + mHTTPStatusCodeText, + mnHTTPStatusCode ); + break; default: - mpDAVException = new DAVException( DAVException::DAV_HTTP_ERROR, - mHTTPStatusCodeText, + mpDAVException = new DAVException( DAVException::DAV_HTTP_ERROR, + mHTTPStatusCodeText, mnHTTPStatusCode ); break; } @@ -404,13 +555,12 @@ void SerfRequestProcessor::postprocessPr mpDAVException = new DAVException( DAVException::DAV_HTTP_ERROR ); break; } - } -apr_status_t SerfRequestProcessor::provideSerfCredentials( char ** outUsername, +apr_status_t SerfRequestProcessor::provideSerfCredentials( char ** outUsername, char ** outPassword, - serf_request_t * inRequest, - int inCode, + serf_request_t * inRequest, + int inCode, const char *inAuthProtocol, const char *inRealm, apr_pool_t *inAprPool ) @@ -486,7 +636,7 @@ apr_status_t SerfRequestProcessor::handl // some general response handling and error handling { - if ( !inSerfResponseBucket ) + if ( !inSerfResponseBucket ) { /* A NULL response can come back if the request failed completely */ mbProcessingDone = true; @@ -495,11 +645,29 @@ apr_status_t SerfRequestProcessor::handl serf_status_line sl; apr_status_t status = serf_bucket_response_status( inSerfResponseBucket, &sl ); - if ( status ) + if ( status ) { mbProcessingDone = false; // allow another try in order to get a response return status; } + serf_bucket_t *headers = serf_bucket_response_get_headers( inSerfResponseBucket ); + + // check header according: + // http://tools.ietf.org/html/rfc7231#section-7.4.2 + // need to do this so we can adjust the protocol accordingly + // serf_bucket_headers_get is case independent + const char* server = serf_bucket_headers_get( headers, "server" ); + if( server ) + { + //update the server type on session + mrSerfSession.setServerHeaderField( ::rtl::OUString::createFromAscii( server ) ); + } + //the following extension is MS IIS specific, + //see https://msdn.microsoft.com/en-us/library/cc250064.aspx + //site last checked on 2015-03-02 + //TODO i126305 need to be added when serf is updated to a version supporting Windows authentication + //const char* msDavExtErr = serf_bucket_headers_get( headers, "X-MSDAVEXT_ERROR" ); + // TODO - check, if response status code handling is correct mnHTTPStatusCode = ( sl.version != 0 && sl.code >= 0 ) ? static_cast< sal_uInt16 >( sl.code ) @@ -508,7 +676,7 @@ apr_status_t SerfRequestProcessor::handl { mHTTPStatusCodeText = ::rtl::OUString::createFromAscii( sl.reason ); } - if ( ( sl.version == 0 || sl.code < 0 ) || + if ( ( sl.version == 0 || sl.code < 0 ) || mnHTTPStatusCode >= 300 ) { if ( mnHTTPStatusCode == 301 || @@ -517,7 +685,6 @@ apr_status_t SerfRequestProcessor::handl mnHTTPStatusCode == 307 ) { // new location for certain redirections - serf_bucket_t *headers = serf_bucket_response_get_headers( inSerfResponseBucket ); const char* location = serf_bucket_headers_get( headers, "Location" ); if ( location ) { Modified: openoffice/branches/AOO410/main/ucb/source/ucp/webdav/SerfRequestProcessor.hxx URL: http://svn.apache.org/viewvc/openoffice/branches/AOO410/main/ucb/source/ucp/webdav/SerfRequestProcessor.hxx?rev=1705201&r1=1705200&r2=1705201&view=diff ============================================================================== --- openoffice/branches/AOO410/main/ucb/source/ucp/webdav/SerfRequestProcessor.hxx (original) +++ openoffice/branches/AOO410/main/ucb/source/ucp/webdav/SerfRequestProcessor.hxx Thu Sep 24 23:52:34 2015 @@ -32,6 +32,7 @@ #include "DAVResource.hxx" #include "DAVException.hxx" +#include "SerfTypes.hxx" #include "SerfInputStream.hxx" #include <com/sun/star/io/XOutputStream.hpp> @@ -62,6 +63,7 @@ public: // PROPPATCH bool processPropPatch( const std::vector< ProppatchValue > & inProperties, + const com::sun::star::ucb::Lock inLock, apr_status_t& outSerfStatus ); // GET @@ -92,6 +94,7 @@ public: // PUT bool processPut( const char* inData, apr_size_t inDataLen, + const com::sun::star::ucb::Lock inLock, apr_status_t& outSerfStatus ); // POST @@ -99,6 +102,7 @@ public: apr_size_t inDataLen, const rtl::OUString & inContentType, const rtl::OUString & inReferer, + const com::sun::star::ucb::Lock inLock, const com::sun::star::uno::Reference< SerfInputStream >& xioInStrm, apr_status_t& outSerfStatus ); @@ -107,25 +111,47 @@ public: apr_size_t inDataLen, const rtl::OUString & inContentType, const rtl::OUString & inReferer, + const com::sun::star::ucb::Lock inLock, const com::sun::star::uno::Reference< com::sun::star::io::XOutputStream >& xioOutStrm, apr_status_t& outSerfStatus ); // DELETE - bool processDelete( apr_status_t& outSerfStatus ); + bool processDelete( const com::sun::star::ucb::Lock inLock, + apr_status_t& outSerfStatus ); // MKCOL - bool processMkCol( apr_status_t& outSerfStatus ); + bool processMkCol( const com::sun::star::ucb::Lock inLock, + apr_status_t& outSerfStatus ); // COPY bool processCopy( const rtl::OUString & inDestinationPath, const bool inOverwrite, + const com::sun::star::ucb::Lock inLock, apr_status_t& outSerfStatus ); // MOVE bool processMove( const rtl::OUString & inDestinationPath, const bool inOverwrite, + const com::sun::star::ucb::Lock inLock, apr_status_t& outSerfStatus ); + // LOCK + bool processLock( const rtl::OUString & inDestinationPath, + const com::sun::star::ucb::Lock& inLock, + DAVPropertyValue & outLock, + apr_status_t& outSerfStatus ); + + // LOCK refresh + bool processLockRefresh( const rtl::OUString & inDestinationPath, + const com::sun::star::ucb::Lock& inLock, + DAVPropertyValue & outLock, + apr_status_t& outSerfStatus ); + + //UNLOCK + bool processUnlock( const rtl::OUString & inDestinationPath, + const com::sun::star::ucb::Lock& inLock, + apr_status_t& outSerfStatus ); + apr_status_t provideSerfCredentials( char ** outUsername, char ** outPassword, serf_request_t * inRequest, Modified: openoffice/branches/AOO410/main/ucb/source/ucp/webdav/SerfRequestProcessorImplFac.cxx URL: http://svn.apache.org/viewvc/openoffice/branches/AOO410/main/ucb/source/ucp/webdav/SerfRequestProcessorImplFac.cxx?rev=1705201&r1=1705200&r2=1705201&view=diff ============================================================================== --- openoffice/branches/AOO410/main/ucb/source/ucp/webdav/SerfRequestProcessorImplFac.cxx (original) +++ openoffice/branches/AOO410/main/ucb/source/ucp/webdav/SerfRequestProcessorImplFac.cxx Thu Sep 24 23:52:34 2015 @@ -22,6 +22,7 @@ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_ucb.hxx" +#include "SerfTypes.hxx" #include "SerfRequestProcessorImplFac.hxx" #include "SerfPropFindReqProcImpl.hxx" #include "SerfPropPatchReqProcImpl.hxx" @@ -33,6 +34,9 @@ #include "SerfMkColReqProcImpl.hxx" #include "SerfCopyReqProcImpl.hxx" #include "SerfMoveReqProcImpl.hxx" +#include "SerfLockReqProcImpl.hxx" +#include "SerfLockRefreshProcImpl.hxx" +#include "SerfUnlockProcImpl.hxx" namespace http_dav_ucp { @@ -64,11 +68,13 @@ namespace http_dav_ucp SerfRequestProcessorImpl* createPropPatchReqProcImpl( const char* inPath, const DAVRequestHeaders& inRequestHeaders, - const std::vector< ProppatchValue > & inProperties ) + const std::vector< ProppatchValue > & inProperties, + const char* inLockToken ) { SerfRequestProcessorImpl* pReqProcImpl = new SerfPropPatchReqProcImpl( inPath, inRequestHeaders, - inProperties ); + inProperties, + inLockToken ); return pReqProcImpl; } @@ -136,11 +142,13 @@ namespace http_dav_ucp SerfRequestProcessorImpl* createPutReqProcImpl( const char* inPath, const DAVRequestHeaders& inRequestHeaders, const char* inData, + const char* inLockToken, apr_size_t inDataLen ) { SerfRequestProcessorImpl* pReqProcImpl = new SerfPutReqProcImpl( inPath, inRequestHeaders, inData, + inLockToken, inDataLen ); return pReqProcImpl; } @@ -149,6 +157,7 @@ namespace http_dav_ucp const DAVRequestHeaders& inRequestHeaders, const char* inData, apr_size_t inDataLen, + const char* inLockToken, const char* inContentType, const char* inReferer, const com::sun::star::uno::Reference< SerfInputStream >& xioInStrm ) @@ -157,6 +166,7 @@ namespace http_dav_ucp inRequestHeaders, inData, inDataLen, + inLockToken, inContentType, inReferer, xioInStrm ); @@ -167,6 +177,7 @@ namespace http_dav_ucp const DAVRequestHeaders& inRequestHeaders, const char* inData, apr_size_t inDataLen, + const char* inLockToken, const char* inContentType, const char* inReferer, const com::sun::star::uno::Reference< com::sun::star::io::XOutputStream >& xioOutStrm ) @@ -175,6 +186,7 @@ namespace http_dav_ucp inRequestHeaders, inData, inDataLen, + inLockToken, inContentType, inReferer, xioOutStrm ); @@ -182,42 +194,92 @@ namespace http_dav_ucp } SerfRequestProcessorImpl* createDeleteReqProcImpl( const char* inPath, - const DAVRequestHeaders& inRequestHeaders ) + const DAVRequestHeaders& inRequestHeaders, + const char * inLockToken ) { SerfRequestProcessorImpl* pReqProcImpl = new SerfDeleteReqProcImpl( inPath, - inRequestHeaders ); + inRequestHeaders, + inLockToken ); return pReqProcImpl; } SerfRequestProcessorImpl* createMkColReqProcImpl( const char* inPath, - const DAVRequestHeaders& inRequestHeaders ) + const DAVRequestHeaders& inRequestHeaders, + const char * inLockToken ) { SerfRequestProcessorImpl* pReqProcImpl = new SerfMkColReqProcImpl( inPath, - inRequestHeaders ); + inRequestHeaders, + inLockToken ); return pReqProcImpl; } SerfRequestProcessorImpl* createCopyReqProcImpl( const char* inSourcePath, const DAVRequestHeaders& inRequestHeaders, const char* inDestinationPath, - const bool inOverwrite ) + const bool inOverwrite, + const char* inLockToken ) { SerfRequestProcessorImpl* pReqProcImpl = new SerfCopyReqProcImpl( inSourcePath, inRequestHeaders, inDestinationPath, - inOverwrite ); + inOverwrite, + inLockToken ); return pReqProcImpl; } SerfRequestProcessorImpl* createMoveReqProcImpl( const char* inSourcePath, const DAVRequestHeaders& inRequestHeaders, const char* inDestinationPath, - const bool inOverwrite ) + const bool inOverwrite, + const char* inLockToken ) { SerfRequestProcessorImpl* pReqProcImpl = new SerfMoveReqProcImpl( inSourcePath, inRequestHeaders, inDestinationPath, - inOverwrite ); + inOverwrite, + inLockToken ); + return pReqProcImpl; + } + + SerfRequestProcessorImpl* createLockReqProcImpl( const char* inSourcePath, + const DAVRequestHeaders& inRequestHeaders, + const ucb::Lock& inLock, + const char* inTimeout, + DAVPropertyValue & outLock) + { + SerfRequestProcessorImpl* pReqProcImpl = new SerfLockReqProcImpl( inSourcePath, + inRequestHeaders, + inLock, + inTimeout, + outLock); + return pReqProcImpl; + } + + SerfRequestProcessorImpl* createLockRefreshProcImpl( const char* inSourcePath, + const DAVRequestHeaders& inRequestHeaders, + const ucb::Lock& inLock, + const char* inLockToken, + const char* inTimeout, + DAVPropertyValue & outLock) + { + SerfRequestProcessorImpl* pReqProcImpl = new SerfLockRefreshProcImpl( inSourcePath, + inRequestHeaders, + inLock, + inLockToken, + inTimeout, + outLock); + return pReqProcImpl; + } + + SerfRequestProcessorImpl* createUnlockProcImpl( const char* inSourcePath, + const DAVRequestHeaders& inRequestHeaders, + const ucb::Lock& inLock, + const char* inToken ) + { + SerfRequestProcessorImpl* pReqProcImpl = new SerfUnlockProcImpl( inSourcePath, + inRequestHeaders, + inLock, + inToken ); return pReqProcImpl; } Modified: openoffice/branches/AOO410/main/ucb/source/ucp/webdav/SerfRequestProcessorImplFac.hxx URL: http://svn.apache.org/viewvc/openoffice/branches/AOO410/main/ucb/source/ucp/webdav/SerfRequestProcessorImplFac.hxx?rev=1705201&r1=1705200&r2=1705201&view=diff ============================================================================== --- openoffice/branches/AOO410/main/ucb/source/ucp/webdav/SerfRequestProcessorImplFac.hxx (original) +++ openoffice/branches/AOO410/main/ucb/source/ucp/webdav/SerfRequestProcessorImplFac.hxx Thu Sep 24 23:52:34 2015 @@ -27,6 +27,7 @@ #include "DAVTypes.hxx" #include "DAVResource.hxx" +#include "SerfTypes.hxx" #include "SerfRequestProcessorImpl.hxx" #include "SerfInputStream.hxx" #include <com/sun/star/io/XOutputStream.hpp> @@ -46,7 +47,8 @@ namespace http_dav_ucp SerfRequestProcessorImpl* createPropPatchReqProcImpl( const char* inPath, const DAVRequestHeaders& inRequestHeaders, - const std::vector< ProppatchValue > & inProperties ); + const std::vector< ProppatchValue > & inProperties, + const char* inLockToken ); SerfRequestProcessorImpl* createGetReqProcImpl( const char* inPath, const DAVRequestHeaders& inRequestHeaders, @@ -76,12 +78,14 @@ namespace http_dav_ucp SerfRequestProcessorImpl* createPutReqProcImpl( const char* inPath, const DAVRequestHeaders& inRequestHeaders, const char* inData, + const char* inLockToken, apr_size_t inDataLen ); SerfRequestProcessorImpl* createPostReqProcImpl( const char* inPath, const DAVRequestHeaders& inRequestHeaders, const char* inData, apr_size_t inDataLen, + const char* inLockToken, const char* inContentType, const char* inReferer, const com::sun::star::uno::Reference< SerfInputStream >& xioInStrm ); @@ -90,25 +94,48 @@ namespace http_dav_ucp const DAVRequestHeaders& inRequestHeaders, const char* inData, apr_size_t inDataLen, + const char* inLockToken, const char* inContentType, const char* inReferer, const com::sun::star::uno::Reference< com::sun::star::io::XOutputStream >& xioOutStrm ); SerfRequestProcessorImpl* createDeleteReqProcImpl( const char* inPath, - const DAVRequestHeaders& inRequestHeaders ); + const DAVRequestHeaders& inRequestHeaders, + const char * inLockToken ); SerfRequestProcessorImpl* createMkColReqProcImpl( const char* inPath, - const DAVRequestHeaders& inRequestHeaders ); + const DAVRequestHeaders& inRequestHeaders, + const char * inLockToken ); SerfRequestProcessorImpl* createCopyReqProcImpl( const char* inSourcePath, const DAVRequestHeaders& inRequestHeaders, const char* inDestinationPath, - const bool inOverwrite ); + const bool inOverwrite, + const char* inLockToken ); SerfRequestProcessorImpl* createMoveReqProcImpl( const char* inSourcePath, const DAVRequestHeaders& inRequestHeaders, const char* inDestinationPath, - const bool inOverwrite ); + const bool inOverwrite, + const char* inLockToken ); + + SerfRequestProcessorImpl* createLockReqProcImpl( const char* inSourcePath, + const DAVRequestHeaders& inRequestHeaders, + const ucb::Lock& inLock, + const char* inTimeout, + DAVPropertyValue & outLock ); + + SerfRequestProcessorImpl* createLockRefreshProcImpl( const char* inSourcePath, + const DAVRequestHeaders& inRequestHeaders, + const ucb::Lock& inLock, + const char* inToken, + const char* inTimeout, + DAVPropertyValue & outLock ); + + SerfRequestProcessorImpl* createUnlockProcImpl( const char* inSourcePath, + const DAVRequestHeaders& inRequestHeaders, + const ucb::Lock& inLock, + const char* inToken ); } // namespace http_dav_ucp Modified: openoffice/branches/AOO410/main/ucb/source/ucp/webdav/SerfSession.cxx URL: http://svn.apache.org/viewvc/openoffice/branches/AOO410/main/ucb/source/ucp/webdav/SerfSession.cxx?rev=1705201&r1=1705200&r2=1705201&view=diff ============================================================================== --- openoffice/branches/AOO410/main/ucb/source/ucp/webdav/SerfSession.cxx (original) +++ openoffice/branches/AOO410/main/ucb/source/ucp/webdav/SerfSession.cxx Thu Sep 24 23:52:34 2015 @@ -26,6 +26,8 @@ #include <vector> #include <string.h> #include <rtl/string.h> +#include <rtl/ustrbuf.hxx> +#include <osl/time.h> #include "comphelper/sequence.hxx" #include "ucbhelper/simplecertificatevalidationrequest.hxx" @@ -57,10 +59,9 @@ using namespace com::sun::star; using namespace http_dav_ucp; - // ------------------------------------------------------------------- // static members! -//SerfLockStore SerfSession::m_aSerfLockStore; +SerfLockStore SerfSession::m_aSerfLockStore; // ------------------------------------------------------------------- // Constructor @@ -75,6 +76,7 @@ SerfSession::SerfSession( , m_aUri( inUri ) , m_aProxyName() , m_nProxyPort( 0 ) + , m_aServerHeaderField() , m_pSerfConnection( 0 ) , m_pSerfContext( 0 ) , m_bIsHeadRequestInProgress( false ) @@ -97,6 +99,7 @@ SerfSession::~SerfSession( ) { serf_connection_close( m_pSerfConnection ); m_pSerfConnection = 0; + OSL_TRACE("SerfSession::~SerfSession: closed serf connection"); } } @@ -126,6 +129,7 @@ void SerfSession::Init() // Not yet initialized. Create new session. bCreateNewSession = true; + OSL_TRACE("SerfSession::Init: serf connection created"); } else { @@ -166,7 +170,7 @@ void SerfSession::Init() if ( m_aProxyName.getLength() ) { apr_sockaddr_t *proxy_address = NULL; - status = apr_sockaddr_info_get( &proxy_address, + status = apr_sockaddr_info_get( &proxy_address, rtl::OUStringToOString( m_aProxyName, RTL_TEXTENCODING_UTF8 ).getStr(), APR_UNSPEC, static_cast<apr_port_t>(m_nProxyPort), @@ -223,6 +227,55 @@ char* SerfSession::getHostinfo() return m_aUri.getAprUri()->hostinfo; } +// ------------------------------------------------------------------- +// helper function +// it composes the uri for lockstore registration +rtl::OUString SerfSession::composeCurrentUri(const rtl::OUString & inPath) +{ + rtl::OUString aScheme( m_aUri.GetScheme() ); + rtl::OUStringBuffer aBuf( aScheme ); + aBuf.appendAscii( "://" ); + if ( m_aUri.GetUserInfo().getLength() > 0 ) + { + aBuf.append( m_aUri.GetUserInfo() ); + aBuf.appendAscii( "@" ); + } + // Is host a numeric IPv6 address? + if ( ( m_aUri.GetHost().indexOf( ':' ) != -1 ) && + ( m_aUri.GetHost()[ 0 ] != sal_Unicode( '[' ) ) ) + { + aBuf.appendAscii( "[" ); + aBuf.append( m_aUri.GetHost() ); + aBuf.appendAscii( "]" ); + } + else + { + aBuf.append( m_aUri.GetHost() ); + } + + // append port, but only, if not default port. + bool bAppendPort = true; + sal_Int32 aPort = m_aUri.GetPort(); + switch ( aPort ) + { + case DEFAULT_HTTP_PORT: + bAppendPort = aScheme.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "http" ) ); + break; + + case DEFAULT_HTTPS_PORT: + bAppendPort = !aScheme.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "https" ) ); + break; + } + if ( bAppendPort ) + { + aBuf.appendAscii( ":" ); + aBuf.append( rtl::OUString::valueOf( aPort ) ); + } + aBuf.append( inPath ); + + rtl::OUString aUri(aBuf.makeStringAndClear() ); + return aUri; +} // ------------------------------------------------------------------- // virtual @@ -259,11 +312,11 @@ apr_status_t SerfSession::setupSerfConne apr_pool_t* /*inAprPool*/ ) { serf_bucket_t *tmpInputBkt; - tmpInputBkt = serf_context_bucket_socket_create( getSerfContext(), - inAprSocket, + tmpInputBkt = serf_context_bucket_socket_create( getSerfContext(), + inAprSocket, getSerfBktAlloc() ); - - if ( isSSLNeeded() ) + + if ( isSSLNeeded() ) { tmpInputBkt = serf_bucket_ssl_decrypt_create( tmpInputBkt, 0, @@ -276,7 +329,7 @@ apr_status_t SerfSession::setupSerfConne NULL, Serf_CertificateChainValidation, this); - serf_ssl_set_hostname( serf_bucket_ssl_decrypt_context_get( tmpInputBkt ), + serf_ssl_set_hostname( serf_bucket_ssl_decrypt_context_get( tmpInputBkt ), getHostinfo() ); *outSerfOutputBucket = serf_bucket_ssl_encrypt_create( *outSerfOutputBucket, @@ -290,10 +343,10 @@ apr_status_t SerfSession::setupSerfConne } apr_status_t SerfSession::provideSerfCredentials( bool bGiveProvidedCredentialsASecondTry, - char ** outUsername, + char ** outUsername, char ** outPassword, - serf_request_t * /*inRequest*/, - int /*inCode*/, + serf_request_t * /*inRequest*/, + int /*inCode*/, const char *inAuthProtocol, const char *inRealm, apr_pool_t *inAprPool ) @@ -600,7 +653,7 @@ serf_bucket_t* SerfSession::acceptSerfRe SerfBktAlloc ); // create response bucket - responseBkt = serf_bucket_response_create( responseBkt, + responseBkt = serf_bucket_response_create( responseBkt, SerfBktAlloc ); if ( isHeadRequestInProgress() ) @@ -693,7 +746,16 @@ void SerfSession::PROPPATCH( const rtl:: apr_status_t status = APR_SUCCESS; boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) ); + //check whether a lock on this resource is already owned + rtl::OUString aUri( composeCurrentUri( inPath ) ); + ucb::Lock inLock; + SerfLock * pLock = m_aSerfLockStore.findByUri( aUri ); + if ( pLock ) + { + inLock = pLock->getLock(); + } aReqProc->processPropPatch( inValues, + inLock, status ); HandleError( aReqProc ); @@ -843,8 +905,18 @@ void SerfSession::PUT( const rtl::OUStri if ( !getDataFromInputStream( inInputStream, aDataToSend, false ) ) throw DAVException( DAVException::DAV_INVALID_ARG ); apr_status_t status = APR_SUCCESS; + + //check whether a lock on this resource is already owned + rtl::OUString aUri( composeCurrentUri( inPath ) ); + ucb::Lock inLock; + SerfLock * pLock = m_aSerfLockStore.findByUri( aUri ); + if ( pLock ) + { + inLock = pLock->getLock(); + } aReqProc->processPut( reinterpret_cast< const char * >( aDataToSend.getConstArray() ), aDataToSend.getLength(), + inLock, status ); HandleError( aReqProc ); @@ -874,10 +946,19 @@ SerfSession::POST( const rtl::OUString & boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) ); uno::Reference< SerfInputStream > xInputStream( new SerfInputStream ); apr_status_t status = APR_SUCCESS; + //check whether a lock on this resource is already owned + rtl::OUString aUri( composeCurrentUri( inPath ) ); + ucb::Lock inLock; + SerfLock * pLock = m_aSerfLockStore.findByUri( aUri ); + if ( pLock ) + { + inLock = pLock->getLock(); + } aReqProc->processPost( reinterpret_cast< const char * >( aDataToSend.getConstArray() ), aDataToSend.getLength(), rContentType, rReferer, + inLock, xInputStream, status ); @@ -908,10 +989,19 @@ void SerfSession::POST( const rtl::OUStr boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) ); apr_status_t status = APR_SUCCESS; + //check whether a lock on this resource is already owned + rtl::OUString aUri( composeCurrentUri( inPath ) ); + ucb::Lock inLock; + SerfLock * pLock = m_aSerfLockStore.findByUri( aUri ); + if ( pLock ) + { + inLock = pLock->getLock(); + } aReqProc->processPost( reinterpret_cast< const char * >( aDataToSend.getConstArray() ), aDataToSend.getLength(), rContentType, rReferer, + inLock, oOutputStream, status ); @@ -931,7 +1021,15 @@ void SerfSession::MKCOL( const rtl::OUSt boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) ); apr_status_t status = APR_SUCCESS; - aReqProc->processMkCol( status ); + //check whether a lock on the destination resource is already owned + rtl::OUString aUri( composeCurrentUri( inPath ) ); + ucb::Lock inLock; + SerfLock * pLock = m_aSerfLockStore.findByUri( aUri ); + if ( pLock ) + { + inLock = pLock->getLock(); + } + aReqProc->processMkCol( inLock, status ); HandleError( aReqProc ); } @@ -952,8 +1050,17 @@ void SerfSession::COPY( const rtl::OUStr SerfUri theSourceUri( inSourceURL ); boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( theSourceUri.GetPath() ) ); apr_status_t status = APR_SUCCESS; + //check whether a lock on the destination resource is already owned + rtl::OUString aUri( composeCurrentUri( inDestinationURL ) ); + ucb::Lock inLock; + SerfLock * pLock = m_aSerfLockStore.findByUri( aUri ); + if ( pLock ) + { + inLock = pLock->getLock(); + } aReqProc->processCopy( inDestinationURL, (inOverWrite ? true : false), + inLock, status ); HandleError( aReqProc ); @@ -975,8 +1082,17 @@ void SerfSession::MOVE( const rtl::OUStr SerfUri theSourceUri( inSourceURL ); boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( theSourceUri.GetPath() ) ); apr_status_t status = APR_SUCCESS; + //check whether a lock on the destination resource is already owned + rtl::OUString aUri( composeCurrentUri( inDestinationURL ) ); + ucb::Lock inLock; + SerfLock * pLock = m_aSerfLockStore.findByUri( aUri ); + if ( pLock ) + { + inLock = pLock->getLock(); + } aReqProc->processMove( inDestinationURL, (inOverWrite ? true : false), + inLock, status ); HandleError( aReqProc ); @@ -995,25 +1111,33 @@ void SerfSession::DESTROY( const rtl::OU boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) ); apr_status_t status = APR_SUCCESS; - aReqProc->processDelete( status ); + //check whether a lock on this resource is already owned + rtl::OUString aUri( composeCurrentUri( inPath ) ); + ucb::Lock inLock; + SerfLock * pLock = m_aSerfLockStore.findByUri( aUri ); + if ( pLock ) + { + inLock = pLock->getLock(); + } + aReqProc->processDelete( inLock, status ); HandleError( aReqProc ); } // ------------------------------------------------------------------- -/* + namespace { sal_Int32 lastChanceToSendRefreshRequest( TimeValue const & rStart, - int timeout ) + sal_Int32 timeout ) { TimeValue aEnd; osl_getSystemTime( &aEnd ); // Try to estimate a safe absolute time for sending the // lock refresh request. - sal_Int32 lastChanceToSendRefreshRequest = -1; - if ( timeout != NE_TIMEOUT_INFINITE ) + sal_Int32 lastChanceToSendRefreshRequest = DAVINFINITY; + if ( timeout != DAVINFINITY ) { sal_Int32 calltime = aEnd.Seconds - rStart.Seconds; if ( calltime <= timeout ) @@ -1030,108 +1154,62 @@ namespace } } // namespace -*/ + // ------------------------------------------------------------------- // LOCK (set new lock) // ------------------------------------------------------------------- void SerfSession::LOCK( const ::rtl::OUString & inPath, - ucb::Lock & /*rLock*/, + ucb::Lock & rLock, const DAVRequestEnvironment & rEnv ) throw ( DAVException ) { osl::Guard< osl::Mutex > theGuard( m_aMutex ); + //before locking, search in the lock store if we already own a lock for this resource + //if present, return with exception DAV_LOCKED_SELF + rtl::OUString aUri( composeCurrentUri( inPath ) ); + SerfLock * pLock = m_aSerfLockStore.findByUri( aUri ); + if ( pLock ) + { +//already present, meaning already locked by the same AOO session and already in the lockstore +//just return, nothing to do + return; + } + Init( rEnv ); boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) ); - HandleError( aReqProc ); - /* Create a depth zero, exclusive write lock, with default timeout - * (allowing a server to pick a default). token, owner and uri are - * unset. */ - /* - SerfLock * theLock = ne_lock_create(); - - // Set the lock uri - ne_uri aUri; - ne_uri_parse( rtl::OUStringToOString( makeAbsoluteURL( inPath ), - RTL_TEXTENCODING_UTF8 ).getStr(), - &aUri ); - theLock->uri = aUri; - - // Set the lock depth - switch( rLock.Depth ) - { - case ucb::LockDepth_ZERO: - theLock->depth = NE_DEPTH_ZERO; - break; - case ucb::LockDepth_ONE: - theLock->depth = NE_DEPTH_ONE; - break; - case ucb::LockDepth_INFINITY: - theLock->depth = NE_DEPTH_INFINITE; - break; - default: - throw DAVException( DAVException::DAV_INVALID_ARG ); - } - - // Set the lock scope - switch ( rLock.Scope ) - { - case ucb::LockScope_EXCLUSIVE: - theLock->scope = ne_lockscope_exclusive; - break; - case ucb::LockScope_SHARED: - theLock->scope = ne_lockscope_shared; - break; - default: - throw DAVException( DAVException::DAV_INVALID_ARG ); - } + apr_status_t status = APR_SUCCESS; - // Set the lock timeout - theLock->timeout = (long)rLock.Timeout; + //the returned property, a sequence of locks + //only the first is used + DAVPropertyValue outLock; - // Set the lock owner - rtl::OUString aValue; - rLock.Owner >>= aValue; - theLock->owner = - ne_strdup( rtl::OUStringToOString( aValue, - RTL_TEXTENCODING_UTF8 ).getStr() ); TimeValue startCall; osl_getSystemTime( &startCall ); + aReqProc->processLock(inPath, rLock, outLock, status); - int theRetVal = ne_lock( m_pHttpSession, theLock ); + //HandleError will handle the error and throw an exception, if needed + HandleError( aReqProc ); - if ( theRetVal == NE_OK ) + if(outLock.Name.compareToAscii(RTL_CONSTASCII_STRINGPARAM( "DAV:lockdiscovery" )) == 0 ) { - m_aSerfLockStore.addLock( theLock, - this, - lastChanceToSendRefreshRequest( - startCall, theLock->timeout ) ); - - uno::Sequence< rtl::OUString > aTokens( 1 ); - aTokens[ 0 ] = rtl::OUString::createFromAscii( theLock->token ); - rLock.LockTokens = aTokens; + //got a lock, use only the first returned + uno::Sequence< ucb::Lock > aLocks; + outLock.Value >>= aLocks; + ucb::Lock aLock = aLocks[0]; - OSL_TRACE( "SerfSession::LOCK: created lock for %s. token: %s", - rtl::OUStringToOString( makeAbsoluteURL( inPath ), - RTL_TEXTENCODING_UTF8 ).getStr(), - theLock->token ); - } - else - { - ne_lock_destroy( theLock ); - - OSL_TRACE( "SerfSession::LOCK: obtaining lock for %s failed!", - rtl::OUStringToOString( makeAbsoluteURL( inPath ), - RTL_TEXTENCODING_UTF8 ).getStr() ); + SerfLock* aNewLock = new SerfLock( aLock, aUri, inPath ); + // add the store the new lock + m_aSerfLockStore.addLock(aNewLock,this, + lastChanceToSendRefreshRequest( + startCall, static_cast< sal_Int32 >(aLock.Timeout) ) ); } - HandleError( theRetVal, inPath, rEnv ); - */ } // ------------------------------------------------------------------- -// LOCK (refresh existing lock) +// LOCK (refresh existing lock from DAVResourceAccess) // ------------------------------------------------------------------- sal_Int64 SerfSession::LOCK( const ::rtl::OUString & /*inPath*/, sal_Int64 nTimeout, @@ -1172,92 +1250,102 @@ sal_Int64 SerfSession::LOCK( const ::rtl } // ------------------------------------------------------------------- -// LOCK (refresh existing lock) +// LOCK (refresh existing lock from SerfLockStore) // ------------------------------------------------------------------- -bool SerfSession::LOCK( SerfLock * /*pLock*/, - sal_Int32 & /*rlastChanceToSendRefreshRequest*/ ) +bool SerfSession::LOCK( SerfLock * pLock, + sal_Int32 & rlastChanceToSendRefreshRequest ) { osl::Guard< osl::Mutex > theGuard( m_aMutex ); + rtl::OUString inPath = pLock->getResourcePath(); - return true; - /* - // refresh existing lock. + boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) ); + apr_status_t status = APR_SUCCESS; + + //the returned property, a sequence of locks + //only the first is used + DAVPropertyValue outLock; TimeValue startCall; osl_getSystemTime( &startCall ); - if ( ne_lock_refresh( m_pHttpSession, pLock ) == NE_OK ) - { - rlastChanceToSendRefreshRequest - = lastChanceToSendRefreshRequest( startCall, pLock->timeout ); + // refresh existing lock. + aReqProc->processLockRefresh( inPath, pLock->getLock(), outLock, status); - OSL_TRACE( "Lock successfully refreshed." ); - return true; - } - else - { - OSL_TRACE( "Lock not refreshed!" ); - return false; - } - */ + // TODO: possible enhancement as the following: + // - use an interaction handler to alert the user if the lock was not refreshed, + // offering to try again with a new session, asking the user for credential, if necessary. + // This may happen if the WebDAV server goes off-line for whatever reason, or the connection is dropped for time-out + // To implement this behavior, some redesigning of the current session implementation may be needed. + // + + //HandleError will handle the error and throw an exception, if needed + HandleError( aReqProc ); + + uno::Sequence< ucb::Lock > aLocks; + outLock.Value >>= aLocks; + ucb::Lock aLock = aLocks[0]; + + //if ok, udate the lastchance refresh time in lock + rlastChanceToSendRefreshRequest + = lastChanceToSendRefreshRequest( startCall, static_cast< sal_Int32 >(aLock.Timeout) ); + + return true; } // ------------------------------------------------------------------- -// UNLOCK +// UNLOCK called from external (DAVResourceAccess) // ------------------------------------------------------------------- -void SerfSession::UNLOCK( const ::rtl::OUString & /*inPath*/, - const DAVRequestEnvironment & /*rEnv*/ ) +void SerfSession::UNLOCK( const ::rtl::OUString & inPath, + const DAVRequestEnvironment & rEnv ) throw ( DAVException ) { osl::Guard< osl::Mutex > theGuard( m_aMutex ); - /* - // get the neon lock from lock store - SerfLock * theLock - = m_aSerfLockStore.findByUri( makeAbsoluteURL( inPath ) ); - if ( !theLock ) + rtl::OUString aUri( composeCurrentUri( inPath ) ); + SerfLock * pLock = m_aSerfLockStore.findByUri( aUri ); + if ( !pLock ) + { throw DAVException( DAVException::DAV_NOT_LOCKED ); + } Init( rEnv ); - int theRetVal = ne_unlock( m_pHttpSession, theLock ); + boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) ); + apr_status_t status = APR_SUCCESS; - if ( theRetVal == NE_OK ) - { - m_aSerfLockStore.removeLock( theLock ); - ne_lock_destroy( theLock ); - } - else - { - OSL_TRACE( "SerfSession::UNLOCK: unlocking of %s failed.", - rtl::OUStringToOString( makeAbsoluteURL( inPath ), - RTL_TEXTENCODING_UTF8 ).getStr() ); - } + ucb::Lock inLock = pLock->getLock(); + //remove lock from lockstore + // so, if something goes wrong, we don't refresh it anymore + m_aSerfLockStore.removeLock(pLock); + delete pLock; - HandleError( theRetVal, inPath, rEnv ); - */ + // remove existing lock + aReqProc->processUnlock( inPath, inLock, status); + + //HandleError will handle the error and throw an exception, if needed + HandleError( aReqProc ); } // ------------------------------------------------------------------- -// UNLOCK +// UNLOCK (called from SerfLockStore) // ------------------------------------------------------------------- -bool SerfSession::UNLOCK( SerfLock * /*pLock*/ ) +bool SerfSession::UNLOCK( SerfLock * pLock ) { osl::Guard< osl::Mutex > theGuard( m_aMutex ); + rtl::OUString inPath = pLock->getResourcePath(); + + boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) ); + apr_status_t status = APR_SUCCESS; + + rtl::OUString aToken; + aToken = pLock->getLock().LockTokens[0]; + + aReqProc->processUnlock( inPath, pLock->getLock(), status); + + //HandleError will handle the error and throw an exception, if needed + HandleError( aReqProc ); return true; - /* - if ( ne_unlock( m_pHttpSession, pLock ) == NE_OK ) - { - OSL_TRACE( "UNLOCK succeeded." ); - return true; - } - else - { - OSL_TRACE( "UNLOCK failed!" ); - return false; - } - */ } // ------------------------------------------------------------------- @@ -1315,6 +1403,10 @@ bool containsLocktoken( const uno::Seque */ // ------------------------------------------------------------------- +// This method doesn't seem to be used. +// In any case the default behavior is to ask a lock whith a life of 3 minutes +// it will then be refreshed automatically (see SerfLockStore class) +// In case of AOO crash the lock will expire by itself bool SerfSession::removeExpiredLocktoken( const rtl::OUString & /*inURL*/, const DAVRequestEnvironment & /*rEnv*/ ) { @@ -1612,37 +1704,3 @@ SerfSession::isDomainMatch( rtl::OUStrin } return sal_False; } - -/* -// --------------------------------------------------------------------- -rtl::OUString SerfSession::makeAbsoluteURL( rtl::OUString const & rURL ) const -{ - try - { - // Is URL relative or already absolute? - if ( rURL[ 0 ] != sal_Unicode( '/' ) ) - { - // absolute. - return rtl::OUString( rURL ); - } - else - { - ne_uri aUri; - memset( &aUri, 0, sizeof( aUri ) ); - - ne_fill_server_uri( m_pHttpSession, &aUri ); - aUri.path - = ne_strdup( rtl::OUStringToOString( - rURL, RTL_TEXTENCODING_UTF8 ).getStr() ); - SerfUri aSerfUri( &aUri ); - ne_uri_free( &aUri ); - return aSerfUri.GetURI(); - } - } - catch ( DAVException const & ) - { - } - // error. - return rtl::OUString(); -} -*/ Modified: openoffice/branches/AOO410/main/ucb/source/ucp/webdav/SerfSession.hxx URL: http://svn.apache.org/viewvc/openoffice/branches/AOO410/main/ucb/source/ucp/webdav/SerfSession.hxx?rev=1705201&r1=1705200&r2=1705201&view=diff ============================================================================== --- openoffice/branches/AOO410/main/ucb/source/ucp/webdav/SerfSession.hxx (original) +++ openoffice/branches/AOO410/main/ucb/source/ucp/webdav/SerfSession.hxx Thu Sep 24 23:52:34 2015 @@ -27,9 +27,10 @@ #include <vector> #include <boost/shared_ptr.hpp> #include <osl/mutex.hxx> +#include "DAVResource.hxx" #include "DAVSession.hxx" #include "SerfTypes.hxx" -//#include "SerfLockStore.hxx" +#include "SerfLockStore.hxx" #include "SerfUri.hxx" #include <com/sun/star/lang/XMultiServiceFactory.hpp> @@ -54,6 +55,9 @@ private: rtl::OUString m_aProxyName; sal_Int32 m_nProxyPort; + // The server, according RFC7231 + // http://tools.ietf.org/html/rfc7231#section-7.4.2 + rtl::OUString m_aServerHeaderField; SerfConnection* m_pSerfConnection; serf_context_t* m_pSerfContext; @@ -66,12 +70,14 @@ private: DAVRequestEnvironment m_aEnv; -// static SerfLockStore m_aSerfLockStore; + static SerfLockStore m_aSerfLockStore; char* getHostinfo(); bool isSSLNeeded(); - SerfRequestProcessor* createReqProc( const rtl::OUString & inPath ); + SerfRequestProcessor* createReqProc( const rtl::OUString & inPath ); + + rtl::OUString composeCurrentUri( const rtl::OUString & inPath ); protected: virtual ~SerfSession(); @@ -258,6 +264,10 @@ public: sal_Bool isDomainMatch( rtl::OUString certHostName ); + const rtl::OUString & getServerHeaderField() { return m_aServerHeaderField; }; + + void setServerHeaderField( rtl::OUString aServerHeaderField ) { m_aServerHeaderField = aServerHeaderField; }; + private: friend class SerfLockStore; Modified: openoffice/branches/AOO410/main/ucb/source/ucp/webdav/SerfTypes.hxx URL: http://svn.apache.org/viewvc/openoffice/branches/AOO410/main/ucb/source/ucp/webdav/SerfTypes.hxx?rev=1705201&r1=1705200&r2=1705201&view=diff ============================================================================== --- openoffice/branches/AOO410/main/ucb/source/ucp/webdav/SerfTypes.hxx (original) +++ openoffice/branches/AOO410/main/ucb/source/ucp/webdav/SerfTypes.hxx Thu Sep 24 23:52:34 2015 @@ -25,13 +25,42 @@ #define INCLUDED_SERFTYPES_HXX #include <serf.h> +#include <com/sun/star/ucb/Lock.hpp> +#include "DAVTypes.hxx" +#include "DAVRequestEnvironment.hxx" + +using namespace com::sun::star; + +namespace http_dav_ucp +{ typedef serf_connection_t SerfConnection; -// TODO, figure out type of <SerfLock> -typedef int SerfLock; +class SerfLock +{ +private: + ucb::Lock mLock; + const rtl::OUString mResourceUri; + const rtl::OUString mPathStr; + // const DAVRequestEnvironment& mrRequestEnvironment; +public: + + SerfLock(const ucb::Lock inLock, rtl::OUString inUri, rtl::OUString inPath) + : mLock( inLock ) + , mResourceUri( inUri ) + , mPathStr( inPath ) + // , mrRequestEnvironment( rEnv ) + {}; + + void setLock(const ucb::Lock inLock) { mLock = inLock; }; + const ucb::Lock getLock() { return mLock; }; + const rtl::OUString getResourceUri() { return mResourceUri; }; + const rtl::OUString getResourcePath() { return mPathStr; }; + // const DAVRequestEnvironment& getRequestEnvironment() { return mrRequestEnvironment; }; +}; // TODO, check if we need it later on typedef struct { const char *nspace, *name; } SerfPropName; +}; #endif // INCLUDED_SERFTYPES_HXX Modified: openoffice/branches/AOO410/main/ucb/source/ucp/webdav/makefile.mk URL: http://svn.apache.org/viewvc/openoffice/branches/AOO410/main/ucb/source/ucp/webdav/makefile.mk?rev=1705201&r1=1705200&r2=1705201&view=diff ============================================================================== --- openoffice/branches/AOO410/main/ucb/source/ucp/webdav/makefile.mk (original) +++ openoffice/branches/AOO410/main/ucb/source/ucp/webdav/makefile.mk Thu Sep 24 23:52:34 2015 @@ -131,6 +131,10 @@ SLOFILES=\ $(SLO)$/SerfMkColReqProcImpl.obj \ $(SLO)$/SerfCopyReqProcImpl.obj \ $(SLO)$/SerfMoveReqProcImpl.obj \ + $(SLO)$/SerfLockReqProcImpl.obj \ + $(SLO)$/SerfLockRefreshProcImpl.obj \ + $(SLO)$/SerfUnlockProcImpl.obj \ + $(SLO)$/SerfLockStore.obj \ $(SLO)$/SerfSession.obj \ $(SLO)$/SerfCallbacks.obj \ $(SLO)$/SerfInputStream.obj \ @@ -148,6 +152,7 @@ SHL1IMPLIB=i$(TARGET) SHL1VERSIONMAP=$(SOLARENV)/src/component.map SHL1STDLIBS+=\ + $(TOOLSLIB) \ $(CPPUHELPERLIB) \ $(CPPULIB) \ $(SALLIB) \