summaryrefslogtreecommitdiff
path: root/ucb
diff options
context:
space:
mode:
authorMatúš Kukan <matus.kukan@collabora.com>2014-03-20 09:40:06 +0100
committerMatúš Kukan <matus.kukan@collabora.com>2014-04-02 15:35:30 +0200
commit7bfd3fd86affe6ce804e910b39edfbe09890717f (patch)
treee01bdb52f16d519b529b1fea257e91afe5a2c23e /ucb
parentef1ae4bc7371b73df60f846f081f67027aff71a2 (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.mk1
-rw-r--r--ucb/source/ucp/webdav/SerfLockReqProcImpl.cxx165
-rw-r--r--ucb/source/ucp/webdav/SerfLockReqProcImpl.hxx60
-rw-r--r--ucb/source/ucp/webdav/SerfRequestProcessor.cxx11
-rw-r--r--ucb/source/ucp/webdav/SerfRequestProcessor.hxx4
-rw-r--r--ucb/source/ucp/webdav/SerfSession.cxx87
-rw-r--r--ucb/source/ucp/webdav/webdavcontent.cxx5
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" )
{