diff options
author | Matúš Kukan <matus.kukan@collabora.com> | 2014-03-20 09:40:06 +0100 |
---|---|---|
committer | Matúš Kukan <matus.kukan@collabora.com> | 2014-04-02 15:35:30 +0200 |
commit | 7bfd3fd86affe6ce804e910b39edfbe09890717f (patch) | |
tree | e01bdb52f16d519b529b1fea257e91afe5a2c23e /ucb | |
parent | ef1ae4bc7371b73df60f846f081f67027aff71a2 (diff) |
webdav: Lock files when opening them.
The implementation is not perfect but good enough as a start.
(cherry picked from commit 6e0cc0cd40fcceef601c9b680f44b95f6286ffa0)
Conflicts:
ucb/source/ucp/webdav/SerfSession.cxx
Change-Id: I6f006ae7a16ee73de20448e1228d9acfd69becb4
Diffstat (limited to 'ucb')
-rw-r--r-- | ucb/Library_ucpdav1.mk | 1 | ||||
-rw-r--r-- | ucb/source/ucp/webdav/SerfLockReqProcImpl.cxx | 165 | ||||
-rw-r--r-- | ucb/source/ucp/webdav/SerfLockReqProcImpl.hxx | 60 | ||||
-rw-r--r-- | ucb/source/ucp/webdav/SerfRequestProcessor.cxx | 11 | ||||
-rw-r--r-- | ucb/source/ucp/webdav/SerfRequestProcessor.hxx | 4 | ||||
-rw-r--r-- | ucb/source/ucp/webdav/SerfSession.cxx | 87 | ||||
-rw-r--r-- | ucb/source/ucp/webdav/webdavcontent.cxx | 5 |
7 files changed, 249 insertions, 84 deletions
diff --git a/ucb/Library_ucpdav1.mk b/ucb/Library_ucpdav1.mk index 2e23ba861ec9..ad0fe79fae33 100644 --- a/ucb/Library_ucpdav1.mk +++ b/ucb/Library_ucpdav1.mk @@ -84,6 +84,7 @@ $(eval $(call gb_Library_add_exception_objects,ucpdav1,\ ucb/source/ucp/webdav/SerfGetReqProcImpl \ ucb/source/ucp/webdav/SerfHeadReqProcImpl \ ucb/source/ucp/webdav/SerfInputStream \ + ucb/source/ucp/webdav/SerfLockReqProcImpl \ ucb/source/ucp/webdav/SerfMkColReqProcImpl \ ucb/source/ucp/webdav/SerfMoveReqProcImpl \ ucb/source/ucp/webdav/SerfPostReqProcImpl \ diff --git a/ucb/source/ucp/webdav/SerfLockReqProcImpl.cxx b/ucb/source/ucp/webdav/SerfLockReqProcImpl.cxx new file mode 100644 index 000000000000..f5aa35c89806 --- /dev/null +++ b/ucb/source/ucp/webdav/SerfLockReqProcImpl.cxx @@ -0,0 +1,165 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include "SerfLockReqProcImpl.hxx" +#include "DAVException.hxx" + +//#include "webdavresponseparser.hxx" +#include <rtl/strbuf.hxx> + +namespace http_dav_ucp +{ + +SerfLockReqProcImpl::SerfLockReqProcImpl( const char* inPath, + const DAVRequestHeaders& inRequestHeaders, + const css::ucb::Lock & rLock ) + : SerfRequestProcessorImpl( inPath, inRequestHeaders ) + , m_aLock( rLock ) + , m_xInputStream( new SerfInputStream() ) +{ +} + +SerfLockReqProcImpl::~SerfLockReqProcImpl() +{ +} + +serf_bucket_t * SerfLockReqProcImpl::createSerfRequestBucket( serf_request_t * inSerfRequest ) +{ + serf_bucket_alloc_t* pSerfBucketAlloc = serf_request_get_alloc( inSerfRequest ); + + OStringBuffer aBody("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" + "<lockinfo xmlns='DAV:'>\n <lockscope>"); + + // Set the lock scope + switch ( m_aLock.Scope ) + { + case css::ucb::LockScope_EXCLUSIVE: + aBody.append("<exclusive/>"); + break; + case css::ucb::LockScope_SHARED: + aBody.append("<shared/>"); + break; + default: + throw DAVException( DAVException::DAV_INVALID_ARG ); + } + aBody.append("</lockscope>\n <locktype><write/></locktype>\n"); + + // Set the lock owner + OUString aValue; + if ((m_aLock.Owner >>= aValue) && !aValue.isEmpty()) + { + aBody.append(" <owner>"); + aBody.append(OUStringToOString(aValue, RTL_TEXTENCODING_UTF8)); + aBody.append("</owner>\n"); + } + aBody.append("</lockinfo>\n"); + + const OString aBodyText(aBody.makeStringAndClear()); + serf_bucket_t* body_bkt = serf_bucket_simple_copy_create( aBodyText.getStr(), + aBodyText.getLength(), + pSerfBucketAlloc ); + + // create serf request + serf_bucket_t *req_bkt = serf_request_bucket_request_create( inSerfRequest, + "LOCK", + getPathStr(), + body_bkt, + pSerfBucketAlloc ); + handleChunkedEncoding(req_bkt, aBodyText.getLength()); + + // set request header fields + serf_bucket_t* hdrs_bkt = serf_bucket_request_get_headers( req_bkt ); + + // general header fields provided by caller + setRequestHeaders( hdrs_bkt ); + + // request specific header fields + const char * depth = 0; + switch( m_aLock.Depth ) + { + case css::ucb::LockDepth_ZERO: + depth = "0"; + break; + case css::ucb::LockDepth_ONE: + depth = "1"; + break; + case css::ucb::LockDepth_INFINITY: + depth = "infinity"; + break; + default: + throw DAVException( DAVException::DAV_INVALID_ARG ); + } + serf_bucket_headers_set( hdrs_bkt, "Depth", depth ); + serf_bucket_headers_set( hdrs_bkt, "Content-Type", "application/xml" ); + + // Set the lock timeout + if (m_aLock.Timeout == -1) + serf_bucket_headers_set( hdrs_bkt, "Timeout", "Infinite" ); + else if (m_aLock.Timeout > 0) + { + const OString aTimeValue("Second-" + OString::number(m_aLock.Timeout)); + serf_bucket_headers_set( hdrs_bkt, "Timeout", aTimeValue.getStr() ); + } + + osl_getSystemTime( &m_aStartCall ); + + return req_bkt; +} + +void SerfLockReqProcImpl::processChunkOfResponseData( const char* data, + apr_size_t len ) +{ + if ( m_xInputStream.is() ) + { + m_xInputStream->AddToStream( data, len ); + } +} + +void SerfLockReqProcImpl::handleEndOfResponseData( serf_bucket_t * /*inSerfResponseBucket*/ ) +{ + //const std::vector< DAVResourceInfo > rResInfo( parseWebDAVPropNameResponse( m_xInputStream.get() ) ); + + /* + if ( theRetVal == NE_OK ) + { + m_aSerfLockStore.addLock( theLock, + this, + lastChanceToSendRefreshRequest( + startCall, theLock->timeout ) ); + + uno::Sequence< OUString > aTokens( 1 ); + aTokens[ 0 ] = OUString::createFromAscii( theLock->token ); + m_xLock.LockTokens = aTokens; + + SAL_INFO("ucb.ucp.webdav", "SerfSession::LOCK: created lock for " + << makeAbsoluteURL( inPath ) << ". token: " << theLock->token ); + } + else + { + ne_lock_destroy( theLock ); + + SAL_INFO("ucb.ucp.webdav", "SerfSession::LOCK: obtaining lock for " + << makeAbsoluteURL( inPath ) << " failed!"); + } + */ +} + +} // namespace http_dav_ucp + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/ucb/source/ucp/webdav/SerfLockReqProcImpl.hxx b/ucb/source/ucp/webdav/SerfLockReqProcImpl.hxx new file mode 100644 index 000000000000..cb746a30ab16 --- /dev/null +++ b/ucb/source/ucp/webdav/SerfLockReqProcImpl.hxx @@ -0,0 +1,60 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_SERFLOCKREQPROCIMPL_HXX +#define INCLUDED_SERFLOCKREQPROCIMPL_HXX + +#include "SerfRequestProcessorImpl.hxx" +#include "SerfInputStream.hxx" + +#include <com/sun/star/ucb/Lock.hpp> +#include <osl/time.h> + +namespace http_dav_ucp +{ + +class SerfLockReqProcImpl : public SerfRequestProcessorImpl +{ +public: + SerfLockReqProcImpl( const char* inPath, + const DAVRequestHeaders& inRequestHeaders, + const css::ucb::Lock & rLock ); + + virtual ~SerfLockReqProcImpl() SAL_OVERRIDE; + + virtual + serf_bucket_t * createSerfRequestBucket( serf_request_t * inSerfRequest ) SAL_OVERRIDE; + +private: + virtual + void processChunkOfResponseData( const char* data, apr_size_t len ) SAL_OVERRIDE; + + virtual + void handleEndOfResponseData( serf_bucket_t * inSerfResponseBucket ) SAL_OVERRIDE; + + css::ucb::Lock m_aLock; + TimeValue m_aStartCall; + css::uno::Reference< SerfInputStream > m_xInputStream; +}; + +} // namespace http_dav_ucp + +#endif // INCLUDED_SERFLOCKREQPROCIMPL_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/ucb/source/ucp/webdav/SerfRequestProcessor.cxx b/ucb/source/ucp/webdav/SerfRequestProcessor.cxx index 70d5575081e1..8a1663bfc2a5 100644 --- a/ucb/source/ucp/webdav/SerfRequestProcessor.cxx +++ b/ucb/source/ucp/webdav/SerfRequestProcessor.cxx @@ -30,6 +30,7 @@ #include "SerfMkColReqProcImpl.hxx" #include "SerfCopyReqProcImpl.hxx" #include "SerfMoveReqProcImpl.hxx" +#include "SerfLockReqProcImpl.hxx" #include <apr_strings.h> @@ -308,6 +309,16 @@ bool SerfRequestProcessor::processMove( const OUString & inDestinationPath, return outSerfStatus == APR_SUCCESS; } + +bool SerfRequestProcessor::processLock( const css::ucb::Lock & rLock ) +{ + mpProcImpl = new SerfLockReqProcImpl( mPathStr, + mrSerfSession.getRequestEnvironment().m_aRequestHeaders, + rLock ); + + return runProcessor() == APR_SUCCESS; +} + apr_status_t SerfRequestProcessor::runProcessor() { prepareProcessor(); diff --git a/ucb/source/ucp/webdav/SerfRequestProcessor.hxx b/ucb/source/ucp/webdav/SerfRequestProcessor.hxx index 9addb342adcf..f941a4956997 100644 --- a/ucb/source/ucp/webdav/SerfRequestProcessor.hxx +++ b/ucb/source/ucp/webdav/SerfRequestProcessor.hxx @@ -32,6 +32,7 @@ #include "SerfInputStream.hxx" #include <com/sun/star/io/XOutputStream.hpp> +#include <com/sun/star/ucb/Lock.hpp> namespace http_dav_ucp { @@ -124,6 +125,9 @@ public: const bool inOverwrite, apr_status_t& outSerfStatus ); + //LOCK + bool processLock( const css::ucb::Lock & rLock ); + apr_status_t provideSerfCredentials( char ** outUsername, char ** outPassword, serf_request_t * inRequest, diff --git a/ucb/source/ucp/webdav/SerfSession.cxx b/ucb/source/ucp/webdav/SerfSession.cxx index 355c563c4328..9ac01fa72c2c 100644 --- a/ucb/source/ucp/webdav/SerfSession.cxx +++ b/ucb/source/ucp/webdav/SerfSession.cxx @@ -972,7 +972,7 @@ namespace // LOCK (set new lock) // ------------------------------------------------------------------- void SerfSession::LOCK( const OUString & inPath, - ucb::Lock & /*rLock*/, + ucb::Lock & rLock, const DAVRequestEnvironment & rEnv ) throw ( DAVException ) { @@ -981,90 +981,9 @@ void SerfSession::LOCK( const OUString & inPath, 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( 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 ); - } - - // Set the lock timeout - theLock->timeout = (long)rLock.Timeout; - - // Set the lock owner - OUString aValue; - rLock.Owner >>= aValue; - theLock->owner = - ne_strdup( OUStringToOString( aValue, - RTL_TEXTENCODING_UTF8 ).getStr() ); - TimeValue startCall; - osl_getSystemTime( &startCall ); - - int theRetVal = ne_lock( m_pHttpSession, theLock ); - - if ( theRetVal == NE_OK ) - { - m_aSerfLockStore.addLock( theLock, - this, - lastChanceToSendRefreshRequest( - startCall, theLock->timeout ) ); - - uno::Sequence< OUString > aTokens( 1 ); - aTokens[ 0 ] = OUString::createFromAscii( theLock->token ); - rLock.LockTokens = aTokens; - - OSL_TRACE( "SerfSession::LOCK: created lock for %s. token: %s", - OUStringToOString( makeAbsoluteURL( inPath ), - RTL_TEXTENCODING_UTF8 ).getStr(), - theLock->token ); - } - else - { - ne_lock_destroy( theLock ); + aReqProc->processLock( rLock ); - OSL_TRACE( "SerfSession::LOCK: obtaining lock for %s failed!", - OUStringToOString( makeAbsoluteURL( inPath ), - RTL_TEXTENCODING_UTF8 ).getStr() ); - } - - HandleError( theRetVal, inPath, rEnv ); - */ + HandleError( aReqProc ); } // ------------------------------------------------------------------- diff --git a/ucb/source/ucp/webdav/webdavcontent.cxx b/ucb/source/ucp/webdav/webdavcontent.cxx index 7d6ffe36a764..5c9afc215017 100644 --- a/ucb/source/ucp/webdav/webdavcontent.cxx +++ b/ucb/source/ucp/webdav/webdavcontent.cxx @@ -598,6 +598,11 @@ uno::Any SAL_CALL Content::execute( } aRet = open( aOpenCommand, Environment ); + + if ( (aOpenCommand.Mode == ucb::OpenMode::DOCUMENT || + aOpenCommand.Mode == ucb::OpenMode::DOCUMENT_SHARE_DENY_WRITE) && + supportsExclusiveWriteLock( Environment ) ) + lock( Environment ); } else if ( aCommand.Name == "insert" ) { |