webdav: Implement refreshing of locks.

Change-Id: Ia4a1c7b929dac473dfb5a5fa233c7f0c662a95c6
This commit is contained in:
Matúš Kukan
2014-03-25 12:19:35 +01:00
parent 53e9b3393a
commit 166a934cdf
7 changed files with 51 additions and 31 deletions

View File

@@ -32,10 +32,12 @@ namespace http_dav_ucp
SerfLockReqProcImpl::SerfLockReqProcImpl( const char* inPath, SerfLockReqProcImpl::SerfLockReqProcImpl( const char* inPath,
const DAVRequestHeaders& inRequestHeaders, const DAVRequestHeaders& inRequestHeaders,
SerfSession& rSession, SerfSession& rSession,
const css::ucb::Lock & rLock ) const css::ucb::Lock& rLock,
sal_Int32* plastChanceToSendRefreshRequest )
: SerfRequestProcessorImpl( inPath, inRequestHeaders ) : SerfRequestProcessorImpl( inPath, inRequestHeaders )
, m_rSession( rSession ) , m_rSession( rSession )
, m_aLock( rLock ) , m_aLock( rLock )
, m_plastChanceToSendRefreshRequest( plastChanceToSendRefreshRequest )
, m_xInputStream( new SerfInputStream() ) , m_xInputStream( new SerfInputStream() )
{ {
} }
@@ -76,9 +78,12 @@ serf_bucket_t * SerfLockReqProcImpl::createSerfRequestBucket( serf_request_t * i
aBody.append("</lockinfo>\n"); aBody.append("</lockinfo>\n");
const OString aBodyText(aBody.makeStringAndClear()); const OString aBodyText(aBody.makeStringAndClear());
serf_bucket_t* body_bkt = serf_bucket_simple_copy_create( aBodyText.getStr(), serf_bucket_t* body_bkt = 0;
aBodyText.getLength(),
pSerfBucketAlloc ); if (!m_plastChanceToSendRefreshRequest)
body_bkt = serf_bucket_simple_copy_create( aBodyText.getStr(),
aBodyText.getLength(),
pSerfBucketAlloc );
// create serf request // 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,
@@ -86,7 +91,8 @@ serf_bucket_t * SerfLockReqProcImpl::createSerfRequestBucket( serf_request_t * i
getPathStr(), getPathStr(),
body_bkt, body_bkt,
pSerfBucketAlloc ); pSerfBucketAlloc );
handleChunkedEncoding(req_bkt, aBodyText.getLength()); if (!m_plastChanceToSendRefreshRequest)
handleChunkedEncoding(req_bkt, aBodyText.getLength());
// set request header fields // set request header fields
serf_bucket_t* hdrs_bkt = serf_bucket_request_get_headers( req_bkt ); serf_bucket_t* hdrs_bkt = serf_bucket_request_get_headers( req_bkt );
@@ -110,8 +116,18 @@ serf_bucket_t * SerfLockReqProcImpl::createSerfRequestBucket( serf_request_t * i
default: default:
throw DAVException( DAVException::DAV_INVALID_ARG ); throw DAVException( DAVException::DAV_INVALID_ARG );
} }
serf_bucket_headers_set( hdrs_bkt, "Depth", depth ); if (!m_plastChanceToSendRefreshRequest)
serf_bucket_headers_set( hdrs_bkt, "Content-Type", "application/xml" ); {
serf_bucket_headers_set( hdrs_bkt, "Depth", depth );
serf_bucket_headers_set( hdrs_bkt, "Content-Type", "application/xml" );
}
else
{
const OString sToken( "(<" + OUStringToOString( apr_environment::AprEnv::getAprEnv()->
getSerfLockStore()->getLockToken( OUString::createFromAscii(getPathStr())),
RTL_TEXTENCODING_UTF8 ) + ">)" );
serf_bucket_headers_set( hdrs_bkt, "If", sToken.getStr() );
}
// Set the lock timeout // Set the lock timeout
if (m_aLock.Timeout == -1) if (m_aLock.Timeout == -1)
@@ -121,6 +137,8 @@ serf_bucket_t * SerfLockReqProcImpl::createSerfRequestBucket( serf_request_t * i
const OString aTimeValue("Second-" + OString::number(m_aLock.Timeout)); const OString aTimeValue("Second-" + OString::number(m_aLock.Timeout));
serf_bucket_headers_set( hdrs_bkt, "Timeout", aTimeValue.getStr() ); serf_bucket_headers_set( hdrs_bkt, "Timeout", aTimeValue.getStr() );
} }
else
serf_bucket_headers_set( hdrs_bkt, "Timeout", "Second-180" );
osl_getSystemTime( &m_aStartCall ); osl_getSystemTime( &m_aStartCall );
@@ -158,6 +176,13 @@ void SerfLockReqProcImpl::handleEndOfResponseData( serf_bucket_t * )
else else
SAL_WARN("ucb.ucp.webdav", "No chance to refresh lock before timeout!" ); SAL_WARN("ucb.ucp.webdav", "No chance to refresh lock before timeout!" );
} }
if (m_plastChanceToSendRefreshRequest)
{
*m_plastChanceToSendRefreshRequest = lastChanceToSendRefreshRequest;
assert(aLocks.size() == 1);
// We are just refreshing lock, do not add it into SerfLockStore
break;
}
apr_environment::AprEnv::getAprEnv()->getSerfLockStore()->addLock( apr_environment::AprEnv::getAprEnv()->getSerfLockStore()->addLock(
OUString::createFromAscii(getPathStr()), OUString::createFromAscii(getPathStr()),
aLocks[i].LockTokens[0], aLocks[i].LockTokens[0],

View File

@@ -37,7 +37,8 @@ public:
SerfLockReqProcImpl( const char* inPath, SerfLockReqProcImpl( const char* inPath,
const DAVRequestHeaders& inRequestHeaders, const DAVRequestHeaders& inRequestHeaders,
SerfSession& rSession, SerfSession& rSession,
const css::ucb::Lock & rLock ); const css::ucb::Lock& rLock,
sal_Int32* plastChanceToSendRefreshRequest = 0 );
virtual ~SerfLockReqProcImpl() SAL_OVERRIDE; virtual ~SerfLockReqProcImpl() SAL_OVERRIDE;
@@ -53,6 +54,8 @@ private:
SerfSession& m_rSession; SerfSession& m_rSession;
css::ucb::Lock m_aLock; css::ucb::Lock m_aLock;
// if m_plastChanceToSendRefreshRequest is not 0 we are sending just refresh request
sal_Int32* m_plastChanceToSendRefreshRequest;
TimeValue m_aStartCall; TimeValue m_aStartCall;
css::uno::Reference< SerfInputStream > m_xInputStream; css::uno::Reference< SerfInputStream > m_xInputStream;
}; };

View File

@@ -197,8 +197,7 @@ void SerfLockStore::refreshLocks()
// refresh the lock. // refresh the lock.
sal_Int32 nlastChanceToSendRefreshRequest = -1; sal_Int32 nlastChanceToSendRefreshRequest = -1;
if ( rInfo.m_xSession->LOCK( if ( rInfo.m_xSession->LOCK(
(*it).first, (*it).first, &nlastChanceToSendRefreshRequest ) )
/* out param */ nlastChanceToSendRefreshRequest ) )
{ {
rInfo.m_nLastChanceToSendRefreshRequest rInfo.m_nLastChanceToSendRefreshRequest
= nlastChanceToSendRefreshRequest; = nlastChanceToSendRefreshRequest;

View File

@@ -313,12 +313,13 @@ bool SerfRequestProcessor::processMove( const OUString & inDestinationPath,
} }
bool SerfRequestProcessor::processLock( const css::ucb::Lock & rLock ) bool SerfRequestProcessor::processLock( const css::ucb::Lock & rLock, sal_Int32 *plastChanceToSendRefreshRequest )
{ {
mpProcImpl = new SerfLockReqProcImpl( mPathStr, mpProcImpl = new SerfLockReqProcImpl( mPathStr,
mrSerfSession.getRequestEnvironment().m_aRequestHeaders, mrSerfSession.getRequestEnvironment().m_aRequestHeaders,
mrSerfSession, mrSerfSession,
rLock ); rLock,
plastChanceToSendRefreshRequest );
return runProcessor() == APR_SUCCESS; return runProcessor() == APR_SUCCESS;
} }

View File

@@ -126,7 +126,7 @@ public:
apr_status_t& outSerfStatus ); apr_status_t& outSerfStatus );
//LOCK //LOCK
bool processLock( const css::ucb::Lock & rLock ); bool processLock( const css::ucb::Lock & rLock, sal_Int32 *plastChanceToSendRefreshRequest = 0 );
//UNLOCK //UNLOCK
bool processUnlock(); bool processUnlock();

View File

@@ -1060,32 +1060,25 @@ sal_Int64 SerfSession::LOCK( const OUString & /*inPath*/,
// LOCK (refresh existing lock) // LOCK (refresh existing lock)
bool SerfSession::LOCK( const OUString& /*rLock*/, bool SerfSession::LOCK( const OUString& rLock,
sal_Int32 & /*rlastChanceToSendRefreshRequest*/ ) sal_Int32 *plastChanceToSendRefreshRequest )
{ {
osl::Guard< osl::Mutex > theGuard( m_aMutex ); osl::Guard< osl::Mutex > theGuard( m_aMutex );
return true; boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( rLock ) );
/* aReqProc->processLock( ucb::Lock(), plastChanceToSendRefreshRequest );
// refresh existing lock.
TimeValue startCall; try
osl_getSystemTime( &startCall );
if ( ne_lock_refresh( m_pHttpSession, pLock ) == NE_OK )
{ {
rlastChanceToSendRefreshRequest HandleError( aReqProc );
= lastChanceToSendRefreshRequest( startCall, pLock->timeout ); SAL_INFO("ucb.ucp.webdav", "Refreshing LOCK of " << rLock << " succeeded." );
SAL_INFO("ucb.ucp.webdav", "Lock successfully refreshed." );
return true; return true;
} }
else catch(...)
{ {
SAL_INFO("ucb.ucp.webdav", "Lock not refreshed!" ); SAL_INFO("ucb.ucp.webdav", "Refreshing LOCK of " << rLock << " failed!" );
return false; return false;
} }
*/
} }

View File

@@ -267,8 +267,7 @@ private:
const DAVRequestEnvironment & rEnv ); const DAVRequestEnvironment & rEnv );
// refresh lock, called by SerfLockStore::refreshLocks // refresh lock, called by SerfLockStore::refreshLocks
bool LOCK( const OUString& rLock, bool LOCK( const OUString& rLock, sal_Int32 *plastChanceToSendRefreshRequest );
sal_Int32 & rlastChanceToSendRefreshRequest );
// unlock, called by SerfLockStore::~SerfLockStore // unlock, called by SerfLockStore::~SerfLockStore
void UNLOCK( const OUString& rLock ); void UNLOCK( const OUString& rLock );