diff options
author | Michael Stahl <michael.stahl@allotropia.de> | 2021-12-14 16:44:14 +0100 |
---|---|---|
committer | Michael Stahl <michael.stahl@allotropia.de> | 2021-12-15 15:24:52 +0100 |
commit | 023ebf17898db4bca63129f079fd90b5cf76c1a9 (patch) | |
tree | f0c72239af05ea4b1435b69ebf38d9ab88c49e47 /ucb | |
parent | f45b7871e7d31dfc6ed31d1b79928990bba0d0dd (diff) |
ucb: remove --with-webdav=neon
Remove code in ucb/source/ucp/webdav-neon, and now unused external
neon.
The --with-webdav=no option is retained for now.
Change-Id: I4ce429587e3991fa82009da2f8e4a068abe36435
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/126839
Tested-by: Jenkins
Reviewed-by: Michael Stahl <michael.stahl@allotropia.de>
Diffstat (limited to 'ucb')
55 files changed, 0 insertions, 16255 deletions
diff --git a/ucb/IwyuFilter_ucb.yaml b/ucb/IwyuFilter_ucb.yaml index 27115f812783..1b242fd561b3 100644 --- a/ucb/IwyuFilter_ucb.yaml +++ b/ucb/IwyuFilter_ucb.yaml @@ -10,48 +10,6 @@ excludelist: ucb/source/ucp/ftp/ftpcontentprovider.hxx: # Wrapper for external lib - curl.hxx - ucb/source/ucp/webdav-neon/ContentProperties.hxx: - # Needed for LGPL code licensing - - config_lgpl.h - ucb/source/ucp/webdav-neon/DateTimeHelper.hxx: - # Needed for LGPL code licensing - - config_lgpl.h - ucb/source/ucp/webdav-neon/DAVException.hxx: - # Needed for LGPL code licensing - - config_lgpl.h - ucb/source/ucp/webdav-neon/LockSequence.hxx: - # Needed for LGPL code licensing - - config_lgpl.h - ucb/source/ucp/webdav-neon/DAVAuthListenerImpl.hxx: - # Needed for LGPL code licensing - - config_lgpl.h - ucb/source/ucp/webdav-neon/DAVAuthListener.hxx: - # Needed for LGPL code licensing - - config_lgpl.h - ucb/source/ucp/webdav-neon/DAVResource.hxx: - # Needed for LGPL code licensing - - config_lgpl.h - ucb/source/ucp/webdav-neon/NeonInputStream.hxx: - # Needed for LGPL code licensing - - config_lgpl.h - ucb/source/ucp/webdav-neon/DAVTypes.hxx: - # Needed for LGPL code licensing - - config_lgpl.h - ucb/source/ucp/webdav-neon/DAVSessionFactory.hxx: - # Needed for LGPL code licensing - - config_lgpl.h - ucb/source/ucp/webdav-neon/DAVRequestEnvironment.hxx: - # Needed for LGPL code licensing - - config_lgpl.h - ucb/source/ucp/webdav-neon/PropertyMap.hxx: - # Needed for LGPL code licensing - - config_lgpl.h - ucb/source/ucp/webdav-neon/webdavdatasupplier.hxx: - # Needed for LGPL code licensing - - config_lgpl.h - ucb/source/ucp/webdav-neon/webdavprovider.hxx: - # Needed for LGPL code licensing - - config_lgpl.h ucb/source/core/ucb.cxx: # Needed for UnoType - com/sun/star/ucb/XCommandInfo.hpp @@ -97,31 +55,6 @@ excludelist: ucb/source/ucp/tdoc/tdoc_content.cxx: # Needed for UnoType - com/sun/star/ucb/XCommandInfo.hpp - ucb/source/ucp/webdav-neon/DateTimeHelper.cxx: - # Actually in use - - com/sun/star/util/DateTime.hpp - ucb/source/ucp/webdav-neon/LockEntrySequence.cxx: - # Needed for LGPL code licensing - - config_lgpl.h - ucb/source/ucp/webdav-neon/LinkSequence.cxx: - # Needed for LGPL code licensing - - config_lgpl.h - ucb/source/ucp/webdav-neon/LinkSequence.cxx: - # Needed for LGPL code licensing - - config_lgpl.h - ucb/source/ucp/webdav-neon/LockSequence.cxx: - # Needed for LGPL code licensing - - config_lgpl.h - ucb/source/ucp/webdav-neon/NeonSession.cxx: - # Needed for UnoType - - com/sun/star/ucb/Lock.hpp - - com/sun/star/beans/NamedValue.hpp - ucb/source/ucp/webdav-neon/UCBDeadPropertyValue.cxx: - # Needed for LGPL code licensing - - config_lgpl.h - ucb/source/ucp/webdav-neon/webdavcontent.cxx: - # Needed for UnoType - - com/sun/star/ucb/XCommandInfo.hpp ucb/source/ucp/webdav-curl/DateTimeHelper.cxx: # Actually in use - com/sun/star/util/DateTime.hpp diff --git a/ucb/Library_ucpdav1.mk b/ucb/Library_ucpdav1.mk index c2a36d7fcef7..b3c9a2342d6e 100644 --- a/ucb/Library_ucpdav1.mk +++ b/ucb/Library_ucpdav1.mk @@ -27,8 +27,6 @@ $(eval $(call gb_Library_use_libraries,ucpdav1,\ tl \ )) -ifeq ($(WITH_WEBDAV),curl) - $(eval $(call gb_Library_set_componentfile,ucpdav1,ucb/source/ucp/webdav-curl/ucpdav1,services)) $(eval $(call gb_Library_use_externals,ucpdav1,\ @@ -59,50 +57,6 @@ $(eval $(call gb_Library_add_exception_objects,ucpdav1,\ ucb/source/ucp/webdav-curl/webdavresultset \ )) -else -ifeq ($(WITH_WEBDAV),neon) - -$(eval $(call gb_Library_set_componentfile,ucpdav1,ucb/source/ucp/webdav-neon/ucpdav1,services)) - -$(eval $(call gb_Library_use_externals,ucpdav1,\ - boost_headers \ - libxml2 \ - neon \ - openssl \ -)) - -$(eval $(call gb_Library_use_custom_headers,ucpdav1,\ - officecfg/registry \ -)) - -$(eval $(call gb_Library_add_exception_objects,ucpdav1,\ - ucb/source/ucp/webdav-neon/ContentProperties \ - ucb/source/ucp/webdav-neon/DateTimeHelper \ - ucb/source/ucp/webdav-neon/DAVProperties \ - ucb/source/ucp/webdav-neon/DAVResourceAccess \ - ucb/source/ucp/webdav-neon/DAVSessionFactory \ - ucb/source/ucp/webdav-neon/DAVTypes \ - ucb/source/ucp/webdav-neon/LinkSequence \ - ucb/source/ucp/webdav-neon/LockEntrySequence \ - ucb/source/ucp/webdav-neon/LockSequence \ - ucb/source/ucp/webdav-neon/NeonHeadRequest \ - ucb/source/ucp/webdav-neon/NeonInputStream \ - ucb/source/ucp/webdav-neon/NeonLockStore \ - ucb/source/ucp/webdav-neon/NeonPropFindRequest \ - ucb/source/ucp/webdav-neon/NeonSession \ - ucb/source/ucp/webdav-neon/NeonUri \ - ucb/source/ucp/webdav-neon/PropfindCache \ - ucb/source/ucp/webdav-neon/UCBDeadPropertyValue \ - ucb/source/ucp/webdav-neon/webdavcontentcaps \ - ucb/source/ucp/webdav-neon/webdavcontent \ - ucb/source/ucp/webdav-neon/webdavdatasupplier \ - ucb/source/ucp/webdav-neon/webdavprovider \ - ucb/source/ucp/webdav-neon/webdavresultset \ -)) - -endif # WITH_WEBDAV -endif # WITH_WEBDAV - ifeq ($(OS),WNT) $(eval $(call gb_Library_use_system_win32_libs,ucpdav1,\ ws2_32 \ diff --git a/ucb/README.md b/ucb/README.md index 5af5487d7c5d..23d5fefb6db5 100644 --- a/ucb/README.md +++ b/ucb/README.md @@ -2,8 +2,3 @@ Universal Content Broker (has ucp) which do things like convert files to strings in content broker world. -mmeeks: so - I renamed the old LGPLv3 webdav code to `webdav-neon`, and imported -the (not built) serf webdav ucp into the old space. so that in future, we can -merge changes more easily - and still choose which to use. cbosdonnat kindly -volunteered to do some comparative analysis of the two codebases to decide which -is best for what etc. diff --git a/ucb/source/ucp/webdav-neon/ContentProperties.cxx b/ucb/source/ucp/webdav-neon/ContentProperties.cxx deleted file mode 100644 index faee90874f5b..000000000000 --- a/ucb/source/ucp/webdav-neon/ContentProperties.cxx +++ /dev/null @@ -1,558 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - - -/************************************************************************** - TODO - ************************************************************************** - - *************************************************************************/ -#include <memory> -#include <com/sun/star/util/DateTime.hpp> -#include "NeonUri.hxx" -#include "DAVResource.hxx" -#include "DAVProperties.hxx" -#include "DateTimeHelper.hxx" -#include "webdavprovider.hxx" -#include "ContentProperties.hxx" - -using namespace com::sun::star; -using namespace webdav_ucp; - -/* -============================================================================= - - Property Mapping - -============================================================================= -HTTP (entity header) WebDAV (property) UCB (property) -============================================================================= - -Allow -Content-Encoding -Content-Language getcontentlanguage -Content-Length getcontentlength Size -Content-Location -Content-MD5 -Content-Range -Content-Type getcontenttype MediaType -Expires -Last-Modified getlastmodified DateModified - creationdate DateCreated - resourcetype IsFolder,IsDocument,ContentType - displayname -ETag (actually getetag -a response header ) - lockdiscovery - supportedlock - source - Title (always taken from URI) - -============================================================================= - -Important: HTTP headers will not be mapped to DAV properties; only to UCB - properties. (Content-Length,Content-Type,Last-Modified) -*/ - - -// ContentProperties Implementation. - - -// static member! -uno::Any ContentProperties::m_aEmptyAny; - -ContentProperties::ContentProperties( const DAVResource& rResource ) -: m_xProps( new PropertyValueMap ), - m_bTrailingSlash( false ) -{ - assert( !rResource.uri.isEmpty() && "ContentProperties ctor - Empty resource URI!" ); - - // Title - try - { - NeonUri aURI( rResource.uri ); - m_aEscapedTitle = aURI.GetPathBaseName(); - - (*m_xProps)[ OUString("Title") ] - = PropertyValue( - uno::makeAny( aURI.GetPathBaseNameUnescaped() ), true ); - } - catch ( DAVException const & ) - { - (*m_xProps)[ OUString("Title") ] - = PropertyValue( - uno::makeAny( - OUString( - "*** unknown ***" ) ), - true ); - } - - for ( const auto& rProp : rResource.properties ) - { - addProperty( rProp ); - } - - if ( rResource.uri.endsWith("/") ) - m_bTrailingSlash = true; -} - - -ContentProperties::ContentProperties( - const OUString & rTitle, bool bFolder ) -: m_xProps( new PropertyValueMap ), - m_bTrailingSlash( false ) -{ - (*m_xProps)[ OUString("Title") ] - = PropertyValue( uno::makeAny( rTitle ), true ); - (*m_xProps)[ OUString("IsFolder") ] - = PropertyValue( uno::makeAny( bFolder ), true ); - (*m_xProps)[ OUString("IsDocument") ] - = PropertyValue( uno::makeAny( !bFolder ), true ); -} - - -ContentProperties::ContentProperties( const OUString & rTitle ) -: m_xProps( new PropertyValueMap ), - m_bTrailingSlash( false ) -{ - (*m_xProps)[ OUString("Title") ] - = PropertyValue( uno::makeAny( rTitle ), true ); -} - - -ContentProperties::ContentProperties() -: m_xProps( new PropertyValueMap ), - m_bTrailingSlash( false ) -{ -} - -ContentProperties::ContentProperties(const ContentProperties& rOther) - : m_aEscapedTitle(rOther.m_aEscapedTitle) - , m_xProps(rOther.m_xProps ? new PropertyValueMap(*rOther.m_xProps) : new PropertyValueMap) - , m_bTrailingSlash(rOther.m_bTrailingSlash) -{ -} - - -bool ContentProperties::contains( const OUString & rName ) const -{ - return get( rName ) != nullptr; -} - - -const uno::Any & ContentProperties::getValue( - const OUString & rName ) const -{ - const PropertyValue * pProp = get( rName ); - if ( pProp ) - return pProp->value(); - else - return m_aEmptyAny; -} - - -const PropertyValue * ContentProperties::get( - const OUString & rName ) const -{ - PropertyValueMap::const_iterator it = m_xProps->find( rName ); - const PropertyValueMap::const_iterator end = m_xProps->end(); - - if ( it == end ) - { - it = std::find_if(m_xProps->cbegin(), end, - [&rName](const PropertyValueMap::value_type& rEntry) { - return rEntry.first.equalsIgnoreAsciiCase( rName ); - }); - if ( it != end ) - return &(*it).second; - - return nullptr; - } - else - return &(*it).second; -} - - -// static -void ContentProperties::UCBNamesToDAVNames( - const uno::Sequence< beans::Property > & rProps, - std::vector< OUString > & propertyNames ) -{ - - // Assemble list of DAV properties to obtain from server. - // Append DAV properties needed to obtain requested UCB props. - - - // DAV UCB - // creationdate <- DateCreated - // getlastmodified <- DateModified - // getcontenttype <- MediaType - // getcontentlength <- Size - // resourcetype <- IsFolder, IsDocument, ContentType - // (taken from URI) <- Title - - bool bCreationDate = false; - bool bLastModified = false; - bool bContentType = false; - bool bContentLength = false; - bool bResourceType = false; - - for ( const beans::Property & rProp : rProps ) - { - if ( rProp.Name == "Title" ) - { - // Title is always obtained from resource's URI. - continue; - } - else if ( rProp.Name == "DateCreated" || rProp.Name == DAVProperties::CREATIONDATE ) - { - if ( !bCreationDate ) - { - propertyNames.push_back( DAVProperties::CREATIONDATE ); - bCreationDate = true; - } - } - else if ( rProp.Name == "DateModified" || rProp.Name == DAVProperties::GETLASTMODIFIED ) - { - if ( !bLastModified ) - { - propertyNames.push_back( DAVProperties::GETLASTMODIFIED ); - bLastModified = true; - } - } - else if ( rProp.Name == "MediaType" || rProp.Name == DAVProperties::GETCONTENTTYPE ) - { - if ( !bContentType ) - { - propertyNames.push_back( DAVProperties::GETCONTENTTYPE ); - bContentType = true; - } - } - else if ( rProp.Name == "Size" || rProp.Name == DAVProperties::GETCONTENTLENGTH ) - { - if ( !bContentLength ) - { - propertyNames.push_back( DAVProperties::GETCONTENTLENGTH ); - bContentLength = true; - } - } - else if ( rProp.Name == "ContentType" || rProp.Name == "IsDocument" || rProp.Name == "IsFolder" || rProp.Name == DAVProperties::RESOURCETYPE ) - { - if ( !bResourceType ) - { - propertyNames.push_back( DAVProperties::RESOURCETYPE ); - bResourceType = true; - } - } - else - { - propertyNames.push_back( rProp.Name ); - } - } -} - - -// static -void ContentProperties::UCBNamesToHTTPNames( - const uno::Sequence< beans::Property > & rProps, - std::vector< OUString > & propertyNames ) -{ - - // Assemble list of HTTP header names to obtain from server. - // Append HTTP headers needed to obtain requested UCB props. - - - // HTTP UCB - // Last-Modified <- DateModified - // Content-Type <- MediaType - // Content-Length <- Size - - for ( const beans::Property & rProp : rProps ) - { - if ( rProp.Name == "DateModified" ) - { - propertyNames.emplace_back("Last-Modified" ); - } - else if ( rProp.Name == "MediaType" ) - { - propertyNames.emplace_back("Content-Type" ); - } - else if ( rProp.Name == "Size" ) - { - propertyNames.emplace_back("Content-Length" ); - } - else - { - propertyNames.push_back( rProp.Name ); - } - } -} - - -bool ContentProperties::containsAllNames( - const uno::Sequence< beans::Property >& rProps, - std::vector< OUString > & rNamesNotContained ) const -{ - rNamesNotContained.clear(); - - for ( const auto& rProp : rProps ) - { - const OUString & rName = rProp.Name; - if ( !contains( rName ) ) - { - // Not found. - rNamesNotContained.push_back( rName ); - } - } - - return rNamesNotContained.empty(); -} - - -void ContentProperties::addProperties( - const std::vector< OUString > & rProps, - const ContentProperties & rContentProps ) -{ - for ( const OUString & rName : rProps ) - { - if ( !contains( rName ) ) // ignore duplicates - { - const PropertyValue * pProp = rContentProps.get( rName ); - if ( pProp ) - { - // Add it. - addProperty( rName, pProp->value(), pProp->isCaseSensitive() ); - } - else - { - addProperty( rName, uno::Any(), false ); - } - } - } -} - - -void ContentProperties::addProperty( const DAVPropertyValue & rProp ) -{ - addProperty( rProp.Name, rProp.Value, rProp.IsCaseSensitive ); -} - - -void ContentProperties::addProperty( const OUString & rName, - const css::uno::Any & rValue, - bool bIsCaseSensitive ) -{ - if ( rName == DAVProperties::CREATIONDATE ) - { - // Map DAV:creationdate to UCP:DateCreated - OUString aValue; - rValue >>= aValue; - util::DateTime aDate; - DateTimeHelper::convert( aValue, aDate ); - - (*m_xProps)[ OUString("DateCreated") ] - = PropertyValue( uno::makeAny( aDate ), true ); - } - // else if ( rName.equals( DAVProperties::DISPLAYNAME ) ) - // { - // } - // else if ( rName.equals( DAVProperties::GETCONTENTLANGUAGE ) ) - // { - // } - else if ( rName == DAVProperties::GETCONTENTLENGTH ) - { - // Map DAV:getcontentlength to UCP:Size - OUString aValue; - rValue >>= aValue; - - (*m_xProps)[ OUString("Size") ] - = PropertyValue( uno::makeAny( aValue.toInt64() ), true ); - } - else if ( rName.equalsIgnoreAsciiCase( "Content-Length" ) ) - { - // Do NOT map Content-length entity header to DAV:getcontentlength! - // Only DAV resources have this property. - - // Map Content-Length entity header to UCP:Size - OUString aValue; - rValue >>= aValue; - - (*m_xProps)[ OUString("Size") ] - = PropertyValue( uno::makeAny( aValue.toInt64() ), true ); - } - else if ( rName == DAVProperties::GETCONTENTTYPE ) - { - // Map DAV:getcontenttype to UCP:MediaType (1:1) - (*m_xProps)[ OUString("MediaType") ] - = PropertyValue( rValue, true ); - } - else if ( rName.equalsIgnoreAsciiCase( "Content-Type" ) ) - { - // Do NOT map Content-Type entity header to DAV:getcontenttype! - // Only DAV resources have this property. - - // Map DAV:getcontenttype to UCP:MediaType (1:1) - (*m_xProps)[ OUString("MediaType") ] - = PropertyValue( rValue, true ); - } - // else if ( rName.equals( DAVProperties::GETETAG ) ) - // { - // } - else if ( rName == DAVProperties::GETLASTMODIFIED ) - { - // Map the DAV:getlastmodified entity header to UCP:DateModified - OUString aValue; - rValue >>= aValue; - util::DateTime aDate; - DateTimeHelper::convert( aValue, aDate ); - - (*m_xProps)[ OUString("DateModified") ] - = PropertyValue( uno::makeAny( aDate ), true ); - } - else if ( rName.equalsIgnoreAsciiCase( "Last-Modified" ) ) - { - // Do not map Last-Modified entity header to DAV:getlastmodified! - // Only DAV resources have this property. - - // Map the Last-Modified entity header to UCP:DateModified - OUString aValue; - rValue >>= aValue; - util::DateTime aDate; - DateTimeHelper::convert( aValue, aDate ); - - (*m_xProps)[ OUString("DateModified") ] - = PropertyValue( uno::makeAny( aDate ), true ); - } - // else if ( rName.equals( DAVProperties::LOCKDISCOVERY ) ) - // { - // } - else if ( rName == DAVProperties::RESOURCETYPE ) - { - OUString aValue; - rValue >>= aValue; - - // Map DAV:resourcetype to UCP:IsFolder, UCP:IsDocument, UCP:ContentType - bool bFolder = aValue.equalsIgnoreAsciiCase( "collection" ); - - (*m_xProps)[ OUString("IsFolder") ] - = PropertyValue( uno::makeAny( bFolder ), true ); - (*m_xProps)[ OUString("IsDocument") ] - = PropertyValue( uno::makeAny( !bFolder ), true ); - (*m_xProps)[ OUString("ContentType") ] - = PropertyValue( uno::makeAny( bFolder - ? OUString( WEBDAV_COLLECTION_TYPE ) - : OUString( WEBDAV_CONTENT_TYPE ) ), true ); - } - // else if ( rName.equals( DAVProperties::SOURCE ) ) - // { - // } - // else if ( rName.equals( DAVProperties::SUPPORTEDLOCK ) ) - // { - // } - - // Save property. - (*m_xProps)[ rName ] = PropertyValue( rValue, bIsCaseSensitive ); -} - - -// CachableContentProperties Implementation. - - -namespace -{ - bool isCachable( OUString const & rName, - bool isCaseSensitive ) - { - static const OUString aNonCachableProps [] = - { - DAVProperties::LOCKDISCOVERY, - - DAVProperties::GETETAG, - OUString( "ETag" ), - - OUString( "DateModified" ), - OUString( "Last-Modified" ), - DAVProperties::GETLASTMODIFIED, - - OUString( "Size" ), - OUString( "Content-Length" ), - DAVProperties::GETCONTENTLENGTH, - - OUString( "Date" ) - }; - - for (const auto & rNonCachableProp : aNonCachableProps) - { - if ( isCaseSensitive ) - { - if ( rName == rNonCachableProp ) - return false; - } - else - if ( rName.equalsIgnoreAsciiCase( rNonCachableProp ) ) - return false; - } - return true; - } - -} // namespace - - -CachableContentProperties::CachableContentProperties( - const ContentProperties & rProps ) -{ - addProperties( rProps ); -} - - -void CachableContentProperties::addProperties( - const ContentProperties & rProps ) -{ - const std::unique_ptr< PropertyValueMap > & props = rProps.getProperties(); - - for ( const auto& rProp : *props ) - { - if ( isCachable( rProp.first, rProp.second.isCaseSensitive() ) ) - m_aProps.addProperty( rProp.first, - rProp.second.value(), - rProp.second.isCaseSensitive() ); - } -} - - -void CachableContentProperties::addProperties( - const std::vector< DAVPropertyValue > & rProps ) -{ - for ( const auto& rProp : rProps ) - { - if ( isCachable( rProp.Name, rProp.IsCaseSensitive ) ) - m_aProps.addProperty( rProp ); - } -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/ucb/source/ucp/webdav-neon/ContentProperties.hxx b/ucb/source/ucp/webdav-neon/ContentProperties.hxx deleted file mode 100644 index 8f11e8726286..000000000000 --- a/ucb/source/ucp/webdav-neon/ContentProperties.hxx +++ /dev/null @@ -1,183 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -#pragma once - -#include <config_lgpl.h> -#include <memory> -#include <unordered_map> -#include <vector> -#include <rtl/ustring.hxx> -#include <com/sun/star/uno/Any.hxx> -#include <com/sun/star/uno/Sequence.hxx> -#include "DAVResource.hxx" - -namespace com::sun::star::beans { - struct Property; -} - -namespace webdav_ucp -{ - -struct DAVResource; - -// PropertyValueMap. -class PropertyValue -{ -private: - css::uno::Any m_aValue; - bool m_bIsCaseSensitive; - -public: - PropertyValue() - : m_bIsCaseSensitive( true ) {} - - PropertyValue( const css::uno::Any & rValue, - bool bIsCaseSensitive ) - : m_aValue( rValue), - m_bIsCaseSensitive( bIsCaseSensitive ) {} - - bool isCaseSensitive() const { return m_bIsCaseSensitive; } - const css::uno::Any & value() const { return m_aValue; } - -}; - -typedef std::unordered_map< OUString, PropertyValue> PropertyValueMap; - -class ContentProperties -{ -public: - ContentProperties(); - - explicit ContentProperties( const DAVResource& rResource ); - - // Mini props for transient contents. - ContentProperties( const OUString & rTitle, bool bFolder ); - - // Micro props for non-existing contents. - explicit ContentProperties( const OUString & rTitle ); - - ContentProperties( const ContentProperties & rOther ); - - bool contains( const OUString & rName ) const; - - const css::uno::Any & - getValue( const OUString & rName ) const; - - // Maps the UCB property names contained in rProps with their DAV property - // counterparts, if possible. All unmappable properties will be included - // unchanged in resulting vector. - // The vector filled by this method can directly be handed over to - // DAVResourceAccess::PROPFIND. The result from PROPFIND - // (vector< DAVResource >) can be used to create a ContentProperties - // instance which can map DAV properties back to UCB properties. - static void UCBNamesToDAVNames( const css::uno::Sequence< css::beans::Property > & rProps, - std::vector< OUString > & resources ); - - // Maps the UCB property names contained in rProps with their HTTP header - // counterparts, if possible. All unmappable properties will be included - // unchanged in resulting vector. - // The vector filled by this method can directly be handed over to - // DAVResourceAccess::HEAD. The result from HEAD (vector< DAVResource >) - // can be used to create a ContentProperties instance which can map header - // names back to UCB properties. - static void UCBNamesToHTTPNames( const css::uno::Sequence< css::beans::Property > & rProps, - std::vector< OUString > & resources ); - - // return true, if all properties contained in rProps are contained in - // this ContentProperties instance. Otherwise, false will be returned. - // rNamesNotContained contain the missing names. - bool containsAllNames( - const css::uno::Sequence< css::beans::Property >& rProps, - std::vector< OUString > & rNamesNotContained ) const; - - // adds all properties described by rProps that are actually contained in - // rContentProps to this instance. In case of duplicates the value - // already contained in this will left unchanged. - void addProperties( const std::vector< OUString > & rProps, - const ContentProperties & rContentProps ); - - // overwrites probably existing entry. - void addProperty( const OUString & rName, - const css::uno::Any & rValue, - bool bIsCaseSensitive ); - - // overwrites probably existing entry. - void addProperty( const DAVPropertyValue & rProp ); - - bool isTrailingSlash() const { return m_bTrailingSlash; } - - const OUString & getEscapedTitle() const { return m_aEscapedTitle; } - - // Not good to expose implementation details, but this is actually an - // internal class. - const std::unique_ptr< PropertyValueMap > & getProperties() const - { return m_xProps; } - -private: - OUString m_aEscapedTitle; - std::unique_ptr< PropertyValueMap > m_xProps; - bool m_bTrailingSlash; - - static css::uno::Any m_aEmptyAny; - - ContentProperties & operator=( const ContentProperties & ) = delete; - - const PropertyValue * get( const OUString & rName ) const; -}; - -class CachableContentProperties -{ -private: - ContentProperties m_aProps; - - CachableContentProperties & operator=( const CachableContentProperties & ) = delete; - CachableContentProperties( const CachableContentProperties & ) = delete; - -public: - explicit CachableContentProperties( const ContentProperties & rProps ); - - void addProperties( const ContentProperties & rProps ); - - void addProperties( const std::vector< DAVPropertyValue > & rProps ); - - bool containsAllNames( - const css::uno::Sequence< css::beans::Property >& rProps, - std::vector< OUString > & rNamesNotContained ) const - { return m_aProps.containsAllNames( rProps, rNamesNotContained ); } - - const css::uno::Any & - getValue( const OUString & rName ) const - { return m_aProps.getValue( rName ); } - - operator const ContentProperties & () const { return m_aProps; } -}; - -} // namespace webdav_ucp - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/ucb/source/ucp/webdav-neon/DAVAuthListener.hxx b/ucb/source/ucp/webdav-neon/DAVAuthListener.hxx deleted file mode 100644 index 540ac788ca16..000000000000 --- a/ucb/source/ucp/webdav-neon/DAVAuthListener.hxx +++ /dev/null @@ -1,50 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ -#pragma once - -#include <config_lgpl.h> -#include <salhelper/simplereferenceobject.hxx> -#include <rtl/ustring.hxx> - -namespace webdav_ucp -{ - -class DAVAuthListener : public salhelper::SimpleReferenceObject -{ - public: - virtual int authenticate( - const OUString & inRealm, - const OUString & inHostName, - OUString & inoutUserName, - OUString & outPassWord, - bool bCanUseSystemCredentials ) = 0; -}; - -} // namespace webdav_ucp - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/ucb/source/ucp/webdav-neon/DAVAuthListenerImpl.hxx b/ucb/source/ucp/webdav-neon/DAVAuthListenerImpl.hxx deleted file mode 100644 index b3d2a8ad601f..000000000000 --- a/ucb/source/ucp/webdav-neon/DAVAuthListenerImpl.hxx +++ /dev/null @@ -1,69 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -#pragma once - -#include <config_lgpl.h> -#include <com/sun/star/ucb/XCommandEnvironment.hpp> -#include "DAVAuthListener.hxx" - - -namespace webdav_ucp -{ - - - - - class DAVAuthListener_Impl : public DAVAuthListener - { - public: - - DAVAuthListener_Impl( - const css::uno::Reference< css::ucb::XCommandEnvironment>& xEnv, - const OUString & inURL ) - : m_xEnv( xEnv ), m_aURL( inURL ) - { - } - - virtual int authenticate( const OUString & inRealm, - const OUString & inHostName, - OUString & inoutUserName, - OUString & outPassWord, - bool bCanUseSystemCredentials ) override; - private: - - const css::uno::Reference< css::ucb::XCommandEnvironment > m_xEnv; - const OUString m_aURL; - - OUString m_aPrevPassword; - OUString m_aPrevUsername; - }; - -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/ucb/source/ucp/webdav-neon/DAVException.hxx b/ucb/source/ucp/webdav-neon/DAVException.hxx deleted file mode 100644 index 4fdcac3f4f8e..000000000000 --- a/ucb/source/ucp/webdav-neon/DAVException.hxx +++ /dev/null @@ -1,174 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -#pragma once - -#include <config_lgpl.h> -#include <rtl/ustring.hxx> - -namespace webdav_ucp -{ - - -// HTTP/WebDAV status codes - - -const sal_uInt16 SC_NONE = 0; - -// 1xx (Informational - no errors) -const sal_uInt16 SC_CONTINUE = 100; -const sal_uInt16 SC_SWITCHING_PROTOCOLS = 101; -// DAV extensions -const sal_uInt16 SC_PROCESSING = 102; - -//2xx (Successful - no errors) -const sal_uInt16 SC_OK = 200; -const sal_uInt16 SC_CREATED = 201; -const sal_uInt16 SC_ACCEPTED = 202; -const sal_uInt16 SC_NON_AUTHORITATIVE_INFORMATION = 203; -const sal_uInt16 SC_NO_CONTENT = 204; -const sal_uInt16 SC_RESET_CONTENT = 205; -const sal_uInt16 SC_PARTIAL_CONTENT = 206; -// DAV extensions -const sal_uInt16 SC_MULTISTATUS = 207; - -//3xx (Redirection) -const sal_uInt16 SC_MULTIPLE_CHOICES = 300; -const sal_uInt16 SC_MOVED_PERMANENTLY = 301; -const sal_uInt16 SC_MOVED_TEMPORARILY = 302; -const sal_uInt16 SC_SEE_OTHER = 303; -const sal_uInt16 SC_NOT_MODIFIED = 304; -const sal_uInt16 SC_USE_PROXY = 305; -const sal_uInt16 SC_TEMPORARY_REDIRECT = 307; - -//4xx (Client error) -const sal_uInt16 SC_BAD_REQUEST = 400; -const sal_uInt16 SC_UNAUTHORIZED = 401; -const sal_uInt16 SC_PAYMENT_REQUIRED = 402; -const sal_uInt16 SC_FORBIDDEN = 403; -const sal_uInt16 SC_NOT_FOUND = 404; -const sal_uInt16 SC_METHOD_NOT_ALLOWED = 405; -const sal_uInt16 SC_NOT_ACCEPTABLE = 406; -const sal_uInt16 SC_PROXY_AUTHENTICATION_REQUIRED = 407; -const sal_uInt16 SC_REQUEST_TIMEOUT = 408; -const sal_uInt16 SC_CONFLICT = 409; -const sal_uInt16 SC_GONE = 410; -const sal_uInt16 SC_LENGTH_REQUIRED = 411; -const sal_uInt16 SC_PRECONDITION_FAILED = 412; -const sal_uInt16 SC_REQUEST_ENTITY_TOO_LARGE = 413; -const sal_uInt16 SC_REQUEST_URI_TOO_LONG = 414; -const sal_uInt16 SC_UNSUPPORTED_MEDIA_TYPE = 415; -const sal_uInt16 SC_REQUESTED_RANGE_NOT_SATISFIABLE = 416; -const sal_uInt16 SC_EXPECTATION_FAILED = 417; -// DAV extensions -const sal_uInt16 SC_UNPROCESSABLE_ENTITY = 422; -const sal_uInt16 SC_LOCKED = 423; -const sal_uInt16 SC_FAILED_DEPENDENCY = 424; - -//5xx (Server error, general <https://tools.ietf.org/html/rfc7231#section-6.6>) -const sal_uInt16 SC_INTERNAL_SERVER_ERROR = 500; -const sal_uInt16 SC_NOT_IMPLEMENTED = 501; -const sal_uInt16 SC_BAD_GATEWAY = 502; -const sal_uInt16 SC_SERVICE_UNAVAILABLE = 503; -const sal_uInt16 SC_GATEWAY_TIMEOUT = 504; -const sal_uInt16 SC_HTTP_VERSION_NOT_SUPPORTED = 505; -// DAV extensions (<https://tools.ietf.org/html/rfc4918#section-11>) -const sal_uInt16 SC_INSUFFICIENT_STORAGE = 507; - -// unofficial status codes only used internally by LO -// used to cache the connection time out event -const sal_uInt16 USC_CONNECTION_TIMED_OUT = 908; - // name resolution failed -const sal_uInt16 USC_LOOKUP_FAILED = 909; -const sal_uInt16 USC_AUTH_FAILED = 910; -const sal_uInt16 USC_AUTHPROXY_FAILED = 911; - - - -class DAVException : public std::exception -{ - public: - enum ExceptionCode { - DAV_HTTP_ERROR = 0, // Generic error, - // mData = server error message, - // mStatusCode = HTTP status code - DAV_HTTP_LOOKUP, // Name lookup failed, - // mData = server[:port] - DAV_HTTP_AUTH, // User authentication failed on server, - // mData = server[:port] - DAV_HTTP_AUTHPROXY, // User authentication failed on proxy, - // mData = proxy server[:port] - DAV_HTTP_CONNECT, // Could not connect to server, - // mData = server[:port] - DAV_HTTP_TIMEOUT, // Connection timed out - // mData = server[:port] - DAV_HTTP_FAILED, // The precondition failed - // mData = server[:port] - DAV_HTTP_RETRY, // Retry request - // mData = server[:port] - DAV_HTTP_REDIRECT, // Request was redirected, - // mData = new URL - DAV_SESSION_CREATE, // session creation error, - // mData = server[:port] - DAV_INVALID_ARG, // invalid argument - - DAV_LOCK_EXPIRED, // DAV lock expired - - DAV_NOT_LOCKED, // not locked - - DAV_LOCKED_SELF, // locked by this OOo session - - DAV_LOCKED // locked by third party - }; - - private: - ExceptionCode mExceptionCode; - OUString mData; - sal_uInt16 mStatusCode; - - public: - explicit DAVException( ExceptionCode inExceptionCode ) : - mExceptionCode( inExceptionCode ), mStatusCode( SC_NONE ) {}; - DAVException( ExceptionCode inExceptionCode, - const OUString & rData ) : - mExceptionCode( inExceptionCode ), mData( rData ), - mStatusCode( SC_NONE ) {}; - DAVException( ExceptionCode inExceptionCode, - const OUString & rData, - sal_uInt16 nStatusCode ) : - mExceptionCode( inExceptionCode ), mData( rData ), - mStatusCode( nStatusCode ) {}; - - const ExceptionCode & getError() const { return mExceptionCode; } - const OUString & getData() const { return mData; } - sal_uInt16 getStatus() const { return mStatusCode; } -}; - -} // namespace webdav_ucp - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/ucb/source/ucp/webdav-neon/DAVProperties.cxx b/ucb/source/ucp/webdav-neon/DAVProperties.cxx deleted file mode 100644 index b1a4a0273ef8..000000000000 --- a/ucb/source/ucp/webdav-neon/DAVProperties.cxx +++ /dev/null @@ -1,193 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - - -#include <string.h> - -#include <o3tl/string_view.hxx> - -#include "DAVProperties.hxx" - -using namespace webdav_ucp; - -void DAVProperties::createNeonPropName( std::u16string_view rFullName, - NeonPropName & rName ) -{ - if ( o3tl::starts_with( rFullName, u"DAV:" ) ) - { - rName.nspace = "DAV:"; - rName.name - = strdup( OUStringToOString( - rFullName.substr( RTL_CONSTASCII_LENGTH( "DAV:" ) ), - RTL_TEXTENCODING_UTF8 ).getStr() ); - } - else if ( o3tl::starts_with( rFullName, u"http://apache.org/dav/props/" ) ) - { - rName.nspace = "http://apache.org/dav/props/"; - rName.name - = strdup( OUStringToOString( - rFullName.substr( - RTL_CONSTASCII_LENGTH( - "http://apache.org/dav/props/" ) ), - RTL_TEXTENCODING_UTF8 ).getStr() ); - } - else if ( o3tl::starts_with( rFullName, u"http://ucb.openoffice.org/dav/props/" ) ) - { - rName.nspace = "http://ucb.openoffice.org/dav/props/"; - rName.name - = strdup( OUStringToOString( - rFullName.substr( - RTL_CONSTASCII_LENGTH( - "http://ucb.openoffice.org/dav/props/" ) ), - RTL_TEXTENCODING_UTF8 ).getStr() ); - } - else if ( o3tl::starts_with( rFullName, u"<prop:" ) ) - { - // Support for 3rd party namespaces/props - - OString aFullName - = OUStringToOString( rFullName, RTL_TEXTENCODING_UTF8 ); - - // Format: <prop:the_propname xmlns:prop="the_namespace"> - - sal_Int32 nStart = RTL_CONSTASCII_LENGTH( "<prop:" ); - sal_Int32 nLen = aFullName.indexOf( ' ' ) - nStart; - rName.name = strdup( aFullName.copy( nStart, nLen ).getStr() ); - - nStart = aFullName.indexOf( '=', nStart + nLen ) + 2; // after =" - nLen = aFullName.getLength() - RTL_CONSTASCII_LENGTH( "\">" ) - nStart; - rName.nspace = strdup( aFullName.copy( nStart, nLen ).getStr() ); - } - else - { - // Add our namespace to our own properties. - rName.nspace = "http://ucb.openoffice.org/dav/props/"; - rName.name - = strdup( OUStringToOString( rFullName, - RTL_TEXTENCODING_UTF8 ).getStr() ); - } -} - -void DAVProperties::createUCBPropName( const char * nspace, - const char * name, - OUString & rFullName ) -{ - OUString aNameSpace - = OStringToOUString( nspace, RTL_TEXTENCODING_UTF8 ); - OUString aName - = OStringToOUString( name, RTL_TEXTENCODING_UTF8 ); - - if ( aNameSpace.isEmpty() ) - { - // Some servers send XML without proper namespaces. Assume "DAV:" - // in this case, if name is a well-known dav property name. - // Although this is not 100% correct, it solves many problems. - if ( o3tl::equalsIgnoreAsciiCase(aName, std::u16string_view(DAVProperties::RESOURCETYPE).substr(4)) || - o3tl::equalsIgnoreAsciiCase(aName, std::u16string_view(DAVProperties::RESOURCETYPE).substr(4)) || - o3tl::equalsIgnoreAsciiCase(aName, std::u16string_view(DAVProperties::SUPPORTEDLOCK).substr(4)) || - o3tl::equalsIgnoreAsciiCase(aName, std::u16string_view(DAVProperties::LOCKDISCOVERY).substr(4)) || - o3tl::equalsIgnoreAsciiCase(aName, std::u16string_view(DAVProperties::CREATIONDATE).substr(4)) || - o3tl::equalsIgnoreAsciiCase(aName, std::u16string_view(DAVProperties::DISPLAYNAME).substr(4)) || - o3tl::equalsIgnoreAsciiCase(aName, std::u16string_view(DAVProperties::GETCONTENTLANGUAGE).substr(4)) || - o3tl::equalsIgnoreAsciiCase(aName, std::u16string_view(DAVProperties::GETCONTENTLENGTH).substr(4)) || - o3tl::equalsIgnoreAsciiCase(aName, std::u16string_view(DAVProperties::GETCONTENTTYPE).substr(4)) || - o3tl::equalsIgnoreAsciiCase(aName, std::u16string_view(DAVProperties::GETETAG).substr(4)) || - o3tl::equalsIgnoreAsciiCase(aName, std::u16string_view(DAVProperties::GETLASTMODIFIED).substr(4)) || - o3tl::equalsIgnoreAsciiCase(aName, std::u16string_view(DAVProperties::SOURCE).substr(4)) ) - aNameSpace = "DAV:"; - } - - // Note: Concatenating strings BEFORE comparing against known namespaces - // is important. See RFC 2815 ( 23.4.2 Meaning of Qualified Names ). - rFullName = aNameSpace; - rFullName += aName; - - if ( rFullName.startsWith( "DAV:" ) ) - { - // Okay, Just concat strings. - } - else if ( rFullName.startsWith( "http://apache.org/dav/props/" ) ) - { - // Okay, Just concat strings. - } - else if ( rFullName.startsWith( "http://ucb.openoffice.org/dav/props/" ) ) - { - // Remove namespace from our own properties. - rFullName = rFullName.copy( - RTL_CONSTASCII_LENGTH( - "http://ucb.openoffice.org/dav/props/" ) ); - } - else - { - // Create property name that encodes, namespace and name ( XML ). - rFullName = "<prop:" + aName + " xmlns:prop=\"" + aNameSpace + "\">"; - } -} - -bool DAVProperties::isUCBDeadProperty( const NeonPropName & rName ) -{ - return ( rName.nspace && - ( rtl_str_compareIgnoreAsciiCase( - rName.nspace, "http://ucb.openoffice.org/dav/props/" ) - == 0 ) ); -} - -bool DAVProperties::isUCBSpecialProperty( - const OUString& rFullName, OUString& rParsedName) -{ - if ( !rFullName.startsWith( "<prop:" ) || !rFullName.endsWith( "\">" ) ) - return false; - - sal_Int32 nStart = strlen( "<prop:" ); - sal_Int32 nEnd = rFullName.indexOf( ' ', nStart ); - if ( nEnd <= nStart ) // incl. -1 for "not found" - return false; - - OUString sPropName( rFullName.copy( nStart, nEnd - nStart ) ); - - // TODO skip whitespaces? - if ( !rFullName.match( "xmlns:prop=\"", ++nEnd ) ) - return false; - - nStart = nEnd + strlen( "xmlns:prop=\"" ); - nEnd = rFullName.indexOf( '"', nStart ); - if ( nEnd != rFullName.getLength() - sal_Int32( strlen( "\">" ) ) - || nEnd == nStart ) - { - return false; - } - - rParsedName = rFullName.copy( nStart, nEnd - nStart ); - if ( !rParsedName.endsWith( "/" ) ) - rParsedName += "/"; - rParsedName += sPropName; - - return rParsedName.getLength(); -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/ucb/source/ucp/webdav-neon/DAVProperties.hxx b/ucb/source/ucp/webdav-neon/DAVProperties.hxx deleted file mode 100644 index 3eeddcb847e1..000000000000 --- a/ucb/source/ucp/webdav-neon/DAVProperties.hxx +++ /dev/null @@ -1,69 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ -#pragma once - -#include <sal/config.h> - -#include <string_view> - -#include <config_lgpl.h> -#include <rtl/ustring.hxx> -#include "NeonTypes.hxx" - -namespace webdav_ucp -{ - -struct DAVProperties -{ - static constexpr OUStringLiteral CREATIONDATE = u"DAV:creationdate"; - static constexpr OUStringLiteral DISPLAYNAME = u"DAV:displayname"; - static constexpr OUStringLiteral GETCONTENTLANGUAGE = u"DAV:getcontentlanguage"; - static constexpr OUStringLiteral GETCONTENTLENGTH = u"DAV:getcontentlength"; - static constexpr OUStringLiteral GETCONTENTTYPE = u"DAV:getcontenttype"; - static constexpr OUStringLiteral GETETAG = u"DAV:getetag"; - static constexpr OUStringLiteral GETLASTMODIFIED = u"DAV:getlastmodified"; - static constexpr OUStringLiteral LOCKDISCOVERY = u"DAV:lockdiscovery"; - static constexpr OUStringLiteral RESOURCETYPE = u"DAV:resourcetype"; - static constexpr OUStringLiteral SOURCE = u"DAV:source"; - static constexpr OUStringLiteral SUPPORTEDLOCK = u"DAV:supportedlock"; - static constexpr OUStringLiteral EXECUTABLE = u"http://apache.org/dav/props/executable"; - - static void createNeonPropName( std::u16string_view rFullName, - NeonPropName & rName ); - static void createUCBPropName ( const char * nspace, - const char * name, - OUString & rFullName ); - - static bool isUCBDeadProperty( const NeonPropName & rName ); - static bool isUCBSpecialProperty( const OUString & rFullName, - OUString & rParsedName ); -}; - -} // namespace webdav_ucp - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/ucb/source/ucp/webdav-neon/DAVRequestEnvironment.hxx b/ucb/source/ucp/webdav-neon/DAVRequestEnvironment.hxx deleted file mode 100644 index 9059f6162804..000000000000 --- a/ucb/source/ucp/webdav-neon/DAVRequestEnvironment.hxx +++ /dev/null @@ -1,64 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ -#pragma once - -#include <config_lgpl.h> -#include <vector> -#include <rtl/ref.hxx> -#include <com/sun/star/ucb/XCommandEnvironment.hpp> -#include "DAVAuthListener.hxx" - -namespace webdav_ucp -{ - typedef std::pair< OUString, OUString > DAVRequestHeader; - typedef std::vector< DAVRequestHeader > DAVRequestHeaders; - -struct DAVRequestEnvironment -{ - OUString m_aRequestURI; - rtl::Reference< DAVAuthListener > m_xAuthListener; -// rtl::Reference< DAVStatusListener > m_xStatusListener; -// rtl::Reference< DAVProgressListener > m_xStatusListener; - DAVRequestHeaders m_aRequestHeaders; - uno::Reference< ucb::XCommandEnvironment > m_xEnv; - -DAVRequestEnvironment( const OUString & rRequestURI, - const rtl::Reference< DAVAuthListener > & xListener, - DAVRequestHeaders && rRequestHeaders, - const uno::Reference< ucb::XCommandEnvironment > & xEnv) - : m_aRequestURI( rRequestURI ), - m_xAuthListener( xListener ), - m_aRequestHeaders( std::move(rRequestHeaders) ), - m_xEnv( xEnv ){} - - DAVRequestEnvironment() {} -}; - -} // namespace webdav_ucp - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/ucb/source/ucp/webdav-neon/DAVResource.hxx b/ucb/source/ucp/webdav-neon/DAVResource.hxx deleted file mode 100644 index d26206de71e0..000000000000 --- a/ucb/source/ucp/webdav-neon/DAVResource.hxx +++ /dev/null @@ -1,70 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -#pragma once - -#include <config_lgpl.h> -#include <vector> - -#include <rtl/ustring.hxx> -#include <com/sun/star/uno/Any.hxx> - -namespace webdav_ucp -{ - -struct DAVPropertyValue -{ - OUString Name; - css::uno::Any Value; - bool IsCaseSensitive; - - DAVPropertyValue() : IsCaseSensitive( true ) {} -}; - -struct DAVResource -{ - OUString uri; - std::vector< DAVPropertyValue > properties; - - DAVResource() {} - explicit DAVResource( const OUString & inUri ) : uri( inUri ) {} -}; - -struct DAVResourceInfo -{ - std::vector < OUString > properties; - - bool operator==( const struct DAVResourceInfo& a ) const - { - return (properties == a.properties ); - } -}; - -} // namespace webdav_ucp - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/ucb/source/ucp/webdav-neon/DAVResourceAccess.cxx b/ucb/source/ucp/webdav-neon/DAVResourceAccess.cxx deleted file mode 100644 index b13edc253c0c..000000000000 --- a/ucb/source/ucp/webdav-neon/DAVResourceAccess.cxx +++ /dev/null @@ -1,1192 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - - -#include <com/sun/star/io/IOException.hpp> -#include <com/sun/star/lang/IllegalArgumentException.hpp> -#include <com/sun/star/task/XInteractionAbort.hpp> -#include <com/sun/star/ucb/XWebDAVCommandEnvironment.hpp> - -#include <ucbhelper/simpleauthenticationrequest.hxx> -#include <comphelper/seekableinput.hxx> - -#include "DAVAuthListenerImpl.hxx" -#include "DAVResourceAccess.hxx" - -using namespace webdav_ucp; -using namespace com::sun::star; - - -// DAVAuthListener_Impl Implementation. - -constexpr sal_uInt32 g_nRedirectLimit = 5; - -// virtual -int DAVAuthListener_Impl::authenticate( - const OUString & inRealm, - const OUString & inHostName, - OUString & inoutUserName, - OUString & outPassWord, - bool bCanUseSystemCredentials ) -{ - if ( m_xEnv.is() ) - { - uno::Reference< task::XInteractionHandler > xIH - = m_xEnv->getInteractionHandler(); - - if ( xIH.is() ) - { - // #102871# - Supply username and password from previous try. - // Password container service depends on this! - if ( inoutUserName.isEmpty() ) - inoutUserName = m_aPrevUsername; - - if ( outPassWord.isEmpty() ) - outPassWord = m_aPrevPassword; - - rtl::Reference< ucbhelper::SimpleAuthenticationRequest > xRequest - = new ucbhelper::SimpleAuthenticationRequest( - m_aURL, inHostName, inRealm, inoutUserName, - outPassWord, bCanUseSystemCredentials ); - xIH->handle( xRequest ); - - rtl::Reference< ucbhelper::InteractionContinuation > xSelection - = xRequest->getSelection(); - - if ( xSelection.is() ) - { - // Handler handled the request. - uno::Reference< task::XInteractionAbort > xAbort( - xSelection.get(), uno::UNO_QUERY ); - if ( !xAbort.is() ) - { - const rtl::Reference< - ucbhelper::InteractionSupplyAuthentication > & xSupp - = xRequest->getAuthenticationSupplier(); - - bool bUseSystemCredentials = false; - - if ( bCanUseSystemCredentials ) - bUseSystemCredentials - = xSupp->getUseSystemCredentials(); - - if ( bUseSystemCredentials ) - { - // This is the (strange) way to tell neon to use - // system credentials. - inoutUserName.clear(); - outPassWord.clear(); - } - else - { - inoutUserName = xSupp->getUserName(); - outPassWord = xSupp->getPassword(); - } - - // #102871# - Remember username and password. - m_aPrevUsername = inoutUserName; - m_aPrevPassword = outPassWord; - - // go on. - return 0; - } - } - } - } - // Abort. - return -1; -} - - -// DAVResourceAccess Implementation. - - -DAVResourceAccess::DAVResourceAccess( - const uno::Reference< uno::XComponentContext > & rxContext, - rtl::Reference< DAVSessionFactory > const & rSessionFactory, - const OUString & rURL ) -: m_aURL( rURL ), - m_xSessionFactory( rSessionFactory ), - m_xContext( rxContext ) -{ -} - - -DAVResourceAccess::DAVResourceAccess( const DAVResourceAccess & rOther ) -: m_aURL( rOther.m_aURL ), - m_aPath( rOther.m_aPath ), - m_aFlags( rOther.m_aFlags ), - m_xSession( rOther.m_xSession ), - m_xSessionFactory( rOther.m_xSessionFactory ), - m_xContext( rOther.m_xContext ), - m_aRedirectURIs( rOther.m_aRedirectURIs ) -{ -} - - -DAVResourceAccess & DAVResourceAccess::operator=( - const DAVResourceAccess & rOther ) -{ - m_aURL = rOther.m_aURL; - m_aPath = rOther.m_aPath; - m_aFlags = rOther.m_aFlags; - m_xSession = rOther.m_xSession; - m_xSessionFactory = rOther.m_xSessionFactory; - m_xContext = rOther.m_xContext; - m_aRedirectURIs = rOther.m_aRedirectURIs; - - return *this; -} - -void DAVResourceAccess::OPTIONS( - DAVOptions & rOptions, - const css::uno::Reference< - css::ucb::XCommandEnvironment > & xEnv ) -{ - initialize(); - - int errorCount = 0; - bool bRetry; - do - { - bRetry = false; - try - { - DAVRequestHeaders aHeaders; - - getUserRequestHeaders( xEnv, - getRequestURI(), - css::ucb::WebDAVHTTPMethod_OPTIONS, - aHeaders ); - - m_xSession->OPTIONS( getRequestURI(), - rOptions, - DAVRequestEnvironment( - getRequestURI(), - new DAVAuthListener_Impl( xEnv, m_aURL ), - std::move(aHeaders), xEnv ) ); - } - catch ( const DAVException & e ) - { - errorCount++; - bRetry = handleException( e, errorCount ); - if ( !bRetry ) - throw; - } - } - while ( bRetry ); -} - -void DAVResourceAccess::PROPFIND( - const Depth nDepth, - const std::vector< OUString > & rPropertyNames, - std::vector< DAVResource > & rResources, - const uno::Reference< ucb::XCommandEnvironment > & xEnv ) -{ - initialize(); - - int errorCount = 0; - bool bRetry; - do - { - bRetry = false; - try - { - DAVRequestHeaders aHeaders; - - getUserRequestHeaders( xEnv, - getRequestURI(), - ucb::WebDAVHTTPMethod_PROPFIND, - aHeaders ); - - m_xSession->PROPFIND( getRequestURI(), - nDepth, - rPropertyNames, - rResources, - DAVRequestEnvironment( - getRequestURI(), - new DAVAuthListener_Impl( xEnv, m_aURL ), - std::move(aHeaders), xEnv ) ); - } - catch ( const DAVException & e ) - { - errorCount++; - bRetry = handleException( e, errorCount ); - if ( !bRetry ) - throw; - } - } - while ( bRetry ); -} - - -void DAVResourceAccess::PROPFIND( - const Depth nDepth, - std::vector< DAVResourceInfo > & rResInfo, - const uno::Reference< ucb::XCommandEnvironment > & xEnv ) -{ - initialize(); - - int errorCount = 0; - bool bRetry; - do - { - bRetry = false; - try - { - DAVRequestHeaders aHeaders; - getUserRequestHeaders( xEnv, - getRequestURI(), - ucb::WebDAVHTTPMethod_PROPFIND, - aHeaders ); - - m_xSession->PROPFIND( getRequestURI(), - nDepth, - rResInfo, - DAVRequestEnvironment( - getRequestURI(), - new DAVAuthListener_Impl( xEnv, m_aURL ), - std::move(aHeaders), xEnv ) ) ; - } - catch ( const DAVException & e ) - { - errorCount++; - bRetry = handleException( e, errorCount ); - if ( !bRetry ) - throw; - } - } - while ( bRetry ); -} - - -void DAVResourceAccess::PROPPATCH( - const std::vector< ProppatchValue >& rValues, - const uno::Reference< ucb::XCommandEnvironment >& xEnv ) -{ - initialize(); - - int errorCount = 0; - bool bRetry; - do - { - bRetry = false; - try - { - DAVRequestHeaders aHeaders; - getUserRequestHeaders( xEnv, - getRequestURI(), - ucb::WebDAVHTTPMethod_PROPPATCH, - aHeaders ); - - m_xSession->PROPPATCH( getRequestURI(), - rValues, - DAVRequestEnvironment( - getRequestURI(), - new DAVAuthListener_Impl( xEnv, m_aURL ), - std::move(aHeaders), xEnv ) ); - } - catch ( const DAVException & e ) - { - errorCount++; - bRetry = handleException( e, errorCount ); - if ( !bRetry ) - throw; - } - } - while ( bRetry ); -} - - -void DAVResourceAccess::HEAD( - const std::vector< OUString > & rHeaderNames, - DAVResource & rResource, - const uno::Reference< ucb::XCommandEnvironment >& xEnv ) -{ - initialize(); - - int errorCount = 0; - bool bRetry; - do - { - bRetry = false; - try - { - DAVRequestHeaders aHeaders; - getUserRequestHeaders( xEnv, - getRequestURI(), - ucb::WebDAVHTTPMethod_HEAD, - aHeaders ); - - m_xSession->HEAD( getRequestURI(), - rHeaderNames, - rResource, - DAVRequestEnvironment( - getRequestURI(), - new DAVAuthListener_Impl( xEnv, m_aURL ), - std::move(aHeaders), xEnv ) ); - } - catch ( const DAVException & e ) - { - errorCount++; - bRetry = handleException( e, errorCount ); - if ( !bRetry ) - throw; - } - } - while ( bRetry ); -} - - -uno::Reference< io::XInputStream > DAVResourceAccess::GET( - const uno::Reference< ucb::XCommandEnvironment > & xEnv ) -{ - initialize(); - - uno::Reference< io::XInputStream > xStream; - int errorCount = 0; - bool bRetry; - do - { - bRetry = false; - try - { - DAVRequestHeaders aHeaders; - getUserRequestHeaders( xEnv, - getRequestURI(), - ucb::WebDAVHTTPMethod_GET, - aHeaders ); - - xStream = m_xSession->GET( getRequestURI(), - DAVRequestEnvironment( - getRequestURI(), - new DAVAuthListener_Impl( - xEnv, m_aURL ), - std::move(aHeaders), xEnv ) ); - } - catch ( const DAVException & e ) - { - errorCount++; - bRetry = handleException( e, errorCount ); - if ( !bRetry ) - throw; - } - } - while ( bRetry ); - - return xStream; -} - - -void DAVResourceAccess::GET( - uno::Reference< io::XOutputStream > & rStream, - const uno::Reference< ucb::XCommandEnvironment > & xEnv ) -{ - initialize(); - - int errorCount = 0; - bool bRetry; - do - { - bRetry = false; - try - { - DAVRequestHeaders aHeaders; - getUserRequestHeaders( xEnv, - getRequestURI(), - ucb::WebDAVHTTPMethod_GET, - aHeaders ); - - m_xSession->GET( getRequestURI(), - rStream, - DAVRequestEnvironment( - getRequestURI(), - new DAVAuthListener_Impl( xEnv, m_aURL ), - std::move(aHeaders), xEnv ) ); - } - catch ( const DAVException & e ) - { - errorCount++; - bRetry = handleException( e, errorCount ); - if ( !bRetry ) - throw; - } - } - while ( bRetry ); -} - -uno::Reference< io::XInputStream > DAVResourceAccess::GET( - const std::vector< OUString > & rHeaderNames, - DAVResource & rResource, - const uno::Reference< ucb::XCommandEnvironment > & xEnv ) -{ - initialize(); - - uno::Reference< io::XInputStream > xStream; - int errorCount = 0; - bool bRetry; - do - { - bRetry = false; - try - { - DAVRequestHeaders aHeaders; - getUserRequestHeaders( xEnv, - getRequestURI(), - ucb::WebDAVHTTPMethod_GET, - aHeaders ); - - xStream = m_xSession->GET( getRequestURI(), - rHeaderNames, - rResource, - DAVRequestEnvironment( - getRequestURI(), - new DAVAuthListener_Impl( - xEnv, m_aURL ), - std::move(aHeaders), xEnv ) ); - } - catch ( const DAVException & e ) - { - errorCount++; - bRetry = handleException( e, errorCount ); - if ( !bRetry ) - throw; - } - } - while ( bRetry ); - - return xStream; -} - -// used as HEAD substitute when HEAD is not implemented on server -void DAVResourceAccess::GET0( - DAVRequestHeaders &rRequestHeaders, - const std::vector< OUString > & rHeaderNames, - DAVResource & rResource, - const uno::Reference< ucb::XCommandEnvironment > & xEnv ) -{ - initialize(); - - int errorCount = 0; - bool bRetry; - do - { - bRetry = false; - try - { - getUserRequestHeaders( xEnv, - getRequestURI(), - ucb::WebDAVHTTPMethod_GET, - rRequestHeaders ); - - m_xSession->GET0( getRequestURI(), - rHeaderNames, - rResource, - DAVRequestEnvironment( - getRequestURI(), - new DAVAuthListener_Impl( - xEnv, m_aURL ), - DAVRequestHeaders(rRequestHeaders), xEnv ) ); - } - catch ( const DAVException & e ) - { - errorCount++; - bRetry = handleException( e, errorCount ); - if ( !bRetry ) - throw; - } - } - while ( bRetry ); -} - - -void DAVResourceAccess::GET( - uno::Reference< io::XOutputStream > & rStream, - const std::vector< OUString > & rHeaderNames, - DAVResource & rResource, - const uno::Reference< ucb::XCommandEnvironment > & xEnv ) -{ - initialize(); - - bool bRetry; - int errorCount = 0; - do - { - bRetry = false; - try - { - DAVRequestHeaders aHeaders; - getUserRequestHeaders( xEnv, - getRequestURI(), - ucb::WebDAVHTTPMethod_GET, - aHeaders ); - - m_xSession->GET( getRequestURI(), - rStream, - rHeaderNames, - rResource, - DAVRequestEnvironment( - getRequestURI(), - new DAVAuthListener_Impl( xEnv, m_aURL ), - std::move(aHeaders), xEnv ) ); - } - catch ( const DAVException & e ) - { - errorCount++; - bRetry = handleException( e, errorCount ); - if ( !bRetry ) - throw; - } - } - while ( bRetry ); -} - - -void DAVResourceAccess::abort() -{ - initialize(); - m_xSession->abort(); -} - - -namespace { - - /// @throws DAVException - void resetInputStream( const uno::Reference< io::XInputStream > & rStream ) - { - try - { - uno::Reference< io::XSeekable > xSeekable( - rStream, uno::UNO_QUERY ); - if ( xSeekable.is() ) - { - xSeekable->seek( 0 ); - return; - } - } - catch ( lang::IllegalArgumentException const & ) - { - } - catch ( io::IOException const & ) - { - } - - throw DAVException( DAVException::DAV_INVALID_ARG ); - } - -} // namespace - - -void DAVResourceAccess::PUT( - const uno::Reference< io::XInputStream > & rStream, - const uno::Reference< ucb::XCommandEnvironment > & xEnv ) -{ - initialize(); - - // Make stream seekable, if it not. Needed, if request must be retried. - uno::Reference< io::XInputStream > xSeekableStream - = comphelper::OSeekableInputWrapper::CheckSeekableCanWrap( - rStream, m_xContext ); - - int errorCount = 0; - bool bRetry = false; - do - { - if ( bRetry ) - resetInputStream( xSeekableStream ); - - bRetry = false; - try - { - DAVRequestHeaders aHeaders; - getUserRequestHeaders( xEnv, - getRequestURI(), - ucb::WebDAVHTTPMethod_PUT, - aHeaders ); - - m_xSession->PUT( getRequestURI(), - xSeekableStream, - DAVRequestEnvironment( - getRequestURI(), - new DAVAuthListener_Impl( xEnv, m_aURL ), - std::move(aHeaders), xEnv ) ); - } - catch ( const DAVException & e ) - { - errorCount++; - bRetry = handleException( e, errorCount ); - if ( !bRetry ) - throw; - } - } - while ( bRetry ); -} - - -uno::Reference< io::XInputStream > DAVResourceAccess::POST( - const OUString & rContentType, - const OUString & rReferer, - const uno::Reference< io::XInputStream > & rInputStream, - const uno::Reference< ucb::XCommandEnvironment >& xEnv ) -{ - initialize(); - - // Make stream seekable, if it not. Needed, if request must be retried. - uno::Reference< io::XInputStream > xSeekableStream - = comphelper::OSeekableInputWrapper::CheckSeekableCanWrap( - rInputStream, m_xContext ); - - uno::Reference< io::XInputStream > xStream; - int errorCount = 0; - bool bRetry = false; - do - { - if ( bRetry ) - { - resetInputStream( xSeekableStream ); - bRetry = false; - } - - try - { - DAVRequestHeaders aHeaders; - getUserRequestHeaders( xEnv, - getRequestURI(), - ucb::WebDAVHTTPMethod_POST, - aHeaders ); - - xStream = m_xSession->POST( getRequestURI(), - rContentType, - rReferer, - xSeekableStream, - DAVRequestEnvironment( - getRequestURI(), - new DAVAuthListener_Impl( - xEnv, m_aURL ), - std::move(aHeaders), xEnv ) ); - } - catch ( const DAVException & e ) - { - errorCount++; - bRetry = handleException( e, errorCount ); - if ( !bRetry ) - throw; - - if ( e.getError() == DAVException::DAV_HTTP_REDIRECT ) - { - // #i74980# - Upon POST redirect, do a GET. - return GET( xEnv ); - } - } - } - while ( bRetry ); - - return xStream; -} - - -void DAVResourceAccess::POST( - const OUString & rContentType, - const OUString & rReferer, - const uno::Reference< io::XInputStream > & rInputStream, - uno::Reference< io::XOutputStream > & rOutputStream, - const uno::Reference< ucb::XCommandEnvironment >& xEnv ) -{ - initialize(); - - // Make stream seekable, if it not. Needed, if request must be retried. - uno::Reference< io::XInputStream > xSeekableStream - = comphelper::OSeekableInputWrapper::CheckSeekableCanWrap( - rInputStream, m_xContext ); - - int errorCount = 0; - bool bRetry = false; - do - { - if ( bRetry ) - { - resetInputStream( xSeekableStream ); - bRetry = false; - } - - try - { - DAVRequestHeaders aHeaders; - getUserRequestHeaders( xEnv, - getRequestURI(), - ucb::WebDAVHTTPMethod_POST, - aHeaders ); - - m_xSession->POST( getRequestURI(), - rContentType, - rReferer, - xSeekableStream, - rOutputStream, - DAVRequestEnvironment( - getRequestURI(), - new DAVAuthListener_Impl( xEnv, m_aURL ), - std::move(aHeaders), xEnv ) ); - } - catch ( const DAVException & e ) - { - errorCount++; - bRetry = handleException( e, errorCount ); - if ( !bRetry ) - throw; - - if ( e.getError() == DAVException::DAV_HTTP_REDIRECT ) - { - // #i74980# - Upon POST redirect, do a GET. - GET( rOutputStream, xEnv ); - return; - } - } - } - while ( bRetry ); -} - - -void DAVResourceAccess::MKCOL( - const uno::Reference< ucb::XCommandEnvironment > & xEnv ) -{ - initialize(); - - int errorCount = 0; - bool bRetry; - do - { - bRetry = false; - try - { - DAVRequestHeaders aHeaders; - getUserRequestHeaders( xEnv, - getRequestURI(), - ucb::WebDAVHTTPMethod_MKCOL, - aHeaders ); - - m_xSession->MKCOL( getRequestURI(), - DAVRequestEnvironment( - getRequestURI(), - new DAVAuthListener_Impl( xEnv, m_aURL ), - std::move(aHeaders), xEnv ) ); - } - catch ( const DAVException & e ) - { - errorCount++; - bRetry = handleException( e, errorCount ); - if ( !bRetry ) - throw; - } - } - while ( bRetry ); -} - - -void DAVResourceAccess::COPY( - const OUString & rSourcePath, - const OUString & rDestinationURI, - bool bOverwrite, - const uno::Reference< ucb::XCommandEnvironment > & xEnv ) -{ - initialize(); - - int errorCount = 0; - bool bRetry; - do - { - bRetry = false; - try - { - DAVRequestHeaders aHeaders; - getUserRequestHeaders( xEnv, - getRequestURI(), - ucb::WebDAVHTTPMethod_COPY, - aHeaders ); - - m_xSession->COPY( rSourcePath, - rDestinationURI, - DAVRequestEnvironment( - getRequestURI(), - new DAVAuthListener_Impl( xEnv, m_aURL ), - std::move(aHeaders), xEnv ), - bOverwrite ); - } - catch ( const DAVException & e ) - { - errorCount++; - bRetry = handleException( e, errorCount ); - if ( !bRetry ) - throw; - } - } - while ( bRetry ); -} - - -void DAVResourceAccess::MOVE( - const OUString & rSourcePath, - const OUString & rDestinationURI, - bool bOverwrite, - const uno::Reference< ucb::XCommandEnvironment > & xEnv ) -{ - initialize(); - - int errorCount = 0; - bool bRetry; - do - { - bRetry = false; - try - { - DAVRequestHeaders aHeaders; - getUserRequestHeaders( xEnv, - getRequestURI(), - ucb::WebDAVHTTPMethod_MOVE, - aHeaders ); - - m_xSession->MOVE( rSourcePath, - rDestinationURI, - DAVRequestEnvironment( - getRequestURI(), - new DAVAuthListener_Impl( xEnv, m_aURL ), - std::move(aHeaders), xEnv ), - bOverwrite ); - } - catch ( const DAVException & e ) - { - errorCount++; - bRetry = handleException( e, errorCount ); - if ( !bRetry ) - throw; - } - } - while ( bRetry ); -} - - -void DAVResourceAccess::DESTROY( - const uno::Reference< ucb::XCommandEnvironment > & xEnv ) -{ - initialize(); - - int errorCount = 0; - bool bRetry; - do - { - bRetry = false; - try - { - DAVRequestHeaders aHeaders; - getUserRequestHeaders( xEnv, - getRequestURI(), - ucb::WebDAVHTTPMethod_DELETE, - aHeaders ); - - m_xSession->DESTROY( getRequestURI(), - DAVRequestEnvironment( - getRequestURI(), - new DAVAuthListener_Impl( xEnv, m_aURL ), - std::move(aHeaders), xEnv ) ); - } - catch ( const DAVException & e ) - { - errorCount++; - bRetry = handleException( e, errorCount ); - if ( !bRetry ) - throw; - } - } - while ( bRetry ); -} - - -// set new lock. -void DAVResourceAccess::LOCK( - ucb::Lock & inLock, - const uno::Reference< ucb::XCommandEnvironment > & xEnv ) -{ - initialize(); - - int errorCount = 0; - bool bRetry; - do - { - bRetry = false; - try - { - DAVRequestHeaders aHeaders; - getUserRequestHeaders( xEnv, - getRequestURI(), - ucb::WebDAVHTTPMethod_LOCK, - aHeaders ); - - m_xSession->LOCK( getRequestURI(), - inLock, - DAVRequestEnvironment( - getRequestURI(), - new DAVAuthListener_Impl( xEnv, m_aURL ), - std::move(aHeaders), xEnv ) ); - } - catch ( const DAVException & e ) - { - errorCount++; - bRetry = handleException( e, errorCount ); - if ( !bRetry ) - throw; - } - } - while ( bRetry ); -} - -void DAVResourceAccess::UNLOCK( - const uno::Reference< ucb::XCommandEnvironment > & xEnv ) -{ - initialize(); - - int errorCount = 0; - bool bRetry; - do - { - bRetry = false; - try - { - DAVRequestHeaders aHeaders; - getUserRequestHeaders( xEnv, - getRequestURI(), - ucb::WebDAVHTTPMethod_UNLOCK, - aHeaders ); - - m_xSession->UNLOCK( getRequestURI(), - DAVRequestEnvironment( - getRequestURI(), - new DAVAuthListener_Impl( xEnv, m_aURL ), - std::move(aHeaders), xEnv ) ); - } - catch ( const DAVException & e ) - { - errorCount++; - bRetry = handleException( e, errorCount ); - if ( !bRetry ) - throw; - } - } - while ( bRetry ); -} - - -void DAVResourceAccess::setFlags( const uno::Sequence< beans::NamedValue >& rFlags ) -{ - osl::Guard< osl::Mutex > aGuard( m_aMutex ); - m_aFlags = rFlags; -} - - -void DAVResourceAccess::setURL( const OUString & rNewURL ) -{ - osl::Guard< osl::Mutex > aGuard( m_aMutex ); - m_aURL = rNewURL; - m_aPath.clear(); // Next initialize() will create new session. -} - - -// init dav session and path -void DAVResourceAccess::initialize() -{ - osl::Guard< osl::Mutex > aGuard( m_aMutex ); - if ( !m_aPath.isEmpty() ) - return; - - NeonUri aURI( m_aURL ); - const OUString& aPath( aURI.GetPath() ); - - /* #134089# - Check URI */ - if ( aPath.isEmpty() ) - throw DAVException( DAVException::DAV_INVALID_ARG ); - - /* #134089# - Check URI */ - if ( aURI.GetHost().isEmpty() ) - throw DAVException( DAVException::DAV_INVALID_ARG ); - - if ( !m_xSession.is() || !m_xSession->CanUse( m_aURL, m_aFlags ) ) - { - m_xSession.clear(); - - // create new webdav session - m_xSession - = m_xSessionFactory->createDAVSession( m_aURL, m_aFlags, m_xContext ); - - if ( !m_xSession.is() ) - return; - } - - // Own URI is needed to redirect cycle detection. - m_aRedirectURIs.push_back( aURI ); - - // Success. - m_aPath = aPath; - - // Not only the path has to be encoded - m_aURL = aURI.GetURI(); -} - - -const OUString & DAVResourceAccess::getRequestURI() const -{ - assert( m_xSession.is() && "DAVResourceAccess::getRequestURI - Not initialized!" ); - - // In case a proxy is used we have to use the absolute URI for a request. - if ( m_xSession->UsesProxy() ) - return m_aURL; - - return m_aPath; -} - - -// static -void DAVResourceAccess::getUserRequestHeaders( - const uno::Reference< ucb::XCommandEnvironment > & xEnv, - const OUString & rURI, - ucb::WebDAVHTTPMethod eMethod, - DAVRequestHeaders & rRequestHeaders ) -{ - if ( xEnv.is() ) - { - uno::Reference< ucb::XWebDAVCommandEnvironment > xDAVEnv( - xEnv, uno::UNO_QUERY ); - - if ( xDAVEnv.is() ) - { - const uno::Sequence< beans::StringPair > aRequestHeaders - = xDAVEnv->getUserRequestHeaders( rURI, eMethod ); - - for ( const auto& rRequestHeader : aRequestHeaders ) - { - rRequestHeaders.emplace_back( - rRequestHeader.First, - rRequestHeader.Second ); - } - } - } - - // Make sure a User-Agent header is always included, as at least - // en.wikipedia.org:80 forces back 403 "Scripts should use an informative - // User-Agent string with contact information, or they may be IP-blocked - // without notice" otherwise: - if ( std::any_of(rRequestHeaders.begin(), rRequestHeaders.end(), - [](const DAVRequestHeader& rHeader) { return rHeader.first.equalsIgnoreAsciiCase( "User-Agent" ); }) ) - { - return; - } - rRequestHeaders.emplace_back( "User-Agent", "LibreOffice" ); -} - -// This function member implements the control on cyclical redirections -bool DAVResourceAccess::detectRedirectCycle( - const OUString& rRedirectURL ) -{ - osl::Guard< osl::Mutex > aGuard( m_aMutex ); - - NeonUri aUri( rRedirectURL ); - - // Check for maximum number of redirections - // according to <https://tools.ietf.org/html/rfc7231#section-6.4>. - // A practical limit may be 5, due to earlier specifications: - // <https://tools.ietf.org/html/rfc2068#section-10.3> - // it can be raised keeping in mind the added net activity. - if( static_cast< size_t >( g_nRedirectLimit ) <= m_aRedirectURIs.size() ) - return true; - - // try to detect a cyclical redirection - return std::any_of(m_aRedirectURIs.begin(), m_aRedirectURIs.end(), - [&aUri](const NeonUri& rUri) { - // if equal, cyclical redirection detected - return aUri == rUri; }); -} - - -void DAVResourceAccess::resetUri() -{ - osl::Guard< osl::Mutex > aGuard( m_aMutex ); - if ( !m_aRedirectURIs.empty() ) - { - std::vector< NeonUri >::const_iterator it = m_aRedirectURIs.begin(); - - NeonUri aUri( *it ); - m_aRedirectURIs.clear(); - setURL ( aUri.GetURI() ); - initialize(); - } -} - - -bool DAVResourceAccess::handleException( const DAVException & e, int errorCount ) -{ - switch ( e.getError() ) - { - case DAVException::DAV_HTTP_REDIRECT: - if ( !detectRedirectCycle( e.getData() ) ) - { - // set new URL and path. - setURL( e.getData() ); - initialize(); - return true; - } - return false; - // #67048# copy & paste images doesn't display. This bug refers - // to an old OOo problem about getting resources from sites with a bad connection. - // If we have a bad connection try again. Up to three times. - case DAVException::DAV_HTTP_ERROR: - // retry up to three times, if not a client-side error (4xx error codes) - if ( e.getStatus() < SC_BAD_REQUEST && errorCount < 3 ) - return true; - // check the server side errors - switch( e.getStatus() ) - { - // the HTTP server side response status codes that can be retried - case SC_BAD_GATEWAY: // retry, can be an excessive load - case SC_GATEWAY_TIMEOUT: // retry, may be we get lucky - case SC_SERVICE_UNAVAILABLE: // retry, the service may become available - case SC_INSUFFICIENT_STORAGE: // space may be freed, retry - { - return errorCount < 3; - } - break; - // all the other HTTP server response status codes are NOT retry - default: - return false; - } - break; - // if connection has said retry then retry! - case DAVException::DAV_HTTP_RETRY: - return true; - default: - return false; // Abort - } -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/ucb/source/ucp/webdav-neon/DAVResourceAccess.hxx b/ucb/source/ucp/webdav-neon/DAVResourceAccess.hxx deleted file mode 100644 index 03eeb879696b..000000000000 --- a/ucb/source/ucp/webdav-neon/DAVResourceAccess.hxx +++ /dev/null @@ -1,231 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -#pragma once - -#include <config_lgpl.h> -#include <vector> -#include <rtl/ustring.hxx> -#include <rtl/ref.hxx> -#include <osl/mutex.hxx> -#include <com/sun/star/io/XInputStream.hpp> -#include <com/sun/star/io/XOutputStream.hpp> -#include <com/sun/star/beans/NamedValue.hpp> -#include <com/sun/star/ucb/Lock.hpp> -#include <com/sun/star/ucb/WebDAVHTTPMethod.hpp> -#include <com/sun/star/ucb/XCommandEnvironment.hpp> -#include "DAVAuthListener.hxx" -#include "DAVException.hxx" -#include "DAVSession.hxx" -#include "DAVResource.hxx" -#include "DAVTypes.hxx" -#include "NeonUri.hxx" - -namespace webdav_ucp -{ - -class DAVSessionFactory; - -class DAVResourceAccess -{ - osl::Mutex m_aMutex; - OUString m_aURL; - OUString m_aPath; - css::uno::Sequence< css::beans::NamedValue > m_aFlags; - rtl::Reference< DAVSession > m_xSession; - rtl::Reference< DAVSessionFactory > m_xSessionFactory; - css::uno::Reference< css::uno::XComponentContext > m_xContext; - std::vector< NeonUri > m_aRedirectURIs; - -public: - DAVResourceAccess( const css::uno::Reference< css::uno::XComponentContext > & rxContext, - rtl::Reference< DAVSessionFactory > const & rSessionFactory, - const OUString & rURL ); - DAVResourceAccess( const DAVResourceAccess & rOther ); - - DAVResourceAccess & operator=( const DAVResourceAccess & rOther ); - - /// @throws DAVException - void setFlags( const css::uno::Sequence< css::beans::NamedValue >& rFlags ); - - /// @throws DAVException - void setURL( const OUString & rNewURL ); - - void resetUri(); - - const OUString & getURL() const { return m_aURL; } - - const rtl::Reference< DAVSessionFactory >& getSessionFactory() const - { return m_xSessionFactory; } - - // DAV methods - - /// @throws DAVException - void - OPTIONS( DAVOptions & rOptions, - const css::uno::Reference< - css::ucb::XCommandEnvironment > & xEnv ); - - // allprop & named - /// @throws DAVException - void - PROPFIND( const Depth nDepth, - const std::vector< OUString > & rPropertyNames, - std::vector< DAVResource > & rResources, - const css::uno::Reference< css::ucb::XCommandEnvironment > & xEnv ); - - // propnames - /// @throws DAVException - void - PROPFIND( const Depth nDepth, - std::vector< DAVResourceInfo > & rResInfo, - const css::uno::Reference< css::ucb::XCommandEnvironment > & xEnv ); - - /// @throws DAVException - void - PROPPATCH( const std::vector< ProppatchValue > & rValues, - const css::uno::Reference< css::ucb::XCommandEnvironment >& xEnv ); - - /// @throws DAVException - void - HEAD( const std::vector< OUString > & rHeaderNames, // empty == 'all' - DAVResource & rResource, - const css::uno::Reference< css::ucb::XCommandEnvironment >& xEnv ); - - /// @throws DAVException - css::uno::Reference< css::io::XInputStream > - GET( const css::uno::Reference< css::ucb::XCommandEnvironment > & xEnv ); - - /// @throws DAVException - void - GET( css::uno::Reference< css::io::XOutputStream > & rStream, - const css::uno::Reference< css::ucb::XCommandEnvironment > & xEnv ); - - /// @throws css::uno::RuntimeException - /// @throws DAVException - css::uno::Reference< css::io::XInputStream > - GET( const std::vector< OUString > & rHeaderNames, // empty == 'all' - DAVResource & rResource, - const css::uno::Reference< css::ucb::XCommandEnvironment > & xEnv ); - - // used as HEAD substitute when HEAD is not implemented on server - /// @throws DAVException - void - GET0( DAVRequestHeaders & rRequestHeaders, - const std::vector< OUString > & rHeaderNames, // empty == 'all' - DAVResource & rResource, - const css::uno::Reference< css::ucb::XCommandEnvironment > & xEnv ); - - /// @throws DAVException - void - GET( css::uno::Reference< css::io::XOutputStream > & rStream, - const std::vector< OUString > & rHeaderNames, // empty == 'all' - DAVResource & rResource, - const css::uno::Reference< css::ucb::XCommandEnvironment > & xEnv ); - - /// @throws css::uno::RuntimeException - /// @throws DAVException - void - PUT( const css::uno::Reference< css::io::XInputStream > & rStream, - const css::uno::Reference< css::ucb::XCommandEnvironment > & xEnv ); - - /// @throws css::uno::RuntimeException - /// @throws DAVException - css::uno::Reference< css::io::XInputStream > - POST( const OUString & rContentType, - const OUString & rReferer, - const css::uno::Reference< css::io::XInputStream > & rInputStream, - const css::uno::Reference< css::ucb::XCommandEnvironment >& xEnv ); - - /// @throws css::uno::RuntimeException - /// @throws DAVException - void - POST( const OUString & rContentType, - const OUString & rReferer, - const css::uno::Reference< css::io::XInputStream > & rInputStream, - css::uno::Reference< css::io::XOutputStream > & rOutputStream, - const css::uno::Reference< css::ucb::XCommandEnvironment >& xEnv ); - - /// @throws DAVException - void - MKCOL( const css::uno::Reference< css::ucb::XCommandEnvironment > & xEnv ); - - /// @throws DAVException - void - COPY( const OUString & rSourcePath, - const OUString & rDestinationURI, - bool bOverwrite, - const css::uno::Reference< css::ucb::XCommandEnvironment > & xEnv ); - - /// @throws DAVException - void - MOVE( const OUString & rSourcePath, - const OUString & rDestinationURI, - bool bOverwrite, - const css::uno::Reference< css::ucb::XCommandEnvironment > & xEnv ); - - /// @throws DAVException - void - DESTROY( const css::uno::Reference< css::ucb::XCommandEnvironment > & xEnv ); - - // set new lock. - /// @throws DAVException - void - LOCK( css::ucb::Lock & inLock, - const css::uno::Reference< css::ucb::XCommandEnvironment > & xEnv ); - - /// @throws DAVException - void - UNLOCK( const css::uno::Reference< css::ucb::XCommandEnvironment > & xEnv ); - - /// @throws DAVException - void - abort(); - - // helper - static void - getUserRequestHeaders( - const css::uno::Reference< css::ucb::XCommandEnvironment > & xEnv, - const OUString & rURI, - css::ucb::WebDAVHTTPMethod eMethod, - DAVRequestHeaders & rRequestHeaders ); - - /// @throws DAVException - bool handleException( const DAVException & e, int errorCount ); - -private: - const OUString & getRequestURI() const; - /// @throws DAVException - bool detectRedirectCycle( const OUString& rRedirectURL ); - /// @throws DAVException - void initialize(); -}; - -} // namespace webdav_ucp - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/ucb/source/ucp/webdav-neon/DAVSession.hxx b/ucb/source/ucp/webdav-neon/DAVSession.hxx deleted file mode 100644 index f61bbdb6ad90..000000000000 --- a/ucb/source/ucp/webdav-neon/DAVSession.hxx +++ /dev/null @@ -1,213 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -#pragma once - -#include <config_lgpl.h> -#include <memory> -#include <rtl/ustring.hxx> -#include <com/sun/star/io/XInputStream.hpp> -#include <com/sun/star/io/XOutputStream.hpp> -#include "DAVProperties.hxx" -#include "DAVResource.hxx" -#include "DAVSessionFactory.hxx" -#include "DAVTypes.hxx" -#include "DAVRequestEnvironment.hxx" - -namespace com::sun::star::beans { - struct NamedValue; -} - -namespace com::sun::star::ucb { - struct Lock; -} - -namespace webdav_ucp -{ - -class DAVSession -{ -public: - void acquire() - { - osl_atomic_increment( &m_nRefCount ); - } - - void release() - { - if ( osl_atomic_decrement( &m_nRefCount ) == 0 ) - { - m_xFactory->releaseElement( this ); - delete this; - } - } - - virtual bool CanUse( const OUString & inPath, - const css::uno::Sequence< css::beans::NamedValue >& rFlags ) = 0; - - virtual bool UsesProxy() = 0; - - // DAV methods - - /// @throws std::exception - virtual void OPTIONS( const OUString & inPath, - DAVOptions& rOptions, - const DAVRequestEnvironment & rEnv ) = 0; - - // allprop & named - /// @throws std::exception - virtual void PROPFIND( const OUString & inPath, - const Depth inDepth, - const std::vector< OUString > & inPropertyNames, - std::vector< DAVResource > & ioResources, - const DAVRequestEnvironment & rEnv ) = 0; - - // propnames - /// @throws std::exception - virtual void PROPFIND( const OUString & inPath, - const Depth inDepth, - std::vector< DAVResourceInfo > & ioResInfo, - const DAVRequestEnvironment & rEnv ) = 0; - - /// @throws std::exception - virtual void PROPPATCH( const OUString & inPath, - const std::vector< ProppatchValue > & inValues, - const DAVRequestEnvironment & rEnv ) = 0; - - /// @throws std::exception - virtual void HEAD( const OUString & inPath, - const std::vector< OUString > & inHeaderNames, - DAVResource & ioResource, - const DAVRequestEnvironment & rEnv ) = 0; - - /// @throws std::exception - virtual css::uno::Reference< css::io::XInputStream > - GET( const OUString & inPath, - const DAVRequestEnvironment & rEnv ) = 0; - - /// @throws std::exception - virtual void GET( const OUString & inPath, - css::uno::Reference< css::io::XOutputStream >& o, - const DAVRequestEnvironment & rEnv ) = 0; - - /// @throws std::exception - virtual css::uno::Reference< css::io::XInputStream > - GET( const OUString & inPath, - const std::vector< OUString > & inHeaderNames, - DAVResource & ioResource, - const DAVRequestEnvironment & rEnv ) = 0; - - // used as HEAD substitute when HEAD is not implemented on server - /// @throws std::exception - virtual void - GET0( const OUString & inPath, - const std::vector< OUString > & inHeaderNames, - DAVResource & ioResource, - const DAVRequestEnvironment & rEnv ) = 0; - - /// @throws std::exception - virtual void - GET( const OUString & inPath, - css::uno::Reference< css::io::XOutputStream >& o, - const std::vector< OUString > & inHeaderNames, - DAVResource & ioResource, - const DAVRequestEnvironment & rEnv ) = 0; - - /// @throws std::exception - virtual void PUT( const OUString & inPath, - const css::uno::Reference< css::io::XInputStream >& s, - const DAVRequestEnvironment & rEnv ) = 0; - - /// @throws std::exception - virtual css::uno::Reference< css::io::XInputStream > - POST( const OUString & inPath, - const OUString & rContentType, - const OUString & rReferer, - const css::uno::Reference< css::io::XInputStream > & inInputStream, - const DAVRequestEnvironment & rEnv ) = 0; - - /// @throws std::exception - virtual void POST( const OUString & inPath, - const OUString & rContentType, - const OUString & rReferer, - const css::uno::Reference< css::io::XInputStream > & inInputStream, - css::uno::Reference< css::io::XOutputStream > & oOutputStream, - const DAVRequestEnvironment & rEnv ) = 0; - - /// @throws std::exception - virtual void MKCOL( const OUString & inPath, - const DAVRequestEnvironment & rEnv ) = 0; - - /// @throws std::exception - virtual void COPY( const OUString & inSource, - const OUString & inDestination, - const DAVRequestEnvironment & rEnv, - bool inOverwrite ) = 0; - - /// @throws std::exception - virtual void MOVE( const OUString & inSource, - const OUString & inDestination, - const DAVRequestEnvironment & rEnv, - bool inOverwrite ) = 0; - - /// @throws std::exception - virtual void DESTROY( const OUString & inPath, - const DAVRequestEnvironment & rEnv ) = 0; - - // set new lock. - /// @throws std::exception - virtual void LOCK( const OUString & inPath, - css::ucb::Lock & inLock, - const DAVRequestEnvironment & rEnv ) = 0; - - /// @throws std::exception - virtual void UNLOCK( const OUString & inPath, - const DAVRequestEnvironment & rEnv ) = 0; - - /// @throws std::exception - virtual void abort() = 0; - -protected: - rtl::Reference< DAVSessionFactory > m_xFactory; - - explicit DAVSession( rtl::Reference< DAVSessionFactory > const & rFactory ) - : m_xFactory( rFactory ), m_nRefCount( 0 ) {} - - virtual ~DAVSession() {} - -private: - DAVSessionFactory::Map::iterator m_aContainerIt; - oslInterlockedCount m_nRefCount; - - friend class DAVSessionFactory; - friend struct std::default_delete< DAVSession >; -}; - -} // namespace webdav_ucp - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/ucb/source/ucp/webdav-neon/DAVSessionFactory.cxx b/ucb/source/ucp/webdav-neon/DAVSessionFactory.cxx deleted file mode 100644 index d58171bdef6e..000000000000 --- a/ucb/source/ucp/webdav-neon/DAVSessionFactory.cxx +++ /dev/null @@ -1,99 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -#include <memory> -#include "DAVSessionFactory.hxx" -#include "NeonSession.hxx" -#include "NeonUri.hxx" -#include <osl/diagnose.h> - -using namespace webdav_ucp; -using namespace com::sun::star; - -DAVSessionFactory::~DAVSessionFactory() -{ -} - -rtl::Reference< DAVSession > DAVSessionFactory::createDAVSession( - const OUString & inUri, - const uno::Sequence< beans::NamedValue >& rFlags, - const uno::Reference< uno::XComponentContext > & rxContext ) -{ - std::scoped_lock aGuard( m_aMutex ); - - m_xContext = rxContext; - - if (!m_xProxyDecider) - m_xProxyDecider.reset( new ucbhelper::InternetProxyDecider( rxContext ) ); - - Map::iterator aIt = std::find_if(m_aMap.begin(), m_aMap.end(), - [&inUri, &rFlags](const Map::value_type& rEntry) { return rEntry.second->CanUse( inUri, rFlags ); }); - - if ( aIt == m_aMap.end() ) - { - NeonUri aURI( inUri ); - - std::unique_ptr<DAVSession> xElement( - new NeonSession(this, inUri, rFlags, *m_xProxyDecider)); - - aIt = m_aMap.emplace( inUri, xElement.get() ).first; - aIt->second->m_aContainerIt = aIt; - xElement.release(); - return aIt->second; - } - else if ( osl_atomic_increment( &aIt->second->m_nRefCount ) > 1 ) - { - rtl::Reference< DAVSession > xElement( aIt->second ); - osl_atomic_decrement( &aIt->second->m_nRefCount ); - return xElement; - } - else - { - osl_atomic_decrement( &aIt->second->m_nRefCount ); - aIt->second->m_aContainerIt = m_aMap.end(); - - // If URL scheme is different from http or https we definitely - // have to use a proxy and therefore can optimize the getProxy - // call a little: - NeonUri aURI( inUri ); - - aIt->second = new NeonSession(this, inUri, rFlags, *m_xProxyDecider); - aIt->second->m_aContainerIt = aIt; - return aIt->second; - } -} - -void DAVSessionFactory::releaseElement( DAVSession const * pElement ) -{ - OSL_ASSERT( pElement ); - std::scoped_lock aGuard( m_aMutex ); - if ( pElement->m_aContainerIt != m_aMap.end() ) - m_aMap.erase( pElement->m_aContainerIt ); -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/ucb/source/ucp/webdav-neon/DAVSessionFactory.hxx b/ucb/source/ucp/webdav-neon/DAVSessionFactory.hxx deleted file mode 100644 index fd185d11ae8a..000000000000 --- a/ucb/source/ucp/webdav-neon/DAVSessionFactory.hxx +++ /dev/null @@ -1,85 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ -#pragma once - -#ifdef min -#undef min // GNU libstdc++ <memory> includes <limit> which defines methods called min... -#endif -#include <config_lgpl.h> -#include <map> -#include <memory> -#include <mutex> -#include <salhelper/simplereferenceobject.hxx> -#include <rtl/ref.hxx> -#include <com/sun/star/uno/Reference.hxx> -#include <ucbhelper/proxydecider.hxx> - -using namespace com::sun::star; - -namespace com::sun::star::beans { - struct NamedValue; -} - -namespace com::sun::star::lang { - class XMultiServiceFactory; -} - -namespace webdav_ucp -{ - -class DAVSession; - -class DAVSessionFactory : public salhelper::SimpleReferenceObject -{ -public: - virtual ~DAVSessionFactory() override; - - /// @throws DAVException - rtl::Reference< DAVSession > - createDAVSession( const OUString & inUri, - const ::uno::Sequence< css::beans::NamedValue >& rFlags, - const ::uno::Reference< ::uno::XComponentContext >& rxContext ); - - const ::uno::Reference< ::uno::XComponentContext >& getComponentContext() const { return m_xContext; } -private: - typedef std::map< OUString, DAVSession * > Map; - - Map m_aMap; - std::mutex m_aMutex; - std::unique_ptr< ucbhelper::InternetProxyDecider > m_xProxyDecider; - - ::uno::Reference< ::uno::XComponentContext > m_xContext; - - void releaseElement( DAVSession const * pElement ); - - friend class DAVSession; -}; - -} // namespace webdav_ucp - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/ucb/source/ucp/webdav-neon/DAVTypes.cxx b/ucb/source/ucp/webdav-neon/DAVTypes.cxx deleted file mode 100644 index e39f5b2cf946..000000000000 --- a/ucb/source/ucp/webdav-neon/DAVTypes.cxx +++ /dev/null @@ -1,189 +0,0 @@ -/* -*- 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/. - */ - - -#include <osl/time.h> - -#include "DAVTypes.hxx" -#include "../inc/urihelper.hxx" -#include "NeonUri.hxx" - -using namespace webdav_ucp; -using namespace com::sun::star; - -// DAVOptions implementation - -DAVOptions::DAVOptions() : - m_isClass1( false ), - m_isClass2( false ), - m_isClass3( false ), - m_isHeadAllowed( true ), - m_isLocked( false ), - m_nStaleTime( 0 ), - m_nRequestedTimeLife( 0 ), - m_nHttpResponseStatusCode( 0 ) -{ -} - -DAVOptions::DAVOptions( const DAVOptions & rOther ) : - m_isClass1( rOther.m_isClass1 ), - m_isClass2( rOther.m_isClass2 ), - m_isClass3( rOther.m_isClass3 ), - m_isHeadAllowed( rOther.m_isHeadAllowed ), - m_isLocked( rOther.m_isLocked ), - m_aAllowedMethods( rOther.m_aAllowedMethods ), - m_nStaleTime( rOther.m_nStaleTime ), - m_nRequestedTimeLife( rOther.m_nRequestedTimeLife ), - m_sURL( rOther.m_sURL ), - m_sRedirectedURL( rOther.m_sRedirectedURL), - m_nHttpResponseStatusCode( rOther.m_nHttpResponseStatusCode ), - m_sHttpResponseStatusText( rOther.m_sHttpResponseStatusText ) -{ -} - -DAVOptions::~DAVOptions() -{ -} - -DAVOptions & DAVOptions::operator=( const DAVOptions& rOpts ) -{ - m_isClass1 = rOpts.m_isClass1; - m_isClass2 = rOpts.m_isClass2; - m_isClass3 = rOpts.m_isClass3; - m_isLocked = rOpts.m_isLocked; - m_isHeadAllowed = rOpts.m_isHeadAllowed; - m_aAllowedMethods = rOpts.m_aAllowedMethods; - m_nStaleTime = rOpts.m_nStaleTime; - m_nRequestedTimeLife = rOpts.m_nRequestedTimeLife; - m_sURL = rOpts.m_sURL; - m_sRedirectedURL = rOpts.m_sRedirectedURL; - m_nHttpResponseStatusCode = rOpts.m_nHttpResponseStatusCode; - m_sHttpResponseStatusText = rOpts.m_sHttpResponseStatusText; - return *this; -} - -bool DAVOptions::operator==( const DAVOptions& rOpts ) const -{ - return - m_isClass1 == rOpts.m_isClass1 && - m_isClass2 == rOpts.m_isClass2 && - m_isClass3 == rOpts.m_isClass3 && - m_isLocked == rOpts.m_isLocked && - m_isHeadAllowed == rOpts.m_isHeadAllowed && - m_aAllowedMethods == rOpts.m_aAllowedMethods && - m_nStaleTime == rOpts.m_nStaleTime && - m_nRequestedTimeLife == rOpts.m_nRequestedTimeLife && - m_sURL == rOpts.m_sURL && - m_sRedirectedURL == rOpts.m_sRedirectedURL && - m_nHttpResponseStatusCode == rOpts.m_nHttpResponseStatusCode && - m_sHttpResponseStatusText == rOpts.m_sHttpResponseStatusText; -} - - -// DAVOptionsCache implementation - -DAVOptionsCache::DAVOptionsCache() -{ -} - -DAVOptionsCache::~DAVOptionsCache() -{ -} - -bool DAVOptionsCache::getDAVOptions( const OUString & rURL, DAVOptions & rDAVOptions ) -{ - osl::MutexGuard aGuard( m_aMutex ); - OUString aEncodedUrl( ucb_impl::urihelper::encodeURI( NeonUri::unescape( rURL ) ) ); - normalizeURLLastChar( aEncodedUrl ); - - // search the URL in the static map - DAVOptionsMap::iterator it = m_aTheCache.find( aEncodedUrl ); - if ( it == m_aTheCache.end() ) - return false; - else - { - // check if the capabilities are stale, before restoring - TimeValue t1; - osl_getSystemTime( &t1 ); - if ( (*it).second.getStaleTime() < t1.Seconds ) - { - // if stale, remove from cache, do not restore - m_aTheCache.erase( it ); - return false; - // return false instead - } - rDAVOptions = (*it).second; - return true; - } -} - -void DAVOptionsCache::removeDAVOptions( const OUString & rURL ) -{ - osl::MutexGuard aGuard( m_aMutex ); - OUString aEncodedUrl( ucb_impl::urihelper::encodeURI( NeonUri::unescape( rURL ) ) ); - normalizeURLLastChar( aEncodedUrl ); - - DAVOptionsMap::iterator it = m_aTheCache.find( aEncodedUrl ); - if ( it != m_aTheCache.end() ) - { - m_aTheCache.erase( it ); - } -} - -void DAVOptionsCache::addDAVOptions( DAVOptions & rDAVOptions, const sal_uInt32 nLifeTime ) -{ - osl::MutexGuard aGuard( m_aMutex ); - OUString aURL( rDAVOptions.getURL() ); - - OUString aEncodedUrl( ucb_impl::urihelper::encodeURI( NeonUri::unescape( aURL ) ) ); - normalizeURLLastChar( aEncodedUrl ); - rDAVOptions.setURL( aEncodedUrl ); - -// unchanged, it may be used to access a server - OUString aRedirURL( rDAVOptions.getRedirectedURL() ); - rDAVOptions.setRedirectedURL( aRedirURL ); - - // check if already cached - DAVOptionsMap::iterator it = m_aTheCache.find( aEncodedUrl ); - if ( it != m_aTheCache.end() ) - { // already in cache, check LifeTime - if ( (*it).second.getRequestedTimeLife() == nLifeTime ) - return; // same lifetime, do nothing - } - // not in cache, add it - TimeValue t1; - osl_getSystemTime( &t1 ); - rDAVOptions.setStaleTime( t1.Seconds + nLifeTime ); - - m_aTheCache[ aEncodedUrl ] = rDAVOptions; -} - -void DAVOptionsCache::setHeadAllowed( const OUString & rURL, const bool HeadAllowed ) -{ - osl::MutexGuard aGuard( m_aMutex ); - OUString aEncodedUrl( ucb_impl::urihelper::encodeURI( NeonUri::unescape( rURL ) ) ); - normalizeURLLastChar( aEncodedUrl ); - - DAVOptionsMap::iterator it = m_aTheCache.find( aEncodedUrl ); - if ( it == m_aTheCache.end() ) - return; - - // first check for stale - TimeValue t1; - osl_getSystemTime( &t1 ); - if( (*it).second.getStaleTime() < t1.Seconds ) - { - m_aTheCache.erase( it ); - return; - } - // check if the resource was present on server - (*it).second.setHeadAllowed( HeadAllowed ); -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/ucb/source/ucp/webdav-neon/DAVTypes.hxx b/ucb/source/ucp/webdav-neon/DAVTypes.hxx deleted file mode 100644 index ceee3dbee0b6..000000000000 --- a/ucb/source/ucp/webdav-neon/DAVTypes.hxx +++ /dev/null @@ -1,208 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -#pragma once - -#include <config_lgpl.h> -#include <map> -#include <osl/mutex.hxx> -#include <rtl/ustring.hxx> -#include <com/sun/star/uno/Any.hxx> - -namespace webdav_ucp -{ -/* Excerpt from RFC 4918 - <https://tools.ietf.org/html/rfc4918#section-18> - - 18.1 Class 1 - - A class 1 compliant resource MUST meet all "MUST" requirements in all - sections of this document. - - Class 1 compliant resources MUST return, at minimum, the value "1" in - the DAV header on all responses to the OPTIONS method. - - 18.2 Class 2 - - A class 2 compliant resource MUST meet all class 1 requirements and - support the LOCK method, the DAV:supportedlock property, the DAV: - lockdiscovery property, the Time-Out response header and the Lock- - Token request header. A class 2 compliant resource SHOULD also - support the Timeout request header and the 'owner' XML element. - - Class 2 compliant resources MUST return, at minimum, the values "1" - and "2" in the DAV header on all responses to the OPTIONS method. - - 18.3. Class 3 - - A resource can explicitly advertise its support for the revisions to - [RFC2518] made in this document. Class 1 MUST be supported as well. - Class 2 MAY be supported. Advertising class 3 support in addition to - class 1 and 2 means that the server supports all the requirements in - this specification. Advertising class 3 and class 1 support, but not - class 2, means that the server supports all the requirements in this - specification except possibly those that involve locking support. - -*/ - - class DAVOptions final - { - private: - bool m_isClass1; - bool m_isClass2; - bool m_isClass3; - /// for server that do not implement it - bool m_isHeadAllowed; - /// Internally used to maintain the locked state of the resource, only if it's a Class 2 resource - bool m_isLocked; - /// contains the methods allowed on this resource - OUString m_aAllowedMethods; - - /// target time when this capability becomes stale - sal_uInt32 m_nStaleTime; - sal_uInt32 m_nRequestedTimeLife; - OUString m_sURL; - OUString m_sRedirectedURL; - - /// The cached HTT response status code. It's 0 if the code was dealt with and there is no need to cache it - sal_uInt16 m_nHttpResponseStatusCode; - /// The cached string with the server returned HTTP response status code string, corresponds to m_nHttpResponseStatusCode. - OUString m_sHttpResponseStatusText; - - public: - DAVOptions(); - - DAVOptions( const DAVOptions & rOther ); - - ~DAVOptions(); - - bool isClass1() const { return m_isClass1; }; - void setClass1( bool Class1 = true ) { m_isClass1 = Class1; }; - - bool isClass2() const { return m_isClass2; }; - void setClass2( bool Class2 = true ) { m_isClass2 = Class2; }; - - bool isClass3() const { return m_isClass3; }; - void setClass3( bool Class3 = true ) { m_isClass3 = Class3; }; - - bool isHeadAllowed() const { return m_isHeadAllowed; }; - void setHeadAllowed( bool HeadAllowed = true ) { m_isHeadAllowed = HeadAllowed; }; - - sal_uInt32 getStaleTime() const { return m_nStaleTime ; }; - void setStaleTime( const sal_uInt32 nStaleTime ) { m_nStaleTime = nStaleTime; }; - - sal_uInt32 getRequestedTimeLife() const { return m_nRequestedTimeLife; }; - void setRequestedTimeLife( const sal_uInt32 nRequestedTimeLife ) { m_nRequestedTimeLife = nRequestedTimeLife; }; - - const OUString & getURL() const { return m_sURL; }; - void setURL( const OUString & sURL ) { m_sURL = sURL; }; - - const OUString & getRedirectedURL() const { return m_sRedirectedURL; }; - void setRedirectedURL( const OUString & sRedirectedURL ) { m_sRedirectedURL = sRedirectedURL; }; - - void setAllowedMethods( const OUString & aAllowedMethods ) { m_aAllowedMethods = aAllowedMethods; } ; - const OUString & getAllowedMethods() const { return m_aAllowedMethods; } ; - bool isLockAllowed() const { return ( m_aAllowedMethods.indexOf( "LOCK" ) != -1 ); }; - - void setLocked( bool locked = true ) { m_isLocked = locked; } ; - bool isLocked() const { return m_isLocked; }; - - sal_uInt16 getHttpResponseStatusCode() const { return m_nHttpResponseStatusCode; }; - void setHttpResponseStatusCode( const sal_uInt16 nHttpResponseStatusCode ) { m_nHttpResponseStatusCode = nHttpResponseStatusCode; }; - - const OUString & getHttpResponseStatusText() const { return m_sHttpResponseStatusText; }; - void setHttpResponseStatusText( const OUString & rHttpResponseStatusText ) { m_sHttpResponseStatusText = rHttpResponseStatusText; }; - - void init() { - m_isClass1 = false; - m_isClass2 = false; - m_isClass3 = false; - m_isHeadAllowed = true; - m_isLocked = false; - m_aAllowedMethods.clear(); - m_nStaleTime = 0; - m_nRequestedTimeLife = 0; - m_sURL.clear(); - m_sRedirectedURL.clear(); - m_nHttpResponseStatusCode = 0; - m_sHttpResponseStatusText.clear(); - }; - - DAVOptions & operator=( const DAVOptions& rOpts ); - bool operator==( const DAVOptions& rOpts ) const; - - }; - - // TODO: the OUString key element in std::map needs to be changed with a URI representation - // along with a specific compare (std::less) implementation, as suggested in - // <https://tools.ietf.org/html/rfc3986#section-6>, to find by URI and not by string comparison - typedef std::map< OUString, DAVOptions, - std::less< OUString > > DAVOptionsMap; - - class DAVOptionsCache - { - DAVOptionsMap m_aTheCache; - osl::Mutex m_aMutex; - public: - explicit DAVOptionsCache(); - ~DAVOptionsCache(); - - bool getDAVOptions( const OUString & rURL, DAVOptions & rDAVOptions ); - void removeDAVOptions( const OUString & rURL ); - void addDAVOptions( DAVOptions & rDAVOptions, const sal_uInt32 nLifeTime ); - - void setHeadAllowed( const OUString & rURL, bool HeadAllowed = true ); - - private: - - /// remove the last '/' in aUrl, if it exists - static void normalizeURLLastChar( OUString& aUrl ) { - if ( aUrl.getLength() > 1 && - ( ( aUrl.lastIndexOf( '/' ) + 1 ) == aUrl.getLength() ) ) - aUrl = aUrl.copy(0, aUrl.getLength() - 1 ); - }; - }; - - enum Depth { DAVZERO = 0, DAVONE = 1, DAVINFINITY = -1 }; - - enum ProppatchOperation { PROPSET = 0, PROPREMOVE = 1 }; - - struct ProppatchValue - { - ProppatchOperation operation; - OUString name; - css::uno::Any value; - - ProppatchValue( const ProppatchOperation o, - const OUString & n, - const css::uno::Any & v ) - : operation( o ), name( n ), value( v ) {} - }; -} // namespace webdav_ucp - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/ucb/source/ucp/webdav-neon/DateTimeHelper.cxx b/ucb/source/ucp/webdav-neon/DateTimeHelper.cxx deleted file mode 100644 index 649838aaaae4..000000000000 --- a/ucb/source/ucp/webdav-neon/DateTimeHelper.cxx +++ /dev/null @@ -1,247 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - - -#include <osl/time.h> -#include <com/sun/star/util/DateTime.hpp> -#include "DateTimeHelper.hxx" - -using namespace com::sun::star::util; - -using namespace webdav_ucp; - - -bool DateTimeHelper::ISO8601_To_DateTime (const OUString& s, - DateTime& dateTime) -{ - OString aDT (s.getStr(), s.getLength(), RTL_TEXTENCODING_ASCII_US); - - int year, month, day, hours, minutes, off_hours, off_minutes, fix; - double seconds; - - // 2001-01-01T12:30:00Z - int n = sscanf( aDT.getStr(), "%04d-%02d-%02dT%02d:%02d:%lfZ", - &year, &month, &day, &hours, &minutes, &seconds ); - if ( n == 6 ) - { - fix = 0; - } - else - { - // 2001-01-01T12:30:00+03:30 - n = sscanf( aDT.getStr(), "%04d-%02d-%02dT%02d:%02d:%lf+%02d:%02d", - &year, &month, &day, &hours, &minutes, &seconds, - &off_hours, &off_minutes ); - if ( n == 8 ) - { - fix = - off_hours * 3600 - off_minutes * 60; - } - else - { - // 2001-01-01T12:30:00-03:30 - n = sscanf( aDT.getStr(), "%04d-%02d-%02dT%02d:%02d:%lf-%02d:%02d", - &year, &month, &day, &hours, &minutes, &seconds, - &off_hours, &off_minutes ); - if ( n == 8 ) - { - fix = off_hours * 3600 + off_minutes * 60; - } - else - { - return false; - } - } - } - - // Convert to local time... - - oslDateTime aDateTime; - aDateTime.NanoSeconds = 0; - aDateTime.Seconds = sal::static_int_cast< sal_uInt16 >(seconds); // 0-59 - aDateTime.Minutes = sal::static_int_cast< sal_uInt16 >(minutes); // 0-59 - aDateTime.Hours = sal::static_int_cast< sal_uInt16 >(hours); // 0-23 - aDateTime.Day = sal::static_int_cast< sal_uInt16 >(day); // 1-31 - aDateTime.DayOfWeek = 0; // 0-6, 0 = Sunday - aDateTime.Month = sal::static_int_cast< sal_uInt16 >(month); // 1-12 - aDateTime.Year = sal::static_int_cast< sal_Int16 >(year); - - TimeValue aTimeValue; - if ( osl_getTimeValueFromDateTime( &aDateTime, &aTimeValue ) ) - { - aTimeValue.Seconds += fix; - - if ( osl_getLocalTimeFromSystemTime( &aTimeValue, &aTimeValue ) ) - { - if ( osl_getDateTimeFromTimeValue( &aTimeValue, &aDateTime ) ) - { - dateTime.Year = aDateTime.Year; - dateTime.Month = aDateTime.Month; - dateTime.Day = aDateTime.Day; - dateTime.Hours = aDateTime.Hours; - dateTime.Minutes = aDateTime.Minutes; - dateTime.Seconds = aDateTime.Seconds; - - return true; - } - } - } - - return false; -} - -sal_Int32 DateTimeHelper::convertMonthToInt (std::u16string_view month) -{ - if (month == u"Jan") - return 1; - else if (month == u"Feb") - return 2; - else if (month == u"Mar") - return 3; - else if (month == u"Apr") - return 4; - else if (month == u"May") - return 5; - else if (month == u"Jun") - return 6; - else if (month == u"Jul") - return 7; - else if (month == u"Aug") - return 8; - else if (month == u"Sep") - return 9; - else if (month == u"Oct") - return 10; - else if (month == u"Nov") - return 11; - else if (month == u"Dec") - return 12; - else - return 0; -} - -bool DateTimeHelper::RFC2068_To_DateTime (const OUString& s, - DateTime& dateTime) -{ - int year; - int day; - int hours; - int minutes; - int seconds; - char string_month[3 + 1]; - char string_day[3 + 1]; - - sal_Int32 found = s.indexOf (','); - if (found != -1) - { - OString aDT (s.getStr(), s.getLength(), RTL_TEXTENCODING_ASCII_US); - - // RFC 1123 - found = sscanf (aDT.getStr(), "%3s, %2d %3s %4d %2d:%2d:%2d GMT", - string_day, &day, string_month, &year, &hours, &minutes, &seconds); - if (found != 7) - { - // RFC 1036 - found = sscanf (aDT.getStr(), "%3s, %2d-%3s-%2d %2d:%2d:%2d GMT", - string_day, &day, string_month, &year, &hours, &minutes, &seconds); - } - found = (found == 7) ? 1 : 0; - } - else - { - OString aDT (s.getStr(), s.getLength(), RTL_TEXTENCODING_ASCII_US); - - // ANSI C's asctime () format - found = sscanf (aDT.getStr(), "%3s %3s %d %2d:%2d:%2d %4d", - string_day, string_month, - &day, &hours, &minutes, &seconds, &year); - found = (found == 7) ? 1 : 0; - } - - if (found) - { - found = 0; - - int month = DateTimeHelper::convertMonthToInt ( - OUString::createFromAscii (string_month)); - if (month) - { - // Convert to local time... - - oslDateTime aDateTime; - aDateTime.NanoSeconds = 0; - aDateTime.Seconds = sal::static_int_cast< sal_uInt16 >(seconds); - // 0-59 - aDateTime.Minutes = sal::static_int_cast< sal_uInt16 >(minutes); - // 0-59 - aDateTime.Hours = sal::static_int_cast< sal_uInt16 >(hours); - // 0-23 - aDateTime.Day = sal::static_int_cast< sal_uInt16 >(day); - // 1-31 - aDateTime.DayOfWeek = 0; //dayofweek; // 0-6, 0 = Sunday - aDateTime.Month = sal::static_int_cast< sal_uInt16 >(month); - // 1-12 - aDateTime.Year = sal::static_int_cast< sal_Int16 >(year); - - TimeValue aTimeValue; - if ( osl_getTimeValueFromDateTime( &aDateTime, - &aTimeValue ) ) - { - if ( osl_getLocalTimeFromSystemTime( &aTimeValue, - &aTimeValue ) ) - { - if ( osl_getDateTimeFromTimeValue( &aTimeValue, - &aDateTime ) ) - { - dateTime.Year = aDateTime.Year; - dateTime.Month = aDateTime.Month; - dateTime.Day = aDateTime.Day; - dateTime.Hours = aDateTime.Hours; - dateTime.Minutes = aDateTime.Minutes; - dateTime.Seconds = aDateTime.Seconds; - - found = 1; - } - } - } - } - } - - return found != 0; -} - -bool DateTimeHelper::convert (const OUString& s, DateTime& dateTime) -{ - if (ISO8601_To_DateTime (s, dateTime)) - return true; - else if (RFC2068_To_DateTime (s, dateTime)) - return true; - else - return false; -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/ucb/source/ucp/webdav-neon/DateTimeHelper.hxx b/ucb/source/ucp/webdav-neon/DateTimeHelper.hxx deleted file mode 100644 index 6794aa2510a8..000000000000 --- a/ucb/source/ucp/webdav-neon/DateTimeHelper.hxx +++ /dev/null @@ -1,61 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -#pragma once - -#include <config_lgpl.h> -#include <sal/types.h> -#include <rtl/ustring.hxx> - -namespace com::sun::star::util { - struct DateTime; -} - - -namespace webdav_ucp -{ - -class DateTimeHelper -{ -private: - static sal_Int32 convertMonthToInt (std::u16string_view ); - - static bool ISO8601_To_DateTime (const OUString&, - css::util::DateTime& ); - - static bool RFC2068_To_DateTime (const OUString&, - css::util::DateTime& ); - -public: - static bool convert (const OUString&, - css::util::DateTime& ); -}; - -} // namespace webdav_ucp - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/ucb/source/ucp/webdav-neon/LinkSequence.cxx b/ucb/source/ucp/webdav-neon/LinkSequence.cxx deleted file mode 100644 index 9ff9d877ec30..000000000000 --- a/ucb/source/ucp/webdav-neon/LinkSequence.cxx +++ /dev/null @@ -1,214 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -#include <config_lgpl.h> -#include <string.h> -#include <ne_xml.h> -#include <memory> - -#include "LinkSequence.hxx" - -using namespace webdav_ucp; -using namespace com::sun::star; - -namespace { - -struct LinkSequenceParseContext -{ - std::unique_ptr<ucb::Link> pLink; - bool hasSource; - bool hasDestination; - - LinkSequenceParseContext() - : hasSource( false ), hasDestination( false ) {} -}; - -} - -#define STATE_TOP (1) - -#define STATE_LINK (STATE_TOP) -#define STATE_DST (STATE_TOP + 1) -#define STATE_SRC (STATE_TOP + 2) - - -extern "C" { - -static int LinkSequence_startelement_callback( - void *, - int parent, - const char * /*nspace*/, - const char *name, - const char ** ) -{ - if ( name != nullptr ) - { - switch ( parent ) - { - case NE_XML_STATEROOT: - if ( strcmp( name, "link" ) == 0 ) - return STATE_LINK; - break; - - case STATE_LINK: - if ( strcmp( name, "dst" ) == 0 ) - return STATE_DST; - else if ( strcmp( name, "src" ) == 0 ) - return STATE_SRC; - break; - } - } - return NE_XML_DECLINE; -} - - -static int LinkSequence_chardata_callback( - void *userdata, - int state, - const char *buf, - size_t len ) -{ - LinkSequenceParseContext * pCtx - = static_cast< LinkSequenceParseContext * >( userdata ); - if ( !pCtx->pLink ) - pCtx->pLink.reset( new ucb::Link ); - - switch ( state ) - { - case STATE_DST: - pCtx->pLink->Destination - = OUString( buf, len, RTL_TEXTENCODING_ASCII_US ); - pCtx->hasDestination = true; - break; - - case STATE_SRC: - pCtx->pLink->Source - = OUString( buf, len, RTL_TEXTENCODING_ASCII_US ); - pCtx->hasSource = true; - break; - } - return 0; // zero to continue, non-zero to abort parsing -} - - -static int LinkSequence_endelement_callback( - void *userdata, - int state, - const char *, - const char * ) -{ - LinkSequenceParseContext * pCtx - = static_cast< LinkSequenceParseContext * >( userdata ); - if ( !pCtx->pLink ) - pCtx->pLink.reset( new ucb::Link ); - - switch ( state ) - { - case STATE_LINK: - if ( !pCtx->hasDestination || !pCtx->hasSource ) - return 1; // abort - break; - } - return 0; // zero to continue, non-zero to abort parsing -} - -} - -// static -bool LinkSequence::createFromXML( const OString & rInData, - uno::Sequence< ucb::Link > & rOutData ) -{ - const sal_Int32 TOKEN_LENGTH = 7; // </link> - bool success = true; - - // rInData may contain multiple <link>...</link> tags. - sal_Int32 nCount = 0; - sal_Int32 nStart = 0; - sal_Int32 nEnd = rInData.indexOf( "</link>" ); - while ( nEnd > -1 ) - { - ne_xml_parser * parser = ne_xml_create(); - if ( !parser ) - { - success = false; - break; - } - - LinkSequenceParseContext aCtx; - ne_xml_push_handler( parser, - LinkSequence_startelement_callback, - LinkSequence_chardata_callback, - LinkSequence_endelement_callback, - &aCtx ); - - ne_xml_parse( parser, - rInData.getStr() + nStart, - nEnd - nStart + TOKEN_LENGTH ); - - success = !ne_xml_failed( parser ); - - ne_xml_destroy( parser ); - - if ( !success ) - break; - - if ( aCtx.pLink ) - { - nCount++; - if ( nCount > rOutData.getLength() ) - rOutData.realloc( rOutData.getLength() + 1 ); - - rOutData.getArray()[ nCount - 1 ] = *aCtx.pLink; - } - - nStart = nEnd + TOKEN_LENGTH; - nEnd = rInData.indexOf( "</link>", nStart ); - } - - return success; -} - - -// static -bool LinkSequence::toXML( const uno::Sequence< ucb::Link > & rInData, - OUString & rOutData ) -{ - // <link><src>value</src><dst>value</dst></link><link><src>... - - for ( const auto& rLink : rInData ) - { - rOutData += "<link><src>"; - rOutData += rLink.Source; - rOutData += "</src><dst>"; - rOutData += rLink.Destination; - rOutData += "</dst></link>"; - } - return rInData.hasElements(); -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/ucb/source/ucp/webdav-neon/LinkSequence.hxx b/ucb/source/ucp/webdav-neon/LinkSequence.hxx deleted file mode 100644 index d081fc4e65d9..000000000000 --- a/ucb/source/ucp/webdav-neon/LinkSequence.hxx +++ /dev/null @@ -1,49 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -#pragma once - -#include <rtl/string.hxx> -#include <com/sun/star/uno/Sequence.hxx> -#include <com/sun/star/ucb/Link.hpp> - -namespace webdav_ucp -{ - -class LinkSequence -{ -public: - static bool createFromXML( const OString & rInData, - css::uno::Sequence< css::ucb::Link > & rOutData ); - static bool toXML( const css::uno::Sequence< css::ucb::Link > & rInData, - OUString & rOutData ); -}; - -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/ucb/source/ucp/webdav-neon/LockEntrySequence.cxx b/ucb/source/ucp/webdav-neon/LockEntrySequence.cxx deleted file mode 100644 index 1ba2466d5aa2..000000000000 --- a/ucb/source/ucp/webdav-neon/LockEntrySequence.cxx +++ /dev/null @@ -1,246 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -#include <config_lgpl.h> -#include <string.h> -#include <ne_xml.h> -#include "LockEntrySequence.hxx" -#include <memory> - -using namespace webdav_ucp; -using namespace com::sun::star; - -namespace { - -struct LockEntrySequenceParseContext -{ - std::unique_ptr<ucb::LockEntry> pEntry; - bool hasScope; - bool hasType; - - LockEntrySequenceParseContext() - : hasScope( false ), hasType( false ) {} -}; - -} - -#define STATE_TOP (1) - -#define STATE_LOCKENTRY (STATE_TOP) -#define STATE_LOCKSCOPE (STATE_TOP + 1) -#define STATE_EXCLUSIVE (STATE_TOP + 2) -#define STATE_SHARED (STATE_TOP + 3) -#define STATE_LOCKTYPE (STATE_TOP + 4) -#define STATE_WRITE (STATE_TOP + 5) - - -extern "C" { - -static int LockEntrySequence_startelement_callback( - void *, - int parent, - const char * /*nspace*/, - const char *name, - const char ** ) -{ - if ( name != nullptr ) - { - switch ( parent ) - { - case NE_XML_STATEROOT: - if ( strcmp( name, "lockentry" ) == 0 ) - return STATE_LOCKENTRY; - break; - - case STATE_LOCKENTRY: - if ( strcmp( name, "lockscope" ) == 0 ) - return STATE_LOCKSCOPE; - else if ( strcmp( name, "locktype" ) == 0 ) - return STATE_LOCKTYPE; - -#define IIS_BUGS_WORKAROUND - -#ifdef IIS_BUGS_WORKAROUND - /* IIS (6) returns XML violating RFC 4918 - for DAV:supportedlock property value. - - <lockentry> - <write></write> - <shared></shared> - </lockentry> - <lockentry> - <write></write> - <exclusive></exclusive> - </lockentry> - - Bother... - */ - else if ( strcmp( name, "exclusive" ) == 0 ) - return STATE_EXCLUSIVE; - else if ( strcmp( name, "shared" ) == 0 ) - return STATE_SHARED; - else if ( strcmp( name, "write" ) == 0 ) - return STATE_WRITE; -#endif - break; - - case STATE_LOCKSCOPE: - if ( strcmp( name, "exclusive" ) == 0 ) - return STATE_EXCLUSIVE; - else if ( strcmp( name, "shared" ) == 0 ) - return STATE_SHARED; - break; - - case STATE_LOCKTYPE: - if ( strcmp( name, "write" ) == 0 ) - return STATE_WRITE; - break; - } - } - return NE_XML_DECLINE; -} - - -static int LockEntrySequence_chardata_callback( - void *, - int, - const char *, - size_t ) -{ - return 0; // zero to continue, non-zero to abort parsing -} - - -static int LockEntrySequence_endelement_callback( - void *userdata, - int state, - const char *, - const char * ) -{ - LockEntrySequenceParseContext * pCtx - = static_cast< LockEntrySequenceParseContext * >( userdata ); - if ( !pCtx->pEntry ) - pCtx->pEntry.reset( new ucb::LockEntry ); - - switch ( state ) - { - case STATE_EXCLUSIVE: - pCtx->pEntry->Scope = ucb::LockScope_EXCLUSIVE; - pCtx->hasScope = true; - break; - - case STATE_SHARED: - pCtx->pEntry->Scope = ucb::LockScope_SHARED; - pCtx->hasScope = true; - break; - - case STATE_WRITE: - pCtx->pEntry->Type = ucb::LockType_WRITE; - pCtx->hasType = true; - break; - - case STATE_LOCKSCOPE: - if ( !pCtx->hasScope ) - return 1; // abort - break; - - case STATE_LOCKTYPE: - if ( !pCtx->hasType ) - return 1; // abort - break; - - case STATE_LOCKENTRY: - if ( !pCtx->hasType || !pCtx->hasScope ) - return 1; // abort - break; - - default: - break; - } - return 0; // zero to continue, non-zero to abort parsing -} - -} - -// static -bool LockEntrySequence::createFromXML( const OString & rInData, - uno::Sequence< - ucb::LockEntry > & rOutData ) -{ - const sal_Int32 TOKEN_LENGTH = 12; // </lockentry> - bool success = true; - - // rInData may contain multiple <lockentry>...</lockentry> tags. - sal_Int32 nCount = 0; - sal_Int32 nStart = 0; - sal_Int32 nEnd = rInData.indexOf( "</lockentry>" ); - while ( nEnd > -1 ) - { - ne_xml_parser * parser = ne_xml_create(); - if ( !parser ) - { - success = false; - break; - } - - LockEntrySequenceParseContext aCtx; - ne_xml_push_handler( parser, - LockEntrySequence_startelement_callback, - LockEntrySequence_chardata_callback, - LockEntrySequence_endelement_callback, - &aCtx ); - - ne_xml_parse( parser, - rInData.getStr() + nStart, - nEnd - nStart + TOKEN_LENGTH ); - - success = !ne_xml_failed( parser ); - - ne_xml_destroy( parser ); - - if ( !success ) - break; - - if ( aCtx.pEntry ) - { - nCount++; - if ( nCount > rOutData.getLength() ) - rOutData.realloc( rOutData.getLength() + 2 ); - - rOutData.getArray()[ nCount - 1 ] = *aCtx.pEntry; - } - - nStart = nEnd + TOKEN_LENGTH; - nEnd = rInData.indexOf( "</lockentry>", nStart ); - } - - rOutData.realloc( nCount ); - return success; -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/ucb/source/ucp/webdav-neon/LockEntrySequence.hxx b/ucb/source/ucp/webdav-neon/LockEntrySequence.hxx deleted file mode 100644 index 7674c2de1cb7..000000000000 --- a/ucb/source/ucp/webdav-neon/LockEntrySequence.hxx +++ /dev/null @@ -1,45 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -#pragma once - -#include <rtl/string.hxx> -#include <com/sun/star/uno/Sequence.hxx> -#include <com/sun/star/ucb/LockEntry.hpp> - -namespace webdav_ucp -{ -class LockEntrySequence -{ -public: - static bool createFromXML(const OString& rInData, - css::uno::Sequence<css::ucb::LockEntry>& rOutData); -}; -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/ucb/source/ucp/webdav-neon/LockSequence.cxx b/ucb/source/ucp/webdav-neon/LockSequence.cxx deleted file mode 100644 index 8680a31363d7..000000000000 --- a/ucb/source/ucp/webdav-neon/LockSequence.cxx +++ /dev/null @@ -1,360 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -#include <config_lgpl.h> -#include <string.h> -#include <ne_xml.h> -#include "LockSequence.hxx" -#include <memory> -#include <sal/log.hxx> - -using namespace webdav_ucp; -using namespace com::sun::star; - -namespace { - -struct LockSequenceParseContext -{ - std::unique_ptr<ucb::Lock> pLock; - bool hasLockScope; - bool hasLockType; - bool hasDepth; - bool hasHREF; - bool hasTimeout; - - LockSequenceParseContext() - : hasLockScope( false ), hasLockType( false ), - hasDepth( false ), hasHREF( false ), hasTimeout( false ) {} -}; - -} - -#define STATE_TOP (1) - -#define STATE_ACTIVELOCK (STATE_TOP) -#define STATE_LOCKSCOPE (STATE_TOP + 1) -#define STATE_LOCKTYPE (STATE_TOP + 2) -#define STATE_DEPTH (STATE_TOP + 3) -#define STATE_OWNER (STATE_TOP + 4) -#define STATE_TIMEOUT (STATE_TOP + 5) -#define STATE_LOCKTOKEN (STATE_TOP + 6) -#define STATE_EXCLUSIVE (STATE_TOP + 7) -#define STATE_SHARED (STATE_TOP + 8) -#define STATE_WRITE (STATE_TOP + 9) -#define STATE_HREF (STATE_TOP + 10) - - -extern "C" { - -static int LockSequence_startelement_callback( - void *, - int parent, - const char * /*nspace*/, - const char *name, - const char ** ) -{ - if ( name != nullptr ) - { - switch ( parent ) - { - case NE_XML_STATEROOT: - if ( strcmp( name, "activelock" ) == 0 ) - return STATE_ACTIVELOCK; - break; - - case STATE_ACTIVELOCK: - if ( strcmp( name, "lockscope" ) == 0 ) - return STATE_LOCKSCOPE; - else if ( strcmp( name, "locktype" ) == 0 ) - return STATE_LOCKTYPE; - else if ( strcmp( name, "depth" ) == 0 ) - return STATE_DEPTH; - else if ( strcmp( name, "owner" ) == 0 ) - return STATE_OWNER; - else if ( strcmp( name, "timeout" ) == 0 ) - return STATE_TIMEOUT; - else if ( strcmp( name, "locktoken" ) == 0 ) - return STATE_LOCKTOKEN; - break; - - case STATE_LOCKSCOPE: - if ( strcmp( name, "exclusive" ) == 0 ) - return STATE_EXCLUSIVE; - else if ( strcmp( name, "shared" ) == 0 ) - return STATE_SHARED; - break; - - case STATE_LOCKTYPE: - if ( strcmp( name, "write" ) == 0 ) - return STATE_WRITE; - break; - - case STATE_LOCKTOKEN: - if ( strcmp( name, "href" ) == 0 ) - return STATE_HREF; - break; - - case STATE_OWNER: - // owner elem contains ANY. Accept anything; no state change. - return STATE_OWNER; - } - } - return NE_XML_DECLINE; -} - - -static int LockSequence_chardata_callback( - void *userdata, - int state, - const char *buf, - size_t len ) -{ - LockSequenceParseContext * pCtx - = static_cast< LockSequenceParseContext * >( userdata ); - if ( !pCtx->pLock ) - pCtx->pLock.reset( new ucb::Lock ); - - // Beehive sends XML values containing trailing newlines. - if ( buf[ len - 1 ] == 0x0a ) - len--; - - switch ( state ) - { - case STATE_DEPTH: - if ( rtl_str_compareIgnoreAsciiCase_WithLength( - buf, len, "0", 1 ) == 0 ) - { - pCtx->pLock->Depth = ucb::LockDepth_ZERO; - pCtx->hasDepth = true; - } - else if ( rtl_str_compareIgnoreAsciiCase_WithLength( - buf, len, "1", 1 ) == 0 ) - { - pCtx->pLock->Depth = ucb::LockDepth_ONE; - pCtx->hasDepth = true; - } - else if ( rtl_str_compareIgnoreAsciiCase_WithLength( - buf, len, "infinity", 8 ) == 0 ) - { - pCtx->pLock->Depth = ucb::LockDepth_INFINITY; - pCtx->hasDepth = true; - } - else - SAL_WARN( "ucb.ucp.webdav", "LockSequence_chardata_callback - Unknown depth!" ); - break; - - case STATE_OWNER: - { - // collect raw XML data... (owner contains ANY) - OUString aValue; - pCtx->pLock->Owner >>= aValue; - aValue += OUString( buf, len, RTL_TEXTENCODING_ASCII_US ); - pCtx->pLock->Owner <<= aValue; - break; - } - - case STATE_TIMEOUT: - - // RFC2518, RFC2616: - - // TimeType = ("Second-" DAVTimeOutVal | "Infinite" | Other) - // DAVTimeOutVal = 1*digit - // Other = "Extend" field-value - // field-value = *( field-content | LWS ) - // field-content = <the OCTETs making up the field-value - // and consisting of either *TEXT or combinations - // of token, separators, and quoted-string> - // - // RFC4918, <http://tools.ietf.org/html/rfc4918#section-10.7> - // "The timeout value for TimeType "Second" MUST - // NOT be greater than 2^32-1." - - if ( rtl_str_compareIgnoreAsciiCase_WithLength( - buf, len, "Infinite", 8 ) == 0 ) - { - pCtx->pLock->Timeout = sal_Int64( -1 ); - pCtx->hasTimeout = true; - } - else if ( rtl_str_shortenedCompareIgnoreAsciiCase_WithLength( - buf, len, "Second-", 7, 7 ) == 0 ) - { - pCtx->pLock->Timeout - = OString( buf + 7, len - 7 ).toInt64(); - pCtx->hasTimeout = true; - } -// else if ( rtl_str_shortenedCompareIgnoreCase_WithLength( -// buf, len, "Extend", 6, 6 ) == 0 ) -// { -// @@@ -// } - else - { - pCtx->pLock->Timeout = sal_Int64( -1 ); - pCtx->hasTimeout = true; - SAL_WARN( "ucb.ucp.webdav", "LockSequence_chardata_callback - Unknown timeout!" ); - } - break; - - case STATE_HREF: - { - // collect hrefs. - sal_Int32 nPos = pCtx->pLock->LockTokens.getLength(); - pCtx->pLock->LockTokens.realloc( nPos + 1 ); - pCtx->pLock->LockTokens.getArray()[ nPos ] - = OUString( buf, len, RTL_TEXTENCODING_ASCII_US ); - pCtx->hasHREF = true; - break; - } - - } - - return 0; // zero to continue, non-zero to abort parsing -} - - -static int LockSequence_endelement_callback( - void *userdata, - int state, - const char *, - const char * ) -{ - LockSequenceParseContext * pCtx - = static_cast< LockSequenceParseContext * >( userdata ); - if ( !pCtx->pLock ) - pCtx->pLock.reset( new ucb::Lock ); - - switch ( state ) - { - case STATE_EXCLUSIVE: - pCtx->pLock->Scope = ucb::LockScope_EXCLUSIVE; - pCtx->hasLockScope = true; - break; - - case STATE_SHARED: - pCtx->pLock->Scope = ucb::LockScope_SHARED; - pCtx->hasLockScope = true; - break; - - case STATE_WRITE: - pCtx->pLock->Type = ucb::LockType_WRITE; - pCtx->hasLockType = true; - break; - - case STATE_DEPTH: - if ( !pCtx->hasDepth ) - return 1; // abort - break; - - case STATE_HREF: - if ( !pCtx->hasHREF ) - return 1; // abort - break; - - case STATE_TIMEOUT: - if ( !pCtx->hasTimeout ) - return 1; // abort - break; - - case STATE_LOCKSCOPE: - if ( !pCtx->hasLockScope ) - return 1; // abort - break; - - case STATE_LOCKTYPE: - if ( !pCtx->hasLockType ) - return 1; // abort - break; - - case STATE_ACTIVELOCK: - if ( !pCtx->hasLockType || !pCtx->hasDepth ) - return 1; // abort - break; - - default: - break; - } - return 0; // zero to continue, non-zero to abort parsing -} - -} - -// static -bool LockSequence::createFromXML( const OString & rInData, - uno::Sequence< ucb::Lock > & rOutData ) -{ - const sal_Int32 TOKEN_LENGTH = 13; // </activelock> - bool success = true; - - // rInData may contain multiple <activelock>...</activelock> tags. - sal_Int32 nCount = 0; - sal_Int32 nStart = 0; - sal_Int32 nEnd = rInData.indexOf( "</activelock>" ); - while ( nEnd > -1 ) - { - ne_xml_parser * parser = ne_xml_create(); - if ( !parser ) - { - success = false; - break; - } - - LockSequenceParseContext aCtx; - ne_xml_push_handler( parser, - LockSequence_startelement_callback, - LockSequence_chardata_callback, - LockSequence_endelement_callback, - &aCtx ); - - ne_xml_parse( parser, - rInData.getStr() + nStart, - nEnd - nStart + TOKEN_LENGTH ); - - success = !ne_xml_failed( parser ); - - ne_xml_destroy( parser ); - - if ( !success ) - break; - - if ( aCtx.pLock ) - { - nCount++; - if ( nCount > rOutData.getLength() ) - rOutData.realloc( rOutData.getLength() + 1 ); - - rOutData.getArray()[ nCount - 1 ] = *aCtx.pLock; - } - - nStart = nEnd + TOKEN_LENGTH; - nEnd = rInData.indexOf( "</activelock>", nStart ); - } - - return success; -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/ucb/source/ucp/webdav-neon/LockSequence.hxx b/ucb/source/ucp/webdav-neon/LockSequence.hxx deleted file mode 100644 index dc14064410f3..000000000000 --- a/ucb/source/ucp/webdav-neon/LockSequence.hxx +++ /dev/null @@ -1,48 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -#pragma once - -#include <config_lgpl.h> -#include <rtl/string.hxx> -#include <com/sun/star/uno/Sequence.hxx> -#include <com/sun/star/ucb/Lock.hpp> - -namespace webdav_ucp -{ - -class LockSequence -{ -public: - static bool createFromXML( const OString & rInData, - css::uno::Sequence< css::ucb::Lock > & rOutData ); -}; - -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/ucb/source/ucp/webdav-neon/NeonHeadRequest.cxx b/ucb/source/ucp/webdav-neon/NeonHeadRequest.cxx deleted file mode 100644 index 68f24f440d94..000000000000 --- a/ucb/source/ucp/webdav-neon/NeonHeadRequest.cxx +++ /dev/null @@ -1,139 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -#include <osl/mutex.hxx> -#include <sal/log.hxx> -#include "NeonHeadRequest.hxx" -#include "NeonSession.hxx" - -using namespace webdav_ucp; -using namespace com::sun::star; - -namespace { - -void process_headers( ne_request * req, - DAVResource & rResource, - const std::vector< OUString > & rHeaderNames ) -{ - void * cursor = nullptr; - const char * name, *value; - -#if defined SAL_LOG_INFO - { - for ( const auto& rHeader : rHeaderNames ) - { - SAL_INFO( "ucb.ucp.webdav", "HEAD - requested header: " << rHeader ); - } - } -#endif - while ( ( cursor = ne_response_header_iterate( req, cursor, - &name, &value ) ) != nullptr ) { - // The HTTP header `field-name` must be a `token`, which can only contain a subset of ASCII; - // assume that Neon will already have rejected any invalid data, so that it is guaranteed - // that `name` is ASCII-only: - OUString aHeaderName( OUString::createFromAscii( name ) ); - // The HTTP header `field-value` may contain obsolete (as per RFC 7230) `obs-text` non-ASCII - // %x80-FF octets, lets preserve them as individual characters in `aHeaderValue` by treating - // `value` as ISO 8859-1: - OUString aHeaderValue(value, strlen(value), RTL_TEXTENCODING_ISO_8859_1); - - SAL_INFO( "ucb.ucp.webdav", "HEAD - received header: " << aHeaderName << ":" << aHeaderValue); - - // Note: Empty vector means that all headers are requested. - bool bIncludeIt = rHeaderNames.empty(); - - if ( !bIncludeIt ) - { - // Check whether this header was requested. - auto it = std::find_if(rHeaderNames.begin(), rHeaderNames.end(), - [&aHeaderName](const OUString& rName) { - // header names are case insensitive - return rName.equalsIgnoreAsciiCase( aHeaderName ); - }); - - if ( it != rHeaderNames.end() ) - { - aHeaderName = *it; - bIncludeIt = true; - } - } - - if ( bIncludeIt ) - { - // Create & set the PropertyValue - DAVPropertyValue thePropertyValue; - // header names are case insensitive, so are the - // corresponding property names - thePropertyValue.Name = aHeaderName.toAsciiLowerCase(); - thePropertyValue.IsCaseSensitive = false; - thePropertyValue.Value <<= aHeaderValue; - - // Add the newly created PropertyValue - rResource.properties.push_back( thePropertyValue ); - } - } -} - -} // namespace - -NeonHeadRequest::NeonHeadRequest( HttpSession * inSession, - const OUString & inPath, - const std::vector< OUString > & - inHeaderNames, - DAVResource & ioResource, - int & nError ) -{ - ioResource.uri = inPath; - ioResource.properties.clear(); - - // Create and dispatch HEAD request. Install catcher for all response - // header fields. - ne_request * req = ne_request_create( inSession, - "HEAD", - OUStringToOString( - inPath, - RTL_TEXTENCODING_UTF8 ).getStr() ); - - { - osl::Guard< osl::Mutex > theGlobalGuard(getGlobalNeonMutex()); - nError = ne_request_dispatch( req ); - } - - process_headers( req, ioResource, inHeaderNames ); - - if ( nError == NE_OK && ne_get_status( req )->klass != 2 ) - nError = NE_ERROR; - - ne_request_destroy( req ); -} - -NeonHeadRequest::~NeonHeadRequest() -{ -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/ucb/source/ucp/webdav-neon/NeonHeadRequest.hxx b/ucb/source/ucp/webdav-neon/NeonHeadRequest.hxx deleted file mode 100644 index 943d4138a41d..000000000000 --- a/ucb/source/ucp/webdav-neon/NeonHeadRequest.hxx +++ /dev/null @@ -1,53 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -#pragma once - -#include <config_lgpl.h> -#include <vector> -#include "NeonTypes.hxx" -#include "DAVResource.hxx" - -namespace webdav_ucp -{ - -class NeonHeadRequest -{ -public: - // named / allprop - NeonHeadRequest( HttpSession* inSession, - const OUString & inPath, - const std::vector< OUString > & inHeaderNames, - DAVResource & ioResource, - int & nError ); - ~NeonHeadRequest(); -}; - -} // namespace webdav_ucp - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/ucb/source/ucp/webdav-neon/NeonInputStream.cxx b/ucb/source/ucp/webdav-neon/NeonInputStream.cxx deleted file mode 100644 index 848dc2b81cf8..000000000000 --- a/ucb/source/ucp/webdav-neon/NeonInputStream.cxx +++ /dev/null @@ -1,136 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -#include "NeonInputStream.hxx" - -#include <com/sun/star/lang/IllegalArgumentException.hpp> -#include <cppuhelper/queryinterface.hxx> - -#include <string.h> - -using namespace cppu; -using namespace com::sun::star::io; -using namespace com::sun::star::uno; -using namespace webdav_ucp; - -NeonInputStream::NeonInputStream() -: mLen( 0 ), - mPos( 0 ) -{ -} - -NeonInputStream::~NeonInputStream() -{ -} - -// Allows the caller to add some data to the "end" of the stream -void NeonInputStream::AddToStream( const char * inBuf, sal_Int32 inLen ) -{ - mInputBuffer.realloc( sal::static_int_cast<sal_Int32>(mLen) + inLen ); - memcpy( mInputBuffer.getArray() + mLen, inBuf, inLen ); - mLen += inLen; -} - -Any NeonInputStream::queryInterface( const Type &type ) -{ - Any aRet = ::cppu::queryInterface( type, - static_cast< XInputStream * >( this ), - static_cast< XSeekable * >( this ) ); - return aRet.hasValue() ? aRet : OWeakObject::queryInterface( type ); -} - -// "Reads" the specified number of bytes from the stream -sal_Int32 SAL_CALL NeonInputStream::readBytes( - css::uno::Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead ) -{ - // Work out how much we're actually going to write - sal_Int32 theBytes2Read = nBytesToRead; - sal_Int32 theBytesLeft = sal::static_int_cast<sal_Int32>(mLen - mPos); - if ( theBytes2Read > theBytesLeft ) - theBytes2Read = theBytesLeft; - - // Realloc buffer. - aData.realloc( theBytes2Read ); - - // Write the data - memcpy( - aData.getArray(), mInputBuffer.getConstArray() + mPos, theBytes2Read ); - - // Update our stream position for next time - mPos += theBytes2Read; - - return theBytes2Read; -} - -sal_Int32 SAL_CALL NeonInputStream::readSomeBytes( - css::uno::Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead ) -{ - // Warning: What should this be doing ? - return readBytes( aData, nMaxBytesToRead ); -} - -// Moves the current stream position forward -void SAL_CALL NeonInputStream::skipBytes( sal_Int32 nBytesToSkip ) -{ - mPos += nBytesToSkip; - if ( mPos >= mLen ) - mPos = mLen; -} - -// Returns the number of unread bytes currently remaining on the stream -sal_Int32 SAL_CALL NeonInputStream::available( ) -{ - return std::min<sal_Int64>(SAL_MAX_INT32, mLen - mPos); -} - -void SAL_CALL NeonInputStream::closeInput() -{ -} - -void SAL_CALL NeonInputStream::seek( sal_Int64 location ) -{ - if ( location < 0 ) - throw css::lang::IllegalArgumentException(); - - if ( location > mLen ) - throw css::lang::IllegalArgumentException(); - - mPos = location; -} - -sal_Int64 SAL_CALL NeonInputStream::getPosition() -{ - return mPos; -} - -sal_Int64 SAL_CALL NeonInputStream::getLength() -{ - return mLen; -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/ucb/source/ucp/webdav-neon/NeonInputStream.hxx b/ucb/source/ucp/webdav-neon/NeonInputStream.hxx deleted file mode 100644 index aa685e28335f..000000000000 --- a/ucb/source/ucp/webdav-neon/NeonInputStream.hxx +++ /dev/null @@ -1,95 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ -#pragma once - -#include <config_lgpl.h> -#include <sal/types.h> -#include <cppuhelper/weak.hxx> -#include <com/sun/star/io/XInputStream.hpp> -#include <com/sun/star/io/XSeekable.hpp> - - -namespace webdav_ucp -{ - -// A simple XInputStream implementation provided specifically for use -// by the DAVSession::GET method. -class NeonInputStream : public css::io::XInputStream, - public css::io::XSeekable, - public ::cppu::OWeakObject -{ - private: - css::uno::Sequence< sal_Int8 > mInputBuffer; - sal_Int64 mLen; - sal_Int64 mPos; - - public: - NeonInputStream(); - virtual ~NeonInputStream() override; - - // Add some data to the end of the stream - void AddToStream( const char * inBuf, sal_Int32 inLen ); - - // XInterface - virtual css::uno::Any SAL_CALL queryInterface( const css::uno::Type & type ) override; - - virtual void SAL_CALL acquire() - noexcept override - { OWeakObject::acquire(); } - - virtual void SAL_CALL release() - noexcept override - { OWeakObject::release(); } - - - // XInputStream - virtual sal_Int32 SAL_CALL readBytes( - css::uno::Sequence< sal_Int8 > & aData, - sal_Int32 nBytesToRead ) override; - - virtual sal_Int32 SAL_CALL readSomeBytes( - css::uno::Sequence< sal_Int8 > & aData, - sal_Int32 nMaxBytesToRead ) override; - - virtual void SAL_CALL skipBytes( sal_Int32 nBytesToSkip ) override; - - virtual sal_Int32 SAL_CALL available() override; - - virtual void SAL_CALL closeInput() override; - - // XSeekable - virtual void SAL_CALL seek( sal_Int64 location ) override; - - virtual sal_Int64 SAL_CALL getPosition() override; - - virtual sal_Int64 SAL_CALL getLength() override; -}; - -} // namespace webdav_ucp - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/ucb/source/ucp/webdav-neon/NeonLockStore.cxx b/ucb/source/ucp/webdav-neon/NeonLockStore.cxx deleted file mode 100644 index c00f18627fa0..000000000000 --- a/ucb/source/ucp/webdav-neon/NeonLockStore.cxx +++ /dev/null @@ -1,241 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - - -#include <ne_uri.h> -#include <rtl/ustring.hxx> -#include <osl/time.h> -#include <osl/thread.hxx> -#include <sal/log.hxx> -#include <salhelper/thread.hxx> -#include "NeonSession.hxx" -#include "NeonLockStore.hxx" - -using namespace webdav_ucp; - -namespace webdav_ucp { - -class TickerThread : public salhelper::Thread -{ - bool m_bFinish; - NeonLockStore & m_rLockStore; - -public: - - explicit TickerThread( NeonLockStore & rLockStore ) - : Thread( "NeonTickerThread" ), m_bFinish( false ) - , m_rLockStore( rLockStore ) - { - } - - void finish() { m_bFinish = true; } - -private: - - virtual void execute() override; -}; - -} // namespace webdav_ucp - -void TickerThread::execute() -{ - SAL_INFO( "ucb.ucp.webdav", "TickerThread: start." ); - - // we have to go through the loop more often to be able to finish ~quickly - const int nNth = 25; - - int nCount = nNth; - while ( !m_bFinish ) - { - if (--nCount < 0) - { - m_rLockStore.refreshLocks(); - nCount = nNth; - } - - salhelper::Thread::wait(TimeValue(0, 1000000000 / nNth)); - } - - SAL_INFO( "ucb.ucp.webdav", "TickerThread: stop." ); -} - -NeonLockStore::NeonLockStore() - : m_pNeonLockStore( ne_lockstore_create() ) -{ - /* - * ne_lockstore_create() never returns a NULL; neon calls abort() in case of an out-of-memory - * situation. - * Please see: - * <http://www.webdav.org/neon/doc/html/refneon.html> - * topic title "Memory handling", copied here verbatim: - * - * "neon does not attempt to cope gracefully with an out-of-memory situation; - * instead, by default, the abort function is called to immediately terminate - * the process. An application may register a custom function which will be - * called before abort in such a situation; see ne_oom_callback." - */ -} - -NeonLockStore::~NeonLockStore() -{ - { - osl::ClearableMutexGuard aGuard(m_aMutex); - stopTicker(aGuard); - } // actually no threads should even try to access members now - - // release active locks, if any. - SAL_WARN_IF( !m_aLockInfoMap.empty(), "ucb.ucp.webdav", "NeonLockStore::~NeonLockStore - Releasing active locks!" ); - - for ( auto& rLockInfo : m_aLockInfoMap ) - { - NeonLock * pLock = rLockInfo.first; - rLockInfo.second.xSession->UNLOCK( pLock ); - - ne_lockstore_remove( m_pNeonLockStore, pLock ); - ne_lock_destroy( pLock ); - } - - ne_lockstore_destroy( m_pNeonLockStore ); -} - -void NeonLockStore::startTicker() -{ - osl::MutexGuard aGuard( m_aMutex ); - - if ( !m_pTickerThread.is() ) - { - m_pTickerThread = new TickerThread( *this ); - m_pTickerThread->launch(); - } -} - -void NeonLockStore::stopTicker(osl::ClearableMutexGuard & rGuard) -{ - rtl::Reference<TickerThread> pTickerThread; - - if (m_pTickerThread.is()) - { - m_pTickerThread->finish(); // needs mutex - // the TickerThread may run refreshLocks() at most once after this - pTickerThread = m_pTickerThread; - m_pTickerThread.clear(); - } - - rGuard.clear(); - - if (pTickerThread.is() && pTickerThread->getIdentifier() != osl::Thread::getCurrentIdentifier()) - pTickerThread->join(); // without m_aMutex locked (to prevent deadlock) -} - -void NeonLockStore::registerSession( HttpSession * pHttpSession ) -{ - osl::MutexGuard aGuard( m_aMutex ); - - ne_lockstore_register( m_pNeonLockStore, pHttpSession ); -} - -NeonLock * NeonLockStore::findByUri( std::u16string_view rUri ) -{ - osl::MutexGuard aGuard( m_aMutex ); - - ne_uri aUri; - ne_uri_parse( OUStringToOString( - rUri, RTL_TEXTENCODING_UTF8 ).getStr(), &aUri ); - return ne_lockstore_findbyuri( m_pNeonLockStore, &aUri ); -} - -void NeonLockStore::addLock( NeonLock * pLock, - rtl::Reference< NeonSession > const & xSession, - sal_Int32 nLastChanceToSendRefreshRequest ) -{ - osl::MutexGuard aGuard( m_aMutex ); - - ne_lockstore_add( m_pNeonLockStore, pLock ); - m_aLockInfoMap[ pLock ] - = LockInfo( xSession, nLastChanceToSendRefreshRequest ); - - startTicker(); -} - -void NeonLockStore::removeLock( NeonLock * pLock ) -{ - osl::ClearableMutexGuard aGuard( m_aMutex ); - - m_aLockInfoMap.erase( pLock ); - ne_lockstore_remove( m_pNeonLockStore, pLock ); - - if ( m_aLockInfoMap.empty() ) - stopTicker(aGuard); -} - -void NeonLockStore::removeLockDeferred(NeonLock* pLock) -{ - osl::MutexGuard aGuard(m_aMutex); - - m_aRemoveDeferred.push_back(pLock); -} - -void NeonLockStore::refreshLocks() -{ - osl::MutexGuard aGuard( m_aMutex ); - - for ( auto& rLockInfo : m_aLockInfoMap ) - { - LockInfo & rInfo = rLockInfo.second; - if ( rInfo.nLastChanceToSendRefreshRequest != -1 ) - { - // 30 seconds or less remaining until lock expires? - TimeValue t1; - osl_getSystemTime( &t1 ); - if ( rInfo.nLastChanceToSendRefreshRequest - 30 - <= sal_Int32( t1.Seconds ) ) - { - // refresh the lock. - sal_Int32 nlastChanceToSendRefreshRequest = -1; - if ( rInfo.xSession->LOCK( - rLockInfo.first, - /* out param */ nlastChanceToSendRefreshRequest ) ) - { - rInfo.nLastChanceToSendRefreshRequest - = nlastChanceToSendRefreshRequest; - } - else - { - // refresh failed. stop auto-refresh. - rInfo.nLastChanceToSendRefreshRequest = -1; - } - } - } - } - // removeLock will not need to actually release the lock, because this is run from TickerThread - for (auto pLock : m_aRemoveDeferred) - removeLock(pLock); - m_aRemoveDeferred.clear(); -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/ucb/source/ucp/webdav-neon/NeonLockStore.hxx b/ucb/source/ucp/webdav-neon/NeonLockStore.hxx deleted file mode 100644 index d6e37f4e8d84..000000000000 --- a/ucb/source/ucp/webdav-neon/NeonLockStore.hxx +++ /dev/null @@ -1,97 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ -#pragma once - -#include <config_lgpl.h> -#include <map> -#include <string_view> - -#include <ne_locks.h> - -#include <osl/mutex.hxx> -#include <rtl/ref.hxx> -#include "NeonTypes.hxx" - -namespace webdav_ucp -{ - -class TickerThread; -class NeonSession; - -struct LockInfo -{ - rtl::Reference< NeonSession > xSession; - sal_Int32 nLastChanceToSendRefreshRequest; - - LockInfo() - : nLastChanceToSendRefreshRequest( -1 ) {} - - LockInfo( rtl::Reference< NeonSession > const & _xSession, - sal_Int32 _nLastChanceToSendRefreshRequest ) - : xSession( _xSession ), - nLastChanceToSendRefreshRequest( _nLastChanceToSendRefreshRequest ) {} - -}; - -typedef std::map< NeonLock *, LockInfo > LockInfoMap; - -class NeonLockStore -{ - osl::Mutex m_aMutex; - ne_lock_store * m_pNeonLockStore; - rtl::Reference< TickerThread > m_pTickerThread; - LockInfoMap m_aLockInfoMap; - std::vector<NeonLock*> m_aRemoveDeferred; - -public: - NeonLockStore(); - ~NeonLockStore(); - - void registerSession( HttpSession * pHttpSession ); - - NeonLock * findByUri( std::u16string_view rUri ); - - void addLock( NeonLock * pLock, - rtl::Reference< NeonSession > const & xSession, - // time in seconds since Jan 1 1970 - // -1: infinite lock, no refresh - sal_Int32 nLastChanceToSendRefreshRequest ); - - void removeLock( NeonLock * pLock ); - void removeLockDeferred(NeonLock* pLock); - - void refreshLocks(); - -private: - void startTicker(); - void stopTicker(osl::ClearableMutexGuard & rGuard); -}; - -} // namespace webdav_ucp - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/ucb/source/ucp/webdav-neon/NeonPropFindRequest.cxx b/ucb/source/ucp/webdav-neon/NeonPropFindRequest.cxx deleted file mode 100644 index 83252bf837aa..000000000000 --- a/ucb/source/ucp/webdav-neon/NeonPropFindRequest.cxx +++ /dev/null @@ -1,320 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - - -#include <osl/mutex.hxx> -#include <rtl/strbuf.hxx> -#include <sal/log.hxx> -#include "NeonSession.hxx" -#include "NeonTypes.hxx" -#include "DAVProperties.hxx" -#include "NeonPropFindRequest.hxx" -#include "LinkSequence.hxx" -#include "LockSequence.hxx" -#include "LockEntrySequence.hxx" -#include "UCBDeadPropertyValue.hxx" -#include <memory> - -using namespace com::sun::star::uno; -using namespace com::sun::star::ucb; -using namespace webdav_ucp; - - -namespace -{ - // strip "DAV:" namespace from XML snippets to avoid - // parser error (undeclared namespace) later on. - OString stripDavNamespace( const OString & in ) - { - const OString inXML( in.toAsciiLowerCase() ); - - OStringBuffer buf; - sal_Int32 start = 0; - sal_Int32 end = inXML.indexOf( "dav:" ); - while ( end != -1 ) - { - if ( inXML[ end - 1 ] == '<' || - inXML[ end - 1 ] == '/' ) - { - // copy from original buffer - preserve case. - buf.append( in.subView( start, end - start ) ); - } - else - { - // copy from original buffer - preserve case. - buf.append( in.subView( start, end - start + 4 ) ); - } - start = end + 4; - end = inXML.indexOf( "dav:", start ); - } - buf.append( inXML.subView( start ) ); - - return buf.makeStringAndClear(); - } -} - -extern "C" { - -static int NPFR_propfind_iter( void* userdata, - const NeonPropName* pname, - const char* value, - const HttpStatus* status ) -{ - /* - HTTP Response Status Classes: - - - 1: Informational - Request received, continuing process - - - 2: Success - The action was successfully received, - understood, and accepted - - - 3: Redirection - Further action must be taken in order to - complete the request - - - 4: Client Error - The request contains bad syntax or cannot - be fulfilled - - - 5: Server Error - The server failed to fulfill an apparently - valid request - */ - - if ( status->klass > 2 ) - return 0; // Error getting this property. Go on. - - // Create & set the PropertyValue - DAVPropertyValue thePropertyValue; - thePropertyValue.IsCaseSensitive = true; - - SAL_WARN_IF( !pname->nspace, "ucb.ucp.webdav", "NPFR_propfind_iter - No XML namespace!" ); - - DAVProperties::createUCBPropName( pname->nspace, - pname->name, - thePropertyValue.Name ); - bool bHasValue = false; - if ( DAVProperties::isUCBDeadProperty( *pname ) ) - { - // DAV dead property added by WebDAV UCP? - if ( UCBDeadPropertyValue::createFromXML( - value, thePropertyValue.Value ) ) - { - SAL_WARN_IF( !thePropertyValue.Value.hasValue(), - "ucb.ucp.webdav", "NPFR_propfind_iter - No value for UCBDeadProperty!" ); - bHasValue = true; - } - } - - if ( !bHasValue ) - { - if ( rtl_str_compareIgnoreAsciiCase( - pname->name, "resourcetype" ) == 0 ) - { - OString aValue( value ); - aValue = aValue.trim(); // #107358# remove leading/trailing spaces - if ( !aValue.isEmpty() ) - { - aValue = stripDavNamespace( aValue ).toAsciiLowerCase(); - if ( aValue.startsWith("<collection") ) - { - thePropertyValue.Value - <<= OUString("collection"); - } - } - - if ( !thePropertyValue.Value.hasValue() ) - { - // Take over the value exactly as supplied by the server. - thePropertyValue.Value <<= OUString::createFromAscii( value ); - } - } - else if ( rtl_str_compareIgnoreAsciiCase( - pname->name, "supportedlock" ) == 0 ) - { - Sequence< LockEntry > aEntries; - LockEntrySequence::createFromXML( - stripDavNamespace( value ), aEntries ); - thePropertyValue.Value <<= aEntries; - } - else if ( rtl_str_compareIgnoreAsciiCase( - pname->name, "lockdiscovery" ) == 0 ) - { - Sequence< Lock > aLocks; - LockSequence::createFromXML( - stripDavNamespace( value ), aLocks ); - thePropertyValue.Value <<= aLocks; - } - else if ( rtl_str_compareIgnoreAsciiCase( pname->name, "source" ) == 0 ) - { - Sequence< Link > aLinks; - LinkSequence::createFromXML( - stripDavNamespace( value ), aLinks ); - thePropertyValue.Value <<= aLinks; - } - else - { - thePropertyValue.Value - <<= OStringToOUString( value, RTL_TEXTENCODING_UTF8 ); - } - } - - // Add the newly created PropertyValue - DAVResource* theResource = static_cast< DAVResource * >( userdata ); - theResource->properties.push_back( thePropertyValue ); - - return 0; // Go on. -} - -static void NPFR_propfind_results( void* userdata, - const ne_uri* uri, - const NeonPropFindResultSet* set ) -{ - // @@@ href is not the uri! DAVResource ctor wants uri! - - DAVResource theResource( - OStringToOUString( uri->path, RTL_TEXTENCODING_UTF8 ) ); - - ne_propset_iterate( set, NPFR_propfind_iter, &theResource ); - - // Add entry to resources list. - std::vector< DAVResource > * theResources - = static_cast< std::vector< DAVResource > * >( userdata ); - theResources->push_back( theResource ); -} - -static int NPFR_propnames_iter( void* userdata, - const NeonPropName* pname, - const char* /*value*/, - const HttpStatus* /*status*/ ) -{ - OUString aFullName; - DAVProperties::createUCBPropName( pname->nspace, - pname->name, - aFullName ); - - DAVResourceInfo* theResource = static_cast< DAVResourceInfo * >( userdata ); - theResource->properties.push_back( aFullName ); - return 0; -} - -static void NPFR_propnames_results( void* userdata, - const ne_uri* /*uri*/, - const NeonPropFindResultSet* results ) -{ - // @@@ href is not the uri! DAVResourceInfo ctor wants uri! - // Create entry for the resource. - DAVResourceInfo theResource; - - // Fill entry. - ne_propset_iterate( results, NPFR_propnames_iter, &theResource ); - - // Add entry to resources list. - std::vector< DAVResourceInfo > * theResources - = static_cast< std::vector< DAVResourceInfo > * >( userdata ); - theResources->push_back( theResource ); -} - -} - -NeonPropFindRequest::NeonPropFindRequest( HttpSession* inSession, - const char* inPath, - const Depth inDepth, - const std::vector< OUString >& inPropNames, - std::vector< DAVResource >& ioResources, - int & nError ) -{ - // Generate the list of properties we're looking for - int thePropCount = inPropNames.size(); - if ( thePropCount > 0 ) - { - std::unique_ptr<NeonPropName[]> thePropNames(new NeonPropName[ thePropCount + 1 ]); - int theIndex; - - for ( theIndex = 0; theIndex < thePropCount; theIndex ++ ) - { - // Split fullname into namespace and name! - DAVProperties::createNeonPropName( - inPropNames[ theIndex ], thePropNames[ theIndex ] ); - } - thePropNames[ theIndex ].nspace = nullptr; - thePropNames[ theIndex ].name = nullptr; - - { - osl::Guard< osl::Mutex > theGlobalGuard(getGlobalNeonMutex()); - nError = ne_simple_propfind( inSession, - inPath, - inDepth, - thePropNames.get(), - NPFR_propfind_results, - &ioResources ); - } - - for ( theIndex = 0; theIndex < thePropCount; theIndex ++ ) - free( const_cast<char *>(thePropNames[ theIndex ].name) ); - } - else - { - // ALLPROP - osl::Guard< osl::Mutex > theGlobalGuard(getGlobalNeonMutex()); - nError = ne_simple_propfind( inSession, - inPath, - inDepth, - nullptr, // 0 == allprop - NPFR_propfind_results, - &ioResources ); - } - - // #87585# - Sometimes neon lies (because some servers lie). - if ( ( nError == NE_OK ) && ioResources.empty() ) - nError = NE_ERROR; -} - -NeonPropFindRequest::NeonPropFindRequest( - HttpSession* inSession, - const char* inPath, - const Depth inDepth, - std::vector< DAVResourceInfo > & ioResInfo, - int & nError ) -{ - { - osl::Guard< osl::Mutex > theGlobalGuard(getGlobalNeonMutex()); - nError = ne_propnames( inSession, - inPath, - inDepth, - NPFR_propnames_results, - &ioResInfo ); - } - - // #87585# - Sometimes neon lies (because some servers lie). - if ( ( nError == NE_OK ) && ioResInfo.empty() ) - nError = NE_ERROR; -} - -NeonPropFindRequest::~NeonPropFindRequest( ) -{ -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/ucb/source/ucp/webdav-neon/NeonPropFindRequest.hxx b/ucb/source/ucp/webdav-neon/NeonPropFindRequest.hxx deleted file mode 100644 index b1a2d2b69b16..000000000000 --- a/ucb/source/ucp/webdav-neon/NeonPropFindRequest.hxx +++ /dev/null @@ -1,63 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -#pragma once - -#include <config_lgpl.h> -#include <vector> -#include <rtl/ustring.hxx> -#include "NeonTypes.hxx" -#include "DAVTypes.hxx" -#include "DAVResource.hxx" - -namespace webdav_ucp -{ - -class NeonPropFindRequest -{ -public: - // named / allprop - NeonPropFindRequest( HttpSession* inSession, - const char* inPath, - const Depth inDepth, - const std::vector< OUString > & inPropNames, - std::vector< DAVResource > & ioResources, - int & nError ); - // propnames - NeonPropFindRequest( HttpSession* inSession, - const char* inPath, - const Depth inDepth, - std::vector< DAVResourceInfo > & ioResInfo, - int & nError ); - - ~NeonPropFindRequest(); -}; - -} // namespace webdav_ucp - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/ucb/source/ucp/webdav-neon/NeonSession.cxx b/ucb/source/ucp/webdav-neon/NeonSession.cxx deleted file mode 100644 index f08e41a4646f..000000000000 --- a/ucb/source/ucp/webdav-neon/NeonSession.cxx +++ /dev/null @@ -1,2359 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - - -#include <unordered_map> -#include <vector> -#include <string.h> -#include <sal/log.hxx> -#include <osl/diagnose.h> -#include <osl/thread.h> -#include <osl/time.h> -#include <ne_socket.h> -#include <ne_auth.h> -#include <ne_redirect.h> -#include <ne_ssl.h> - -// old neon versions forgot to set this -extern "C" { -#include <ne_compress.h> -} - -#include <libxml/parser.h> -#include <comphelper/sequence.hxx> -#include <ucbhelper/simplecertificatevalidationrequest.hxx> - -#include "DAVAuthListener.hxx" -#include "NeonTypes.hxx" -#include "NeonSession.hxx" -#include "NeonInputStream.hxx" -#include "NeonPropFindRequest.hxx" -#include "NeonHeadRequest.hxx" -#include "NeonUri.hxx" -#include "LinkSequence.hxx" -#include "UCBDeadPropertyValue.hxx" - -#include <officecfg/Inet.hxx> -#include <com/sun/star/io/BufferSizeExceededException.hpp> -#include <com/sun/star/io/IOException.hpp> -#include <com/sun/star/io/NotConnectedException.hpp> -#include <com/sun/star/xml/crypto/XSecurityEnvironment.hpp> -#include <com/sun/star/security/XCertificate.hpp> -#include <com/sun/star/security/CertificateValidity.hpp> -#include <com/sun/star/security/CertificateContainerStatus.hpp> -#include <com/sun/star/security/CertificateContainer.hpp> -#include <com/sun/star/security/XCertificateContainer.hpp> -#include <com/sun/star/ucb/Lock.hpp> -#include <com/sun/star/beans/NamedValue.hpp> -#include <com/sun/star/xml/crypto/SEInitializer.hpp> - - -using namespace com::sun::star; -using namespace webdav_ucp; - -#ifndef EOL -# define EOL "\r\n" -#endif - -namespace { - -struct RequestData -{ - // POST - OUString aContentType; - OUString aReferer; - - RequestData() {} - RequestData( const OUString & rContentType, - const OUString & rReferer ) - : aContentType( rContentType ), aReferer( rReferer ) {} -}; - -struct equalPtr -{ - bool operator()( const ne_request* p1, const ne_request* p2 ) const - { - return p1 == p2; - } -}; - -struct hashPtr -{ - size_t operator()( const ne_request* p ) const - { - return reinterpret_cast<size_t>(p); - } -}; - -} - -typedef std::unordered_map -< - ne_request*, - RequestData, - hashPtr, - equalPtr -> -RequestDataMap; - -static sal_uInt16 makeStatusCode( const OUString & rStatusText ) -{ - // Extract status code from session error string. Unfortunately - // neon provides no direct access to the status code... - - if ( rStatusText.getLength() < 3 ) - { - SAL_WARN( "ucb.ucp.webdav", "makeStatusCode - status text string to short!" ); - return 0; - } - - sal_Int32 nPos = rStatusText.indexOf( ' ' ); - if ( nPos == -1 ) - { - SAL_WARN( "ucb.ucp.webdav", "makeStatusCode - wrong status text format!" ); - return 0; - } - - return sal_uInt16( rStatusText.copy( 0, nPos ).toInt32() ); -} - -static bool noKeepAlive( const uno::Sequence< beans::NamedValue >& rFlags ) -{ - if ( !rFlags.hasElements() ) - return false; - - // find "KeepAlive" property - const beans::NamedValue* pValue( - std::find_if(rFlags.begin(), rFlags.end(), - [] (beans::NamedValue const& rNV) { return rNV.Name == "KeepAlive"; } )); - return pValue != rFlags.end() && !pValue->Value.get<bool>(); -} - -namespace { - -struct NeonRequestContext -{ - uno::Reference< io::XOutputStream > xOutputStream; - rtl::Reference< NeonInputStream > xInputStream; - const std::vector< OUString > * pHeaderNames; - DAVResource * pResource; - - explicit NeonRequestContext( uno::Reference< io::XOutputStream > const & xOutStrm ) - : xOutputStream( xOutStrm ), - pHeaderNames( nullptr ), pResource( nullptr ) {} - - explicit NeonRequestContext( const rtl::Reference< NeonInputStream > & xInStrm ) - : xInputStream( xInStrm ), - pHeaderNames( nullptr ), pResource( nullptr ) {} - - NeonRequestContext( uno::Reference< io::XOutputStream > const & xOutStrm, - const std::vector< OUString > & inHeaderNames, - DAVResource & ioResource ) - : xOutputStream( xOutStrm ), - pHeaderNames( &inHeaderNames ), pResource( &ioResource ) {} - - NeonRequestContext( const rtl::Reference< NeonInputStream > & xInStrm, - const std::vector< OUString > & inHeaderNames, - DAVResource & ioResource ) - : xInputStream( xInStrm ), - pHeaderNames( &inHeaderNames ), pResource( &ioResource ) {} - - void ResponseBlockReader(const char * inBuf, size_t inLen) - { - if (xInputStream.is()) - xInputStream->AddToStream( inBuf, inLen ); - } - - void ResponseBlockWriter(const char * inBuf, size_t inLen) - { - if (xOutputStream.is()) - { - const uno::Sequence< sal_Int8 > aSeq( reinterpret_cast<sal_Int8 const *>(inBuf), inLen ); - xOutputStream->writeBytes( aSeq ); - } - } - -}; - -} - -// A simple Neon response_block_reader for use with an XInputStream -extern "C" { - -static int NeonSession_ResponseBlockReader(void * inUserData, - const char * inBuf, - size_t inLen ) -{ - // neon sometimes calls this function with (inLen == 0)... - if ( inLen > 0 ) - { - NeonRequestContext * pCtx = static_cast<NeonRequestContext*>(inUserData); - pCtx->ResponseBlockReader(inBuf, inLen); - } - return 0; -} - -// A simple Neon response_block_reader for use with an XOutputStream -static int NeonSession_ResponseBlockWriter( void * inUserData, - const char * inBuf, - size_t inLen ) -{ - // neon calls this function with (inLen == 0)... - if ( inLen > 0 ) - { - NeonRequestContext * pCtx = static_cast<NeonRequestContext*>(inUserData); - pCtx->ResponseBlockWriter(inBuf, inLen); - } - return 0; -} - -static int NeonSession_NeonAuth( void * inUserData, -#if defined NE_FEATURE_SSPI && ! defined SYSTEM_NEON - const char * inAuthProtocol, -#endif - const char * inRealm, - int attempt, - char * inoutUserName, - char * inoutPassWord ) -{ -/* The callback used to request the username and password in the given - * realm. The username and password must be copied into the buffers - * which are both of size NE_ABUFSIZ. The 'attempt' parameter is zero - * on the first call to the callback, and increases by one each time - * an attempt to authenticate fails. - * - * The callback must return zero to indicate that authentication - * should be attempted with the username/password, or non-zero to - * cancel the request. (if non-zero, username and password are - * ignored.) */ - - NeonSession * theSession = static_cast<NeonSession*>(inUserData); - const char * pAuthProtocol; -#if defined NE_FEATURE_SSPI && ! defined SYSTEM_NEON - pAuthProtocol = inAuthProtocol; -#else - pAuthProtocol = nullptr; -#endif - return theSession->NeonAuth(pAuthProtocol, inRealm, attempt, inoutUserName, inoutPassWord); -} - -} - -int NeonSession::NeonAuth(const char* inAuthProtocol, const char* inRealm, - int attempt, char* inoutUserName, char * inoutPassWord) -{ - osl::Guard< osl::Mutex > theGuard( m_aMutex ); - -/* The callback used to request the username and password in the given - * realm. The username and password must be copied into the buffers - * which are both of size NE_ABUFSIZ. The 'attempt' parameter is zero - * on the first call to the callback, and increases by one each time - * an attempt to authenticate fails. - * - * The callback must return zero to indicate that authentication - * should be attempted with the username/password, or non-zero to - * cancel the request. (if non-zero, username and password are - * ignored.) */ - - DAVAuthListener * pListener - = getRequestEnvironment().m_xAuthListener.get(); - if ( !pListener ) - { - // abort - return -1; - } - OUString theUserName; - OUString thePassWord; - - if ( attempt == 0 ) - { - // neon does not handle username supplied with request URI (for - // instance when doing FTP over proxy - last checked: 0.23.5 ) - - try - { - NeonUri uri( getRequestEnvironment().m_aRequestURI ); - const OUString& aUserInfo( uri.GetUserInfo() ); - if ( !aUserInfo.isEmpty() ) - { - sal_Int32 nPos = aUserInfo.indexOf( '@' ); - if ( nPos == -1 ) - { - theUserName = aUserInfo; - } - else - { - theUserName = aUserInfo.copy( 0, nPos ); - thePassWord = aUserInfo.copy( nPos + 1 ); - } - } - } - catch ( DAVException const & ) - { - // abort - return -1; - } - } - else - { - // username buffer is prefilled with user name from last attempt. - theUserName = OUString::createFromAscii( inoutUserName ); - // @@@ Neon does not initialize password buffer (last checked: 0.22.0). - //thePassWord = OUString::createFromAscii( inoutPassWord ); - } - -#if defined NE_FEATURE_SSPI && ! defined SYSTEM_NEON - const bool bCanUseSystemCreds - = (attempt == 0) && // avoid endless loops - ne_has_support( NE_FEATURE_SSPI ) && // Windows-only feature. - ( ( ne_strcasecmp( inAuthProtocol, "NTLM" ) == 0 ) || - ( ne_strcasecmp( inAuthProtocol, "Negotiate" ) == 0 ) ); -#else - (void)inAuthProtocol; - const bool bCanUseSystemCreds = false; -#endif - - int theRetVal = pListener->authenticate( - OUString::createFromAscii( inRealm ), - getHostName(), - theUserName, - thePassWord, - bCanUseSystemCreds); - - OString aUser( OUStringToOString( theUserName, RTL_TEXTENCODING_UTF8 ) ); - if ( aUser.getLength() > ( NE_ABUFSIZ - 1 ) ) - { - SAL_WARN( "ucb.ucp.webdav", "NeonSession_NeonAuth - username too long!" ); - return -1; - } - - OString aPass( OUStringToOString( thePassWord, RTL_TEXTENCODING_UTF8 ) ); - if ( aPass.getLength() > ( NE_ABUFSIZ - 1 ) ) - { - SAL_WARN( "ucb.ucp.webdav", "NeonSession_NeonAuth - password too long!" ); - return -1; - } - - // #100211# - checked - strcpy( inoutUserName, aUser.getStr() ); - strcpy( inoutPassWord, aPass.getStr() ); - - return theRetVal; -} - -namespace { - OUString GetHostnamePart( const OUString& _rRawString ) - { - OUString sPart; - OUString sPartId("CN="); - sal_Int32 nContStart = _rRawString.indexOf( sPartId ); - if ( nContStart != -1 ) - { - nContStart += sPartId.getLength(); - sal_Int32 nContEnd = _rRawString.indexOf( ',', nContStart ); - sPart = nContEnd != -1 ? - _rRawString.copy(nContStart, nContEnd - nContStart) : - _rRawString.copy(nContStart); - } - return sPart; - } -} // namespace - -extern "C" { - -static int NeonSession_CertificationNotify( void *userdata, - int, - const ne_ssl_certificate *cert ) -{ - NeonSession * pSession = static_cast< NeonSession * >( userdata ); - return pSession->CertificationNotify(cert); -} - -} - -int NeonSession::CertificationNotify(const ne_ssl_certificate *cert) -{ - osl::Guard< osl::Mutex > theGuard( m_aMutex ); - - OSL_ASSERT( cert ); - - uno::Reference< security::XCertificateContainer > xCertificateContainer; - try - { - xCertificateContainer = security::CertificateContainer::create( getComponentContext() ); - } - catch ( uno::Exception const & ) - { - } - - if ( !xCertificateContainer.is() ) - return 1; - - char * dn = ne_ssl_readable_dname( ne_ssl_cert_subject( cert ) ); - OUString cert_subject( dn, strlen( dn ), RTL_TEXTENCODING_UTF8, 0 ); - - ne_free( dn ); - - security::CertificateContainerStatus certificateContainer( - xCertificateContainer->hasCertificate( - getHostName(), cert_subject ) ); - - if ( certificateContainer != security::CertificateContainerStatus_NOCERT ) - return - certificateContainer == security::CertificateContainerStatus_TRUSTED - ? 0 - : 1; - - uno::Reference< xml::crypto::XSEInitializer > xSEInitializer; - try - { - xSEInitializer = xml::crypto::SEInitializer::create( getComponentContext() ); - } - catch ( uno::Exception const & ) - { - } - - if ( !xSEInitializer.is() ) - return 1; - - uno::Reference< xml::crypto::XXMLSecurityContext > xSecurityContext( - xSEInitializer->createSecurityContext( OUString() ) ); - - uno::Reference< xml::crypto::XSecurityEnvironment > xSecurityEnv( - xSecurityContext->getSecurityEnvironment() ); - - //The end entity certificate - char * eeCertB64 = ne_ssl_cert_export( cert ); - - OString sEECertB64( eeCertB64 ); - - uno::Reference< security::XCertificate > xEECert( - xSecurityEnv->createCertificateFromAscii( - OStringToOUString( sEECertB64, RTL_TEXTENCODING_ASCII_US ) ) ); - - ne_free( eeCertB64 ); - eeCertB64 = nullptr; - - std::vector< uno::Reference< security::XCertificate > > vecCerts; - const ne_ssl_certificate * issuerCert = cert; - do - { - //get the intermediate certificate - //the returned value is const ! Therefore it does not need to be freed - //with ne_ssl_cert_free, which takes a non-const argument - issuerCert = ne_ssl_cert_signedby( issuerCert ); - if ( nullptr == issuerCert ) - break; - - char * imCertB64 = ne_ssl_cert_export( issuerCert ); - OString sInterMediateCertB64( imCertB64 ); - ne_free( imCertB64 ); - - uno::Reference< security::XCertificate> xImCert( - xSecurityEnv->createCertificateFromAscii( - OStringToOUString( sInterMediateCertB64, RTL_TEXTENCODING_ASCII_US ) ) ); - if ( xImCert.is() ) - vecCerts.push_back( xImCert ); - } - while ( true ); - - sal_Int64 certValidity = xSecurityEnv->verifyCertificate( xEECert, - ::comphelper::containerToSequence( vecCerts ) ); - - if ( isDomainMatch( - GetHostnamePart( xEECert->getSubjectName() ) ) ) - { - // if host name matched with certificate then look if the - // certificate was ok - if( certValidity == security::CertificateValidity::VALID ) - return 0; - } - - const uno::Reference< ucb::XCommandEnvironment > xEnv( - getRequestEnvironment().m_xEnv ); - if ( xEnv.is() ) - { - uno::Reference< task::XInteractionHandler > xIH( - xEnv->getInteractionHandler() ); - if ( xIH.is() ) - { - rtl::Reference< ucbhelper::SimpleCertificateValidationRequest > - xRequest( new ucbhelper::SimpleCertificateValidationRequest( - static_cast<sal_Int32>(certValidity), xEECert, getHostName() ) ); - xIH->handle( xRequest ); - - rtl::Reference< ucbhelper::InteractionContinuation > xSelection - = xRequest->getSelection(); - - if ( xSelection.is() ) - { - uno::Reference< task::XInteractionApprove > xApprove( - xSelection.get(), uno::UNO_QUERY ); - if ( xApprove.is() ) - { - xCertificateContainer->addCertificate( - getHostName(), cert_subject, true ); - return 0; - } - else - { - // Don't trust cert - xCertificateContainer->addCertificate( - getHostName(), cert_subject, false ); - return 1; - } - } - } - else - { - // Don't trust cert - xCertificateContainer->addCertificate( - getHostName(), cert_subject, false ); - return 1; - } - } - return 1; -} - -extern "C" { - -static void NeonSession_PreSendRequest( ne_request * req, - void * userdata, - ne_buffer * headers ) -{ - // userdata -> value returned by 'create' - NeonSession * pSession = static_cast< NeonSession * >( userdata ); - if (!pSession) - return; - pSession->PreSendRequest(req, headers); -} - -} - -void NeonSession::PreSendRequest(ne_request* req, ne_buffer* headers) -{ - osl::Guard< osl::Mutex > theGuard( m_aMutex ); - - // If there is a proxy server in between, it shall never use - // cached data. We always want 'up-to-date' data. - ne_buffer_concat( headers, "Pragma: no-cache", EOL, nullptr ); - // alternative, but understood by HTTP 1.1 servers only: - // ne_buffer_concat( headers, "Cache-Control: max-age=0", EOL, NULL ); - - const RequestDataMap * pRequestData - = static_cast< const RequestDataMap* >( - getRequestData() ); - - RequestDataMap::const_iterator it = pRequestData->find( req ); - if ( it != pRequestData->end() ) - { - if ( !(*it).second.aContentType.isEmpty() ) - { - char * pData = headers->data; - if ( strstr( pData, "Content-Type:" ) == nullptr ) - { - OString aType - = OUStringToOString( (*it).second.aContentType, - RTL_TEXTENCODING_UTF8 ); - ne_buffer_concat( headers, "Content-Type: ", - aType.getStr(), EOL, nullptr ); - } - } - - if ( !(*it).second.aReferer.isEmpty() ) - { - char * pData = headers->data; - if ( strstr( pData, "Referer:" ) == nullptr ) - { - OString aReferer - = OUStringToOString( (*it).second.aReferer, - RTL_TEXTENCODING_UTF8 ); - ne_buffer_concat( headers, "Referer: ", - aReferer.getStr(), EOL, nullptr ); - } - } - } - - const DAVRequestHeaders & rHeaders - = getRequestEnvironment().m_aRequestHeaders; - - for ( const auto& rHeader : rHeaders ) - { - OString aHeader - = OUStringToOString( rHeader.first, - RTL_TEXTENCODING_UTF8 ); - OString aValue - = OUStringToOString( rHeader.second, - RTL_TEXTENCODING_UTF8 ); - ne_buffer_concat( headers, aHeader.getStr(), ": ", - aValue.getStr(), EOL, nullptr ); - } -} - -//See https://bugzilla.redhat.com/show_bug.cgi?id=544619#c4 -//neon is threadsafe, but uses gnutls which is only thread-safe -//if initialized to be thread-safe. cups, unfortunately, generally -//initializes it first, and as non-thread-safe, leaving the entire -//stack unsafe -namespace webdav_ucp -{ - osl::Mutex& getGlobalNeonMutex() - { - static osl::Mutex aMutex; - return aMutex; - } -} - -// static members -bool NeonSession::m_bGlobalsInited = false; -NeonLockStore NeonSession::m_aNeonLockStore; - -NeonSession::NeonSession( const rtl::Reference< DAVSessionFactory > & rSessionFactory, - const OUString& inUri, - const uno::Sequence< beans::NamedValue >& rFlags, - const ucbhelper::InternetProxyDecider & rProxyDecider ) - : DAVSession( rSessionFactory ) - , m_nProxyPort( 0 ) - , m_aFlags( rFlags ) - , m_pHttpSession( nullptr ) - , m_pRequestData( new RequestDataMap ) - , m_rProxyDecider( rProxyDecider ) -{ - NeonUri theUri( inUri ); - m_aScheme = theUri.GetScheme(); - m_aHostName = theUri.GetHost(); - m_nPort = theUri.GetPort(); - SAL_INFO( "ucb.ucp.webdav", "NeonSession ctor - URL <" << inUri << ">" ); -} - -NeonSession::~NeonSession( ) -{ - if ( m_pHttpSession ) - { - { - osl::Guard< osl::Mutex > theGlobalGuard(getGlobalNeonMutex()); - ne_session_destroy( m_pHttpSession ); - } - m_pHttpSession = nullptr; - } - delete static_cast< RequestDataMap * >( m_pRequestData ); -} - -void NeonSession::Init( const DAVRequestEnvironment & rEnv ) -{ - osl::Guard< osl::Mutex > theGuard( m_aMutex ); - m_aEnv = rEnv; - Init(); -} - -void NeonSession::Init() -{ - osl::Guard< osl::Mutex > theGuard( m_aMutex ); - - bool bCreateNewSession = m_bNeedNewSession; - m_bNeedNewSession = false; - - if ( m_pHttpSession == nullptr ) - { - // Ensure that Neon sockets are initialized - osl::Guard< osl::Mutex > theGlobalGuard(getGlobalNeonMutex()); - if (!m_bGlobalsInited ) - { - if ( ne_sock_init() != 0 ) - throw DAVException( DAVException::DAV_SESSION_CREATE, - NeonUri::makeConnectionEndPointString( - m_aHostName, m_nPort ) ); - - // #122205# - libxml2 needs to be initialized once if used by - // multithreaded programs like OOo. - xmlInitParser(); -#if OSL_DEBUG_LEVEL > 0 - // for more debug flags see ne_utils.h; NE_DEBUGGING must be defined - // while compiling neon in order to actually activate neon debug - // output. - ne_debug_init( stderr, NE_DBG_FLUSH - | NE_DBG_HTTP - // | NE_DBG_HTTPBODY - // | NE_DBG_HTTPAUTH - // | NE_DBG_XML - // | NE_DBG_XMLPARSE - | NE_DBG_LOCKS - | NE_DBG_SSL - ); -#endif - m_bGlobalsInited = true; - } - - const ucbhelper::InternetProxyServer & rProxyCfg = getProxySettings(); - - m_aProxyName = rProxyCfg.aName; - m_nProxyPort = rProxyCfg.nPort; - - // Not yet initialized. Create new session. - bCreateNewSession = true; - } - else - { - // #112271# Check whether proxy settings are still valid (They may - // change at any time). If not, create new Neon session. - - const ucbhelper::InternetProxyServer & rProxyCfg = getProxySettings(); - - if ( ( rProxyCfg.aName != m_aProxyName ) - || ( rProxyCfg.nPort != m_nProxyPort ) ) - { - m_aProxyName = rProxyCfg.aName; - m_nProxyPort = rProxyCfg.nPort; - - bCreateNewSession = true; - } - - if (bCreateNewSession) - { - // new session needed, destroy old first - { - osl::Guard< osl::Mutex > theGlobalGuard(getGlobalNeonMutex()); - ne_session_destroy( m_pHttpSession ); - } - m_pHttpSession = nullptr; - } - } - - if ( !bCreateNewSession ) - return; - - const sal_Int32 nConnectTimeoutMax = 180; - const sal_Int32 nConnectTimeoutMin = 2; - const sal_Int32 nReadTimeoutMax = 180; - const sal_Int32 nReadTimeoutMin = 20; - - // @@@ For FTP over HTTP proxy inUserInfo is needed to be able to - // build the complete request URI (including user:pass), but - // currently (0.22.0) neon does not allow to pass the user info - // to the session - - { - osl::Guard< osl::Mutex > theGlobalGuard(getGlobalNeonMutex()); - m_pHttpSession = ne_session_create( - OUStringToOString( m_aScheme, RTL_TEXTENCODING_UTF8 ).getStr(), - /* theUri.GetUserInfo(), - @@@ for FTP via HTTP proxy, but not supported by Neon */ - OUStringToOString( m_aHostName, RTL_TEXTENCODING_UTF8 ).getStr(), - m_nPort ); - } - - if ( m_pHttpSession == nullptr ) - throw DAVException( DAVException::DAV_SESSION_CREATE, - NeonUri::makeConnectionEndPointString( - m_aHostName, m_nPort ) ); - - // Register the session with the lock store - m_aNeonLockStore.registerSession( m_pHttpSession ); - - if ( m_aScheme.equalsIgnoreAsciiCase("https") ) - { - // Set a failure callback for certificate check - ne_ssl_set_verify( - m_pHttpSession, NeonSession_CertificationNotify, this); - - // Tell Neon to tell the SSL library used (OpenSSL or - // GnuTLS, I guess) to use a default set of root - // certificates. - ne_ssl_trust_default_ca(m_pHttpSession); - } - - // Add hooks (i.e. for adding additional headers to the request) - ne_hook_pre_send( m_pHttpSession, NeonSession_PreSendRequest, this ); - - if ( !m_aProxyName.isEmpty() ) - { - ne_session_proxy( m_pHttpSession, - OUStringToOString( - m_aProxyName, - RTL_TEXTENCODING_UTF8 ).getStr(), - m_nProxyPort ); - } - - // avoid KeepAlive? - if ( noKeepAlive(m_aFlags) ) - ne_set_session_flag( m_pHttpSession, NE_SESSFLAG_PERSIST, 0 ); - - // Register for redirects. - ne_redirect_register( m_pHttpSession ); - - // authentication callbacks. - ne_add_server_auth( m_pHttpSession, NE_AUTH_ALL, NeonSession_NeonAuth, this ); - ne_add_proxy_auth ( m_pHttpSession, NE_AUTH_ALL, NeonSession_NeonAuth, this ); - - // set timeout to connect - // if connect_timeout is not set, neon returns NE_CONNECT when the TCP socket default - // timeout elapses - // with connect_timeout set neon returns NE_TIMEOUT if elapsed when the connection - // didn't succeed - // grab it from configuration - uno::Reference< uno::XComponentContext > rContext = m_xFactory->getComponentContext(); - - // set the timeout (in seconds) used when making a connection - sal_Int32 nConnectTimeout = officecfg::Inet::Settings::ConnectTimeout::get( rContext ); - ne_set_connect_timeout( m_pHttpSession, - std::max( nConnectTimeoutMin, - std::min( nConnectTimeout, nConnectTimeoutMax ) ) ); - - // provides a read time out facility as well - // set the timeout (in seconds) used when reading from a socket. - sal_Int32 nReadTimeout = officecfg::Inet::Settings::ReadTimeout::get( rContext ); - ne_set_read_timeout( m_pHttpSession, - std::max( nReadTimeoutMin, - std::min( nReadTimeout, nReadTimeoutMax ) ) ); - - ne_set_session_flag(m_pHttpSession, NE_SESSFLAG_SHAREPOINT, 1); -} - -bool NeonSession::CanUse( const OUString & inUri, - const uno::Sequence< beans::NamedValue >& rFlags ) -{ - try - { - NeonUri theUri( inUri ); - if ( ( theUri.GetPort() == m_nPort ) && - ( theUri.GetHost() == m_aHostName ) && - ( theUri.GetScheme() == m_aScheme ) && - ( rFlags == m_aFlags ) ) - return true; - } - catch ( DAVException const & ) - { - return false; - } - return false; -} - -bool NeonSession::UsesProxy() -{ - Init(); - return !m_aProxyName.isEmpty() ; -} - -void NeonSession::OPTIONS( const OUString & inPath, - DAVOptions & rOptions, // contains the name+values of every header - const DAVRequestEnvironment & rEnv ) -{ - osl::Guard< osl::Mutex > theGuard( m_aMutex ); - - SAL_INFO( "ucb.ucp.webdav", "OPTIONS - relative URL <" << inPath << ">" ); - - rOptions.init(); - - Init( rEnv ); - int theRetVal; - - ne_request *req = ne_request_create(m_pHttpSession, "OPTIONS", OUStringToOString( - inPath, RTL_TEXTENCODING_UTF8 ).getStr()); - { - osl::Guard< osl::Mutex > theGlobalGuard(getGlobalNeonMutex()); - theRetVal = ne_request_dispatch(req); - } - - //check if http error is in the 200 class (no error) - if (theRetVal == NE_OK && ne_get_status(req)->klass != 2) { - theRetVal = NE_ERROR; - } - - if ( theRetVal == NE_OK ) - { - void *cursor = nullptr; - const char *name, *value; - while ( ( cursor = ne_response_header_iterate( - req, cursor, &name, &value ) ) != nullptr ) - { - OUString aHeaderName(OUString(name, strlen(name), RTL_TEXTENCODING_ASCII_US).toAsciiLowerCase()); - OUString aHeaderValue(value, strlen(value), RTL_TEXTENCODING_ASCII_US); - - // display the single header - SAL_INFO( "ucb.ucp.webdav", "OPTIONS - received header: " << aHeaderName << ":" << aHeaderValue ); - - if ( aHeaderName == "allow" ) - { - rOptions.setAllowedMethods( aHeaderValue ); - } - else if ( aHeaderName == "dav" ) - { - // check type of dav capability - // need to parse the value, token separator: "," - // see <http://tools.ietf.org/html/rfc4918#section-10.1>, - // <http://tools.ietf.org/html/rfc4918#section-18>, - // and <http://tools.ietf.org/html/rfc7230#section-3.2> - // we detect the class (1, 2 and 3), other elements (token, URL) - // are not used for now - // silly parser written using OUString, not very efficient - // but quick and easy to write... - sal_Int32 nFromIndex = 0; - sal_Int32 nNextIndex = 0; - while( ( nNextIndex = aHeaderValue.indexOf( ",", nFromIndex ) ) != -1 ) - { // found a comma - // try to convert from nFromIndex to nNextIndex -1 in a number - // if this is 1 or 2 or 3, use for class setting - sal_Int32 nClass = - aHeaderValue.copy( nFromIndex, nNextIndex - nFromIndex ).toInt32(); - switch( nClass ) - { - case 1: - rOptions.setClass1(); - break; - case 2: - rOptions.setClass2(); - break; - case 3: - rOptions.setClass3(); - break; - default: - ; - } - // next starting point - nFromIndex = nNextIndex + 1; - } - // check for last fragment - if ( nFromIndex < aHeaderValue.getLength() ) - { - sal_Int32 nClass = aHeaderValue.copy( nFromIndex ).toInt32(); - switch( nClass ) - { - case 1: - rOptions.setClass1(); - break; - case 2: - rOptions.setClass2(); - break; - case 3: - rOptions.setClass3(); - break; - default: - ; - } - } - } - } - // if applicable, check for lock state: - if( rOptions.isClass2() || rOptions.isClass3() ) - { - //dav with lock possible, check for locked state - if ( m_aNeonLockStore.findByUri( - makeAbsoluteURL( inPath ) ) != nullptr ) - { - // we own a lock for this URL, - // set locked state - rOptions.setLocked(); - } - } - } - - ne_request_destroy(req); - - HandleError( theRetVal, inPath, rEnv ); -} - -void NeonSession::PROPFIND( const OUString & inPath, - const Depth inDepth, - const std::vector< OUString > & inPropNames, - std::vector< DAVResource > & ioResources, - const DAVRequestEnvironment & rEnv ) -{ - - osl::Guard< osl::Mutex > theGuard( m_aMutex ); - -#if defined SAL_LOG_INFO - { //debug - SAL_INFO( "ucb.ucp.webdav", "PROPFIND - relative URL: <" << inPath << "> Depth: " << inDepth ); - for(const auto& rPropName : inPropNames) - { - SAL_INFO( "ucb.ucp.webdav", "PROPFIND - property requested: " << rPropName ); - } - } //debug -#endif - - Init( rEnv ); - - int theRetVal = NE_OK; - NeonPropFindRequest theRequest( m_pHttpSession, - OUStringToOString( - inPath, RTL_TEXTENCODING_UTF8 ).getStr(), - inDepth, - inPropNames, - ioResources, - theRetVal ); - - HandleError( theRetVal, inPath, rEnv ); -} - -void NeonSession::PROPFIND( const OUString & inPath, - const Depth inDepth, - std::vector< DAVResourceInfo > & ioResInfo, - const DAVRequestEnvironment & rEnv ) -{ - osl::Guard< osl::Mutex > theGuard( m_aMutex ); - SAL_INFO( "ucb.ucp.webdav", "PROPFIND - relative URL: <" << inPath << "> Depth: " << inDepth ); - - Init( rEnv ); - - int theRetVal = NE_OK; - NeonPropFindRequest theRequest( m_pHttpSession, - OUStringToOString( - inPath, RTL_TEXTENCODING_UTF8 ).getStr(), - inDepth, - ioResInfo, - theRetVal ); - -#if defined SAL_LOG_INFO - { //debug - for ( const auto& rResInfo : ioResInfo ) - { - for ( const auto& rProp : rResInfo.properties ) - { - SAL_INFO( "ucb.ucp.webdav", "PROPFIND - returned property (name only): " << rProp ); - } - } - } //debug -#endif - - HandleError( theRetVal, inPath, rEnv ); -} - -void NeonSession::PROPPATCH( const OUString & inPath, - const std::vector< ProppatchValue > & inValues, - const DAVRequestEnvironment & rEnv ) -{ - SAL_INFO( "ucb.ucp.webdav", "PROPPATCH - relative URL <" << inPath << ">" ); - - /* @@@ Which standard live properties can be set by the client? - This is a known WebDAV RFC issue ( verified: 04/10/2001 ) - --> http://www.ics.uci.edu/pub/ietf/webdav/protocol/issues.html - - mod_dav implementation: - - creationdate r ( File System prop ) - displayname w - getcontentlanguage r ( #ifdef DAV_DISABLE_WRITEABLE_PROPS ) - getcontentlength r ( File System prop ) - getcontenttype r ( #ifdef DAV_DISABLE_WRITEABLE_PROPS ) - getetag r ( File System prop ) - getlastmodified r ( File System prop ) - lockdiscovery r - resourcetype r - source w - supportedlock r - executable w ( #ifndef WIN32 ) - - All dead properties are of course writable. - */ - - int theRetVal = NE_OK; - - int n; // for the "for" loop - - // Generate the list of properties we want to set. - int nPropCount = inValues.size(); - std::unique_ptr<ne_proppatch_operation[]> pItems( - new ne_proppatch_operation[ nPropCount + 1 ]); - for ( n = 0; n < nPropCount; ++n ) - { - const ProppatchValue & rValue = inValues[ n ]; - - // Split fullname into namespace and name! - ne_propname * pName = new ne_propname; - DAVProperties::createNeonPropName( rValue.name, *pName ); - pItems[ n ].name = pName; - - if ( rValue.operation == PROPSET ) - { - pItems[ n ].type = ne_propset; - - OUString aStringValue; - if ( DAVProperties::isUCBDeadProperty( *pName ) ) - { - // DAV dead property added by WebDAV UCP? - if ( !UCBDeadPropertyValue::toXML( rValue.value, - aStringValue ) ) - { - // Error! - pItems[ n ].value = nullptr; - theRetVal = NE_ERROR; - nPropCount = n + 1; - break; - } - } - else if ( !( rValue.value >>= aStringValue ) ) - { - // complex properties... - if ( rValue.name == DAVProperties::SOURCE ) - { - uno::Sequence< ucb::Link > aLinks; - if ( rValue.value >>= aLinks ) - { - LinkSequence::toXML( aLinks, aStringValue ); - } - else - { - // Error! - pItems[ n ].value = nullptr; - theRetVal = NE_ERROR; - nPropCount = n + 1; - break; - } - } - else - { - SAL_WARN( "ucb.ucp.webdav", "PROPPATCH - Unsupported type!" ); - // Error! - pItems[ n ].value = nullptr; - theRetVal = NE_ERROR; - nPropCount = n + 1; - break; - } - } - pItems[ n ].value - = strdup( OUStringToOString( aStringValue, - RTL_TEXTENCODING_UTF8 ).getStr() ); - } - else - { - pItems[ n ].type = ne_propremove; - pItems[ n ].value = nullptr; - } - } - - if ( theRetVal == NE_OK ) - { - osl::Guard< osl::Mutex > theGuard( m_aMutex ); - - Init( rEnv ); - - pItems[ n ].name = nullptr; - - theRetVal = ne_proppatch( m_pHttpSession, - OUStringToOString( - inPath, RTL_TEXTENCODING_UTF8 ).getStr(), - pItems.get() ); - } - - for ( n = 0; n < nPropCount; ++n ) - { - free( const_cast<char *>(pItems[ n ].name->name) ); - delete pItems[ n ].name; - free( const_cast<char *>(pItems[ n ].value) ); - } - - HandleError( theRetVal, inPath, rEnv ); -} - -void NeonSession::HEAD( const OUString & inPath, - const std::vector< OUString > & inHeaderNames, - DAVResource & ioResource, - const DAVRequestEnvironment & rEnv ) -{ - osl::Guard< osl::Mutex > theGuard( m_aMutex ); - SAL_INFO( "ucb.ucp.webdav", "HEAD - relative URL <" << inPath << ">" ); - - Init( rEnv ); - - int theRetVal = NE_OK; - NeonHeadRequest theRequest( m_pHttpSession, - inPath, - inHeaderNames, - ioResource, - theRetVal ); - - HandleError( theRetVal, inPath, rEnv ); -} - -uno::Reference< io::XInputStream > -NeonSession::GET( const OUString & inPath, - const DAVRequestEnvironment & rEnv ) -{ - osl::Guard< osl::Mutex > theGuard( m_aMutex ); - SAL_INFO( "ucb.ucp.webdav", "GET - relative URL <" << inPath << ">" ); - - Init( rEnv ); - - rtl::Reference< NeonInputStream > xInputStream( new NeonInputStream ); - NeonRequestContext aCtx( xInputStream ); - int theRetVal = GET( m_pHttpSession, - OUStringToOString( - inPath, RTL_TEXTENCODING_UTF8 ).getStr(), - NeonSession_ResponseBlockReader, - false, - &aCtx ); - - HandleError( theRetVal, inPath, rEnv ); - - return xInputStream; -} - -void NeonSession::GET( const OUString & inPath, - uno::Reference< io::XOutputStream > & ioOutputStream, - const DAVRequestEnvironment & rEnv ) -{ - osl::Guard< osl::Mutex > theGuard( m_aMutex ); - SAL_INFO( "ucb.ucp.webdav", "GET - relative URL <" << inPath << ">" ); - - Init( rEnv ); - - NeonRequestContext aCtx( ioOutputStream ); - int theRetVal = GET( m_pHttpSession, - OUStringToOString( - inPath, RTL_TEXTENCODING_UTF8 ).getStr(), - NeonSession_ResponseBlockWriter, - false, - &aCtx ); - - HandleError( theRetVal, inPath, rEnv ); -} - -uno::Reference< io::XInputStream > -NeonSession::GET( const OUString & inPath, - const std::vector< OUString > & inHeaderNames, - DAVResource & ioResource, - const DAVRequestEnvironment & rEnv ) -{ - 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 = GET( m_pHttpSession, - OUStringToOString( - inPath, RTL_TEXTENCODING_UTF8 ).getStr(), - NeonSession_ResponseBlockReader, - true, - &aCtx ); - - HandleError( theRetVal, inPath, rEnv ); - - return xInputStream; -} - -void NeonSession::GET0( const OUString & inPath, - const std::vector< OUString > & inHeaderNames, - DAVResource & ioResource, - const DAVRequestEnvironment & rEnv ) -{ - 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, - DAVResource & ioResource, - const DAVRequestEnvironment & rEnv ) -{ - osl::Guard< osl::Mutex > theGuard( m_aMutex ); - SAL_INFO( "ucb.ucp.webdav", "GET - relative URL <" << inPath << ">" ); - - Init( rEnv ); - - ioResource.uri = inPath; - ioResource.properties.clear(); - - NeonRequestContext aCtx( ioOutputStream, inHeaderNames, ioResource ); - int theRetVal = GET( m_pHttpSession, - OUStringToOString( - inPath, RTL_TEXTENCODING_UTF8 ).getStr(), - NeonSession_ResponseBlockWriter, - true, - &aCtx ); - - HandleError( theRetVal, inPath, rEnv ); -} - -void NeonSession::PUT( const OUString & inPath, - const uno::Reference< io::XInputStream > & inInputStream, - const DAVRequestEnvironment & rEnv ) -{ - osl::Guard< osl::Mutex > theGuard( m_aMutex ); - SAL_INFO( "ucb.ucp.webdav", "PUT - relative URL <" << inPath << ">" ); - - uno::Sequence< sal_Int8 > aDataToSend; - if ( !getDataFromInputStream( inInputStream, aDataToSend, false ) ) - throw DAVException( DAVException::DAV_INVALID_ARG ); - - Init( rEnv ); - - int theRetVal = PUT( m_pHttpSession, - OUStringToOString( - inPath, RTL_TEXTENCODING_UTF8 ).getStr(), - reinterpret_cast< const char * >( - aDataToSend.getConstArray() ), - aDataToSend.getLength() ); - - HandleError( theRetVal, inPath, rEnv ); -} - -uno::Reference< io::XInputStream > -NeonSession::POST( const OUString & inPath, - const OUString & rContentType, - const OUString & rReferer, - const uno::Reference< io::XInputStream > & inInputStream, - const DAVRequestEnvironment & rEnv ) -{ - osl::Guard< osl::Mutex > theGuard( m_aMutex ); - SAL_INFO( "ucb.ucp.webdav", "POST - relative URL <" << inPath << ">" ); - - uno::Sequence< sal_Int8 > aDataToSend; - if ( !getDataFromInputStream( inInputStream, aDataToSend, true ) ) - throw DAVException( DAVException::DAV_INVALID_ARG ); - - Init( rEnv ); - - rtl::Reference< NeonInputStream > xInputStream( new NeonInputStream ); - NeonRequestContext aCtx( xInputStream ); - int theRetVal = POST( m_pHttpSession, - OUStringToOString( - inPath, RTL_TEXTENCODING_UTF8 ).getStr(), - reinterpret_cast< const char * >( - aDataToSend.getConstArray() ), - NeonSession_ResponseBlockReader, - &aCtx, - rContentType, - rReferer ); - - HandleError( theRetVal, inPath, rEnv ); - - return xInputStream; -} - -void NeonSession::POST( const OUString & inPath, - const OUString & rContentType, - const OUString & rReferer, - const uno::Reference< io::XInputStream > & inInputStream, - uno::Reference< io::XOutputStream > & oOutputStream, - const DAVRequestEnvironment & rEnv ) -{ - osl::Guard< osl::Mutex > theGuard( m_aMutex ); - SAL_INFO( "ucb.ucp.webdav", "POST - relative URL <" << inPath << ">" ); - - uno::Sequence< sal_Int8 > aDataToSend; - if ( !getDataFromInputStream( inInputStream, aDataToSend, true ) ) - throw DAVException( DAVException::DAV_INVALID_ARG ); - - Init( rEnv ); - - NeonRequestContext aCtx( oOutputStream ); - int theRetVal = POST( m_pHttpSession, - OUStringToOString( - inPath, RTL_TEXTENCODING_UTF8 ).getStr(), - reinterpret_cast< const char * >( - aDataToSend.getConstArray() ), - NeonSession_ResponseBlockWriter, - &aCtx, - rContentType, - rReferer ); - - HandleError( theRetVal, inPath, rEnv ); -} - -void NeonSession::MKCOL( const OUString & inPath, - const DAVRequestEnvironment & rEnv ) -{ - osl::Guard< osl::Mutex > theGuard( m_aMutex ); - SAL_INFO( "ucb.ucp.webdav", "MKCOL - relative URL <" << inPath << ">" ); - - Init( rEnv ); - - int theRetVal = ne_mkcol( m_pHttpSession, - OUStringToOString( - inPath, RTL_TEXTENCODING_UTF8 ).getStr() ); - - HandleError( theRetVal, inPath, rEnv ); -} - -void NeonSession::COPY( const OUString & inSourceURL, - const OUString & inDestinationURL, - const DAVRequestEnvironment & rEnv, - bool inOverWrite ) -{ - osl::Guard< osl::Mutex > theGuard( m_aMutex ); - SAL_INFO( "ucb.ucp.webdav", "COPY - inSourceURL: "<<inSourceURL<<" inDestinationURL: "<<inDestinationURL); - - Init( rEnv ); - - NeonUri theSourceUri( inSourceURL ); - NeonUri theDestinationUri( inDestinationURL ); - - int theRetVal = ne_copy( m_pHttpSession, - inOverWrite ? 1 : 0, - NE_DEPTH_INFINITE, - OUStringToOString( - theSourceUri.GetPath(), - RTL_TEXTENCODING_UTF8 ).getStr(), - OUStringToOString( - theDestinationUri.GetPath(), - RTL_TEXTENCODING_UTF8 ).getStr() ); - - HandleError( theRetVal, inSourceURL, rEnv ); -} - -void NeonSession::MOVE( const OUString & inSourceURL, - const OUString & inDestinationURL, - const DAVRequestEnvironment & rEnv, - bool inOverWrite ) -{ - osl::Guard< osl::Mutex > theGuard( m_aMutex ); - SAL_INFO( "ucb.ucp.webdav", "MOVE - inSourceURL: "<<inSourceURL<<" inDestinationURL: "<<inDestinationURL); - - Init( rEnv ); - - NeonUri theSourceUri( inSourceURL ); - NeonUri theDestinationUri( inDestinationURL ); - int theRetVal = ne_move( m_pHttpSession, - inOverWrite ? 1 : 0, - OUStringToOString( - theSourceUri.GetPath(), - RTL_TEXTENCODING_UTF8 ).getStr(), - OUStringToOString( - theDestinationUri.GetPath(), - RTL_TEXTENCODING_UTF8 ).getStr() ); - - HandleError( theRetVal, inSourceURL, rEnv ); -} - -void NeonSession::DESTROY( const OUString & inPath, - const DAVRequestEnvironment & rEnv ) -{ - osl::Guard< osl::Mutex > theGuard( m_aMutex ); - SAL_INFO( "ucb.ucp.webdav", "DESTROY - relative URL <" << inPath << ">" ); - - Init( rEnv ); - - int theRetVal = ne_delete( m_pHttpSession, - OUStringToOString( - inPath, RTL_TEXTENCODING_UTF8 ).getStr() ); - - HandleError( theRetVal, inPath, rEnv ); -} - -namespace -{ - sal_Int32 lastChanceToSendRefreshRequest( TimeValue const & rStart, - int 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 calltime = aEnd.Seconds - rStart.Seconds; - if ( calltime <= timeout ) - { - lastChanceToSendRefreshRequest = rStart.Seconds + timeout; - } - else - { - SAL_WARN( "ucb.ucp.webdav", "LOCK - no chance to refresh lock before timeout!" ); - } - } - return lastChanceToSendRefreshRequest; - } - -} // namespace - -// Set new lock -void NeonSession::LOCK( const OUString & inPath, - ucb::Lock & rLock, - const DAVRequestEnvironment & rEnv ) -{ - osl::Guard< osl::Mutex > theGuard( m_aMutex ); - SAL_INFO( "ucb.ucp.webdav", "LOCK (create) - relative URL: <" << inPath << ">" ); - - // before issuing the lock command, - // better check first if we already have one on this href - if ( m_aNeonLockStore.findByUri( - makeAbsoluteURL( inPath ) ) != nullptr ) - { - // we already own a lock for this href - // no need to ask for another - // TODO: add a lockdiscovery request for confirmation - // checking the locktoken, the only item that's unique - return; - } - - Init( rEnv ); - - /* Create a depth zero, exclusive write lock, with default timeout - * (allowing a server to pick a default). token, owner and uri are - * unset. */ - NeonLock * 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 = static_cast<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_aNeonLockStore.addLock( theLock, - this, - lastChanceToSendRefreshRequest( - startCall, theLock->timeout ) ); - - uno::Sequence< OUString > aTokens{ OUString::createFromAscii( theLock->token ) }; - rLock.LockTokens = aTokens; - - SAL_INFO( "ucb.ucp.webdav", "LOCK (create) - Created lock for <" << makeAbsoluteURL( inPath ) - << "> token: <" << theLock->token << "> timeout: " << theLock->timeout << " sec."); - } - else - { - ne_lock_destroy( theLock ); - - SAL_INFO( "ucb.ucp.webdav", "LOCK (create) - Obtaining lock for <" - << makeAbsoluteURL( inPath ) << " failed!" ); - } - - HandleError( theRetVal, inPath, rEnv ); -} - -// Refresh existing lock -bool NeonSession::LOCK( NeonLock * pLock, - sal_Int32 & rlastChanceToSendRefreshRequest ) -{ - osl::Guard< osl::Mutex > theGuard( m_aMutex ); - -#if defined SAL_LOG_INFO - { - char * p = ne_uri_unparse( &(pLock->uri) ); - SAL_INFO( "ucb.ucp.webdav", "LOCK (refresh) - relative URL: <" << p << "> token: <" << pLock->token << ">" ); - ne_free( p ); - } -#endif - - // refresh existing lock. - - TimeValue startCall; - osl_getSystemTime( &startCall ); - - // save the current requested timeout, because ne_lock_refresh uses - // pLock->timeout as an out parameter. This prevents a feedback-loop, - // where we would request a shorter timeout on each refresh. - long timeout = pLock->timeout; - const int theRetVal = ne_lock_refresh(m_pHttpSession, pLock); - if (theRetVal == NE_OK) - { - rlastChanceToSendRefreshRequest - = lastChanceToSendRefreshRequest( startCall, pLock->timeout ); - - SAL_INFO( "ucb.ucp.webdav", "LOCK (refresh) - Lock successfully refreshed." ); - pLock->timeout = timeout; - return true; - } - else - { -#if defined SAL_LOG_WARN - char * p = ne_uri_unparse( &(pLock->uri) ); - SAL_WARN( "ucb.ucp.webdav", "LOCK (refresh) - not refreshed! Relative URL: <" << p << "> token: <" << pLock->token << ">" ); - ne_free( p ); -#endif - if (theRetVal == NE_AUTH) - { - // tdf#126279: see handling of NE_AUTH in HandleError - m_bNeedNewSession = true; - m_aNeonLockStore.removeLockDeferred(pLock); - } - return false; - } -} - -void NeonSession::UNLOCK( const OUString & inPath, - const DAVRequestEnvironment & rEnv ) -{ - osl::Guard< osl::Mutex > theGuard( m_aMutex ); - - // get the neon lock from lock store - NeonLock * theLock - = m_aNeonLockStore.findByUri( makeAbsoluteURL( inPath ) ); - if ( !theLock ) - throw DAVException( DAVException::DAV_NOT_LOCKED ); - - SAL_INFO( "ucb.ucp.webdav", "UNLOCK - relative URL: <" << inPath << "> token: <" << theLock->token << ">" ); - Init( rEnv ); - - int theRetVal = ne_unlock( m_pHttpSession, theLock ); - - if ( theRetVal == NE_OK ) - { - m_aNeonLockStore.removeLock( theLock ); - ne_lock_destroy( theLock ); - } - else - { - SAL_INFO( "ucb.ucp.webdav", "UNLOCK - Unlocking of <" - << makeAbsoluteURL( inPath ) << "> failed." ); - } - - HandleError( theRetVal, inPath, rEnv ); -} - -bool NeonSession::UNLOCK( NeonLock * pLock ) -{ - osl::Guard< osl::Mutex > theGuard( m_aMutex ); - -#if defined SAL_LOG_INFO - { - char * p = ne_uri_unparse( &(pLock->uri) ); - SAL_INFO( "ucb.ucp.webdav", "UNLOCK (from store) - relative URL: <" << p << "> token: <" << pLock->token << ">" ); - ne_free( p ); - } -#endif - - const int theRetVal = ne_unlock(m_pHttpSession, pLock); - if (theRetVal == NE_OK) - { -#if defined SAL_LOG_INFO - { - char * p = ne_uri_unparse( &(pLock->uri) ); - SAL_INFO( "ucb.ucp.webdav", "UNLOCK (from store) - relative URL: <" << p << "> token: <" << pLock->token << "> succeeded." ); - ne_free( p ); - } -#endif - return true; - } - else - { -#if defined SAL_LOG_INFO - { - char * p = ne_uri_unparse( &(pLock->uri) ); - SAL_INFO( "ucb.ucp.webdav", "UNLOCK (from store) - relative URL: <" << p << "> token: <" << pLock->token << "> failed!" ); - ne_free( p ); - } -#endif - if (theRetVal == NE_AUTH) - { - // tdf#126279: see handling of NE_AUTH in HandleError - m_bNeedNewSession = true; - } - return false; - } -} - -void NeonSession::abort() -{ - SAL_INFO( "ucb.ucp.webdav", "neon commands cannot be aborted" ); -} - -ucbhelper::InternetProxyServer NeonSession::getProxySettings() const -{ - if ( m_aScheme == "http" || m_aScheme == "https" ) - { - return m_rProxyDecider.getProxy( m_aScheme, - m_aHostName, - m_nPort ); - } - else - { - return m_rProxyDecider.getProxy( m_aScheme, - OUString() /* not used */, - -1 /* not used */ ); - } -} - -namespace { - -bool containsLocktoken( const uno::Sequence< ucb::Lock > & rLocks, - const char * token ) -{ - return std::any_of(rLocks.begin(), rLocks.end(), [&token](const ucb::Lock& rLock) { - const uno::Sequence< OUString > & rTokens = rLock.LockTokens; - return std::any_of(rTokens.begin(), rTokens.end(), - [&token](const OUString& rToken) { return rToken.equalsAscii( token ); }); - }); -} - -} // namespace - -bool NeonSession::removeExpiredLocktoken( const OUString & inURL, - const DAVRequestEnvironment & rEnv ) -{ - NeonLock * theLock = m_aNeonLockStore.findByUri( inURL ); - if ( !theLock ) - return false; - - // do a lockdiscovery to check whether this lock is still valid. - try - { - // @@@ Alternative: use ne_lock_discover() => less overhead - - std::vector< DAVResource > aResources; - - PROPFIND( rEnv.m_aRequestURI, DAVZERO, { DAVProperties::LOCKDISCOVERY }, aResources, rEnv ); - - if ( aResources.empty() ) - return false; - - for ( const auto& rProp : aResources[ 0 ].properties ) - { - if ( rProp.Name == DAVProperties::LOCKDISCOVERY ) - { - uno::Sequence< ucb::Lock > aLocks; - if ( !( rProp.Value >>= aLocks ) ) - return false; - - if ( !containsLocktoken( aLocks, theLock->token ) ) - { - // expired! - break; - } - - // still valid. - return false; - } - } - - // No lockdiscovery prop in propfind result / locktoken not found - // in propfind result -> not locked - SAL_WARN( "ucb.ucp.webdav", "Removing expired lock token for <" << inURL - << "> token: " << theLock->token ); - - m_aNeonLockStore.removeLock( theLock ); - ne_lock_destroy( theLock ); - return true; - } - catch ( DAVException const & ) - { - } - return false; -} - -// Common error handler -void NeonSession::HandleError( int nError, - const OUString & inPath, - const DAVRequestEnvironment & rEnv ) -{ - // Map error code to DAVException. - switch ( nError ) - { - case NE_OK: - return; - - case NE_ERROR: // Generic error - { - const char* sErr = ne_get_error(m_pHttpSession); - OUString aText(sErr, strlen(sErr), osl_getThreadTextEncoding()); - - sal_uInt16 code = makeStatusCode( aText ); - - SAL_WARN( "ucb.ucp.webdav", "Neon returned NE_ERROR, http response status code was: " << code << " '" << aText << "'" ); - if ( SC_BAD_REQUEST <= code && code < SC_INTERNAL_SERVER_ERROR ) - { - // error codes in the range 4xx - switch ( code ) - { - case SC_LOCKED: - { - if ( m_aNeonLockStore.findByUri( - makeAbsoluteURL( inPath ) ) == nullptr ) - { - // locked by 3rd party - throw DAVException( DAVException::DAV_LOCKED ); - } - else - { - // locked by ourself - throw DAVException( DAVException::DAV_LOCKED_SELF ); - } - } - break; - case SC_PRECONDITION_FAILED: - case SC_BAD_REQUEST: - { - // Special handling for 400 and 412 status codes, which may indicate - // that a lock previously obtained by us has been released meanwhile - // by the server. Unfortunately, RFC is not clear at this point, - // thus server implementations behave different... - if ( removeExpiredLocktoken( makeAbsoluteURL( inPath ), rEnv ) ) - throw DAVException( DAVException::DAV_LOCK_EXPIRED ); - } - break; - case SC_REQUEST_TIMEOUT: - { - throw DAVException( DAVException::DAV_HTTP_TIMEOUT, - NeonUri::makeConnectionEndPointString( - m_aHostName, m_nPort ) ); - } - break; - case SC_UNAUTHORIZED: // User authentication failed on server - { - throw DAVException( DAVException::DAV_HTTP_AUTH, - NeonUri::makeConnectionEndPointString( - m_aHostName, m_nPort ) ); - } - break; - case SC_GONE: - case SC_LENGTH_REQUIRED: - case SC_REQUEST_ENTITY_TOO_LARGE: - case SC_REQUEST_URI_TOO_LONG: - case SC_UNSUPPORTED_MEDIA_TYPE: - case SC_REQUESTED_RANGE_NOT_SATISFIABLE: - case SC_EXPECTATION_FAILED: - case SC_UNPROCESSABLE_ENTITY: - case SC_FAILED_DEPENDENCY: - case SC_CONFLICT: - case SC_NOT_ACCEPTABLE: - case SC_PAYMENT_REQUIRED: - case SC_PROXY_AUTHENTICATION_REQUIRED: - default: - // set 400 error, if not one of others - code = SC_BAD_REQUEST; - [[fallthrough]]; - case SC_FORBIDDEN: - case SC_NOT_FOUND: - case SC_METHOD_NOT_ALLOWED: - throw DAVException( DAVException::DAV_HTTP_ERROR, aText, code ); - break; - } - } - else if ( SC_INTERNAL_SERVER_ERROR <= code ) - { - // deal with HTTP response status codes higher then 500 - // error codes in the range 5xx, server errors - // but there exists unofficial code in the range 1000 and up - // for example see: - // <https://support.cloudflare.com/hc/en-us/sections/200820298-Error-Pages> (retrieved 2016-10-05) - switch ( code ) - { - // the error codes case before the default case are not actively - // managed by LO - case SC_BAD_GATEWAY: - case SC_SERVICE_UNAVAILABLE: - case SC_GATEWAY_TIMEOUT: - case SC_HTTP_VERSION_NOT_SUPPORTED: - case SC_INSUFFICIENT_STORAGE: - default: - // set 500 error, if not one of others - // expand the error code - code = SC_INTERNAL_SERVER_ERROR; - [[fallthrough]]; - case SC_INTERNAL_SERVER_ERROR: - case SC_NOT_IMPLEMENTED: - throw DAVException( DAVException::DAV_HTTP_ERROR, aText, code ); - break; - } - } - else - throw DAVException( DAVException::DAV_HTTP_ERROR, aText, code ); - } - break; - case NE_LOOKUP: // Name lookup failed. - SAL_WARN( "ucb.ucp.webdav", "Name lookup failed" ); - throw DAVException( DAVException::DAV_HTTP_LOOKUP, - NeonUri::makeConnectionEndPointString( - m_aHostName, m_nPort ) ); - - case NE_AUTH: // User authentication failed on server - // m_pHttpSession could get invalidated, e.g., as result of clean_session called in - // ah_post_send in case when auth_challenge failed, which invalidates the auth_session - // which we established in Init(): the auth_session's sspi_host gets disposed, and - // next attempt to authenticate would crash in continue_sspi trying to dereference it - m_bNeedNewSession = true; - throw DAVException( DAVException::DAV_HTTP_AUTH, - NeonUri::makeConnectionEndPointString( - m_aHostName, m_nPort ) ); - - case NE_PROXYAUTH: // User authentication failed on proxy - SAL_WARN( "ucb.ucp.webdav", "DAVException::DAV_HTTP_AUTHPROXY" ); - throw DAVException( DAVException::DAV_HTTP_AUTHPROXY, - NeonUri::makeConnectionEndPointString( - m_aProxyName, m_nProxyPort ) ); - - case NE_CONNECT: // Could not connect to server - SAL_WARN( "ucb.ucp.webdav", "DAVException::DAV_HTTP_CONNECT" ); - throw DAVException( DAVException::DAV_HTTP_CONNECT, - NeonUri::makeConnectionEndPointString( - m_aHostName, m_nPort ) ); - - case NE_TIMEOUT: // Connection timed out - SAL_WARN( "ucb.ucp.webdav", "DAVException::DAV_HTTP_TIMEOUT" ); - throw DAVException( DAVException::DAV_HTTP_TIMEOUT, - NeonUri::makeConnectionEndPointString( - m_aHostName, m_nPort ) ); - - case NE_FAILED: // The precondition failed - SAL_WARN( "ucb.ucp.webdav", "The precondition failed" ); - throw DAVException( DAVException::DAV_HTTP_FAILED, - NeonUri::makeConnectionEndPointString( - m_aHostName, m_nPort ) ); - - case NE_RETRY: // Retry request (ne_end_request ONLY) - throw DAVException( DAVException::DAV_HTTP_RETRY, - NeonUri::makeConnectionEndPointString( - m_aHostName, m_nPort ) ); - - case NE_REDIRECT: - { - NeonUri aUri( ne_redirect_location( m_pHttpSession ) ); - SAL_INFO( "ucb.ucp.webdav", "DAVException::DAV_HTTP_REDIRECT: new URI: " << aUri.GetURI() ); - throw DAVException( - DAVException::DAV_HTTP_REDIRECT, aUri.GetURI() ); - } - default: - { - SAL_WARN( "ucb.ucp.webdav", "Unknown Neon error code!" ); - const char* sErr = ne_get_error(m_pHttpSession); - throw DAVException( DAVException::DAV_HTTP_ERROR, - OUString(sErr, strlen(sErr), osl_getThreadTextEncoding()) ); - } - } -} - -namespace { - -void runResponseHeaderHandler( void * userdata, - const char * value ) -{ - OUString aHeader(value, strlen(value), RTL_TEXTENCODING_ASCII_US); - sal_Int32 nPos = aHeader.indexOf( ':' ); - - if ( nPos == -1 ) - return; - - OUString aHeaderName( aHeader.copy( 0, nPos ) ); - - NeonRequestContext * pCtx - = static_cast< NeonRequestContext * >( userdata ); - - // Note: Empty vector means that all headers are requested. - bool bIncludeIt = pCtx->pHeaderNames->empty(); - - if ( !bIncludeIt ) - { - // Check whether this header was requested. - auto it = std::find_if(pCtx->pHeaderNames->cbegin(), pCtx->pHeaderNames->cend(), - [&aHeaderName](const OUString& rName) { - // header names are case insensitive - return rName.equalsIgnoreAsciiCase( aHeaderName ); }); - - if ( it != pCtx->pHeaderNames->end() ) - { - aHeaderName = *it; - bIncludeIt = true; - } - } - - if ( !bIncludeIt ) - return; - - // Create & set the PropertyValue - DAVPropertyValue thePropertyValue; - // header names are case insensitive, so are the - // corresponding property names. - thePropertyValue.Name = aHeaderName.toAsciiLowerCase(); - thePropertyValue.IsCaseSensitive = false; - - if ( nPos < aHeader.getLength() ) - thePropertyValue.Value <<= aHeader.copy( nPos + 1 ).trim(); - - // Add the newly created PropertyValue - pCtx->pResource->properties.push_back( thePropertyValue ); -} - -} // namespace - -int NeonSession::GET( ne_session * sess, - const char * uri, - ne_block_reader reader, - bool getheaders, - void * userdata ) -{ - //struct get_context ctx; - ne_request * req = ne_request_create( sess, "GET", uri ); - int ret; - - ne_decompress * dc - = ne_decompress_reader( req, ne_accept_2xx, reader, userdata ); - - { - osl::Guard< osl::Mutex > theGlobalGuard(getGlobalNeonMutex()); - 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; - - if ( dc != nullptr ) - ne_decompress_destroy(dc); - - ne_request_destroy( req ); - 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(getGlobalNeonMutex()); - 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, - size_t size) -{ - ne_request * req = ne_request_create( sess, "PUT", uri ); - int ret; - - // tdf#99246 - // extract the path of uri - // ne_lock_using_resource below compares path, ignores all the rest. - // in case of Web proxy active, this function uri parameter is instead absolute - ne_uri aUri; - ne_uri_parse( uri, &aUri ); - ne_lock_using_resource( req, aUri.path, 0 ); - ne_lock_using_parent( req, uri ); - - ne_set_request_body_buffer( req, buffer, size ); - - { - osl::Guard< osl::Mutex > theGlobalGuard(getGlobalNeonMutex()); - ret = ne_request_dispatch( req ); - } - - if ( ret == NE_OK && ne_get_status( req )->klass != 2 ) - ret = NE_ERROR; - - ne_request_destroy( req ); - return ret; -} - -int NeonSession::POST( ne_session * sess, - const char * uri, - const char * buffer, - ne_block_reader reader, - void * userdata, - const OUString & rContentType, - const OUString & rReferer ) -{ - ne_request * req = ne_request_create( sess, "POST", uri ); - //struct get_context ctx; - int ret; - - RequestDataMap * pData = nullptr; - - if ( !rContentType.isEmpty() || !rReferer.isEmpty() ) - { - // Remember contenttype and referer. Data will be added to HTTP request - // header in 'PreSendRequest' callback. - pData = static_cast< RequestDataMap* >( m_pRequestData ); - (*pData)[ req ] = RequestData( rContentType, rReferer ); - } - - //ctx.total = -1; - //ctx.fd = fd; - //ctx.error = 0; - //ctx.session = sess; - - ///* Read the value of the Content-Length header into ctx.total */ - //ne_add_response_header_handler( req, "Content-Length", - // ne_handle_numeric_header, &ctx.total ); - - ne_add_response_body_reader( req, ne_accept_2xx, reader, userdata ); - - ne_set_request_body_buffer( req, buffer, strlen( buffer ) ); - - { - osl::Guard< osl::Mutex > theGlobalGuard(getGlobalNeonMutex()); - ret = ne_request_dispatch( req ); - } - - //if ( ctx.error ) - // ret = NE_ERROR; - //else - if ( ret == NE_OK && ne_get_status( req )->klass != 2 ) - ret = NE_ERROR; - - ne_request_destroy( req ); - - if ( pData ) - { - // Remove request data from session's list. - RequestDataMap::iterator it = pData->find( req ); - if ( it != pData->end() ) - pData->erase( it ); - } - - return ret; -} - -bool -NeonSession::getDataFromInputStream( - const uno::Reference< io::XInputStream > & xStream, - uno::Sequence< sal_Int8 > & rData, - bool bAppendTrailingZeroByte ) -{ - if ( xStream.is() ) - { - uno::Reference< io::XSeekable > xSeekable( xStream, uno::UNO_QUERY ); - if ( xSeekable.is() ) - { - try - { - sal_Int32 nSize - = sal::static_int_cast<sal_Int32>(xSeekable->getLength()); - sal_Int32 nRead - = xStream->readBytes( rData, nSize ); - - if ( nRead == nSize ) - { - if ( bAppendTrailingZeroByte ) - { - rData.realloc( nSize + 1 ); - rData.getArray()[ nSize ] = sal_Int8( 0 ); - } - return true; - } - } - catch ( io::NotConnectedException const & ) - { - // readBytes - } - catch ( io::BufferSizeExceededException const & ) - { - // readBytes - } - catch ( io::IOException const & ) - { - // getLength, readBytes - } - } - else - { - try - { - uno::Sequence< sal_Int8 > aBuffer; - sal_Int32 nPos = 0; - - sal_Int32 nRead = xStream->readSomeBytes( aBuffer, 65536 ); - while ( nRead > 0 ) - { - if ( rData.getLength() < ( nPos + nRead ) ) - rData.realloc( nPos + nRead ); - - aBuffer.realloc( nRead ); - memcpy( static_cast<void*>( rData.getArray() + nPos ), - static_cast<const void*>(aBuffer.getConstArray()), - nRead ); - nPos += nRead; - - aBuffer.realloc( 0 ); - nRead = xStream->readSomeBytes( aBuffer, 65536 ); - } - - if ( bAppendTrailingZeroByte ) - { - rData.realloc( nPos + 1 ); - rData.getArray()[ nPos ] = sal_Int8( 0 ); - } - return true; - } - catch ( io::NotConnectedException const & ) - { - // readBytes - } - catch ( io::BufferSizeExceededException const & ) - { - // readBytes - } - catch ( io::IOException const & ) - { - // readBytes - } - } - } - return false; -} - -bool -NeonSession::isDomainMatch( const OUString& certHostName ) const -{ - OUString hostName = getHostName(); - - if (hostName.equalsIgnoreAsciiCase( certHostName ) ) - return true; - - if ( certHostName.startsWith( "*" ) && - hostName.getLength() >= certHostName.getLength() ) - { - OUString cmpStr = certHostName.copy( 1 ); - - if ( hostName.matchIgnoreAsciiCase( - cmpStr, hostName.getLength() - cmpStr.getLength() ) ) - return true; - } - return false; -} - -OUString NeonSession::makeAbsoluteURL( OUString const & rURL ) const -{ - try - { - // Is URL relative or already absolute? - if ( !rURL.isEmpty() && rURL[ 0 ] != '/' ) - { - // absolute. - return rURL; - } - else - { - ne_uri aUri = {}; - - ne_fill_server_uri( m_pHttpSession, &aUri ); - aUri.path - = ne_strdup( OUStringToOString( - rURL, RTL_TEXTENCODING_UTF8 ).getStr() ); - NeonUri aNeonUri( &aUri ); - ne_uri_free( &aUri ); - return aNeonUri.GetURI(); - } - } - catch ( DAVException const & ) - { - } - // error. - return OUString(); -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/ucb/source/ucp/webdav-neon/NeonSession.hxx b/ucb/source/ucp/webdav-neon/NeonSession.hxx deleted file mode 100644 index 615f750a11aa..000000000000 --- a/ucb/source/ucp/webdav-neon/NeonSession.hxx +++ /dev/null @@ -1,285 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -#pragma once - -#include <config_lgpl.h> -#include <vector> -#include <osl/mutex.hxx> -#include "DAVSession.hxx" -#include "NeonTypes.hxx" -#include "NeonLockStore.hxx" -#include <com/sun/star/lang/XMultiServiceFactory.hpp> - -namespace ucbhelper { class ProxyDecider; } - -namespace webdav_ucp -{ - -// A DAVSession implementation using the neon/expat library -class NeonSession : public DAVSession -{ -private: - osl::Mutex m_aMutex; - OUString m_aScheme; - OUString m_aHostName; - OUString m_aProxyName; - sal_Int32 m_nPort; - sal_Int32 m_nProxyPort; - css::uno::Sequence< css::beans::NamedValue > m_aFlags; - HttpSession * m_pHttpSession; - bool m_bNeedNewSession = false; // Something happened that could invalidate m_pHttpSession - void * m_pRequestData; - const ucbhelper::InternetProxyDecider & m_rProxyDecider; - - // @@@ This should really be per-request data. But Neon currently - // (0.23.5) has no interface for passing per-request user data. - // Theoretically, a NeonSession instance could handle multiple requests - // at a time --currently it doesn't. Thus this is not an issue at the - // moment. - DAVRequestEnvironment m_aEnv; - - static bool m_bGlobalsInited; - static NeonLockStore m_aNeonLockStore; - -protected: - virtual ~NeonSession() override; - -public: - /// @throws std::exception - NeonSession( const rtl::Reference< DAVSessionFactory > & rSessionFactory, - const OUString& inUri, - const css::uno::Sequence< css::beans::NamedValue >& rFlags, - const ucbhelper::InternetProxyDecider & rProxyDecider ); - - // DAVSession methods - virtual bool CanUse( const OUString & inPath, - const css::uno::Sequence< css::beans::NamedValue >& rFlags ) override; - - virtual bool UsesProxy() override; - - const DAVRequestEnvironment & getRequestEnvironment() const - { return m_aEnv; } - - virtual void - OPTIONS( const OUString & inPath, - DAVOptions& rOptions, // contains the name+values - const DAVRequestEnvironment & rEnv ) override; - - // allprop & named - virtual void - PROPFIND( const OUString & inPath, - const Depth inDepth, - const std::vector< OUString > & inPropNames, - std::vector< DAVResource > & ioResources, - const DAVRequestEnvironment & rEnv ) override; - - // propnames - virtual void - PROPFIND( const OUString & inPath, - const Depth inDepth, - std::vector< DAVResourceInfo >& ioResInfo, - const DAVRequestEnvironment & rEnv ) override; - - virtual void - PROPPATCH( const OUString & inPath, - const std::vector< ProppatchValue > & inValues, - const DAVRequestEnvironment & rEnv ) override; - - virtual void - HEAD( const OUString & inPath, - const std::vector< OUString > & inHeaderNames, - DAVResource & ioResource, - const DAVRequestEnvironment & rEnv ) override; - - virtual css::uno::Reference< css::io::XInputStream > - GET( const OUString & inPath, - const DAVRequestEnvironment & rEnv ) override; - - virtual void - GET( const OUString & inPath, - css::uno::Reference< css::io::XOutputStream > & ioOutputStream, - const DAVRequestEnvironment & rEnv ) override; - - virtual css::uno::Reference< css::io::XInputStream > - GET( const OUString & inPath, - const std::vector< OUString > & inHeaderNames, - DAVResource & ioResource, - const DAVRequestEnvironment & rEnv ) override; - - virtual void - GET0( const OUString & inPath, - const std::vector< OUString > & inHeaderNames, - DAVResource & ioResource, - const DAVRequestEnvironment & rEnv ) override; - - virtual void - GET( const OUString & inPath, - css::uno::Reference< css::io::XOutputStream > & ioOutputStream, - const std::vector< OUString > & inHeaderNames, - DAVResource & ioResource, - const DAVRequestEnvironment & rEnv ) override; - - virtual void - PUT( const OUString & inPath, - const css::uno::Reference< css::io::XInputStream > & inInputStream, - const DAVRequestEnvironment & rEnv ) override; - - virtual css::uno::Reference< css::io::XInputStream > - POST( const OUString & inPath, - const OUString & rContentType, - const OUString & rReferer, - const css::uno::Reference< css::io::XInputStream > & inInputStream, - const DAVRequestEnvironment & rEnv ) override; - - virtual void - POST( const OUString & inPath, - const OUString & rContentType, - const OUString & rReferer, - const css::uno::Reference< css::io::XInputStream > & inInputStream, - css::uno::Reference< css::io::XOutputStream > & oOutputStream, - const DAVRequestEnvironment & rEnv ) override; - - virtual void - MKCOL( const OUString & inPath, - const DAVRequestEnvironment & rEnv ) override; - - virtual void - COPY( const OUString & inSourceURL, - const OUString & inDestinationURL, - const DAVRequestEnvironment & rEnv, - bool inOverWrite ) override; - - virtual void - MOVE( const OUString & inSourceURL, - const OUString & inDestinationURL, - const DAVRequestEnvironment & rEnv, - bool inOverWrite ) override; - - virtual void DESTROY( const OUString & inPath, - const DAVRequestEnvironment & rEnv ) override; - - // set new lock. - virtual void LOCK( const OUString & inURL, - css::ucb::Lock & inLock, - const DAVRequestEnvironment & rEnv ) override; - - virtual void UNLOCK( const OUString & inURL, - const DAVRequestEnvironment & rEnv ) override; - - // helpers - virtual void abort() override; - - const OUString & getHostName() const { return m_aHostName; } - - ::uno::Reference< ::uno::XComponentContext > const & getComponentContext() const - { return m_xFactory->getComponentContext(); } - - const void * getRequestData() const { return m_pRequestData; } - - bool isDomainMatch( const OUString& certHostName ) const; - - int CertificationNotify(const ne_ssl_certificate *cert); - - int NeonAuth(const char* inAuthProtocol, const char* inRealm, - int attempt, char* inoutUserName, char * inoutPassWord); - - void PreSendRequest(ne_request* req, ne_buffer* headers); - -private: - friend class NeonLockStore; - - /// @throws css::uno::RuntimeException - void Init(); - - /// @throws css::uno::RuntimeException - void Init( const DAVRequestEnvironment & rEnv ); - - // ret: true => retry request. - /// @throws std::exception - void HandleError( int nError, - const OUString & inPath, - const DAVRequestEnvironment & rEnv ); - - ucbhelper::InternetProxyServer getProxySettings() const; - - bool removeExpiredLocktoken( const OUString & inURL, - const DAVRequestEnvironment & rEnv ); - - // refresh lock, called by NeonLockStore::refreshLocks - bool LOCK( NeonLock * pLock, - sal_Int32 & rlastChanceToSendRefreshRequest ); - - // unlock, called by NeonLockStore::~NeonLockStore - bool UNLOCK( NeonLock * pLock ); - - // low level GET implementation, used by public GET implementations - static int GET( ne_session * sess, - const char * uri, - ne_block_reader reader, - 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, - const char * uri, - const char * buffer, - size_t size ); - - // Buffer-based POST implementation. Neon only has file descriptor- - // based API. - int POST( ne_session * sess, - const char * uri, - const char * buffer, - ne_block_reader reader, - void * userdata, - const OUString & rContentType, - const OUString & rReferer ); - - // Helper: XInputStream -> Sequence< sal_Int8 > - static bool getDataFromInputStream( - const css::uno::Reference< css::io::XInputStream > & xStream, - css::uno::Sequence< sal_Int8 > & rData, - bool bAppendTrailingZeroByte ); - - OUString makeAbsoluteURL( OUString const & rURL ) const; -}; - -osl::Mutex& getGlobalNeonMutex(); - -} // namespace webdav_ucp - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/ucb/source/ucp/webdav-neon/NeonTypes.hxx b/ucb/source/ucp/webdav-neon/NeonTypes.hxx deleted file mode 100644 index eb40c03a6f4a..000000000000 --- a/ucb/source/ucp/webdav-neon/NeonTypes.hxx +++ /dev/null @@ -1,54 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -#pragma once - -#include <config_lgpl.h> -#include <ne_session.h> -#include <ne_utils.h> -#include <ne_basic.h> -#include <ne_props.h> - -#if defined(__GNUC__) -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wshadow" -#endif -#include <ne_locks.h> -#if defined(__GNUC__) -# pragma GCC diagnostic pop -#endif - -typedef ne_session HttpSession; -typedef ne_status HttpStatus; - -typedef ne_propname NeonPropName; -typedef ne_prop_result_set NeonPropFindResultSet; - -typedef struct ne_lock NeonLock; - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/ucb/source/ucp/webdav-neon/NeonUri.cxx b/ucb/source/ucp/webdav-neon/NeonUri.cxx deleted file mode 100644 index df641fce518d..000000000000 --- a/ucb/source/ucp/webdav-neon/NeonUri.cxx +++ /dev/null @@ -1,291 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -#include <sal/config.h> - -#include <rtl/uri.hxx> -#include <rtl/ustring.hxx> -#include <rtl/ustrbuf.hxx> -#include <ne_alloc.h> -#include "NeonUri.hxx" -#include "DAVException.hxx" - -#include "../inc/urihelper.hxx" - -using namespace webdav_ucp; - -// FIXME: not sure whether initializing a ne_uri statically is supposed to work -// the string fields of ne_uri are char*, not const char* - -#ifdef __GNUC__ -#pragma GCC diagnostic ignored "-Wwrite-strings" -#endif - -namespace { - -const ne_uri g_sUriDefaultsHTTP = { const_cast<char *>("http"), - const_cast<char *>(""), - const_cast<char *>(""), - DEFAULT_HTTP_PORT, - const_cast<char *>(""), - nullptr, - nullptr }; -const ne_uri g_sUriDefaultsHTTPS = { const_cast<char *>("https"), - const_cast<char *>(""), - const_cast<char *>(""), - DEFAULT_HTTPS_PORT, - const_cast<char *>(""), - nullptr, - nullptr }; -const ne_uri g_sUriDefaultsFTP = { const_cast<char *>("ftp"), - const_cast<char *>(""), - const_cast<char *>(""), - DEFAULT_FTP_PORT, - const_cast<char *>(""), - nullptr, - nullptr }; -} // namespace - -NeonUri::NeonUri( const ne_uri * inUri ) -{ - if ( inUri == nullptr ) - throw DAVException( DAVException::DAV_INVALID_ARG ); - - char * uri = ne_uri_unparse( inUri ); - - if ( uri == nullptr ) - throw DAVException( DAVException::DAV_INVALID_ARG ); - - init( OString( uri ), inUri ); - ne_free( uri ); - - calculateURI(); -} - -NeonUri::NeonUri( const OUString & inUri ) -{ - if ( inUri.isEmpty() ) - throw DAVException( DAVException::DAV_INVALID_ARG ); - - // #i77023# - OUString aEscapedUri( ucb_impl::urihelper::encodeURI( inUri ) ); - - OString theInputUri( - aEscapedUri.getStr(), aEscapedUri.getLength(), RTL_TEXTENCODING_UTF8 ); - - ne_uri theUri; - if ( ne_uri_parse( theInputUri.getStr(), &theUri ) != 0 ) - { - ne_uri_free( &theUri ); - throw DAVException( DAVException::DAV_INVALID_ARG ); - } - - init( theInputUri, &theUri ); - ne_uri_free( &theUri ); - - calculateURI(); -} - -void NeonUri::init( const OString & rUri, const ne_uri * pUri ) -{ - // Complete URI. - const ne_uri * pUriDefs - = rUri.matchIgnoreAsciiCase( "ftp:" ) ? - &g_sUriDefaultsFTP : - rUri.matchIgnoreAsciiCase( "https:" ) ? - &g_sUriDefaultsHTTPS : - &g_sUriDefaultsHTTP; - - mScheme = OStringToOUString( - pUri->scheme ? pUri->scheme : pUriDefs->scheme, - RTL_TEXTENCODING_UTF8 ); - mUserInfo = OStringToOUString( - pUri->userinfo ? pUri->userinfo : pUriDefs->userinfo, - RTL_TEXTENCODING_UTF8 ); - mHostName = OStringToOUString( - pUri->host ? pUri->host : pUriDefs->host, - RTL_TEXTENCODING_UTF8 ); - mPort = pUri->port > 0 ? pUri->port : pUriDefs->port; - mPath = OStringToOUString( - pUri->path ? pUri->path : pUriDefs->path, - RTL_TEXTENCODING_UTF8 ); - - if ( pUri->query ) - { - mPath += "?" + OStringToOUString( pUri->query, RTL_TEXTENCODING_UTF8 ); - } - - if ( pUri->fragment ) - { - mPath += "#" + OStringToOUString( pUri->fragment, RTL_TEXTENCODING_UTF8 ); - } -} - -void NeonUri::calculateURI () -{ - OUStringBuffer aBuf( 256 ); - aBuf.append( mScheme ); - aBuf.append( "://" ); - if ( !mUserInfo.isEmpty() ) - { - //TODO! differentiate between empty and missing userinfo - aBuf.append( mUserInfo ); - aBuf.append( "@" ); - } - // Is host a numeric IPv6 address? - if ( ( mHostName.indexOf( ':' ) != -1 ) && - ( mHostName[ 0 ] != '[' ) ) - { - aBuf.append( "[" ); - aBuf.append( mHostName ); - aBuf.append( "]" ); - } - else - { - aBuf.append( mHostName ); - } - - // append port, but only, if not default port. - bool bAppendPort = true; - switch ( mPort ) - { - case DEFAULT_HTTP_PORT: - bAppendPort = mScheme != "http"; - break; - - case DEFAULT_HTTPS_PORT: - bAppendPort = mScheme != "https"; - break; - - case DEFAULT_FTP_PORT: - bAppendPort = mScheme != "ftp"; - break; - } - if ( bAppendPort ) - { - aBuf.append( ":" ); - aBuf.append( mPort ); - } - aBuf.append( mPath ); - - mURI = aBuf.makeStringAndClear(); -} - -OUString NeonUri::GetPathBaseName () const -{ - sal_Int32 nPos = mPath.lastIndexOf ('/'); - sal_Int32 nTrail = 0; - if (nPos == mPath.getLength () - 1) - { - // Trailing slash found. Skip. - nTrail = 1; - nPos = mPath.lastIndexOf ('/', nPos); - } - if (nPos != -1) - { - OUString aTemp( - mPath.copy (nPos + 1, mPath.getLength () - nPos - 1 - nTrail) ); - - // query, fragment present? - nPos = aTemp.indexOf( '?' ); - if ( nPos == -1 ) - nPos = aTemp.indexOf( '#' ); - - if ( nPos != -1 ) - aTemp = aTemp.copy( 0, nPos ); - - return aTemp; - } - else - return "/"; -} - -bool NeonUri::operator== ( const NeonUri & rOther ) const -{ - return ( mURI == rOther.mURI ); -} - -OUString NeonUri::GetPathBaseNameUnescaped () const -{ - return unescape( GetPathBaseName() ); -} - -void NeonUri::AppendPath (std::u16string_view rPath) -{ - if (mPath.lastIndexOf ('/') != mPath.getLength () - 1) - mPath += "/"; - - mPath += rPath; - calculateURI (); -}; - -// static -OUString NeonUri::escapeSegment( const OUString& segment ) -{ - return rtl::Uri::encode( segment, - rtl_UriCharClassPchar, - rtl_UriEncodeIgnoreEscapes, - RTL_TEXTENCODING_UTF8 ); -} - -// static -OUString NeonUri::unescape( const OUString& segment ) -{ - return rtl::Uri::decode( segment, - rtl_UriDecodeWithCharset, - RTL_TEXTENCODING_UTF8 ); -} - -// static -OUString NeonUri::makeConnectionEndPointString( - const OUString & rHostName, int nPort ) -{ - OUStringBuffer aBuf; - - // Is host a numeric IPv6 address? - if ( ( rHostName.indexOf( ':' ) != -1 ) && - ( rHostName[ 0 ] != '[' ) ) - { - aBuf.append( "[" ); - aBuf.append( rHostName ); - aBuf.append( "]" ); - } - else - { - aBuf.append( rHostName ); - } - - if ( ( nPort != DEFAULT_HTTP_PORT ) && ( nPort != DEFAULT_HTTPS_PORT ) ) - { - aBuf.append( ":" ); - aBuf.append( static_cast<sal_Int32>(nPort) ); - } - return aBuf.makeStringAndClear(); -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/ucb/source/ucp/webdav-neon/NeonUri.hxx b/ucb/source/ucp/webdav-neon/NeonUri.hxx deleted file mode 100644 index 319026250047..000000000000 --- a/ucb/source/ucp/webdav-neon/NeonUri.hxx +++ /dev/null @@ -1,103 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ -#pragma once - -#include <sal/config.h> - -#include <string_view> - -#include <config_lgpl.h> -#include <ne_uri.h> -#include <rtl/ustring.hxx> -#include "DAVException.hxx" - -namespace webdav_ucp -{ - -#define DEFAULT_HTTP_PORT 80 -#define DEFAULT_HTTPS_PORT 443 -#define DEFAULT_FTP_PORT 21 - -// A URI implementation for use with the neon/expat library -class NeonUri -{ - private: - OUString mURI; - OUString mScheme; - OUString mUserInfo; - OUString mHostName; - sal_Int32 mPort; - OUString mPath; - - void init( const OString & rUri, const ne_uri * pUri ); - void calculateURI (); - - public: - /// @throws DAVException - explicit NeonUri( const OUString & inUri ); - /// @throws DAVException - explicit NeonUri( const ne_uri * inUri ); - - bool operator== ( const NeonUri & rOther ) const; - bool operator!= ( const NeonUri & rOther ) const - { return !operator==( rOther ); } - - const OUString & GetURI() const - { return mURI; }; - const OUString & GetScheme() const - { return mScheme; }; - const OUString & GetUserInfo() const - { return mUserInfo; }; - const OUString & GetHost() const - { return mHostName; }; - sal_Int32 GetPort() const - { return mPort; }; - const OUString & GetPath() const - { return mPath; }; - - OUString GetPathBaseName() const; - - OUString GetPathBaseNameUnescaped() const; - - void SetScheme (const OUString& scheme) - { mScheme = scheme; calculateURI (); }; - - void AppendPath (std::u16string_view rPath); - - static OUString escapeSegment( const OUString& segment ); - static OUString unescape( const OUString& string ); - - // "host:port", omit ":port" for port 80 and 443 - static OUString makeConnectionEndPointString( - const OUString & rHostName, - int nPort ); -}; - -} // namespace webdav_ucp - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/ucb/source/ucp/webdav-neon/PropertyMap.hxx b/ucb/source/ucp/webdav-neon/PropertyMap.hxx deleted file mode 100644 index 508823a8d199..000000000000 --- a/ucb/source/ucp/webdav-neon/PropertyMap.hxx +++ /dev/null @@ -1,65 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -#pragma once - -#include <config_lgpl.h> -#include <com/sun/star/beans/Property.hpp> -#include <unordered_set> - -namespace webdav_ucp { - - -struct equalPropertyName -{ - bool operator()( const css::beans::Property & p1, - const css::beans::Property & p2 ) const - { - return p1.Name == p2.Name; - } -}; - -struct hashPropertyName -{ - size_t operator()( const css::beans::Property & p ) const - { - return p.Name.hashCode(); - } -}; - -typedef std::unordered_set -< - css::beans::Property, - hashPropertyName, - equalPropertyName -> -PropertyMap; - -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/ucb/source/ucp/webdav-neon/PropfindCache.cxx b/ucb/source/ucp/webdav-neon/PropfindCache.cxx deleted file mode 100644 index 951f4a201790..000000000000 --- a/ucb/source/ucp/webdav-neon/PropfindCache.cxx +++ /dev/null @@ -1,86 +0,0 @@ -/* -*- 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/. - */ - -#include <osl/time.h> -#include "PropfindCache.hxx" - -namespace webdav_ucp -{ - - // PropertyNames implementation - - PropertyNames::PropertyNames() : - m_nStaleTime( 0 ) - { - } - - PropertyNames::PropertyNames( const OUString& rURL ) : - m_nStaleTime( 0 ), - m_sURL( rURL ) - { - } - - //PropertyNamesCache implementation - - PropertyNamesCache::PropertyNamesCache() - { - } - - PropertyNamesCache::~PropertyNamesCache() - { - } - - bool PropertyNamesCache::getCachedPropertyNames( const OUString& rURL, PropertyNames& rCacheElement ) - { - // search the URL in the static map - std::scoped_lock aGuard( m_aMutex ); - PropNameCache::const_iterator it = m_aTheCache.find( rURL ); - if ( it == m_aTheCache.end() ) - return false; - else - { - // check if the element is stale, before restoring - TimeValue t1; - osl_getSystemTime( &t1 ); - if ( (*it).second.getStaleTime() < t1.Seconds ) - { - // if stale, remove from cache, do not restore - m_aTheCache.erase( it ); - return false; - // return false instead - } - rCacheElement = (*it).second; - return true; - } - } - - void PropertyNamesCache::removeCachedPropertyNames( const OUString& rURL ) - { - std::scoped_lock aGuard( m_aMutex ); - PropNameCache::const_iterator it = m_aTheCache.find( rURL ); - if ( it != m_aTheCache.end() ) - { - m_aTheCache.erase( it ); - } - } - - void PropertyNamesCache::addCachePropertyNames( PropertyNames& rCacheElement ) - { - std::scoped_lock aGuard( m_aMutex ); - OUString aURL( rCacheElement.getURL() ); - TimeValue t1; - osl_getSystemTime( &t1 ); - rCacheElement.setStaleTime( t1.Seconds + 10 ); - - m_aTheCache[ aURL ] = rCacheElement; - } - -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/ucb/source/ucp/webdav-neon/PropfindCache.hxx b/ucb/source/ucp/webdav-neon/PropfindCache.hxx deleted file mode 100644 index f78d526a7fe0..000000000000 --- a/ucb/source/ucp/webdav-neon/PropfindCache.hxx +++ /dev/null @@ -1,77 +0,0 @@ -/* -*- 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/. - */ - -#pragma once - -#include <sal/types.h> -#include <rtl/ustring.hxx> -#include <mutex> -#include <map> -#include <vector> - -#include "DAVResource.hxx" - -namespace webdav_ucp -{ - // A property names cache mechanism, URL driven. - // It is used to cache the property names received - // from the WebDAV server, to minimize the need of - // net transactions (e.g. PROPFIND). - // The cache lifetime should be short - // just to remove the annoying slowness when - // typing text or moving cursor around when the - // net link is slow. - - // Define the properties cache element - class PropertyNames final - { - /// target time when this element becomes stale - sal_uInt32 m_nStaleTime; - OUString m_sURL; - // the property name list received from WebDAV server - std::vector< DAVResourceInfo > m_aPropertiesNames; - - public: - PropertyNames(); - explicit PropertyNames( const OUString& rURL ); - - sal_uInt32 getStaleTime() const { return m_nStaleTime; }; - void setStaleTime( const sal_uInt32 nStaleTime ) { m_nStaleTime = nStaleTime; }; - - OUString& getURL() { return m_sURL; }; - - const std::vector< DAVResourceInfo >& getPropertiesNames() const { return m_aPropertiesNames; }; - void setPropertiesNames( std::vector< DAVResourceInfo >&& aPropertiesNames ) { m_aPropertiesNames = std::move(aPropertiesNames); }; - }; - - // Define the PropertyNames cache - // TODO: the OUString key element in std::map needs to be changed with a URI representation - // with a specific compare (std::less) implementation, this last one implementing - // as suggested in <https://tools.ietf.org/html/rfc3986#section-6>. - // To find by URI and not by string equality. - typedef std::map< OUString, PropertyNames, - std::less< OUString > >PropNameCache; - - class PropertyNamesCache final - { - PropNameCache m_aTheCache; - std::mutex m_aMutex; - - public: - PropertyNamesCache(); - ~PropertyNamesCache(); - - bool getCachedPropertyNames( const OUString& URL, PropertyNames& rCacheElement ); - void removeCachedPropertyNames( const OUString& URL ); - void addCachePropertyNames( PropertyNames& rCacheElement ); - }; - -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/ucb/source/ucp/webdav-neon/UCBDeadPropertyValue.cxx b/ucb/source/ucp/webdav-neon/UCBDeadPropertyValue.cxx deleted file mode 100644 index 967d1f36debe..000000000000 --- a/ucb/source/ucp/webdav-neon/UCBDeadPropertyValue.cxx +++ /dev/null @@ -1,509 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -#include <config_lgpl.h> -#include <string.h> -#include <ne_xml.h> -#include <rtl/ustrbuf.hxx> -#include <sal/log.hxx> -#include "UCBDeadPropertyValue.hxx" -#include <memory> - -using namespace webdav_ucp; -using namespace com::sun::star; - -namespace { - -struct UCBDeadPropertyValueParseContext -{ - std::unique_ptr<OUString> pType; - std::unique_ptr<OUString> pValue; - - UCBDeadPropertyValueParseContext() {} -}; - -} - -constexpr OUStringLiteral aTypeString = u"string"; -constexpr OUStringLiteral aTypeLong = u"long"; -constexpr OUStringLiteral aTypeShort = u"short"; -constexpr OUStringLiteral aTypeBoolean = u"boolean"; -constexpr OUStringLiteral aTypeChar = u"char"; -constexpr OUStringLiteral aTypeByte = u"byte"; -constexpr OUStringLiteral aTypeHyper = u"hyper"; -constexpr OUStringLiteral aTypeFloat = u"float"; -constexpr OUStringLiteral aTypeDouble = u"double"; - -constexpr OUStringLiteral aXMLPre = u"<ucbprop><type>"; -constexpr OUStringLiteral aXMLMid = u"</type><value>"; -constexpr OUStringLiteral aXMLEnd = u"</value></ucbprop>"; - - -#define STATE_TOP (1) - -#define STATE_UCBPROP (STATE_TOP) -#define STATE_TYPE (STATE_TOP + 1) -#define STATE_VALUE (STATE_TOP + 2) - - -extern "C" { - -static int UCBDeadPropertyValue_startelement_callback( - void *, - int parent, - const char * /*nspace*/, - const char *name, - const char ** ) -{ - if ( name != nullptr ) - { - switch ( parent ) - { - case NE_XML_STATEROOT: - if ( strcmp( name, "ucbprop" ) == 0 ) - return STATE_UCBPROP; - break; - - case STATE_UCBPROP: - if ( strcmp( name, "type" ) == 0 ) - return STATE_TYPE; - else if ( strcmp( name, "value" ) == 0 ) - return STATE_VALUE; - break; - } - } - return NE_XML_DECLINE; -} - - -static int UCBDeadPropertyValue_chardata_callback( - void *userdata, - int state, - const char *buf, - size_t len ) -{ - UCBDeadPropertyValueParseContext * pCtx - = static_cast< UCBDeadPropertyValueParseContext * >( userdata ); - - switch ( state ) - { - case STATE_TYPE: - assert( !pCtx->pType && - "UCBDeadPropertyValue_endelement_callback - " - "Type already set!" ); - pCtx->pType.reset( new OUString( buf, len, RTL_TEXTENCODING_ASCII_US ) ); - break; - - case STATE_VALUE: - assert( !pCtx->pValue && - "UCBDeadPropertyValue_endelement_callback - " - "Value already set!" ); - pCtx->pValue.reset( new OUString( buf, len, RTL_TEXTENCODING_ASCII_US ) ); - break; - } - return 0; // zero to continue, non-zero to abort parsing -} - - -static int UCBDeadPropertyValue_endelement_callback( - void *userdata, - int state, - const char *, - const char * ) -{ - UCBDeadPropertyValueParseContext * pCtx - = static_cast< UCBDeadPropertyValueParseContext * >( userdata ); - - switch ( state ) - { - case STATE_TYPE: - if ( !pCtx->pType ) - return 1; // abort - break; - - case STATE_VALUE: - if ( !pCtx->pValue ) - return 1; // abort - break; - - case STATE_UCBPROP: - if ( !pCtx->pType || ! pCtx->pValue ) - return 1; // abort - break; - } - return 0; // zero to continue, non-zero to abort parsing -} - -} - -static OUString encodeValue( const OUString & rValue ) -{ - // Note: I do not use the usual & + < + > encoding, because - // I want to prevent any XML parser from trying to 'understand' - // the value. This caused problems: - - // Example: - // - Unencoded property value: x<z - // PROPPATCH: - // - Encoded property value: x<z - // - UCBDeadPropertyValue::toXML result: - // <ucbprop><type>string</type><value>x<z</value></ucbprop> - // PROPFIND: - // - parser replaces < by > ==> error (not well formed) - - OUStringBuffer aResult; - const sal_Unicode * pValue = rValue.getStr(); - - sal_Int32 nCount = rValue.getLength(); - for ( sal_Int32 n = 0; n < nCount; ++n ) - { - const sal_Unicode c = pValue[ n ]; - - if ( '%' == c ) - aResult.append( "%per;" ); - else if ( '<' == c ) - aResult.append( "%lt;" ); - else if ( '>' == c ) - aResult.append( "%gt;" ); - else - aResult.append( c ); - } - return aResult.makeStringAndClear(); -} - - -static OUString decodeValue( const OUString & rValue ) -{ - OUStringBuffer aResult; - const sal_Unicode * pValue = rValue.getStr(); - - sal_Int32 nPos = 0; - sal_Int32 nEnd = rValue.getLength(); - - while ( nPos < nEnd ) - { - sal_Unicode c = pValue[ nPos ]; - - if ( '%' == c ) - { - nPos++; - - if ( nPos == nEnd ) - { - SAL_WARN( "ucb.ucp.webdav", "decodeValue() - syntax error!" ); - return OUString(); - } - - c = pValue[ nPos ]; - - if ( 'p' == c ) - { - // %per; - - if ( nPos > nEnd - 4 ) - { - SAL_WARN( "ucb.ucp.webdav", "decodeValue() - syntax error!" ); - return OUString(); - } - - if ( ( 'e' == pValue[ nPos + 1 ] ) - && - ( 'r' == pValue[ nPos + 2 ] ) - && - ( ';' == pValue[ nPos + 3 ] ) ) - { - aResult.append( '%' ); - nPos += 3; - } - else - { - SAL_WARN( "ucb.ucp.webdav", "decodeValue() - syntax error!" ); - return OUString(); - } - } - else if ( 'l' == c ) - { - // %lt; - - if ( nPos > nEnd - 3 ) - { - SAL_WARN( "ucb.ucp.webdav", "decodeValue() - syntax error!" ); - return OUString(); - } - - if ( ( 't' == pValue[ nPos + 1 ] ) - && - ( ';' == pValue[ nPos + 2 ] ) ) - { - aResult.append( '<' ); - nPos += 2; - } - else - { - SAL_WARN( "ucb.ucp.webdav", "decodeValue() - syntax error!" ); - return OUString(); - } - } - else if ( 'g' == c ) - { - // %gt; - - if ( nPos > nEnd - 3 ) - { - SAL_WARN( "ucb.ucp.webdav", "decodeValue() - syntax error!" ); - return OUString(); - } - - if ( ( 't' == pValue[ nPos + 1 ] ) - && - ( ';' == pValue[ nPos + 2 ] ) ) - { - aResult.append( '>' ); - nPos += 2; - } - else - { - SAL_WARN( "ucb.ucp.webdav", "decodeValue() - syntax error!" ); - return OUString(); - } - } - else - { - SAL_WARN( "ucb.ucp.webdav", "decodeValue() - syntax error!" ); - return OUString(); - } - } - else - aResult.append( c ); - - nPos++; - } - - return aResult.makeStringAndClear(); -} - - -// static -bool UCBDeadPropertyValue::supportsType( const uno::Type & rType ) -{ - return rType == cppu::UnoType<OUString>::get() - || rType == cppu::UnoType<sal_Int32>::get() - || rType == cppu::UnoType<sal_Int16>::get() - || rType == cppu::UnoType<bool>::get() - || rType == cppu::UnoType<cppu::UnoCharType>::get() - || rType == cppu::UnoType<sal_Int8>::get() - || rType == cppu::UnoType<sal_Int64>::get() - || rType == cppu::UnoType<float>::get() - || rType == cppu::UnoType<double>::get(); -} - - -// static -bool UCBDeadPropertyValue::createFromXML( const OString & rInData, - uno::Any & rOutData ) -{ - bool success = false; - - ne_xml_parser * parser = ne_xml_create(); - if ( parser ) - { - UCBDeadPropertyValueParseContext aCtx; - ne_xml_push_handler( parser, - UCBDeadPropertyValue_startelement_callback, - UCBDeadPropertyValue_chardata_callback, - UCBDeadPropertyValue_endelement_callback, - &aCtx ); - - ne_xml_parse( parser, rInData.getStr(), rInData.getLength() ); - - success = !ne_xml_failed( parser ); - - ne_xml_destroy( parser ); - - if ( success ) - { - if ( aCtx.pType && aCtx.pValue ) - { - // Decode aCtx.pValue! It may contain XML reserved chars. - OUString aStringValue = decodeValue( *aCtx.pValue ); - if ( aCtx.pType->equalsIgnoreAsciiCase( aTypeString ) ) - { - rOutData <<= aStringValue; - } - else if ( aCtx.pType->equalsIgnoreAsciiCase( aTypeLong ) ) - { - rOutData <<= aStringValue.toInt32(); - } - else if ( aCtx.pType->equalsIgnoreAsciiCase( aTypeShort ) ) - { - rOutData <<= sal_Int16( aStringValue.toInt32() ); - } - else if ( aCtx.pType->equalsIgnoreAsciiCase( aTypeBoolean ) ) - { - if ( aStringValue.equalsIgnoreAsciiCase("true") ) - rOutData <<= true; - else - rOutData <<= false; - } - else if ( aCtx.pType->equalsIgnoreAsciiCase( aTypeChar ) ) - { - rOutData <<= aStringValue.toChar(); - } - else if ( aCtx.pType->equalsIgnoreAsciiCase( aTypeByte ) ) - { - rOutData <<= sal_Int8( aStringValue.toChar() ); - } - else if ( aCtx.pType->equalsIgnoreAsciiCase( aTypeHyper ) ) - { - rOutData <<= aStringValue.toInt64(); - } - else if ( aCtx.pType->equalsIgnoreAsciiCase( aTypeFloat ) ) - { - rOutData <<= aStringValue.toFloat(); - } - else if ( aCtx.pType->equalsIgnoreAsciiCase( aTypeDouble ) ) - { - rOutData <<= aStringValue.toDouble(); - } - else - { - SAL_WARN( "ucb.ucp.webdav", "createFromXML() - " - "Unsupported property type!" ); - success = false; - } - } - else - success = false; - } - } - - return success; -} - - -// static -bool UCBDeadPropertyValue::toXML( const uno::Any & rInData, - OUString & rOutData ) -{ - // <ucbprop><type>the_type</type><value>the_value</value></ucbprop> - - // Check property type. Extract type and value as string. - - const uno::Type& rType = rInData.getValueType(); - OUString aStringValue; - OUString aStringType; - - if ( rType == cppu::UnoType<OUString>::get() ) - { - // string - rInData >>= aStringValue; - aStringType = aTypeString; - } - else if ( rType == cppu::UnoType<sal_Int32>::get() ) - { - // long - sal_Int32 nValue = 0; - rInData >>= nValue; - aStringValue = OUString::number( nValue ); - aStringType = aTypeLong; - } - else if ( rType == cppu::UnoType<sal_Int16>::get() ) - { - // short - sal_Int32 nValue = 0; - rInData >>= nValue; - aStringValue = OUString::number( nValue ); - aStringType = aTypeShort; - } - else if ( rType == cppu::UnoType<bool>::get() ) - { - // boolean - bool bValue = false; - rInData >>= bValue; - aStringValue = OUString::boolean( bValue ); - aStringType = aTypeBoolean; - } - else if ( rType == cppu::UnoType<cppu::UnoCharType>::get() ) - { - // char - sal_Unicode cValue = 0; - rInData >>= cValue; - aStringValue = OUString( cValue ); - aStringType = aTypeChar; - } - else if ( rType == cppu::UnoType<sal_Int8>::get() ) - { - // byte - sal_Int8 nValue = 0; - rInData >>= nValue; - aStringValue = OUString( sal_Unicode( nValue ) ); - aStringType = aTypeByte; - } - else if ( rType == cppu::UnoType<sal_Int64>::get() ) - { - // hyper - sal_Int64 nValue = 0; - rInData >>= nValue; - aStringValue = OUString::number( nValue ); - aStringType = aTypeHyper; - } - else if ( rType == cppu::UnoType<float>::get() ) - { - // float - float nValue = 0; - rInData >>= nValue; - aStringValue = OUString::number( nValue ); - aStringType = aTypeFloat; - } - else if ( rType == cppu::UnoType<double>::get() ) - { - // double - double nValue = 0; - rInData >>= nValue; - aStringValue = OUString::number( nValue ); - aStringType = aTypeDouble; - } - else - { - SAL_WARN( "ucb.ucp.webdav", "toXML() - unsupported property type!" ); - return false; - } - - // Encode value! It must not contain XML reserved chars! - aStringValue = encodeValue( aStringValue ); - - rOutData = aXMLPre; - rOutData += aStringType; - rOutData += aXMLMid; - rOutData += aStringValue; - rOutData += aXMLEnd; - - return true; -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/ucb/source/ucp/webdav-neon/UCBDeadPropertyValue.hxx b/ucb/source/ucp/webdav-neon/UCBDeadPropertyValue.hxx deleted file mode 100644 index 5f2b38ed1f9e..000000000000 --- a/ucb/source/ucp/webdav-neon/UCBDeadPropertyValue.hxx +++ /dev/null @@ -1,50 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -#pragma once - -#include <rtl/string.hxx> -#include <com/sun/star/uno/Any.hxx> - -namespace webdav_ucp -{ - -class UCBDeadPropertyValue -{ -public: - static bool supportsType( const css::uno::Type & rType ); - - static bool createFromXML( const OString & rInData, - css::uno::Any & rOutData ); - static bool toXML( const css::uno::Any & rInData, - OUString & rOutData ); -}; - -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/ucb/source/ucp/webdav-neon/ucpdav1.component b/ucb/source/ucp/webdav-neon/ucpdav1.component deleted file mode 100644 index 23be195bf453..000000000000 --- a/ucb/source/ucp/webdav-neon/ucpdav1.component +++ /dev/null @@ -1,35 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!--********************************************************************** -* -* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -* -* Copyright 2000, 2010 Oracle and/or its affiliates. -* -* OpenOffice.org - a multi-platform office productivity suite -* -* This file is part of OpenOffice.org. -* -* OpenOffice.org is free software: you can redistribute it and/or modify -* it under the terms of the GNU Lesser General Public License version 3 -* only, as published by the Free Software Foundation. -* -* OpenOffice.org is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License version 3 for more details -* (a copy is included in the LICENSE file that accompanied this code). -* -* You should have received a copy of the GNU Lesser General Public License -* version 3 along with OpenOffice.org. If not, see -* <http://www.openoffice.org/license.html> -* for a copy of the LGPLv3 License. -* -**********************************************************************--> - -<component loader="com.sun.star.loader.SharedLibrary" environment="@CPPU_ENV@" - xmlns="http://openoffice.org/2010/uno-components"> - <implementation name="com.sun.star.comp.WebDAVContentProvider" - constructor="ucb_webdav_neon_ContentProvider_get_implementation"> - <service name="com.sun.star.ucb.WebDAVContentProvider"/> - </implementation> -</component> diff --git a/ucb/source/ucp/webdav-neon/webdavcontent.cxx b/ucb/source/ucp/webdav-neon/webdavcontent.cxx deleted file mode 100644 index c3310e24f9cc..000000000000 --- a/ucb/source/ucp/webdav-neon/webdavcontent.cxx +++ /dev/null @@ -1,4197 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - - -/************************************************************************** - TODO - ************************************************************************** - - *************************************************************************/ - -#include <memory> -#include <rtl/uri.hxx> -#include <rtl/ustrbuf.hxx> -#include <sal/log.hxx> -#include <cppuhelper/queryinterface.hxx> -#include <officecfg/Inet.hxx> -#include <ucbhelper/contentidentifier.hxx> -#include <ucbhelper/propertyvalueset.hxx> -#include <ucbhelper/simpleinteractionrequest.hxx> -#include <ucbhelper/cancelcommandexecution.hxx> -#include <com/sun/star/beans/IllegalTypeException.hpp> -#include <com/sun/star/beans/NotRemoveableException.hpp> -#include <com/sun/star/beans/PropertyAttribute.hpp> -#include <com/sun/star/beans/PropertyExistException.hpp> -#include <com/sun/star/beans/PropertySetInfoChange.hpp> -#include <com/sun/star/beans/PropertySetInfoChangeEvent.hpp> -#include <com/sun/star/beans/PropertyValue.hpp> -#include <com/sun/star/io/XActiveDataSink.hpp> -#include <com/sun/star/io/XOutputStream.hpp> -#include <com/sun/star/lang/IllegalAccessException.hpp> -#include <com/sun/star/sdbc/SQLException.hpp> -#include <com/sun/star/task/PasswordContainerInteractionHandler.hpp> -#include <com/sun/star/ucb/CommandEnvironment.hpp> -#include <com/sun/star/ucb/CommandFailedException.hpp> -#include <com/sun/star/ucb/ContentInfoAttribute.hpp> -#include <com/sun/star/ucb/IllegalIdentifierException.hpp> -#include <com/sun/star/ucb/InsertCommandArgument.hpp> -#include <com/sun/star/ucb/InteractiveBadTransferURLException.hpp> -#include <com/sun/star/ucb/InteractiveAugmentedIOException.hpp> -#include <com/sun/star/ucb/InteractiveLockingLockedException.hpp> -#include <com/sun/star/ucb/InteractiveLockingLockExpiredException.hpp> -#include <com/sun/star/ucb/InteractiveLockingNotLockedException.hpp> -#include <com/sun/star/ucb/InteractiveNetworkConnectException.hpp> -#include <com/sun/star/ucb/InteractiveNetworkGeneralException.hpp> -#include <com/sun/star/ucb/InteractiveNetworkReadException.hpp> -#include <com/sun/star/ucb/InteractiveNetworkResolveNameException.hpp> -#include <com/sun/star/ucb/InteractiveNetworkWriteException.hpp> -#include <com/sun/star/ucb/MissingInputStreamException.hpp> -#include <com/sun/star/ucb/MissingPropertiesException.hpp> -#include <com/sun/star/ucb/NameClash.hpp> -#include <com/sun/star/ucb/NameClashException.hpp> -#include <com/sun/star/ucb/OpenCommandArgument3.hpp> -#include <com/sun/star/ucb/OpenMode.hpp> -#include <com/sun/star/ucb/PostCommandArgument2.hpp> -#include <com/sun/star/ucb/PropertyCommandArgument.hpp> -#include <com/sun/star/ucb/TransferInfo.hpp> -#include <com/sun/star/ucb/UnsupportedCommandException.hpp> -#include <com/sun/star/ucb/UnsupportedDataSinkException.hpp> -#include <com/sun/star/ucb/UnsupportedNameClashException.hpp> -#include <com/sun/star/ucb/UnsupportedOpenModeException.hpp> -#include <com/sun/star/ucb/XCommandInfo.hpp> -#include <com/sun/star/ucb/XPersistentPropertySet.hpp> -#include <ucbhelper/macros.hxx> - -#include "webdavcontent.hxx" -#include "webdavprovider.hxx" -#include "webdavresultset.hxx" -#include "ContentProperties.hxx" -#include "NeonUri.hxx" -#include "UCBDeadPropertyValue.hxx" - -using namespace com::sun::star; -using namespace webdav_ucp; - -namespace -{ - // implement a GET to substitute HEAD, when HEAD not available - void lcl_sendPartialGETRequest( bool &bError, - DAVException &aLastException, - const std::vector< OUString >& rProps, - std::vector< OUString > &aHeaderNames, - const std::unique_ptr< DAVResourceAccess > &xResAccess, - std::unique_ptr< ContentProperties > &xProps, - const uno::Reference< ucb::XCommandEnvironment >& xEnv ) - { - DAVResource aResource; - DAVRequestHeaders aPartialGet; - aPartialGet.emplace_back( OUString( "Range" ), // see <https://tools.ietf.org/html/rfc7233#section-3.1> - OUString( "bytes=0-0" ) ); - - bool bIsRequestSize = std::any_of(aHeaderNames.begin(), aHeaderNames.end(), - [](const OUString& rHeaderName) { return rHeaderName == "Content-Length"; }); - - if ( bIsRequestSize ) - { - // we need to know if the server accepts range requests for a resource - // and the range unit it uses - aHeaderNames.emplace_back( "Accept-Ranges" ); // see <https://tools.ietf.org/html/rfc7233#section-2.3> - aHeaderNames.emplace_back( "Content-Range" ); // see <https://tools.ietf.org/html/rfc7233#section-4.2> - } - try - { - xResAccess->GET0( aPartialGet, aHeaderNames, aResource, xEnv ); - bError = false; - - if ( bIsRequestSize ) - { - // the ContentProperties maps "Content-Length" to the UCB "Size" property - // This would have an unrealistic value of 1 byte because we did only a partial GET - // Solution: if "Content-Range" is present, map it with UCB "Size" property - OUString aAcceptRanges, aContentRange, aContentLength; - std::vector< DAVPropertyValue > &aResponseProps = aResource.properties; - for ( const auto& rResponseProp : aResponseProps ) - { - if ( rResponseProp.Name == "Accept-Ranges" ) - rResponseProp.Value >>= aAcceptRanges; - else if ( rResponseProp.Name == "Content-Range" ) - rResponseProp.Value >>= aContentRange; - else if ( rResponseProp.Name == "Content-Length" ) - rResponseProp.Value >>= aContentLength; - } - - sal_Int64 nSize = 1; - if ( aContentLength.getLength() ) - { - nSize = aContentLength.toInt64(); - } - - // according to <> http://tools.ietf.org/html/rfc2616#section-3.12 - // <https://tools.ietf.org/html/rfc7233#section-2> - // needs some explanation for this - // probably some changes? - // the only range unit defined is "bytes" and implementations - // MAY ignore ranges specified using other units. - if ( nSize == 1 && - aContentRange.getLength() && - aAcceptRanges == "bytes" ) - { - // Parse the Content-Range to get the size - // vid. http://tools.ietf.org/html/rfc2616#section-14.16 - // Content-Range: <range unit> <bytes range>/<size> - sal_Int32 nSlash = aContentRange.lastIndexOf( '/' ); - if ( nSlash != -1 ) - { - OUString aSize = aContentRange.copy( nSlash + 1 ); - // "*" means that the instance-length is unknown at the time when the response was generated - if ( aSize != "*" ) - { - auto it = std::find_if(aResponseProps.begin(), aResponseProps.end(), - [](const DAVPropertyValue& rProp) { return rProp.Name == "Content-Length"; }); - if (it != aResponseProps.end()) - { - it->Value <<= aSize; - } - } - } - } - } - - if (xProps) - xProps->addProperties( - rProps, - ContentProperties( aResource ) ); - else - xProps.reset ( new ContentProperties( aResource ) ); - } - catch ( DAVException const & ex ) - { - aLastException = ex; - } - } -} - - -// Static value, to manage a simple OPTIONS cache -// Key is the URL, element is the DAVOptions resulting from an OPTIONS call. -// Cached DAVOptions have a lifetime that depends on the errors received or not received -// and on the value of received options. -static DAVOptionsCache aStaticDAVOptionsCache; - - -// Content Implementation. - - -// ctr for content on an existing webdav resource -Content::Content( - const uno::Reference< uno::XComponentContext >& rxContext, - ContentProvider* pProvider, - const uno::Reference< ucb::XContentIdentifier >& Identifier, - rtl::Reference< DAVSessionFactory > const & rSessionFactory ) -: ContentImplHelper( rxContext, pProvider, Identifier ), - m_eResourceType( UNKNOWN ), - m_eResourceTypeForLocks( UNKNOWN ), - m_pProvider( pProvider ), - m_bTransient( false ), - m_bCollection( false ), - m_bDidGetOrHead( false ) -{ - try - { - initOptsCacheLifeTime(); - m_xResAccess.reset( new DAVResourceAccess( - rxContext, - rSessionFactory, - Identifier->getContentIdentifier() ) ); - - NeonUri aURI( Identifier->getContentIdentifier() ); - m_aEscapedTitle = aURI.GetPathBaseName(); - } - catch ( DAVException const & ) - { - throw ucb::ContentCreationException(); - } -} - - -// ctr for content on a non-existing webdav resource -Content::Content( - const uno::Reference< uno::XComponentContext >& rxContext, - ContentProvider* pProvider, - const uno::Reference< ucb::XContentIdentifier >& Identifier, - rtl::Reference< DAVSessionFactory > const & rSessionFactory, - bool isCollection ) -: ContentImplHelper( rxContext, pProvider, Identifier ), - m_eResourceType( UNKNOWN ), - m_eResourceTypeForLocks( UNKNOWN ), - m_pProvider( pProvider ), - m_bTransient( true ), - m_bCollection( isCollection ), - m_bDidGetOrHead( false ) -{ - try - { - initOptsCacheLifeTime(); - m_xResAccess.reset( new DAVResourceAccess( - rxContext, rSessionFactory, Identifier->getContentIdentifier() ) ); - } - catch ( DAVException const & ) - { - throw ucb::ContentCreationException(); - } - - // Do not set m_aEscapedTitle here! Content::insert relays on this!!! -} - - -// virtual -Content::~Content() -{ -} - - -// XInterface methods. - - -// virtual -void SAL_CALL Content::acquire() - noexcept -{ - ContentImplHelper::acquire(); -} - - -// virtual -void SAL_CALL Content::release() - noexcept -{ - ContentImplHelper::release(); -} - - -// virtual -uno::Any SAL_CALL Content::queryInterface( const uno::Type & rType ) -{ - // Note: isFolder may require network activities! So call it only - // if it is really necessary!!! - uno::Any aRet = cppu::queryInterface( - rType, - static_cast< ucb::XContentCreator * >( this ) ); - if ( aRet.hasValue() ) - { - try - { - uno::Reference< task::XInteractionHandler > xIH( - task::PasswordContainerInteractionHandler::create( m_xContext ) ); - - // Supply a command env to isFolder() that contains an interaction - // handler that uses the password container service to obtain - // credentials without displaying a password gui. - - uno::Reference< ucb::XCommandEnvironment > xCmdEnv( - ucb::CommandEnvironment::create( - m_xContext, - xIH, - uno::Reference< ucb::XProgressHandler >() ) ); - - return isFolder( xCmdEnv ) ? aRet : uno::Any(); - } - catch ( uno::RuntimeException const & ) - { - throw; - } - catch ( uno::Exception const & ) - { - return uno::Any(); - } - } - return aRet.hasValue() ? aRet : ContentImplHelper::queryInterface( rType ); -} - - -// XTypeProvider methods. - - -XTYPEPROVIDER_COMMON_IMPL( Content ); - - -// virtual -uno::Sequence< uno::Type > SAL_CALL Content::getTypes() -{ - bool bFolder = false; - try - { - bFolder - = isFolder( uno::Reference< ucb::XCommandEnvironment >() ); - } - catch ( uno::RuntimeException const & ) - { - throw; - } - catch ( uno::Exception const & ) - { - } - - if ( bFolder ) - { - static cppu::OTypeCollection s_aFolderTypes( - CPPU_TYPE_REF( lang::XTypeProvider ), - CPPU_TYPE_REF( lang::XServiceInfo ), - CPPU_TYPE_REF( lang::XComponent ), - CPPU_TYPE_REF( ucb::XContent ), - CPPU_TYPE_REF( ucb::XCommandProcessor ), - CPPU_TYPE_REF( beans::XPropertiesChangeNotifier ), - CPPU_TYPE_REF( ucb::XCommandInfoChangeNotifier ), - CPPU_TYPE_REF( beans::XPropertyContainer ), - CPPU_TYPE_REF( beans::XPropertySetInfoChangeNotifier ), - CPPU_TYPE_REF( container::XChild ), - CPPU_TYPE_REF( ucb::XContentCreator ) ); - - return s_aFolderTypes.getTypes(); - } - else - { - static cppu::OTypeCollection s_aDocumentTypes( - CPPU_TYPE_REF( lang::XTypeProvider ), - CPPU_TYPE_REF( lang::XServiceInfo ), - CPPU_TYPE_REF( lang::XComponent ), - CPPU_TYPE_REF( ucb::XContent ), - CPPU_TYPE_REF( ucb::XCommandProcessor ), - CPPU_TYPE_REF( beans::XPropertiesChangeNotifier ), - CPPU_TYPE_REF( ucb::XCommandInfoChangeNotifier ), - CPPU_TYPE_REF( beans::XPropertyContainer ), - CPPU_TYPE_REF( beans::XPropertySetInfoChangeNotifier ), - CPPU_TYPE_REF( container::XChild ) ); - - return s_aDocumentTypes.getTypes(); - } -} - - -// XServiceInfo methods. - - -// virtual -OUString SAL_CALL Content::getImplementationName() -{ - return "com.sun.star.comp.ucb.WebDAVContent"; -} - - -// virtual -uno::Sequence< OUString > SAL_CALL Content::getSupportedServiceNames() -{ - return { WEBDAV_CONTENT_SERVICE_NAME }; -} - - -// XContent methods. - - -// virtual -OUString SAL_CALL Content::getContentType() -{ - bool bFolder = false; - try - { - bFolder - = isFolder( uno::Reference< ucb::XCommandEnvironment >() ); - } - catch ( uno::RuntimeException const & ) - { - throw; - } - catch ( uno::Exception const & ) - { - } - - if ( bFolder ) - return WEBDAV_COLLECTION_TYPE; - - return WEBDAV_CONTENT_TYPE; -} - - -// XCommandProcessor methods. - - -// virtual -uno::Any SAL_CALL Content::execute( - const ucb::Command& aCommand, - sal_Int32 /*CommandId*/, - const uno::Reference< ucb::XCommandEnvironment >& Environment ) -{ - SAL_INFO( "ucb.ucp.webdav", "Content::execute: start: command: " << - aCommand.Name << ", env: " << - (Environment.is() ? "present" : "missing") ); - - uno::Any aRet; - - if ( aCommand.Name == "getPropertyValues" ) - { - - // getPropertyValues - - - uno::Sequence< beans::Property > Properties; - if ( !( aCommand.Argument >>= Properties ) ) - { - ucbhelper::cancelCommandExecution( - uno::makeAny( lang::IllegalArgumentException( - "Wrong argument type!", - static_cast< cppu::OWeakObject * >( this ), - -1 ) ), - Environment ); - // Unreachable - } - - aRet <<= getPropertyValues( Properties, Environment ); - } - else if ( aCommand.Name == "setPropertyValues" ) - { - - // setPropertyValues - - - uno::Sequence< beans::PropertyValue > aProperties; - if ( !( aCommand.Argument >>= aProperties ) ) - { - ucbhelper::cancelCommandExecution( - uno::makeAny( lang::IllegalArgumentException( - "Wrong argument type!", - static_cast< cppu::OWeakObject * >( this ), - -1 ) ), - Environment ); - // Unreachable - } - - if ( !aProperties.hasElements() ) - { - ucbhelper::cancelCommandExecution( - uno::makeAny( lang::IllegalArgumentException( - "No properties!", - static_cast< cppu::OWeakObject * >( this ), - -1 ) ), - Environment ); - // Unreachable - } - - aRet <<= setPropertyValues( aProperties, Environment ); - } - else if ( aCommand.Name == "getPropertySetInfo" ) - { - - // getPropertySetInfo - - - // Note: Implemented by base class. - aRet <<= getPropertySetInfo( Environment, - false /* don't cache data */ ); - } - else if ( aCommand.Name == "getCommandInfo" ) - { - - // getCommandInfo - - - // Note: Implemented by base class. - aRet <<= getCommandInfo( Environment, false ); - } - else if ( aCommand.Name == "open" ) - { - - // open - - - ucb::OpenCommandArgument3 aOpenCommand; - ucb::OpenCommandArgument2 aTmp; - if ( !( aCommand.Argument >>= aTmp ) ) - { - ucbhelper::cancelCommandExecution( - uno::makeAny( lang::IllegalArgumentException( - "Wrong argument type!", - static_cast< cppu::OWeakObject * >( this ), - -1 ) ), - Environment ); - // Unreachable - } - if ( !( aCommand.Argument >>= aOpenCommand ) ) - { - // compat mode, extract Arg2 info into newer structure - aOpenCommand.Mode = aTmp.Mode; - aOpenCommand.Priority = aTmp.Priority; - aOpenCommand.Sink = aTmp.Sink; - aOpenCommand.Properties = aTmp.Properties; - aOpenCommand.SortingInfo = aTmp.SortingInfo; - } - - aRet = open( aOpenCommand, Environment ); - - } - else if ( aCommand.Name == "insert" ) - { - - // insert - - - ucb::InsertCommandArgument arg; - if ( !( aCommand.Argument >>= arg ) ) - { - ucbhelper::cancelCommandExecution( - uno::makeAny( lang::IllegalArgumentException( - "Wrong argument type!", - static_cast< cppu::OWeakObject * >( this ), - -1 ) ), - Environment ); - // Unreachable - } - - insert( arg.Data, arg.ReplaceExisting, Environment ); - } - else if ( aCommand.Name == "delete" ) - { - - // delete - - - bool bDeletePhysical = false; - aCommand.Argument >>= bDeletePhysical; - -// KSO: Ignore parameter and destroy the content, if you don't support -// putting objects into trashcan. ( Since we do not have a trash can -// service yet (src603), you actually have no other choice. ) -// if ( bDeletePhysical ) -// { - try - { - std::unique_ptr< DAVResourceAccess > xResAccess; - { - osl::Guard< osl::Mutex > aGuard( m_aMutex ); - xResAccess.reset(new DAVResourceAccess(*m_xResAccess)); - } - aStaticDAVOptionsCache.removeDAVOptions( xResAccess->getURL() ); - // clean cached value of PROPFIND property names - removeCachedPropertyNames( xResAccess->getURL() ); - xResAccess->DESTROY( Environment ); - { - osl::Guard< osl::Mutex > aGuard( m_aMutex ); - m_xResAccess.reset(new DAVResourceAccess(*xResAccess)); - } - } - catch ( DAVException const & e ) - { - cancelCommandExecution( e, Environment, true ); - // Unreachable - } -// } - - // Propagate destruction. - destroy( bDeletePhysical ); - - // Remove own and all children's Additional Core Properties. - removeAdditionalPropertySet(); - } - else if ( aCommand.Name == "transfer" && isFolder( Environment ) ) - { - - // transfer - // ( Not available at documents ) - - - ucb::TransferInfo transferArgs; - if ( !( aCommand.Argument >>= transferArgs ) ) - { - ucbhelper::cancelCommandExecution( - uno::makeAny( lang::IllegalArgumentException( - "Wrong argument type!", - static_cast< cppu::OWeakObject * >( this ), - -1 ) ), - Environment ); - // Unreachable - } - - transfer( transferArgs, Environment ); - } - else if ( aCommand.Name == "post" ) - { - - // post - - - ucb::PostCommandArgument2 aArg; - if ( !( aCommand.Argument >>= aArg ) ) - { - ucbhelper::cancelCommandExecution( - uno::makeAny( lang::IllegalArgumentException( - "Wrong argument type!", - static_cast< cppu::OWeakObject * >( this ), - -1 ) ), - Environment ); - // Unreachable - } - - post( aArg, Environment ); - } - else if ( aCommand.Name == "lock" ) - { - - // lock - - ResourceType eType = resourceTypeForLocks( Environment ); - // when the resource is not yet present the lock is used to create it - // see: http://tools.ietf.org/html/rfc4918#section-7.3 - // If the resource doesn't exists and the lock is not enabled (DAV with - // no lock or a simple web) the error will be dealt with inside lock() method - if ( eType == NOT_FOUND || - eType == DAV ) - { - lock( Environment ); - if ( eType == NOT_FOUND ) - { - m_eResourceType = UNKNOWN; // lock may have created it, need to check again - m_eResourceTypeForLocks = UNKNOWN; - } - } - } - else if ( aCommand.Name == "unlock" ) - { - - // unlock - // do not check for a DAV resource - // the lock store will be checked before sending - unlock( Environment ); - } - else if ( aCommand.Name == "createNewContent" && isFolder( Environment ) ) - { - - // createNewContent - - - ucb::ContentInfo aArg; - if ( !( aCommand.Argument >>= aArg ) ) - { - ucbhelper::cancelCommandExecution( - uno::makeAny( lang::IllegalArgumentException( - "Wrong argument type!", - static_cast< cppu::OWeakObject * >( this ), - -1 ) ), - Environment ); - // Unreachable - } - - aRet <<= createNewContent( aArg ); - } - else if ( aCommand.Name == "addProperty" ) - { - ucb::PropertyCommandArgument aPropArg; - if ( !( aCommand.Argument >>= aPropArg )) - { - ucbhelper::cancelCommandExecution( - uno::makeAny( lang::IllegalArgumentException( - "Wrong argument type!", - static_cast< cppu::OWeakObject * >( this ), - -1 ) ), - Environment ); - } - - // TODO when/if XPropertyContainer is removed, - // the command execution can be canceled in addProperty - try - { - addProperty( aPropArg, Environment ); - } - catch ( const beans::PropertyExistException &e ) - { - ucbhelper::cancelCommandExecution( uno::makeAny( e ), Environment ); - } - catch ( const beans::IllegalTypeException&e ) - { - ucbhelper::cancelCommandExecution( uno::makeAny( e ), Environment ); - } - catch ( const lang::IllegalArgumentException&e ) - { - ucbhelper::cancelCommandExecution( uno::makeAny( e ), Environment ); - } - } - else if ( aCommand.Name == "removeProperty" ) - { - OUString sPropName; - if ( !( aCommand.Argument >>= sPropName ) ) - { - ucbhelper::cancelCommandExecution( - uno::makeAny( lang::IllegalArgumentException( - "Wrong argument type!", - static_cast< cppu::OWeakObject * >( this ), - -1 ) ), - Environment ); - } - - // TODO when/if XPropertyContainer is removed, - // the command execution can be canceled in removeProperty - try - { - removeProperty( sPropName, Environment ); - } - catch( const beans::UnknownPropertyException &e ) - { - ucbhelper::cancelCommandExecution( uno::makeAny( e ), Environment ); - } - catch( const beans::NotRemoveableException &e ) - { - ucbhelper::cancelCommandExecution( uno::makeAny( e ), Environment ); - } - } - else - { - - // Unsupported command - - - ucbhelper::cancelCommandExecution( - uno::makeAny( ucb::UnsupportedCommandException( - aCommand.Name, - static_cast< cppu::OWeakObject * >( this ) ) ), - Environment ); - // Unreachable - } - - SAL_INFO( "ucb.ucp.webdav", "Content::execute: end: command: " << aCommand.Name ); - - return aRet; -} - - -// virtual -void SAL_CALL Content::abort( sal_Int32 /*CommandId*/ ) -{ - try - { - std::unique_ptr< DAVResourceAccess > xResAccess; - { - osl::MutexGuard aGuard( m_aMutex ); - xResAccess.reset(new DAVResourceAccess(*m_xResAccess)); - } - xResAccess->abort(); - { - osl::Guard< osl::Mutex > aGuard( m_aMutex ); - m_xResAccess.reset(new DAVResourceAccess(*xResAccess)); - } - } - catch ( DAVException const & ) - { - // abort failed! - } -} - - -// XPropertyContainer methods. - - -void Content::addProperty( const ucb::PropertyCommandArgument& aCmdArg, - const uno::Reference< ucb::XCommandEnvironment >& xEnv ) -{ -// if ( m_bTransient ) -// @@@ ??? - - if ( aCmdArg.Property.Name.isEmpty() ) - throw lang::IllegalArgumentException( - "\"addProperty\" with empty Property.Name", - static_cast< cppu::OWeakObject * >( this ), - -1 ); - - // Check property type. - if ( !UCBDeadPropertyValue::supportsType( aCmdArg.Property.Type ) ) - { - throw beans::IllegalTypeException( - "\"addProperty\" unsupported Property.Type", - static_cast< cppu::OWeakObject * >( this ) ); - } - - if ( aCmdArg.DefaultValue.hasValue() - && aCmdArg.DefaultValue.getValueType() != aCmdArg.Property.Type ) - { - throw beans::IllegalTypeException( - "\"addProperty\" DefaultValue does not match Property.Type", - static_cast< ::cppu::OWeakObject * >( this ) ); - } - - - // Make sure a property with the requested name does not already - // exist in dynamic and static(!) properties. - - - // Take into account special properties with custom namespace - // using <prop:the_propname xmlns:prop="the_namespace"> - OUString aSpecialName; - bool bIsSpecial = DAVProperties::isUCBSpecialProperty( - aCmdArg.Property.Name, aSpecialName ); - - // Note: This requires network access! - if ( getPropertySetInfo( xEnv, false /* don't cache data */ ) - ->hasPropertyByName( - bIsSpecial ? aSpecialName : aCmdArg.Property.Name ) ) - { - // Property does already exist. - throw beans::PropertyExistException(); - } - - - // Add a new dynamic property. - - - ProppatchValue aValue( - PROPSET, aCmdArg.Property.Name, aCmdArg.DefaultValue ); - - try - { - // Set property value at server. - std::unique_ptr< DAVResourceAccess > xResAccess; - { - osl::Guard< osl::Mutex > aGuard( m_aMutex ); - xResAccess.reset(new DAVResourceAccess(*m_xResAccess)); - } - aStaticDAVOptionsCache.removeDAVOptions( xResAccess->getURL() ); - // clean cached value of PROPFIND property names - // PROPPATCH can change them - removeCachedPropertyNames( xResAccess->getURL() ); - xResAccess->PROPPATCH( { aValue }, xEnv ); - { - osl::Guard< osl::Mutex > aGuard( m_aMutex ); - m_xResAccess.reset(new DAVResourceAccess(*xResAccess)); - } - - // Notify propertyset info change listeners. - beans::PropertySetInfoChangeEvent evt( - static_cast< cppu::OWeakObject * >( this ), - bIsSpecial ? aSpecialName : aCmdArg.Property.Name, - -1, // No handle available - beans::PropertySetInfoChange::PROPERTY_INSERTED ); - notifyPropertySetInfoChange( evt ); - } - catch ( DAVException const & e ) - { - if ( e.getStatus() == SC_FORBIDDEN ) - { - // Support for setting arbitrary dead properties is optional! - - // Store property locally. - ContentImplHelper::addProperty( - bIsSpecial ? aSpecialName : aCmdArg.Property.Name, - aCmdArg.Property.Attributes, aCmdArg.DefaultValue ); - } - else - { - if ( shouldAccessNetworkAfterException( e ) ) - { - try - { - ResourceType eType = getResourceType( xEnv ); - switch ( eType ) - { - case UNKNOWN: - case DAV: - throw lang::IllegalArgumentException(); - - case FTP: - case NON_DAV: - // Store property locally. - ContentImplHelper::addProperty( - bIsSpecial ? aSpecialName : aCmdArg.Property.Name, - aCmdArg.Property.Attributes, aCmdArg.DefaultValue ); - break; - - default: - SAL_WARN( "ucb.ucp.webdav", "Content::addProperty - " - "Unsupported resource type!" ); - break; - } - } - catch ( uno::Exception const & ) - { - SAL_WARN( "ucb.ucp.webdav", "Content::addProperty - " - "Unable to determine resource type!" ); - } - } - else - { - SAL_WARN( "ucb.ucp.webdav", "Content::addProperty - " - "Unable to determine resource type!" ); - } - } - } -} - -void Content::removeProperty( const OUString& Name, - const uno::Reference< ucb::XCommandEnvironment >& xEnv ) -{ - - // Try to remove property from server. - - - try - { - ProppatchValue aValue( PROPREMOVE, Name, uno::Any() ); - - // Remove property value from server. - std::unique_ptr< DAVResourceAccess > xResAccess; - { - osl::Guard< osl::Mutex > aGuard( m_aMutex ); - xResAccess.reset(new DAVResourceAccess(*m_xResAccess)); - } - aStaticDAVOptionsCache.removeDAVOptions( xResAccess->getURL() ); - // clean cached value of PROPFIND property names - // PROPPATCH can change them - removeCachedPropertyNames( xResAccess->getURL() ); - xResAccess->PROPPATCH( { aValue }, xEnv ); - { - osl::Guard< osl::Mutex > aGuard( m_aMutex ); - m_xResAccess.reset(new DAVResourceAccess(*xResAccess)); - } - - // Notify propertyset info change listeners. - beans::PropertySetInfoChangeEvent evt( - static_cast< cppu::OWeakObject * >( this ), - Name, - -1, // No handle available - beans::PropertySetInfoChange::PROPERTY_REMOVED ); - notifyPropertySetInfoChange( evt ); - } - catch ( DAVException const & e ) - { - if ( e.getStatus() == SC_FORBIDDEN ) - { - // Support for setting arbitrary dead properties is optional! - - // Try to remove property from local store. - ContentImplHelper::removeProperty( Name ); - } - else - { - if ( shouldAccessNetworkAfterException( e ) ) - { - try - { - ResourceType eType = getResourceType( xEnv ); - switch ( eType ) - { - case UNKNOWN: - case DAV: - throw beans::UnknownPropertyException(Name); - - case FTP: - case NON_DAV: - // Try to remove property from local store. - ContentImplHelper::removeProperty( Name ); - break; - - default: - SAL_WARN( "ucb.ucp.webdav", "Content::removeProperty - " - "Unsupported resource type!" ); - break; - } - } - catch ( uno::Exception const & ) - { - SAL_WARN( "ucb.ucp.webdav", "Content::removeProperty - " - "Unable to determine resource type!" ); - } - } - else - { - SAL_WARN( "ucb.ucp.webdav", "Content::removeProperty - " - "Unable to determine resource type!" ); -// throw beans::UnknownPropertyException(); - } - } - } -} - -// virtual -void SAL_CALL Content::addProperty( const OUString& Name, - sal_Int16 Attributes, - const uno::Any& DefaultValue ) -{ - beans::Property aProperty; - aProperty.Name = Name; - aProperty.Type = DefaultValue.getValueType(); - aProperty.Attributes = Attributes; - aProperty.Handle = -1; - - addProperty( ucb::PropertyCommandArgument( aProperty, DefaultValue ), - uno::Reference< ucb::XCommandEnvironment >()); -} - -// virtual -void SAL_CALL Content::removeProperty( const OUString& Name ) -{ - removeProperty( Name, - uno::Reference< ucb::XCommandEnvironment >() ); -} - - -// XContentCreator methods. - - -// virtual -uno::Sequence< ucb::ContentInfo > SAL_CALL -Content::queryCreatableContentsInfo() -{ - osl::Guard< osl::Mutex > aGuard( m_aMutex ); - - uno::Sequence< ucb::ContentInfo > aSeq( 2 ); - - // document. - aSeq.getArray()[ 0 ].Type = WEBDAV_CONTENT_TYPE; - aSeq.getArray()[ 0 ].Attributes - = ucb::ContentInfoAttribute::INSERT_WITH_INPUTSTREAM - | ucb::ContentInfoAttribute::KIND_DOCUMENT; - - beans::Property aProp; - m_pProvider->getProperty( - "Title", aProp ); - - uno::Sequence< beans::Property > aDocProps( 1 ); - aDocProps.getArray()[ 0 ] = aProp; - aSeq.getArray()[ 0 ].Properties = aDocProps; - - // folder. - aSeq.getArray()[ 1 ].Type = WEBDAV_COLLECTION_TYPE; - aSeq.getArray()[ 1 ].Attributes - = ucb::ContentInfoAttribute::KIND_FOLDER; - - uno::Sequence< beans::Property > aFolderProps( 1 ); - aFolderProps.getArray()[ 0 ] = aProp; - aSeq.getArray()[ 1 ].Properties = aFolderProps; - return aSeq; -} - - -// virtual -uno::Reference< ucb::XContent > SAL_CALL -Content::createNewContent( const ucb::ContentInfo& Info ) -{ - osl::Guard< osl::Mutex > aGuard( m_aMutex ); - - if ( Info.Type.isEmpty() ) - return uno::Reference< ucb::XContent >(); - - if ( ( Info.Type != WEBDAV_COLLECTION_TYPE ) && ( Info.Type != WEBDAV_CONTENT_TYPE ) ) - return uno::Reference< ucb::XContent >(); - - OUString aURL = m_xIdentifier->getContentIdentifier(); - - assert( !aURL.isEmpty() && "WebdavContent::createNewContent - empty identifier!" ); - - if ( ( aURL.lastIndexOf( '/' ) + 1 ) != aURL.getLength() ) - aURL += "/"; - - bool isCollection; - if ( Info.Type == WEBDAV_COLLECTION_TYPE ) - { - aURL += "New_Collection"; - isCollection = true; - } - else - { - aURL += "New_Content"; - isCollection = false; - } - - uno::Reference< ucb::XContentIdentifier > xId( - new ::ucbhelper::ContentIdentifier( aURL ) ); - - // create the local content - try - { - return new ::webdav_ucp::Content( m_xContext, - m_pProvider, - xId, - m_xResAccess->getSessionFactory(), - isCollection ); - } - catch ( ucb::ContentCreationException & ) - { - return uno::Reference< ucb::XContent >(); - } -} - - -// virtual -OUString Content::getParentURL() -{ - // <scheme>:// -> "" - // <scheme>://foo -> "" - // <scheme>://foo/ -> "" - // <scheme>://foo/bar -> <scheme>://foo/ - // <scheme>://foo/bar/ -> <scheme>://foo/ - // <scheme>://foo/bar/abc -> <scheme>://foo/bar/ - - OUString aURL = m_xIdentifier->getContentIdentifier(); - - sal_Int32 nPos = aURL.lastIndexOf( '/' ); - if ( nPos == ( aURL.getLength() - 1 ) ) - { - // Trailing slash found. Skip. - nPos = aURL.lastIndexOf( '/', nPos ); - } - - sal_Int32 nPos1 = aURL.lastIndexOf( '/', nPos ); - if ( nPos1 != -1 ) - nPos1 = aURL.lastIndexOf( '/', nPos1 ); - - if ( nPos1 == -1 ) - return OUString(); - - return aURL.copy( 0, nPos + 1 ); -} - - -// Non-interface methods. - - -// static -uno::Reference< sdbc::XRow > Content::getPropertyValues( - const uno::Reference< uno::XComponentContext >& rxContext, - const uno::Sequence< beans::Property >& rProperties, - const ContentProperties& rData, - const rtl::Reference< ::ucbhelper::ContentProviderImplHelper >& rProvider, - const OUString& rContentId ) -{ - // Note: Empty sequence means "get values of all supported properties". - - rtl::Reference< ::ucbhelper::PropertyValueSet > xRow - = new ::ucbhelper::PropertyValueSet( rxContext ); - - if ( rProperties.hasElements() ) - { - uno::Reference< beans::XPropertySet > xAdditionalPropSet; - bool bTriedToGetAdditionalPropSet = false; - - for ( const beans::Property& rProp : rProperties ) - { - // Process standard UCB, DAV and HTTP properties. - const uno::Any & rValue = rData.getValue( rProp.Name ); - if ( rValue.hasValue() ) - { - xRow->appendObject( rProp, rValue ); - } - else - { - // Process local Additional Properties. - if ( !bTriedToGetAdditionalPropSet && !xAdditionalPropSet.is() ) - { - xAdditionalPropSet = - rProvider->getAdditionalPropertySet( rContentId, - false ); - bTriedToGetAdditionalPropSet = true; - } - - if ( !xAdditionalPropSet.is() || - !xRow->appendPropertySetValue( - xAdditionalPropSet, rProp ) ) - { - // Append empty entry. - xRow->appendVoid( rProp ); - } - } - } - } - else - { - // Append all standard UCB, DAV and HTTP properties. - const std::unique_ptr< PropertyValueMap > & xProps = rData.getProperties(); - - ContentProvider * pProvider - = static_cast< ContentProvider * >( rProvider.get() ); - beans::Property aProp; - - for ( const auto& rProp : *xProps ) - { - pProvider->getProperty( rProp.first, aProp ); - xRow->appendObject( aProp, rProp.second.value() ); - } - - // Append all local Additional Properties. - uno::Reference< beans::XPropertySet > xSet = - rProvider->getAdditionalPropertySet( rContentId, false ); - xRow->appendPropertySet( xSet ); - } - - return xRow; -} - -namespace { -void GetPropsUsingHeadRequest(DAVResource& resource, - const std::unique_ptr< DAVResourceAccess >& xResAccess, - const std::vector< OUString >& aHTTPNames, - const uno::Reference< ucb::XCommandEnvironment >& xEnv) -{ - if (aHTTPNames.empty()) - return; - - DAVOptions aDAVOptions; - OUString aTargetURL = xResAccess->getURL(); - // retrieve the cached options if any - aStaticDAVOptionsCache.getDAVOptions(aTargetURL, aDAVOptions); - - // clean cached value of PROPFIND property names - // PROPPATCH can change them - Content::removeCachedPropertyNames(aTargetURL); - // test if HEAD allowed, if not, throw, should be caught immediately - // SC_GONE used internally by us, see comment in Content::getPropertyValues - // in the catch scope - if (aDAVOptions.getHttpResponseStatusCode() != SC_GONE && - !aDAVOptions.isHeadAllowed()) - { - throw DAVException(DAVException::DAV_HTTP_ERROR, "405 Not Implemented", SC_METHOD_NOT_ALLOWED); - } - // if HEAD is enabled on this site - // check if there is a relevant HTTP response status code cached - if (aDAVOptions.getHttpResponseStatusCode() != SC_NONE) - { - // throws exception as if there was a server error, a DAV exception - throw DAVException(DAVException::DAV_HTTP_ERROR, - aDAVOptions.getHttpResponseStatusText(), - aDAVOptions.getHttpResponseStatusCode()); - // Unreachable - } - - xResAccess->HEAD(aHTTPNames, resource, xEnv); -} -} - -uno::Reference< sdbc::XRow > Content::getPropertyValues( - const uno::Sequence< beans::Property >& rProperties, - const uno::Reference< ucb::XCommandEnvironment >& xEnv ) -{ - std::unique_ptr< ContentProperties > xProps; - std::unique_ptr< ContentProperties > xCachedProps; - std::unique_ptr< DAVResourceAccess > xResAccess; - OUString aUnescapedTitle; - bool bHasAll = false; - uno::Reference< ucb::XContentIdentifier > xIdentifier; - rtl::Reference< ::ucbhelper::ContentProviderImplHelper > xProvider; - - { - osl::Guard< osl::Mutex > aGuard( m_aMutex ); - - aUnescapedTitle = NeonUri::unescape( m_aEscapedTitle ); - xIdentifier.set( m_xIdentifier ); - xProvider = m_xProvider; - xResAccess.reset(new DAVResourceAccess(*m_xResAccess)); - - // First, ask cache... - if (m_xCachedProps) - { - xCachedProps.reset(new ContentProperties(*m_xCachedProps)); - - std::vector< OUString > aMissingProps; - if ( xCachedProps->containsAllNames( rProperties, aMissingProps ) ) - { - // All properties are already in cache! No server access needed. - bHasAll = true; - } - - // use the cached ContentProperties instance - xProps.reset(new ContentProperties(*xCachedProps)); - } - } - - if ( !m_bTransient && !bHasAll ) - { - - // Obtain values from server... - - - // First, identify whether resource is DAV or not - bool bNetworkAccessAllowed = true; - ResourceType eType = getResourceType( - xEnv, xResAccess, &bNetworkAccessAllowed ); - - if ( eType == DAV ) - { - // cache lookup... getResourceType may fill the props cache via - // PROPFIND! - if (m_xCachedProps) - { - xCachedProps.reset(new ContentProperties(*m_xCachedProps)); - - std::vector< OUString > aMissingProps; - if ( xCachedProps->containsAllNames( - rProperties, aMissingProps ) ) - { - // All properties are already in cache! No server access - // needed. - bHasAll = true; - } - - // use the cached ContentProperties instance - xProps.reset(new ContentProperties(*xCachedProps)); - } - - if ( !bHasAll ) - { - // Only DAV resources support PROPFIND - std::vector< OUString > aPropNames; - - // FIXME: Should m_aFailedPropNames be checked here? It got effectively - // ignored since commit 26e6d4b05ab444e6a7529ffcac7fbe592fc94833. - if ( rProperties.hasElements() ) - ContentProperties::UCBNamesToDAVNames( - rProperties, aPropNames ); - - if ( !aPropNames.empty() ) - { - std::vector< DAVResource > resources; - try - { - xResAccess->PROPFIND( - DAVZERO, aPropNames, resources, xEnv ); - - if ( 1 == resources.size() ) - { -#if defined SAL_LOG_INFO - {//debug - // print received resources - for ( const auto& rProp : resources[0].properties ) - { - OUString aPropValue; - bool bValue; - uno::Sequence< ucb::LockEntry > aSupportedLocks; - if( rProp.Value >>= aPropValue ) - SAL_INFO( "ucb.ucp.webdav", "PROPFIND (getPropertyValues) - returned property: " << rProp.Name << ":" << aPropValue ); - else if( rProp.Value >>= bValue ) - SAL_INFO( "ucb.ucp.webdav", "PROPFIND (getPropertyValues) - returned property: " << rProp.Name << ":" << - ( bValue ? "true" : "false" ) ); - else if( rProp.Value >>= aSupportedLocks ) - { - SAL_INFO( "ucb.ucp.webdav", "PROPFIND (getPropertyValues) - returned property: " << rProp.Name << ":" ); - for ( sal_Int32 n = 0; n < aSupportedLocks.getLength(); ++n ) - { - SAL_INFO( "ucb.ucp.webdav"," scope: " - << ( aSupportedLocks[ n ].Scope == css::ucb::LockScope_SHARED ? "shared" : "exclusive" ) - << ", type: " - << ( aSupportedLocks[ n ].Type != css::ucb::LockType_WRITE ? "" : "write" ) ); - } - } - } - } -#endif - if (xProps) - xProps->addProperties( - aPropNames, - ContentProperties( resources[ 0 ] )); - else - xProps.reset( - new ContentProperties( resources[ 0 ] ) ); - } - } - catch ( DAVException const & e ) - { - bNetworkAccessAllowed = bNetworkAccessAllowed - && shouldAccessNetworkAfterException( e ); - - if ( !bNetworkAccessAllowed ) - { - cancelCommandExecution( e, xEnv ); - // unreachable - } - } - } - } - } - - if ( bNetworkAccessAllowed ) - { - // All properties obtained already? - std::vector< OUString > aMissingProps; - if ( !( xProps - && xProps->containsAllNames( - rProperties, aMissingProps ) ) - && !m_bDidGetOrHead ) - { - // Possibly the missing props can be obtained using a HEAD - // request. - - std::vector< OUString > aHeaderNames; - ContentProperties::UCBNamesToHTTPNames( - rProperties, - aHeaderNames ); - - if( eType != DAV ) - { - // in case of not DAV PROFIND (previously in program flow) failed - // so we need to add the only prop that's common - // to DAV and NON_DAV: MediaType, that maps to Content-Type - aHeaderNames.emplace_back("Content-Type" ); - } - - if (!aHeaderNames.empty()) try - { - DAVResource resource; - GetPropsUsingHeadRequest(resource, xResAccess, aHeaderNames, xEnv); - m_bDidGetOrHead = true; - - if (xProps) - xProps->addProperties( - aMissingProps, - ContentProperties(resource)); - else - xProps.reset(new ContentProperties(resource)); - - if (m_eResourceType == NON_DAV) - xProps->addProperties(aMissingProps, - ContentProperties( - aUnescapedTitle, - false)); - } - catch ( DAVException const & e ) - { - // non "general-purpose servers" may not support HEAD requests - // see http://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html#sec5.1.1 - // In this case, perform a partial GET only to get the header info - // vid. http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.35 - // WARNING if the server does not support partial GETs, - // the GET will transfer the whole content - bool bError = true; - DAVException aLastException = e; - OUString aTargetURL = xResAccess->getURL(); - - if ( e.getError() == DAVException::DAV_HTTP_ERROR ) - { - // According to the spec. the origin server SHOULD return - // * 405 (Method Not Allowed): - // the method is known but not allowed for the requested resource - // * 501 (Not Implemented): - // the method is unrecognized or not implemented - // * 404 (SC_NOT_FOUND) - // is for google-code server and for MS IIS 10.0 Web server - // when only GET is enabled - if ( aLastException.getStatus() == SC_NOT_IMPLEMENTED || - aLastException.getStatus() == SC_METHOD_NOT_ALLOWED || - aLastException.getStatus() == SC_NOT_FOUND ) - { - SAL_WARN( "ucb.ucp.webdav", "HEAD probably not implemented: fall back to a partial GET" ); - aStaticDAVOptionsCache.setHeadAllowed( aTargetURL, false ); - lcl_sendPartialGETRequest( bError, - aLastException, - aMissingProps, - aHeaderNames, - xResAccess, - xProps, - xEnv ); - m_bDidGetOrHead = !bError; - } - } - - if ( bError ) - { - DAVOptions aDAVOptionsException; - - aDAVOptionsException.setURL( aTargetURL ); - // check if the error was SC_NOT_FOUND, meaning that the - // GET fall back didn't succeeded and the element is really missing - // we will consider the resource SC_GONE (410) for some time - // we use SC_GONE because has the same meaning of SC_NOT_FOUND (404) - // see: - // <https://tools.ietf.org/html/rfc7231#section-6.5.9> (retrieved 2016-10-09) - // apparently it's not used to mark the missing HEAD method (so far...) - sal_uInt16 ResponseStatusCode = - ( aLastException.getStatus() == SC_NOT_FOUND ) ? - SC_GONE : - aLastException.getStatus(); - aDAVOptionsException.setHttpResponseStatusCode( ResponseStatusCode ); - aDAVOptionsException.setHttpResponseStatusText( aLastException.getData() ); - aStaticDAVOptionsCache.addDAVOptions( aDAVOptionsException, - m_nOptsCacheLifeNotFound ); - - if ( !shouldAccessNetworkAfterException( aLastException ) ) - { - cancelCommandExecution( aLastException, xEnv ); - // unreachable - } - } - } - } - } - - // might trigger HTTP redirect. - // Therefore, title must be updated here. - NeonUri aUri( xResAccess->getURL() ); - aUnescapedTitle = aUri.GetPathBaseNameUnescaped(); - - if ( eType == UNKNOWN ) - { - xProps.reset( new ContentProperties( aUnescapedTitle ) ); - } - - // For DAV resources we only know the Title, for non-DAV - // resources we additionally know that it is a document. - - if ( eType == DAV ) - { - if (!xProps) - xProps.reset(new ContentProperties(aUnescapedTitle)); - else - xProps->addProperty("Title", uno::makeAny(aUnescapedTitle), true); - } - else - { - if (!xProps) - xProps.reset( new ContentProperties( aUnescapedTitle, false ) ); - else - xProps->addProperty( - "Title", - uno::makeAny( aUnescapedTitle ), - true ); - - xProps->addProperty( - "IsFolder", - uno::makeAny( false ), - true ); - xProps->addProperty( - "IsDocument", - uno::makeAny( true ), - true ); - } - } - else - { - // No server access for just created (not yet committed) objects. - // Only a minimal set of properties supported at this stage. - if (m_bTransient) - xProps.reset( new ContentProperties( aUnescapedTitle, - m_bCollection ) ); - } - - // Add a default for the properties requested but not found. - // Determine still missing properties, add a default. - // Some client function doesn't expect a void uno::Any, - // but instead wants some sort of default. - std::vector< OUString > aMissingProps; - if ( !xProps->containsAllNames( - rProperties, aMissingProps ) ) - { - // - for ( const auto& rProp : aMissingProps ) - { - // For the time being only a couple of properties need to be added - if ( rProp == "DateModified" || rProp == "DateCreated" ) - { - util::DateTime aDate; - xProps->addProperty( - rProp, - uno::makeAny( aDate ), - true ); - } - // If WebDAV didn't return the resource type, assume default - // This happens e.g. for lists exported by SharePoint - else if ( rProp == "IsFolder" ) - { - xProps->addProperty( - rProp, - uno::makeAny( false ), - true ); - } - else if ( rProp == "IsDocument" ) - { - xProps->addProperty( - rProp, - uno::makeAny( true ), - true ); - } - } - } - - for ( const auto& rProperty : rProperties ) - { - const OUString rName = rProperty.Name; - if ( rName == "BaseURI" ) - { - // Add BaseURI property, if requested. - xProps->addProperty( - "BaseURI", - uno::makeAny( getBaseURI( xResAccess ) ), - true ); - } - else if ( rName == "CreatableContentsInfo" ) - { - // Add CreatableContentsInfo property, if requested. - bool bFolder = false; - xProps->getValue( - "IsFolder" ) - >>= bFolder; - xProps->addProperty( - "CreatableContentsInfo", - uno::makeAny( bFolder - ? queryCreatableContentsInfo() - : uno::Sequence< ucb::ContentInfo >() ), - true ); - } - } - - uno::Reference< sdbc::XRow > xResultRow - = getPropertyValues( m_xContext, - rProperties, - *xProps, - xProvider, - xIdentifier->getContentIdentifier() ); - - { - osl::Guard< osl::Mutex > aGuard( m_aMutex ); - - if (!m_xCachedProps) - m_xCachedProps.reset(new CachableContentProperties(*xProps)); - else - m_xCachedProps->addProperties(*xProps); - - m_xResAccess.reset(new DAVResourceAccess(*xResAccess)); - m_aEscapedTitle = NeonUri::escapeSegment( aUnescapedTitle ); - } - - return xResultRow; -} - - -uno::Sequence< uno::Any > Content::setPropertyValues( - const uno::Sequence< beans::PropertyValue >& rValues, - const uno::Reference< ucb::XCommandEnvironment >& xEnv ) -{ - uno::Reference< ucb::XContentIdentifier > xIdentifier; - rtl::Reference< ContentProvider > xProvider; - bool bTransient; - std::unique_ptr< DAVResourceAccess > xResAccess; - - { - osl::Guard< osl::Mutex > aGuard( m_aMutex ); - - xProvider.set( m_pProvider ); - xIdentifier.set( m_xIdentifier ); - bTransient = m_bTransient; - xResAccess.reset(new DAVResourceAccess(*m_xResAccess)); - } - - uno::Sequence< uno::Any > aRet( rValues.getLength() ); - auto aRetRange = asNonConstRange(aRet); - uno::Sequence< beans::PropertyChangeEvent > aChanges( rValues.getLength() ); - sal_Int32 nChanged = 0; - - beans::PropertyChangeEvent aEvent; - aEvent.Source = static_cast< cppu::OWeakObject * >( this ); - aEvent.Further = false; - // aEvent.PropertyName = - aEvent.PropertyHandle = -1; - // aEvent.OldValue = - // aEvent.NewValue = - - std::vector< ProppatchValue > aProppatchValues; - - uno::Reference< ucb::XPersistentPropertySet > xAdditionalPropSet; - bool bTriedToGetAdditionalPropSet = false; - - bool bExchange = false; - OUString aNewTitle; - OUString aOldTitle; - sal_Int32 nTitlePos = -1; - - uno::Reference< beans::XPropertySetInfo > xInfo; - - const beans::PropertyValue* pValues = rValues.getConstArray(); - sal_Int32 nCount = rValues.getLength(); - for ( sal_Int32 n = 0; n < nCount; ++n ) - { - const beans::PropertyValue& rValue = pValues[ n ]; - const OUString & rName = rValue.Name; - - beans::Property aTmpProp; - xProvider->getProperty( rName, aTmpProp ); - - if ( aTmpProp.Attributes & beans::PropertyAttribute::READONLY ) - { - // Read-only property! - aRetRange[ n ] <<= lang::IllegalAccessException( - "Property is read-only!", - static_cast< cppu::OWeakObject * >( this ) ); - continue; - } - - - // Mandatory props. - - - if ( rName == "ContentType" ) - { - // Read-only property! - aRetRange[ n ] <<= lang::IllegalAccessException( - "Property is read-only!", - static_cast< cppu::OWeakObject * >( this ) ); - } - else if ( rName == "IsDocument" ) - { - // Read-only property! - aRetRange[ n ] <<= lang::IllegalAccessException( - "Property is read-only!", - static_cast< cppu::OWeakObject * >( this ) ); - } - else if ( rName == "IsFolder" ) - { - // Read-only property! - aRetRange[ n ] <<= lang::IllegalAccessException( - "Property is read-only!", - static_cast< cppu::OWeakObject * >( this ) ); - } - else if ( rName == "Title" ) - { - OUString aNewValue; - if ( rValue.Value >>= aNewValue ) - { - // No empty titles! - if ( !aNewValue.isEmpty() ) - { - try - { - NeonUri aURI( xIdentifier->getContentIdentifier() ); - aOldTitle = aURI.GetPathBaseNameUnescaped(); - - if ( aNewValue != aOldTitle ) - { - // modified title -> modified URL -> exchange ! - if ( !bTransient ) - bExchange = true; - - // new value will be set later... - aNewTitle = aNewValue; - - // remember position within sequence of values (for - // error handling). - nTitlePos = n; - } - } - catch ( DAVException const & ) - { - aRetRange[ n ] <<= lang::IllegalArgumentException( - "Invalid content identifier!", - static_cast< cppu::OWeakObject * >( this ), - -1 ); - } - } - else - { - aRetRange[ n ] <<= lang::IllegalArgumentException( - "Empty title not allowed!", - static_cast< cppu::OWeakObject * >( this ), - -1 ); - } - } - else - { - aRetRange[ n ] <<= beans::IllegalTypeException( - "Property value has wrong type!", - static_cast< cppu::OWeakObject * >( this ) ); - } - } - else - { - - // Optional props. - - - OUString aSpecialName; - bool bIsSpecial = DAVProperties::isUCBSpecialProperty( - rName, aSpecialName ); - - if ( !xInfo.is() ) - xInfo = getPropertySetInfo( xEnv, - false /* don't cache data */ ); - - if ( !xInfo->hasPropertyByName( - bIsSpecial ? aSpecialName : rName ) ) - { - // Check, whether property exists. Skip otherwise. - // PROPPATCH::set would add the property automatically, which - // is not allowed for "setPropertyValues" command! - aRetRange[ n ] <<= beans::UnknownPropertyException( - "Property is unknown!", - static_cast< cppu::OWeakObject * >( this ) ); - continue; - } - - if ( rName == "Size" ) - { - // Read-only property! - aRetRange[ n ] <<= lang::IllegalAccessException( - "Property is read-only!", - static_cast< cppu::OWeakObject * >( this ) ); - } - else if ( rName == "DateCreated" ) - { - // Read-only property! - aRetRange[ n ] <<= lang::IllegalAccessException( - "Property is read-only!", - static_cast< cppu::OWeakObject * >( this ) ); - } - else if ( rName == "DateModified" ) - { - // Read-only property! - aRetRange[ n ] <<= lang::IllegalAccessException( - "Property is read-only!", - static_cast< cppu::OWeakObject * >( this ) ); - } - else if ( rName == "MediaType" ) - { - // Read-only property! - // (but could be writable, if 'getcontenttype' would be) - aRetRange[ n ] <<= lang::IllegalAccessException( - "Property is read-only!", - static_cast< cppu::OWeakObject * >( this ) ); - } - if ( rName == "CreatableContentsInfo" ) - { - // Read-only property! - aRetRange[ n ] <<= lang::IllegalAccessException( - "Property is read-only!", - static_cast< cppu::OWeakObject * >( this ) ); - } - else - { - if ( getResourceType( xEnv, xResAccess ) == DAV ) - { - // Property value will be set on server. - ProppatchValue aValue( PROPSET, rName, rValue.Value ); - aProppatchValues.push_back( aValue ); - } - else - { - // Property value will be stored in local property store. - if ( !bTriedToGetAdditionalPropSet && - !xAdditionalPropSet.is() ) - { - xAdditionalPropSet - = getAdditionalPropertySet( false ); - bTriedToGetAdditionalPropSet = true; - } - - if ( xAdditionalPropSet.is() ) - { - try - { - uno::Any aOldValue - = xAdditionalPropSet->getPropertyValue( rName ); - if ( aOldValue != rValue.Value ) - { - xAdditionalPropSet->setPropertyValue( - rName, rValue.Value ); - - aEvent.PropertyName = rName; - aEvent.OldValue = aOldValue; - aEvent.NewValue = rValue.Value; - - aChanges.getArray()[ nChanged ] = aEvent; - nChanged++; - } - } - catch ( beans::UnknownPropertyException const & e ) - { - aRetRange[ n ] <<= e; - } - catch ( lang::WrappedTargetException const & e ) - { - aRetRange[ n ] <<= e; - } - catch ( beans::PropertyVetoException const & e ) - { - aRetRange[ n ] <<= e; - } - catch ( lang::IllegalArgumentException const & e ) - { - aRetRange[ n ] <<= e; - } - } - else - { - aRetRange[ n ] <<= uno::Exception( - "No property set for storing the value!", - static_cast< cppu::OWeakObject * >( this ) ); - } - } - } - } - } // for - - if ( !bTransient && !aProppatchValues.empty() ) - { - try - { - // clean cached value of PROPFIND property names - // PROPPATCH can change them - removeCachedPropertyNames( xResAccess->getURL() ); - // Set property values at server. - aStaticDAVOptionsCache.removeDAVOptions( xResAccess->getURL() ); - xResAccess->PROPPATCH( aProppatchValues, xEnv ); - - for ( const auto& rProppatchValue : aProppatchValues ) - { - aEvent.PropertyName = rProppatchValue.name; - aEvent.OldValue = uno::Any(); // @@@ too expensive to obtain! - aEvent.NewValue = rProppatchValue.value; - - aChanges.getArray()[ nChanged ] = aEvent; - nChanged++; - } - } - catch ( DAVException const & e ) - { - SAL_WARN( "ucb.ucp.webdav", "Content::setPropertyValues - PROPPATCH failed!" ); - cancelCommandExecution( e, xEnv ); - // unreachable - } - } - - if ( bExchange ) - { - // Assemble new content identifier... - - OUString aNewURL = getParentURL(); - if ( aNewURL.lastIndexOf( '/' ) != ( aNewURL.getLength() - 1 ) ) - aNewURL += "/"; - - aNewURL += NeonUri::escapeSegment( aNewTitle ); - - uno::Reference< ucb::XContentIdentifier > xNewId - = new ::ucbhelper::ContentIdentifier( aNewURL ); - - NeonUri sourceURI( xIdentifier->getContentIdentifier() ); - NeonUri targetURI( xNewId->getContentIdentifier() ); - - try - { - targetURI.SetScheme( sourceURI.GetScheme() ); - - // clean cached value of PROPFIND property names - removeCachedPropertyNames( sourceURI.GetURI() ); - removeCachedPropertyNames( targetURI.GetURI() ); - aStaticDAVOptionsCache.removeDAVOptions( sourceURI.GetURI() ); - aStaticDAVOptionsCache.removeDAVOptions( targetURI.GetURI() ); - xResAccess->MOVE( - sourceURI.GetPath(), targetURI.GetURI(), false, xEnv ); - - // @@@ Should check for resources that could not be moved - // (due to source access or target overwrite) and send - // this information through the interaction handler. - - // @@@ Existing content should be checked to see if it needs - // to be deleted at the source - - // @@@ Existing content should be checked to see if it has - // been overwritten at the target - - if ( exchangeIdentity( xNewId ) ) - { - xResAccess->setURL( aNewURL ); - -// DAV resources store all additional props on server! -// // Adapt Additional Core Properties. -// renameAdditionalPropertySet( xOldId->getContentIdentifier(), -// xNewId->getContentIdentifier(), -// sal_True ); - } - else - { - // Do not set new title! - aNewTitle.clear(); - - // Set error . - aRetRange[ nTitlePos ] <<= uno::Exception( - "Exchange failed!", - static_cast< cppu::OWeakObject * >( this ) ); - } - } - catch ( DAVException const & e ) - { - // Do not set new title! - aNewTitle.clear(); - - // Set error . - aRetRange[ nTitlePos ] = MapDAVException( e, true ); - } - } - - if ( !aNewTitle.isEmpty() ) - { - osl::Guard< osl::Mutex > aGuard( m_aMutex ); - - aEvent.PropertyName = "Title"; - aEvent.OldValue <<= aOldTitle; - aEvent.NewValue <<= aNewTitle; - - m_aEscapedTitle = NeonUri::escapeSegment( aNewTitle ); - - aChanges.getArray()[ nChanged ] = aEvent; - nChanged++; - } - - if ( nChanged > 0 ) - { - aChanges.realloc( nChanged ); - notifyPropertiesChange( aChanges ); - } - - { - osl::Guard< osl::Mutex > aGuard( m_aMutex ); - m_xResAccess.reset(new DAVResourceAccess(*xResAccess)); - } - - return aRet; -} - - -uno::Any Content::open( - const ucb::OpenCommandArgument3 & rArg, - const uno::Reference< ucb::XCommandEnvironment > & xEnv ) -{ - uno::Any aRet; - - bool bOpenFolder = ( ( rArg.Mode == ucb::OpenMode::ALL ) || - ( rArg.Mode == ucb::OpenMode::FOLDERS ) || - ( rArg.Mode == ucb::OpenMode::DOCUMENTS ) ); - if ( bOpenFolder ) - { - if ( isFolder( xEnv ) ) - { - // Open collection. - - uno::Reference< ucb::XDynamicResultSet > xSet - = new DynamicResultSet( m_xContext, this, rArg, xEnv ); - aRet <<= xSet; - } - else - { - // Error: Not a folder! - - OUStringBuffer aMsg; - if ( getResourceType( xEnv ) == FTP ) - { - aMsg.append( "FTP over HTTP proxy: resource cannot " - "be opened as folder! Wrong Open Mode!" ); - } - else - { - aMsg.append( "Non-folder resource cannot be " - "opened as folder! Wrong Open Mode!" ); - } - - ucbhelper::cancelCommandExecution( - uno::makeAny( - lang::IllegalArgumentException( - aMsg.makeStringAndClear(), - static_cast< cppu::OWeakObject * >( this ), - -1 ) ), - xEnv ); - // Unreachable - } - } - - if ( rArg.Sink.is() ) - { - // Open document. - - if ( ( rArg.Mode == ucb::OpenMode::DOCUMENT_SHARE_DENY_NONE ) || - ( rArg.Mode == ucb::OpenMode::DOCUMENT_SHARE_DENY_WRITE ) ) - { - // Currently(?) unsupported. - ucbhelper::cancelCommandExecution( - uno::makeAny( - ucb::UnsupportedOpenModeException( - OUString(), - static_cast< cppu::OWeakObject * >( this ), - sal_Int16( rArg.Mode ) ) ), - xEnv ); - // Unreachable - } - - uno::Reference< io::XOutputStream > xOut( rArg.Sink, uno::UNO_QUERY ); - if ( xOut.is() ) - { - // PUSH: write data - try - { - std::unique_ptr< DAVResourceAccess > xResAccess; - - { - osl::MutexGuard aGuard( m_aMutex ); - - xResAccess.reset(new DAVResourceAccess(*m_xResAccess)); - } - - xResAccess->setFlags( rArg.OpeningFlags ); - DAVResource aResource; - std::vector< OUString > aHeaders; - - removeCachedPropertyNames( xResAccess->getURL() ); - xResAccess->GET( xOut, aHeaders, aResource, xEnv ); - m_bDidGetOrHead = true; - - { - osl::MutexGuard aGuard( m_aMutex ); - - // cache headers. - if (!m_xCachedProps) - m_xCachedProps.reset( - new CachableContentProperties( ContentProperties( aResource ) ) ); - else - m_xCachedProps->addProperties( ContentProperties( aResource ) ); - - m_xResAccess.reset(new DAVResourceAccess(*xResAccess)); - } - } - catch ( DAVException const & e ) - { - cancelCommandExecution( e, xEnv ); - // Unreachable - } - } - else - { - uno::Reference< io::XActiveDataSink > xDataSink( rArg.Sink, uno::UNO_QUERY ); - if ( xDataSink.is() ) - { - // PULL: wait for client read - OUString aTargetURL = m_xIdentifier->getContentIdentifier(); - try - { - std::unique_ptr< DAVResourceAccess > xResAccess; - { - osl::MutexGuard aGuard( m_aMutex ); - - xResAccess.reset(new DAVResourceAccess(*m_xResAccess)); - } - xResAccess->setFlags( rArg.OpeningFlags ); - - // fill inputstream sync; return if all data present - DAVResource aResource; - std::vector< OUString > aHeaders; - - aTargetURL = xResAccess->getURL(); - removeCachedPropertyNames( aTargetURL ); - // check if the resource was present on the server - // first update it, if necessary - // if the open is called directly, without the default open sequence, - // e.g. the one used when opening a file looking for properties - // first this call will have no effect, since OPTIONS would have already been called - // as a consequence of getPropertyValues() - DAVOptions aDAVOptions; - getResourceOptions( xEnv, aDAVOptions, xResAccess ); - - if ( aDAVOptions.getHttpResponseStatusCode() != SC_NONE ) - { - // throws exception as if there was a server error, a DAV exception - throw DAVException( DAVException::DAV_HTTP_ERROR, - aDAVOptions.getHttpResponseStatusText(), - aDAVOptions.getHttpResponseStatusCode() ); - } - uno::Reference< io::XInputStream > xIn - = xResAccess->GET( aHeaders, aResource, xEnv ); - m_bDidGetOrHead = true; - - { - osl::MutexGuard aGuard( m_aMutex ); - - // cache headers. - if (!m_xCachedProps) - m_xCachedProps.reset( - new CachableContentProperties( ContentProperties( aResource ) ) ); - else - m_xCachedProps->addProperties( - aResource.properties ); - - m_xResAccess.reset(new DAVResourceAccess(*xResAccess)); - } - - xDataSink->setInputStream( xIn ); - } - catch ( DAVException const & e ) - { - //TODO cache the http error if not yet cached - cancelCommandExecution( e, xEnv ); - // Unreachable - } - } - else - { - // Note: aOpenCommand.Sink may contain an XStream - // implementation. Support for this type of - // sink is optional... - ucbhelper::cancelCommandExecution( - uno::makeAny( - ucb::UnsupportedDataSinkException( - OUString(), - static_cast< cppu::OWeakObject * >( this ), - rArg.Sink ) ), - xEnv ); - // Unreachable - } - } - } - - return aRet; -} - -void Content::post( - const ucb::PostCommandArgument2 & rArg, - const uno::Reference< ucb::XCommandEnvironment > & xEnv ) -{ - uno::Reference< io::XActiveDataSink > xSink( rArg.Sink, uno::UNO_QUERY ); - if ( xSink.is() ) - { - try - { - std::unique_ptr< DAVResourceAccess > xResAccess; - { - osl::MutexGuard aGuard( m_aMutex ); - xResAccess.reset(new DAVResourceAccess(*m_xResAccess)); - } - - removeCachedPropertyNames( xResAccess->getURL() ); - uno::Reference< io::XInputStream > xResult - = xResAccess->POST( rArg.MediaType, - rArg.Referer, - rArg.Source, - xEnv ); - - { - osl::MutexGuard aGuard( m_aMutex ); - m_xResAccess.reset(new DAVResourceAccess(*xResAccess)); - } - - xSink->setInputStream( xResult ); - } - catch ( DAVException const & e ) - { - cancelCommandExecution( e, xEnv, true ); - // Unreachable - } - } - else - { - uno::Reference< io::XOutputStream > xResult( rArg.Sink, uno::UNO_QUERY ); - if ( xResult.is() ) - { - try - { - std::unique_ptr< DAVResourceAccess > xResAccess; - { - osl::MutexGuard aGuard( m_aMutex ); - xResAccess.reset(new DAVResourceAccess(*m_xResAccess)); - } - - removeCachedPropertyNames( xResAccess->getURL() ); - xResAccess->POST( rArg.MediaType, - rArg.Referer, - rArg.Source, - xResult, - xEnv ); - - { - osl::MutexGuard aGuard( m_aMutex ); - m_xResAccess.reset(new DAVResourceAccess(*xResAccess)); - } - } - catch ( DAVException const & e ) - { - cancelCommandExecution( e, xEnv, true ); - // Unreachable - } - } - else - { - ucbhelper::cancelCommandExecution( - uno::makeAny( - ucb::UnsupportedDataSinkException( - OUString(), - static_cast< cppu::OWeakObject * >( this ), - rArg.Sink ) ), - xEnv ); - // Unreachable - } - } -} - - -void Content::queryChildren( ContentRefList& rChildren ) -{ - // Obtain a list with a snapshot of all currently instantiated contents - // from provider and extract the contents which are direct children - // of this content. - - ::ucbhelper::ContentRefList aAllContents; - m_xProvider->queryExistingContents( aAllContents ); - - OUString aURL = m_xIdentifier->getContentIdentifier(); - sal_Int32 nURLPos = aURL.lastIndexOf( '/' ); - - if ( nURLPos != ( aURL.getLength() - 1 ) ) - { - // No trailing slash found. Append. - aURL += "/"; - } - - sal_Int32 nLen = aURL.getLength(); - - for ( const auto& rChild : aAllContents ) - { - ::ucbhelper::ContentImplHelperRef xChild = rChild; - OUString aChildURL - = xChild->getIdentifier()->getContentIdentifier(); - - // Is aURL a prefix of aChildURL? - if ( ( aChildURL.getLength() > nLen ) && - ( aChildURL.startsWith( aURL ) ) ) - { - sal_Int32 nPos = aChildURL.indexOf( '/', nLen ); - - if ( ( nPos == -1 ) || - ( nPos == ( aChildURL.getLength() - 1 ) ) ) - { - // No further slashes / only a final slash. It's a child! - rChildren.emplace_back( - static_cast< ::webdav_ucp::Content * >( - xChild.get() ) ); - } - } - } -} - - -void Content::insert( - const uno::Reference< io::XInputStream > & xInputStream, - bool bReplaceExisting, - const uno::Reference< ucb::XCommandEnvironment >& Environment ) -{ - bool bTransient, bCollection; - OUString aEscapedTitle; - std::unique_ptr< DAVResourceAccess > xResAccess; - - { - osl::Guard< osl::Mutex > aGuard( m_aMutex ); - - bTransient = m_bTransient; - bCollection = m_bCollection; - aEscapedTitle = m_aEscapedTitle; - xResAccess.reset(new DAVResourceAccess(*m_xResAccess)); - } - - // Check, if all required properties are present. - - if ( aEscapedTitle.isEmpty() ) - { - SAL_WARN( "ucb.ucp.webdav", "Content::insert - Title missing!" ); - - uno::Sequence<OUString> aProps { "Title" }; - ucbhelper::cancelCommandExecution( - uno::makeAny( ucb::MissingPropertiesException( - OUString(), - static_cast< cppu::OWeakObject * >( this ), - aProps ) ), - Environment ); - // Unreachable - } - - if ( !bReplaceExisting ) - { - /* [RFC 2616] - HTTP - - The PUT method requests that the enclosed entity be stored under the - supplied Request-URI. If the Request-URI refers to an already - existing resource, the enclosed entity SHOULD be considered as a - modified version of the one residing on the origin server. - */ - - /* [RFC 2518] - WebDAV - - MKCOL creates a new collection resource at the location specified by - the Request-URI. If the resource identified by the Request-URI is - non-null then the MKCOL MUST fail. - */ - - // ==> Complain on PUT, continue on MKCOL. - if ( !bTransient || !bCollection ) - { - ucb::UnsupportedNameClashException aEx( - "Unable to write without overwrite!", - static_cast< cppu::OWeakObject * >( this ), - ucb::NameClash::ERROR ); - - uno::Reference< task::XInteractionHandler > xIH; - - if ( Environment.is() ) - xIH = Environment->getInteractionHandler(); - - if ( !xIH.is() ) - { - // No IH; throw. - throw aEx; - } - - uno::Any aExAsAny( uno::makeAny( aEx ) ); - - rtl::Reference< ucbhelper::SimpleInteractionRequest > xRequest - = new ucbhelper::SimpleInteractionRequest( - aExAsAny, - ContinuationFlags::Approve | ContinuationFlags::Disapprove ); - xIH->handle( xRequest ); - - const ContinuationFlags nResp = xRequest->getResponse(); - - switch ( nResp ) - { - case ContinuationFlags::NONE: - // Not handled; throw. - throw aEx; -// break; - - case ContinuationFlags::Approve: - // Continue -> Overwrite. - bReplaceExisting = true; - break; - - case ContinuationFlags::Disapprove: - // Abort. - throw ucb::CommandFailedException( - OUString(), - uno::Reference< uno::XInterface >(), - aExAsAny ); -// break; - - default: - SAL_WARN( "ucb.ucp.webdav", "Content::insert - " - "Unknown interaction selection!" ); - throw ucb::CommandFailedException( - "Unknown interaction selection!", - uno::Reference< uno::XInterface >(), - aExAsAny ); -// break; - } - - } - } - - if ( bTransient ) - { - // Assemble new content identifier... - OUString aURL = getParentURL(); - if ( aURL.lastIndexOf( '/' ) != ( aURL.getLength() - 1 ) ) - aURL += "/"; - - aURL += aEscapedTitle; - - try - { - xResAccess->setURL( aURL ); - - if ( bCollection ) - { - aStaticDAVOptionsCache.removeDAVOptions( xResAccess->getURL() ); - removeCachedPropertyNames( xResAccess->getURL() ); - xResAccess->MKCOL( Environment ); - } - else - { - // remove options from cache, PUT may change it - // it will be refreshed when needed - aStaticDAVOptionsCache.removeDAVOptions( xResAccess->getURL() ); - removeCachedPropertyNames( xResAccess->getURL() ); - xResAccess->PUT( xInputStream, Environment ); - // clean cached value of PROPFIND properties names - } - // no error , set the resourcetype to unknown type - // the resource may have transitioned from NOT FOUND or UNKNOWN to something else - // depending on the server behaviour - // this will force a recheck of the resource type - m_eResourceType = UNKNOWN; - m_eResourceTypeForLocks = UNKNOWN; - } - catch ( DAVException const & except ) - { - if ( bCollection ) - { - if ( except.getStatus() == SC_METHOD_NOT_ALLOWED ) - { - // [RFC 2518] - WebDAV - // 405 (Method Not Allowed) - MKCOL can only be - // executed on a deleted/non-existent resource. - - if ( bReplaceExisting ) - { - // Destroy old resource. - try - { - removeCachedPropertyNames( xResAccess->getURL() ); - xResAccess->DESTROY( Environment ); - } - catch ( DAVException const & e ) - { - cancelCommandExecution( e, Environment, true ); - // Unreachable - } - - // Insert (recursion!). - insert( xInputStream, bReplaceExisting, Environment ); - - { - osl::Guard< osl::Mutex > aGuard( m_aMutex ); - m_xResAccess.reset(new DAVResourceAccess(*xResAccess)); - } - - // Success! - return; - } - else - { - OUString aTitle; - try - { - NeonUri aURI( aURL ); - aTitle = aURI.GetPathBaseNameUnescaped(); - } - catch ( DAVException const & ) - { - } - - ucbhelper::cancelCommandExecution( - uno::makeAny( - ucb::NameClashException( - OUString(), - static_cast< cppu::OWeakObject * >( this ), - task::InteractionClassification_ERROR, - aTitle ) ), - Environment ); - // Unreachable - } - } - } - - cancelCommandExecution( except, Environment, true ); - // Unreachable - } - - { - osl::Guard< osl::Mutex > aGuard( m_aMutex ); - m_xIdentifier = new ::ucbhelper::ContentIdentifier( aURL ); - } - - inserted(); - - { - osl::Guard< osl::Mutex > aGuard( m_aMutex ); - m_bTransient = false; - } - } - else - { - if ( !xInputStream.is() ) - { - ucbhelper::cancelCommandExecution( - uno::makeAny( - ucb::MissingInputStreamException( - OUString(), - static_cast< cppu::OWeakObject * >( this ) ) ), - Environment ); - // Unreachable - } - - // save the URL since it may change due to redirection - OUString aTargetUrl = xResAccess->getURL(); - try - { - removeCachedPropertyNames( xResAccess->getURL() ); - // remove options from cache, PUT may change it - // it will be refreshed when needed - aStaticDAVOptionsCache.removeDAVOptions( aTargetUrl ); - xResAccess->PUT( xInputStream, Environment ); - } - catch ( DAVException const & e ) - { - cancelCommandExecution( e, Environment, true ); - // Unreachable - } - } - - { - osl::Guard< osl::Mutex > aGuard( m_aMutex ); - m_xResAccess.reset(new DAVResourceAccess(*xResAccess)); - } -} - - -void Content::transfer( - const ucb::TransferInfo & rArgs, - const uno::Reference< ucb::XCommandEnvironment >& Environment ) -{ - uno::Reference< ucb::XContentIdentifier > xIdentifier; - uno::Reference< ucb::XContentProvider > xProvider; - std::unique_ptr< DAVResourceAccess > xResAccess; - - { - osl::Guard< osl::Mutex > aGuard( m_aMutex ); - - xIdentifier.set( m_xIdentifier ); - xProvider = m_xProvider; - xResAccess.reset(new DAVResourceAccess(*m_xResAccess)); - } - - NeonUri sourceURI( rArgs.SourceURL ); - NeonUri targetURI( xIdentifier->getContentIdentifier() ); - - OUString aTargetURI; - try - { - aTargetURI = targetURI.GetPathBaseNameUnescaped(); - - // Check source's and target's URL scheme - - OUString aScheme = sourceURI.GetScheme().toAsciiLowerCase(); - if ( aScheme == VNDSUNSTARWEBDAV_URL_SCHEME) - { - sourceURI.SetScheme( HTTP_URL_SCHEME ); - } - else if ( aScheme == VNDSUNSTARWEBDAVS_URL_SCHEME) - { - sourceURI.SetScheme( HTTPS_URL_SCHEME ); - } - else if ( aScheme == DAV_URL_SCHEME ) - { - sourceURI.SetScheme( HTTP_URL_SCHEME ); - } - else if ( aScheme == DAVS_URL_SCHEME ) - { - sourceURI.SetScheme( HTTPS_URL_SCHEME ); - } - else if ( aScheme == WEBDAV_URL_SCHEME ) - { - sourceURI.SetScheme( HTTP_URL_SCHEME ); - } - else if ( aScheme == WEBDAVS_URL_SCHEME ) - { - sourceURI.SetScheme( HTTPS_URL_SCHEME ); - } - else - { - if ( aScheme != HTTP_URL_SCHEME && aScheme != HTTPS_URL_SCHEME ) - { - ucbhelper::cancelCommandExecution( - uno::makeAny( - ucb::InteractiveBadTransferURLException( - "Unsupported URL scheme!", - static_cast< cppu::OWeakObject * >( this ) ) ), - Environment ); - // Unreachable - } - } - - aScheme = targetURI.GetScheme().toAsciiLowerCase(); - if ( aScheme == VNDSUNSTARWEBDAV_URL_SCHEME) - targetURI.SetScheme( HTTP_URL_SCHEME ); - else if ( aScheme == VNDSUNSTARWEBDAVS_URL_SCHEME) - targetURI.SetScheme( HTTPS_URL_SCHEME ); - else if ( aScheme == DAV_URL_SCHEME ) - targetURI.SetScheme( HTTP_URL_SCHEME ); - else if ( aScheme == DAVS_URL_SCHEME ) - targetURI.SetScheme( HTTPS_URL_SCHEME ); - else if ( aScheme == WEBDAV_URL_SCHEME ) - targetURI.SetScheme( HTTP_URL_SCHEME ); - else if ( aScheme == WEBDAVS_URL_SCHEME ) - targetURI.SetScheme( HTTPS_URL_SCHEME ); - - // @@@ This implementation of 'transfer' only works - // if the source and target are located at same host. - // (Neon does not support cross-server copy/move) - - // Check for same host - - if ( !sourceURI.GetHost().isEmpty() && - ( sourceURI.GetHost() != targetURI.GetHost() ) ) - { - ucbhelper::cancelCommandExecution( - uno::makeAny( ucb::InteractiveBadTransferURLException( - "Different hosts!", - static_cast< cppu::OWeakObject * >( this ) ) ), - Environment ); - // Unreachable - } - - OUString aTitle = rArgs.NewTitle; - - if ( aTitle.isEmpty() ) - aTitle = sourceURI.GetPathBaseNameUnescaped(); - - if ( aTitle == "/" ) - { - // kso: ??? - aTitle.clear(); - } - - targetURI.AppendPath( aTitle ); - - OUString aTargetURL = xIdentifier->getContentIdentifier(); - if ( ( aTargetURL.lastIndexOf( '/' ) + 1 ) - != aTargetURL.getLength() ) - aTargetURL += "/"; - - aTargetURL += aTitle; - - uno::Reference< ucb::XContentIdentifier > xTargetId - = new ::ucbhelper::ContentIdentifier( aTargetURL ); - - DAVResourceAccess aSourceAccess( m_xContext, - xResAccess->getSessionFactory(), - sourceURI.GetURI() ); - - if ( rArgs.MoveData ) - { - uno::Reference< ucb::XContentIdentifier > xId - = new ::ucbhelper::ContentIdentifier( rArgs.SourceURL ); - - // Note: The static cast is okay here, because its sure that - // xProvider is always the WebDAVContentProvider. - rtl::Reference< Content > xSource - = static_cast< Content * >( - xProvider->queryContent( xId ).get() ); - - // [RFC 2518] - WebDAV - // If a resource exists at the destination and the Overwrite - // header is "T" then prior to performing the move the server - // MUST perform a DELETE with "Depth: infinity" on the - // destination resource. If the Overwrite header is set to - // "F" then the operation will fail. - - aStaticDAVOptionsCache.removeDAVOptions( sourceURI.GetURI() ); - aStaticDAVOptionsCache.removeDAVOptions( targetURI.GetURI() ); - aSourceAccess.MOVE( sourceURI.GetPath(), - targetURI.GetURI(), - rArgs.NameClash - == ucb::NameClash::OVERWRITE, - Environment ); - - if ( xSource.is() ) - { - // Propagate destruction to listeners. - xSource->destroy( true ); - } - -// DAV resources store all additional props on server! -// // Rename own and all children's Additional Core Properties. -// renameAdditionalPropertySet( xId->getContentIdentifier(), -// xTargetId->getContentIdentifier(), -// sal_True ); - } - else - { - // [RFC 2518] - WebDAV - // If a resource exists at the destination and the Overwrite - // header is "T" then prior to performing the copy the server - // MUST perform a DELETE with "Depth: infinity" on the - // destination resource. If the Overwrite header is set to - // "F" then the operation will fail. - - aStaticDAVOptionsCache.removeDAVOptions( sourceURI.GetURI() ); - aStaticDAVOptionsCache.removeDAVOptions( targetURI.GetURI() ); - aSourceAccess.COPY( sourceURI.GetPath(), - targetURI.GetURI(), - rArgs.NameClash - == ucb::NameClash::OVERWRITE, - Environment ); - -// DAV resources store all additional props on server! -// // Copy own and all children's Additional Core Properties. -// copyAdditionalPropertySet( xId->getContentIdentifier(), -// xTargetId->getContentIdentifier(), -// sal_True ); - } - - // Note: The static cast is okay here, because its sure that - // xProvider is always the WebDAVContentProvider. - rtl::Reference< Content > xTarget - = static_cast< Content * >( - xProvider->queryContent( xTargetId ).get() ); - - // Announce transferred content in its new folder. - xTarget->inserted(); - } - catch ( ucb::IllegalIdentifierException const & ) - { - // queryContent - } - catch ( DAVException const & e ) - { - // [RFC 2518] - WebDAV - // 412 (Precondition Failed) - The server was unable to maintain - // the liveness of the properties listed in the propertybehavior - // XML element or the Overwrite header is "F" and the state of - // the destination resource is non-null. - - if ( e.getStatus() == SC_PRECONDITION_FAILED ) - { - switch ( rArgs.NameClash ) - { - case ucb::NameClash::ERROR: - { - ucbhelper::cancelCommandExecution( - uno::makeAny( - ucb::NameClashException( - OUString(), - static_cast< cppu::OWeakObject * >( this ), - task::InteractionClassification_ERROR, - aTargetURI ) ), - Environment ); - [[fallthrough]]; // Unreachable - } - - case ucb::NameClash::OVERWRITE: - break; - - case ucb::NameClash::KEEP: // deprecated - case ucb::NameClash::RENAME: - case ucb::NameClash::ASK: - default: - { - ucbhelper::cancelCommandExecution( - uno::makeAny( - ucb::UnsupportedNameClashException( - OUString(), - static_cast< cppu::OWeakObject * >( this ), - rArgs.NameClash ) ), - Environment ); - // Unreachable - } - } - } - - cancelCommandExecution( e, Environment, true ); - // Unreachable - } - - { - osl::Guard< osl::Mutex > aGuard( m_aMutex ); - m_xResAccess.reset(new DAVResourceAccess(*xResAccess)); - } -} - - -void Content::destroy( bool bDeletePhysical ) -{ - // @@@ take care about bDeletePhysical -> trashcan support - uno::Reference< ucb::XContent > xThis = this; - - deleted(); - - osl::Guard< osl::Mutex > aGuard( m_aMutex ); - - // Process instantiated children... - - ::webdav_ucp::Content::ContentRefList aChildren; - queryChildren( aChildren ); - - for ( auto& rChild : aChildren ) - { - rChild->destroy( bDeletePhysical ); - } -} - -// returns the resource type, to be checked for locks -Content::ResourceType Content::resourceTypeForLocks( - const uno::Reference< ucb::XCommandEnvironment >& Environment, - const std::unique_ptr< DAVResourceAccess > & rResAccess) -{ - ResourceType eResourceTypeForLocks = UNKNOWN; - { - osl::MutexGuard g(m_aMutex); - //check if cache contains what we need, usually the first PROPFIND on the URI has supported lock - if (m_xCachedProps) - { - uno::Sequence< ucb::LockEntry > aSupportedLocks; - if ( m_xCachedProps->getValue( DAVProperties::SUPPORTEDLOCK ) - >>= aSupportedLocks ) //get the cached value for supportedlock - { - for ( const auto& rSupportedLock : std::as_const(aSupportedLocks) ) - { - if ( rSupportedLock.Scope - == ucb::LockScope_EXCLUSIVE && - rSupportedLock.Type - == ucb::LockType_WRITE ) - eResourceTypeForLocks = DAV; - } - } - } - } - - const OUString & rURL = m_xIdentifier->getContentIdentifier(); - - if ( eResourceTypeForLocks == UNKNOWN ) - { - // resource type for lock/unlock operations still unknown, need to ask the server - - const OUString aScheme( - rURL.copy( 0, rURL.indexOf( ':' ) ).toAsciiLowerCase() ); - - if ( aScheme == FTP_URL_SCHEME ) - { - eResourceTypeForLocks = FTP; - } - else - { - DAVOptions aDAVOptions; - getResourceOptions( Environment, aDAVOptions, rResAccess ); - if( aDAVOptions.isClass1() || - aDAVOptions.isClass2() || - aDAVOptions.isClass3() ) - { - // this is at least a DAV, lock to be confirmed - // class 2 is needed for full lock support - // see - // <https://tools.ietf.org/html/rfc4918#section-18.2> - eResourceTypeForLocks = DAV_NOLOCK; - if( aDAVOptions.isClass2() ) - { - // ok, possible lock, check for it - try - { - // we need only DAV:supportedlock - std::vector< DAVResource > resources; - std::vector< OUString > aPropNames; - uno::Sequence< beans::Property > aProperties{ - { /* Name */ DAVProperties::SUPPORTEDLOCK, {}, {}, {} } - }; - - ContentProperties::UCBNamesToDAVNames( aProperties, aPropNames ); - rResAccess->PROPFIND( DAVZERO, aPropNames, resources, Environment ); - - bool wasSupportedlockFound = false; - - // only one resource should be returned - if ( resources.size() == 1 ) - { - // we may have received a bunch of other properties - // (some servers seems to do so) - // but we need only supported lock for this check - // all returned properties are in - // resources.properties[n].Name/.Value - - for ( const auto& rProp : resources[0].properties ) - { - if ( rProp.Name == DAVProperties::SUPPORTEDLOCK ) - { - wasSupportedlockFound = true; - uno::Sequence< ucb::LockEntry > aSupportedLocks; - if ( rProp.Value >>= aSupportedLocks ) - { - bool isSupported = std::any_of(std::cbegin(aSupportedLocks), std::cend(aSupportedLocks), - [](const ucb::LockEntry& rLock) { - // TODO: if the lock type is changed from 'exclusive write' to 'shared write' - // e.g. to implement 'Calc shared file feature', the ucb::LockScope_EXCLUSIVE - // value should be checked as well, adaptation the code may be needed - return rLock.Scope == ucb::LockScope_EXCLUSIVE - && rLock.Type == ucb::LockType_WRITE; - }); - if (isSupported) - { - // requested locking mode is supported - eResourceTypeForLocks = DAV; - SAL_INFO( "ucb.ucp.webdav", "resourceTypeForLocks - URL: <" - << m_xIdentifier->getContentIdentifier() << ">, DAV lock/unlock supported"); - } - break; - } - } - } - } - else - { - // PROPFIND failed; check if HEAD contains Content-Disposition: attachment (RFC1806, HTTP/1.1 19.5.1), - // which supposedly means no lock for the resource (happens e.g. with SharePoint exported lists) - OUString sContentDisposition; - // First, check cached properties - if (m_xCachedProps) - { - if ((m_xCachedProps->getValue("Content-Disposition") >>= sContentDisposition) - && sContentDisposition.startsWithIgnoreAsciiCase("attachment")) - { - eResourceTypeForLocks = DAV_NOLOCK; - wasSupportedlockFound = true; - } - } - // If no data in cache, try HEAD request - if (sContentDisposition.isEmpty() && !m_bDidGetOrHead) try - { - DAVResource resource; - GetPropsUsingHeadRequest(resource, rResAccess, {"Content-Disposition"}, Environment); - m_bDidGetOrHead = true; - for (const auto& it : resource.properties) - { - if (it.Name.equalsIgnoreAsciiCase("Content-Disposition")) - { - if ((it.Value >>= sContentDisposition) && sContentDisposition.equalsIgnoreAsciiCase("attachment")) - { - eResourceTypeForLocks = DAV_NOLOCK; - wasSupportedlockFound = true; - } - break; - } - } - } - catch (...){} - } - // check if this is still only a DAV_NOLOCK - // a fallback for resources that do not have DAVProperties::SUPPORTEDLOCK property - // we check for the returned OPTION if LOCK is allowed on the resource - if ( !wasSupportedlockFound && eResourceTypeForLocks == DAV_NOLOCK ) - { - SAL_INFO( "ucb.ucp.webdav", "This WebDAV server has no supportedlock property, check for allowed LOCK method in OPTIONS" ); - // ATTENTION: if the lock type is changed from 'exclusive write' to 'shared write' - // e.g. to implement 'Calc shared file feature' on WebDAV directly, and we arrive to this fallback - // and the LOCK is allowed, we should assume that only exclusive write lock is available - // this is just a reminder... - if ( aDAVOptions.isLockAllowed() ) - eResourceTypeForLocks = DAV; - } - } - catch ( DAVException const & e ) - { - rResAccess->resetUri(); - //grab the error code - switch( e.getStatus() ) - { - case SC_NOT_FOUND: - SAL_WARN( "ucb.ucp.webdav", "resourceTypeForLocks() - URL: <" - << m_xIdentifier->getContentIdentifier() << "> was not found. "); - eResourceTypeForLocks = NOT_FOUND; - break; - // some servers returns SC_FORBIDDEN, instead - // the meaning of SC_FORBIDDEN is, according to <http://tools.ietf.org/html/rfc7231#section-6.5.3>: - // The 403 (Forbidden) status code indicates that the server understood - // the request but refuses to authorize it - case SC_FORBIDDEN: - // Errors SC_NOT_IMPLEMENTED and SC_METHOD_NOT_ALLOWED are - // part of base http 1.1 RFCs - case SC_NOT_IMPLEMENTED: // <http://tools.ietf.org/html/rfc7231#section-6.6.2> - case SC_METHOD_NOT_ALLOWED: // <http://tools.ietf.org/html/rfc7231#section-6.5.5> - // they all mean the resource is NON_DAV - SAL_WARN( "ucb.ucp.webdav", "resourceTypeForLocks() DAVException (SC_FORBIDDEN, SC_NOT_IMPLEMENTED or SC_METHOD_NOT_ALLOWED) - URL: <" - << m_xIdentifier->getContentIdentifier() << ">, DAV ExceptionCode: " << e.getError() << ", HTTP error: " << e.getStatus() ); - eResourceTypeForLocks = NON_DAV; - break; - default: - //fallthrough - SAL_WARN( "ucb.ucp.webdav", "resourceTypeForLocks() DAVException - URL: <" - << m_xIdentifier->getContentIdentifier() << ">, DAV ExceptionCode: " << e.getError() << ", HTTP error: " << e.getStatus() ); - eResourceTypeForLocks = UNKNOWN; - } - } - } - } - else - eResourceTypeForLocks = NON_DAV; - - } - } - osl::MutexGuard g(m_aMutex); - if (m_eResourceTypeForLocks == UNKNOWN) - { - m_eResourceTypeForLocks = eResourceTypeForLocks; - } - else - { - SAL_WARN_IF( - eResourceTypeForLocks != m_eResourceTypeForLocks, "ucb.ucp.webdav", - "different resource types for <" << rURL << ">: " - << +eResourceTypeForLocks << " vs. " << +m_eResourceTypeForLocks); - } - SAL_INFO( "ucb.ucp.webdav", "resourceTypeForLocks() - URL: <" - << m_xIdentifier->getContentIdentifier() << ">, m_eResourceTypeForLocks: " << m_eResourceTypeForLocks ); - return m_eResourceTypeForLocks; -} - -Content::ResourceType Content::resourceTypeForLocks( - const uno::Reference< ucb::XCommandEnvironment >& Environment ) -{ - std::unique_ptr< DAVResourceAccess > xResAccess; - { - osl::MutexGuard aGuard( m_aMutex ); - xResAccess.reset(new DAVResourceAccess(*m_xResAccess)); - } - Content::ResourceType ret = resourceTypeForLocks( Environment, xResAccess ); - { - osl::Guard< osl::Mutex > aGuard( m_aMutex ); - m_xResAccess.reset(new DAVResourceAccess(*xResAccess)); - } - return ret; -} - -void Content::lock( - const uno::Reference< ucb::XCommandEnvironment >& Environment ) -{ -// prepare aURL to be used in exception, see below - OUString aURL; - if ( m_bTransient ) - { - aURL = getParentURL(); - if ( aURL.lastIndexOf('/') != ( aURL.getLength() - 1 ) ) - aURL += "/"; - - aURL += m_aEscapedTitle; - } - else - { - aURL = m_xIdentifier->getContentIdentifier(); - } - - try - { - std::unique_ptr< DAVResourceAccess > xResAccess; - { - osl::Guard< osl::Mutex > aGuard( m_aMutex ); - xResAccess.reset(new DAVResourceAccess(*m_xResAccess)); - } - - uno::Any aOwnerAny; - aOwnerAny - <<= OUString("LibreOffice - http://www.libreoffice.org/"); - - ucb::Lock aLock( - ucb::LockScope_EXCLUSIVE, - ucb::LockType_WRITE, - ucb::LockDepth_ZERO, - aOwnerAny, - 180, // lock timeout in secs - //-1, // infinite lock - uno::Sequence< OUString >() ); - - // OPTIONS may change as a consequence of the lock operation - aStaticDAVOptionsCache.removeDAVOptions( xResAccess->getURL() ); - removeCachedPropertyNames( xResAccess->getURL() ); - xResAccess->LOCK( aLock, Environment ); - - { - osl::Guard< osl::Mutex > aGuard( m_aMutex ); - m_xResAccess.reset(new DAVResourceAccess(*xResAccess)); - } - } - catch ( DAVException const & e ) - { - // check if the exception thrown is 'already locked' - // this exception is mapped directly to the ucb correct one, without - // going into the cancelCommandExecution() user interaction - // this exception should be managed by the issuer of 'lock' command - switch( e.getError() ) - { - case DAVException::DAV_LOCKED: - { - SAL_WARN( "ucb.ucp.webdav", "lock() resource already locked - URL: <" - << m_xIdentifier->getContentIdentifier() << ">"); - throw - ucb::InteractiveLockingLockedException( - "Locked!", - static_cast< cppu::OWeakObject * >( this ), - task::InteractionClassification_ERROR, - aURL, - false ); - } - break; - case DAVException::DAV_HTTP_AUTH: - { - SAL_WARN( "ucb.ucp.webdav", "lock() DAVException Authentication error - URL: <" - << m_xIdentifier->getContentIdentifier() << ">" ); - // DAVException::DAV_HTTP_AUTH exception can mean: - // - interaction handler for credential management not present (happens, depending - // on the LO framework processing) - // - the remote site is a WebDAV with special configuration: read/only for read operations - // and read/write for write operations, the user is not allowed to lock/write and - // she cancelled the credentials request. - // this is not actually an error, but the exception is sent directly from here, avoiding the automatic - // management that takes part in cancelCommandExecution() below - // Unfortunately there is no InteractiveNetwork*Exception available to signal this - // since it mostly happens on read/only part of webdav, this appears to be the most correct exception available - throw - ucb::InteractiveNetworkWriteException( - "Authentication error while trying to lock! Write only WebDAV perhaps?", - static_cast< cppu::OWeakObject * >( this ), - task::InteractionClassification_ERROR, - e.getData() ); - } - break; - case DAVException::DAV_HTTP_ERROR: - //grab the error code - switch( e.getStatus() ) - { - // The 'case SC_NOT_FOUND' just below tries to solve a problem in eXo Platform - // WebDAV connector which apparently fail on resource first creation - // rfc4918 section-7.3 (see link below) - case SC_NOT_FOUND: // <http://tools.ietf.org/html/rfc7231#section-6.5.4> - // The 'case SC_PRECONDITION_FAILED' just below tries to solve a problem - // in SharePoint when locking the resource on first creation fails due to this: - // <https://msdn.microsoft.com/en-us/library/jj575265%28v=office.12%29.aspx#id15> - // (retrieved on 2015-08-14) - case SC_PRECONDITION_FAILED: // <http://tools.ietf.org/html/rfc7232#section-4.2> - // Errors SC_NOT_IMPLEMENTED and SC_METHOD_NOT_ALLOWED are - // part of base http 1.1 RFCs - case SC_NOT_IMPLEMENTED: // <http://tools.ietf.org/html/rfc7231#section-6.6.2> - case SC_METHOD_NOT_ALLOWED: // <http://tools.ietf.org/html/rfc7231#section-6.5.5> - SAL_WARN( "ucb.ucp.webdav", "lock() DAVException (SC_NOT_FOUND, SC_PRECONDITION_FAILED, SC_NOT_IMPLEMENTED or SC_METHOD_NOT_ALLOWED) - URL: <" - << m_xIdentifier->getContentIdentifier() << ">, DAV ExceptionCode: " << e.getError() << ", HTTP error: " << e.getStatus() ); - // act as nothing happened - // that's because when a resource is first created - // the lock is sent before the put, so the resource - // is actually created by LOCK, locking it before - // the first PUT, but if LOCK is not supported - // (simple web or DAV with lock disabled) we end with one of these http - // errors. - // These same errors may be reported when the LOCK on an unmapped - // (i.e. non existent) resource is not implemented. - // Detailed specification in: - // <http://tools.ietf.org/html/rfc4918#section-7.3> - return; - default: - //fallthrough - ; - } - break; - case DAVException::DAV_LOCKED_SELF: - // we already hold the lock and it is in our internal lockstore - // just return as if the lock was successful - return; - default: - //fallthrough - ; - } - - SAL_WARN( "ucb.ucp.webdav","lock() DAVException - URL: <" - << m_xIdentifier->getContentIdentifier() << ">, DAV ExceptionCode: " << e.getError() << ", HTTP error: " << e.getStatus() ); - cancelCommandExecution( e, Environment ); - // Unreachable - } -} - - -void Content::unlock( - const uno::Reference< ucb::XCommandEnvironment >& Environment ) -{ - - try - { - std::unique_ptr< DAVResourceAccess > xResAccess; - { - osl::Guard< osl::Mutex > aGuard( m_aMutex ); - xResAccess.reset(new DAVResourceAccess(*m_xResAccess)); - } - - // check if the target URL is a Class1 DAV - DAVOptions aDAVOptions; - getResourceOptions( Environment, aDAVOptions, xResAccess ); - - // at least class one is needed - if( aDAVOptions.isClass1() ) - { - // remove options from cache, unlock may change it - // it will be refreshed when needed - aStaticDAVOptionsCache.removeDAVOptions( xResAccess->getURL() ); - // clean cached value of PROPFIND properties names - removeCachedPropertyNames( xResAccess->getURL() ); - xResAccess->UNLOCK( Environment ); - } - - { - osl::Guard< osl::Mutex > aGuard( m_aMutex ); - m_xResAccess.reset(new DAVResourceAccess(*xResAccess)); - } - } - catch ( DAVException const & e ) - { - switch( e.getError() ) - { - case DAVException::DAV_NOT_LOCKED: - SAL_WARN( "ucb.ucp.webdav", "unlock() DAVException::DAV_NOT_LOCKED - URL: <" - << m_xIdentifier->getContentIdentifier() << ">"); - // means that we don't own any lock on this resource - // intercepted here to remove a confusing indication to the user - // unfortunately this happens in some WebDAV server configuration - // acting as WebDAV and having lock/unlock enabled only - // for authorized user. - return; - case DAVException::DAV_HTTP_ERROR: - //grab the error code - switch( e.getStatus() ) - { - // Errors SC_NOT_IMPLEMENTED and SC_METHOD_NOT_ALLOWED are - // part of base http 1.1 RFCs - case SC_NOT_IMPLEMENTED: // <http://tools.ietf.org/html/rfc7231#section-6.6.2> - case SC_METHOD_NOT_ALLOWED: // <http://tools.ietf.org/html/rfc7231#section-6.5.5> - SAL_WARN( "ucb.ucp.webdav", "unlock() DAVException (SC_NOT_IMPLEMENTED or SC_METHOD_NOT_ALLOWED) - URL: <" - << m_xIdentifier->getContentIdentifier() << ">, DAV ExceptionCode: " << e.getError() << ", HTTP error: " << e.getStatus() ); - return; - default: - //fallthrough - ; - } - break; - default: - //fallthrough - ; - } - SAL_WARN( "ucb.ucp.webdav","unlock() DAVException - URL: <" - << m_xIdentifier->getContentIdentifier() << ">, DAV ExceptionCode: " << e.getError() << ", HTTP error: " << e.getStatus() ); - cancelCommandExecution( e, Environment ); - // Unreachable - } -} - - -bool Content::exchangeIdentity( - const uno::Reference< ucb::XContentIdentifier >& xNewId ) -{ - if ( !xNewId.is() ) - return false; - - osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex ); - - uno::Reference< ucb::XContent > xThis = this; - - // Already persistent? - if ( m_bTransient ) - { - SAL_WARN( "ucb.ucp.webdav", "Content::exchangeIdentity - Not persistent!" ); - return false; - } - - // Exchange own identity. - - // Fail, if a content with given id already exists. -// if ( !hasData( xNewId ) ) - { - OUString aOldURL = m_xIdentifier->getContentIdentifier(); - - aGuard.clear(); - if ( exchange( xNewId ) ) - { - // Process instantiated children... - - ContentRefList aChildren; - queryChildren( aChildren ); - - for ( const auto& rChild : aChildren ) - { - ContentRef xChild = rChild; - - // Create new content identifier for the child... - uno::Reference< ucb::XContentIdentifier > - xOldChildId = xChild->getIdentifier(); - OUString aOldChildURL - = xOldChildId->getContentIdentifier(); - OUString aNewChildURL - = aOldChildURL.replaceAt( - 0, - aOldURL.getLength(), - xNewId->getContentIdentifier() ); - uno::Reference< ucb::XContentIdentifier > xNewChildId - = new ::ucbhelper::ContentIdentifier( aNewChildURL ); - - if ( !xChild->exchangeIdentity( xNewChildId ) ) - return false; - } - return true; - } - } - - SAL_WARN( "ucb.ucp.webdav", "Content::exchangeIdentity - " - "Panic! Cannot exchange identity!" ); - return false; -} - - -bool Content::isFolder( - const uno::Reference< ucb::XCommandEnvironment >& xEnv ) -{ - { - osl::MutexGuard aGuard( m_aMutex ); - - if ( m_bTransient ) - return m_bCollection; - } - - uno::Sequence< beans::Property > aProperties{ - { /* Name */ "IsFolder", /* Handle */ -1, {}, {} } - }; - uno::Reference< sdbc::XRow > xRow( getPropertyValues( aProperties, xEnv ) ); - if ( xRow.is() ) - { - try - { - return xRow->getBoolean( 1 ); - } - catch ( sdbc::SQLException const & ) - { - } - } - - return false; -} - - -uno::Any Content::MapDAVException( const DAVException & e, bool bWrite ) -{ - // Map DAVException... - uno::Any aException; - - OUString aURL; - if ( m_bTransient ) - { - aURL = getParentURL(); - if ( aURL.lastIndexOf('/') != ( aURL.getLength() - 1 ) ) - aURL += "/"; - - aURL += m_aEscapedTitle; - } - else - { - aURL = m_xIdentifier->getContentIdentifier(); - } - - switch ( e.getStatus() ) - { - case SC_NOT_FOUND: - { - uno::Sequence< uno::Any > aArgs{ uno::Any(beans::PropertyValue( - "Uri", -1, - uno::makeAny(aURL), - beans::PropertyState_DIRECT_VALUE)) }; - - aException <<= - ucb::InteractiveAugmentedIOException( - "Not found!", - static_cast< cppu::OWeakObject * >( this ), - task::InteractionClassification_ERROR, - ucb::IOErrorCode_NOT_EXISTING, - aArgs ); - return aException; - } - default: - break; - } - - switch ( e.getError() ) - { - case DAVException::DAV_HTTP_ERROR: - { - if ( bWrite ) - aException <<= - ucb::InteractiveNetworkWriteException( - e.getData(), - static_cast< cppu::OWeakObject * >( this ), - task::InteractionClassification_ERROR, - e.getData() ); - else - aException <<= - ucb::InteractiveNetworkReadException( - e.getData(), - static_cast< cppu::OWeakObject * >( this ), - task::InteractionClassification_ERROR, - e.getData() ); - break; - } - - case DAVException::DAV_HTTP_LOOKUP: - aException <<= - ucb::InteractiveNetworkResolveNameException( - OUString(), - static_cast< cppu::OWeakObject * >( this ), - task::InteractionClassification_ERROR, - e.getData() ); - break; - -// @@@ No matching InteractiveNetwork*Exception -// case DAVException::DAV_HTTP_AUTH: -// break; - -// @@@ No matching InteractiveNetwork*Exception -// case DAVException::DAV_HTTP_AUTHPROXY: -// break; - - case DAVException::DAV_HTTP_TIMEOUT: - case DAVException::DAV_HTTP_CONNECT: - aException <<= - ucb::InteractiveNetworkConnectException( - OUString(), - static_cast< cppu::OWeakObject * >( this ), - task::InteractionClassification_ERROR, - e.getData() ); - break; - -// @@@ No matching InteractiveNetwork*Exception -// case DAVException::DAV_HTTP_REDIRECT: -// break; - -// @@@ No matching InteractiveNetwork*Exception -// case DAVException::DAV_SESSION_CREATE: -// break; - - case DAVException::DAV_INVALID_ARG: - aException <<= - lang::IllegalArgumentException( - OUString(), - static_cast< cppu::OWeakObject * >( this ), - -1 ); - break; - - case DAVException::DAV_LOCKED: - aException <<= - ucb::InteractiveLockingLockedException( - "Locked!", - static_cast< cppu::OWeakObject * >( this ), - task::InteractionClassification_ERROR, - aURL, - false ); // not SelfOwned - break; - - case DAVException::DAV_LOCKED_SELF: - aException <<= - ucb::InteractiveLockingLockedException( - "Locked (self!)", - static_cast< cppu::OWeakObject * >( this ), - task::InteractionClassification_ERROR, - aURL, - true ); // SelfOwned - break; - - case DAVException::DAV_NOT_LOCKED: - aException <<= - ucb::InteractiveLockingNotLockedException( - "Not locked!", - static_cast< cppu::OWeakObject * >( this ), - task::InteractionClassification_ERROR, - aURL ); - break; - - case DAVException::DAV_LOCK_EXPIRED: - aException <<= - ucb::InteractiveLockingLockExpiredException( - "Lock expired!", - static_cast< cppu::OWeakObject * >( this ), - task::InteractionClassification_ERROR, - aURL ); - break; - - default: - aException <<= - ucb::InteractiveNetworkGeneralException( - OUString(), - static_cast< cppu::OWeakObject * >( this ), - task::InteractionClassification_ERROR ); - break; - } - - return aException; -} - - -// static -bool Content::shouldAccessNetworkAfterException( const DAVException & e ) -{ - return !(( e.getStatus() == SC_NOT_FOUND ) || - ( e.getStatus() == SC_GONE ) || - ( e.getError() == DAVException::DAV_HTTP_TIMEOUT ) || - ( e.getError() == DAVException::DAV_HTTP_LOOKUP ) || - ( e.getError() == DAVException::DAV_HTTP_CONNECT ) || - ( e.getError() == DAVException::DAV_HTTP_AUTH ) || - ( e.getError() == DAVException::DAV_HTTP_AUTHPROXY )); -} - - -void Content::cancelCommandExecution( - const DAVException & e, - const uno::Reference< ucb::XCommandEnvironment > & xEnv, - bool bWrite /* = sal_False */ ) -{ - ucbhelper::cancelCommandExecution( MapDAVException( e, bWrite ), xEnv ); - // Unreachable -} - - -OUString -Content::getBaseURI( const std::unique_ptr< DAVResourceAccess > & rResAccess ) -{ - osl::Guard< osl::Mutex > aGuard( m_aMutex ); - - // First, try to obtain value of response header "Content-Location". - if (m_xCachedProps) - { - OUString aLocation; - m_xCachedProps->getValue( "Content-Location" ) >>= aLocation; - if ( !aLocation.isEmpty() ) - { - try - { - // Do not use m_xIdentifier->getContentIdentifier() because it - // for example does not reflect redirects applied to requests - // done using the original URI but m_xResAccess' URI does. - return rtl::Uri::convertRelToAbs( rResAccess->getURL(), - aLocation ); - } - catch ( rtl::MalformedUriException const & ) - { - } - } - } - - return rResAccess->getURL(); -} - -// resource type is the type of the WebDAV resource -Content::ResourceType Content::getResourceType( - const uno::Reference< ucb::XCommandEnvironment >& xEnv, - const std::unique_ptr< DAVResourceAccess > & rResAccess, - bool * networkAccessAllowed) -{ - { - osl::MutexGuard g(m_aMutex); - if (m_eResourceType != UNKNOWN) { - return m_eResourceType; - } - } - - ResourceType eResourceType = UNKNOWN; - DAVOptions aDAVOptions; - - const OUString & rURL = rResAccess->getURL(); - const OUString aScheme( - rURL.copy( 0, rURL.indexOf( ':' ) ).toAsciiLowerCase() ); - - if ( aScheme == FTP_URL_SCHEME ) - { - eResourceType = FTP; - } - else - { - getResourceOptions( xEnv, aDAVOptions, rResAccess, networkAccessAllowed ); - - // at least class one is needed - if( aDAVOptions.isClass1() ) - { - try - { - // Try to fetch some frequently used property value, e.g. those - // used when loading documents... along with identifying whether - // this is a DAV resource. - std::vector< DAVResource > resources; - std::vector< OUString > aPropNames; - uno::Sequence< beans::Property > aProperties{ - { /* Name */ "IsFolder", {}, {}, {} }, - { /* Name */ "IsDocument", {}, {}, {} }, - { /* Name */ "IsReadOnly", {}, {}, {} }, - { /* Name */ "MediaType", {}, {}, {} }, - { /* Name */ DAVProperties::SUPPORTEDLOCK, {}, {}, {} } - }; - - ContentProperties::UCBNamesToDAVNames( aProperties, aPropNames ); - - rResAccess->PROPFIND( DAVZERO, aPropNames, resources, xEnv ); - - if ( resources.size() == 1 ) - { -#if defined SAL_LOG_INFO - {//debug - // print received resources - for ( const auto& rProp : resources[0].properties ) - { - OUString aPropValue; - bool bValue; - uno::Sequence< ucb::LockEntry > aSupportedLocks; - if(rProp.Value >>= aPropValue ) - SAL_INFO( "ucb.ucp.webdav", "PROPFIND (getResourceType) - ret'd prop: " << rProp.Name << ":" << aPropValue ); - else if( rProp.Value >>= bValue ) - SAL_INFO( "ucb.ucp.webdav", "PROPFIND (getResourceType) - ret'd prop: " << rProp.Name << ":" << - ( bValue ? "true" : "false" ) ); - else if( rProp.Value >>= aSupportedLocks ) - { - SAL_INFO( "ucb.ucp.webdav", "PROPFIND (getResourceType) - ret'd prop: " << rProp.Name << ":" ); - for ( sal_Int32 n = 0; n < aSupportedLocks.getLength(); ++n ) - { - SAL_INFO( "ucb.ucp.webdav","PROPFIND (getResourceType) - supportedlock[" << n <<"]: scope: " - << ( aSupportedLocks[ n ].Scope == css::ucb::LockScope_SHARED ? "shared" : "exclusive" ) - << ", type: " - << ( aSupportedLocks[ n ].Type != css::ucb::LockType_WRITE ? "" : "write" ) ); - } - } - } - } -#endif - osl::MutexGuard g(m_aMutex); - m_xCachedProps.reset( - new CachableContentProperties( ContentProperties( resources[ 0 ] ) ) ); - m_xCachedProps->containsAllNames( - aProperties, m_aFailedPropNames ); - } - eResourceType = DAV; - } - catch ( DAVException const & e ) - { - rResAccess->resetUri(); - - SAL_WARN( "ucb.ucp.webdav", "Content::getResourceType returned errors, DAV ExceptionCode: " << e.getError() << ", HTTP error: " << e.getStatus() ); - - if ( e.getStatus() == SC_METHOD_NOT_ALLOWED ) - { - // Status SC_METHOD_NOT_ALLOWED is a safe indicator that the - // resource is NON_DAV - eResourceType = NON_DAV; - } - else if (networkAccessAllowed != nullptr) - { - *networkAccessAllowed = *networkAccessAllowed - && shouldAccessNetworkAfterException(e); - } - if ( e.getStatus() == SC_NOT_FOUND ) - { - // arrives here if OPTIONS is still cached for a resource previously available - // operate on the OPTIONS cache: - // if OPTIONS was not found, do nothing - // else OPTIONS returned on a resource not existent (example a server that allows lock on null resource) set - // not found and adjust lifetime accordingly - DAVOptions aDAVOptionsInner; - if( aStaticDAVOptionsCache.getDAVOptions( rURL, aDAVOptionsInner ) ) - { - // TODO? get redirected url - aDAVOptionsInner.setHttpResponseStatusCode( e.getStatus() ); - aDAVOptionsInner.setHttpResponseStatusText( e.getData() ); - aStaticDAVOptionsCache.addDAVOptions( aDAVOptionsInner, - m_nOptsCacheLifeNotFound ); - } - } - // if the two net events below happen, something - // is going on to the connection so break the command flow - if ( ( e.getError() == DAVException::DAV_HTTP_TIMEOUT ) || - ( e.getError() == DAVException::DAV_HTTP_CONNECT ) ) - { - cancelCommandExecution( e, xEnv ); - // unreachable - } - } - } - else - { - rResAccess->resetUri(); - - // first check if the cached error can be mapped to DAVException::DAV_HTTP_TIMEOUT or mapped to DAVException::DAV_HTTP_CONNECT - if ( aDAVOptions.getHttpResponseStatusCode() == USC_CONNECTION_TIMED_OUT ) - { - // behave same as DAVException::DAV_HTTP_TIMEOUT or DAVException::DAV_HTTP_CONNECT was thrown - try - { - // extract host name and connection port - NeonUri theUri( rURL ); - const OUString& aHostName = theUri.GetHost(); - sal_Int32 nPort = theUri.GetPort(); - throw DAVException( DAVException::DAV_HTTP_TIMEOUT, - NeonUri::makeConnectionEndPointString( aHostName, - nPort ) ); - } - catch ( DAVException& exp ) - { - cancelCommandExecution( exp, xEnv ); - } - } - - if ( aDAVOptions.getHttpResponseStatusCode() != SC_NOT_FOUND && - aDAVOptions.getHttpResponseStatusCode() != SC_GONE ) // the cached OPTIONS can have SC_GONE - { - eResourceType = NON_DAV; - } - else - { - //resource doesn't exist - if ( networkAccessAllowed != nullptr ) - *networkAccessAllowed = false; } - } - } - - osl::MutexGuard g(m_aMutex); - if (m_eResourceType == UNKNOWN) { - m_eResourceType = eResourceType; - } else { - SAL_WARN_IF( - eResourceType != m_eResourceType, "ucb.ucp.webdav", - "different resource types for <" << rURL << ">: " - << +eResourceType << " vs. " << +m_eResourceType); - } - SAL_INFO( "ucb.ucp.webdav", "m_eResourceType for <"<<rURL<<">: " << m_eResourceType ); - return m_eResourceType; -} - - -Content::ResourceType Content::getResourceType( - const uno::Reference< ucb::XCommandEnvironment >& xEnv ) -{ - std::unique_ptr< DAVResourceAccess > xResAccess; - { - osl::MutexGuard aGuard( m_aMutex ); - xResAccess.reset(new DAVResourceAccess(*m_xResAccess)); - } - Content::ResourceType const ret = getResourceType( xEnv, xResAccess ); - { - osl::Guard< osl::Mutex > aGuard( m_aMutex ); - m_xResAccess.reset(new DAVResourceAccess(*xResAccess)); - } - return ret; -} - - -void Content::initOptsCacheLifeTime() -{ - // see description in - // officecfg/registry/schema/org/openoffice/Inet.xcs - // for use of these field values. - sal_uInt32 nAtime; - nAtime = officecfg::Inet::Settings::OptsCacheLifeImplWeb::get( m_xContext ); - m_nOptsCacheLifeImplWeb = std::max( sal_uInt32( 0 ), - std::min( nAtime, sal_uInt32( 3600 ) ) ); - - nAtime = officecfg::Inet::Settings::OptsCacheLifeDAV::get( m_xContext ); - m_nOptsCacheLifeDAV = std::max( sal_uInt32( 0 ), - std::min( nAtime, sal_uInt32( 3600 ) ) ); - - nAtime = officecfg::Inet::Settings::OptsCacheLifeDAVLocked::get( m_xContext ); - m_nOptsCacheLifeDAVLocked = std::max( sal_uInt32( 0 ), - std::min( nAtime, sal_uInt32( 3600 ) ) ); - - nAtime = officecfg::Inet::Settings::OptsCacheLifeNotImpl::get( m_xContext ); - m_nOptsCacheLifeNotImpl = std::max( sal_uInt32( 0 ), - std::min( nAtime, sal_uInt32( 43200 ) ) ); - - nAtime = officecfg::Inet::Settings::OptsCacheLifeNotFound::get( m_xContext ); - m_nOptsCacheLifeNotFound = std::max( sal_uInt32( 0 ), - std::min( nAtime, sal_uInt32( 30 ) ) ); -} - - -void Content::getResourceOptions( - const css::uno::Reference< css::ucb::XCommandEnvironment >& xEnv, - DAVOptions& rDAVOptions, - const std::unique_ptr< DAVResourceAccess > & rResAccess, - bool * networkAccessAllowed ) -{ - OUString aTargetURL = rResAccess->getURL(); - DAVOptions aDAVOptions; - // first check if in cache, if not, then send method to server - if ( !aStaticDAVOptionsCache.getDAVOptions( aTargetURL, aDAVOptions ) ) - { - OUString aRedirURL; - try - { - rResAccess->OPTIONS( aDAVOptions, xEnv ); - // IMPORTANT:the correctly implemented server will answer without errors, even if the resource is not present - sal_uInt32 nLifeTime = ( aDAVOptions.isClass1() || - aDAVOptions.isClass2() || - aDAVOptions.isClass3() ) ? - m_nOptsCacheLifeDAV : // a WebDAV site - m_nOptsCacheLifeImplWeb; // a site implementing OPTIONS but - // it's not DAV - // if resource is locked, will use a - // different lifetime - if( aDAVOptions.isLocked() ) - nLifeTime = m_nOptsCacheLifeDAVLocked; - - // check if redirected - aRedirURL = rResAccess->getURL(); - if( aRedirURL == aTargetURL) - { // no redirection - aRedirURL.clear(); - } - // cache this URL's option - aDAVOptions.setURL( aTargetURL ); - aDAVOptions.setRedirectedURL( aRedirURL ); - aStaticDAVOptionsCache.addDAVOptions( aDAVOptions, - nLifeTime ); - } - catch ( DAVException const & e ) - { - // first, remove from cache, will be added if needed, depending on the error received - aStaticDAVOptionsCache.removeDAVOptions( aTargetURL ); - rResAccess->resetUri(); - - aDAVOptions.setURL( aTargetURL ); - aDAVOptions.setRedirectedURL( aRedirURL ); - switch( e.getError() ) - { - case DAVException::DAV_HTTP_TIMEOUT: - case DAVException::DAV_HTTP_CONNECT: - { - // something bad happened to the connection - // not same as not found, this instead happens when the server doesn't exist or doesn't answer at all - // probably a new bit stating 'timed out' should be added to opts var? - // in any case abort the command - SAL_WARN( "ucb.ucp.webdav", "OPTIONS - DAVException: DAV_HTTP_TIMEOUT or DAV_HTTP_CONNECT for URL <" << m_xIdentifier->getContentIdentifier() << ">" ); - // cache the internal unofficial status code - - aDAVOptions.setHttpResponseStatusCode( USC_CONNECTION_TIMED_OUT ); - // used only internally, so the text doesn't really matter... - aStaticDAVOptionsCache.addDAVOptions( aDAVOptions, - m_nOptsCacheLifeNotFound ); - if ( networkAccessAllowed != nullptr ) - { - *networkAccessAllowed = *networkAccessAllowed - && shouldAccessNetworkAfterException(e); - } - } - break; - case DAVException::DAV_HTTP_LOOKUP: - { - SAL_WARN( "ucb.ucp.webdav", "OPTIONS - DAVException: DAV_HTTP_LOOKUP for URL <" << m_xIdentifier->getContentIdentifier() << ">" ); - aDAVOptions.setHttpResponseStatusCode( USC_LOOKUP_FAILED ); - // used only internally, so the text doesn't really matter... - aStaticDAVOptionsCache.addDAVOptions( aDAVOptions, - m_nOptsCacheLifeNotFound ); - if ( networkAccessAllowed != nullptr ) - { - *networkAccessAllowed = *networkAccessAllowed - && shouldAccessNetworkAfterException(e); - } - } - break; - case DAVException::DAV_HTTP_AUTH: - { - SAL_WARN( "ucb.ucp.webdav", "OPTIONS - DAVException: DAV_HTTP_AUTH for URL <" << m_xIdentifier->getContentIdentifier() << ">" ); - // - the remote site is a WebDAV with special configuration: read/only for read operations - // and read/write for write operations, the user is not allowed to lock/write and - // she cancelled the credentials request. - // this is not actually an error, it means only that for current user this is a standard web, - // though possibly DAV enabled - aDAVOptions.setHttpResponseStatusCode( USC_AUTH_FAILED ); - // used only internally, so the text doesn't really matter... - aStaticDAVOptionsCache.addDAVOptions( aDAVOptions, - m_nOptsCacheLifeNotFound ); - if ( networkAccessAllowed != nullptr ) - { - *networkAccessAllowed = *networkAccessAllowed - && shouldAccessNetworkAfterException(e); - } - } - break; - case DAVException::DAV_HTTP_AUTHPROXY: - { - SAL_WARN( "ucb.ucp.webdav", "OPTIONS - DAVException: DAV_HTTP_AUTHPROXY for URL <" << m_xIdentifier->getContentIdentifier() << ">" ); - aDAVOptions.setHttpResponseStatusCode( USC_AUTHPROXY_FAILED ); - // used only internally, so the text doesn't really matter... - aStaticDAVOptionsCache.addDAVOptions( aDAVOptions, - m_nOptsCacheLifeNotFound ); - if ( networkAccessAllowed != nullptr ) - { - *networkAccessAllowed = *networkAccessAllowed - && shouldAccessNetworkAfterException(e); - } - } - break; - case DAVException::DAV_HTTP_ERROR: - { - switch( e.getStatus() ) - { - case SC_FORBIDDEN: - { - SAL_WARN( "ucb.ucp.webdav","OPTIONS - SC_FORBIDDEN for URL <" << m_xIdentifier->getContentIdentifier() << ">" ); - // cache it, so OPTIONS won't be called again, this URL does not support it - aStaticDAVOptionsCache.addDAVOptions( aDAVOptions, - m_nOptsCacheLifeNotImpl ); - } - break; - case SC_BAD_REQUEST: - case SC_INTERNAL_SERVER_ERROR: - { - SAL_WARN( "ucb.ucp.webdav","OPTIONS - SC_BAD_REQUEST or SC_INTERNAL_SERVER_ERROR for URL <" << m_xIdentifier->getContentIdentifier() << ">, HTTP error: "<< e.getStatus() - << ", '" << e.getData() << "'" ); - // cache it, so OPTIONS won't be called again, this URL detect some problem while answering the method - aDAVOptions.setHttpResponseStatusCode( e.getStatus() ); - aDAVOptions.setHttpResponseStatusText( e.getData() ); - aStaticDAVOptionsCache.addDAVOptions( aDAVOptions, - m_nOptsCacheLifeNotFound ); - } - break; - case SC_NOT_IMPLEMENTED: - case SC_METHOD_NOT_ALLOWED: - { - // OPTIONS method must be implemented in DAV - // resource is NON_DAV, or not advertising it - SAL_WARN( "ucb.ucp.webdav","OPTIONS - SC_NOT_IMPLEMENTED or SC_METHOD_NOT_ALLOWED for URL <" << m_xIdentifier->getContentIdentifier() << ">, HTTP error: "<< e.getStatus() - << ", '" << e.getData() << "'" ); - // cache it, so OPTIONS won't be called again, this URL does not support it - aStaticDAVOptionsCache.addDAVOptions( aDAVOptions, - m_nOptsCacheLifeNotImpl ); - } - break; - case SC_NOT_FOUND: - { - // Apparently on IIS 10.0, if you disabled OPTIONS method, this error is the one reported, - // instead of SC_NOT_IMPLEMENTED or SC_METHOD_NOT_ALLOWED. - // So check if this is an available resource, or a real 'Not Found' event. - sal_uInt32 nLifeTime = m_nOptsCacheLifeNotFound; - if( isResourceAvailable( xEnv, rResAccess, aDAVOptions ) ) - { - SAL_WARN( "ucb.ucp.webdav", "OPTIONS - Got an SC_NOT_FOUND, but the URL <" << m_xIdentifier->getContentIdentifier() << "> resource exists" ); - nLifeTime = m_nOptsCacheLifeNotImpl; - } - else - { - SAL_WARN( "ucb.ucp.webdav", "OPTIONS - SC_NOT_FOUND for URL <" << m_xIdentifier->getContentIdentifier() << ">" ); - if ( networkAccessAllowed != nullptr ) - { - *networkAccessAllowed = *networkAccessAllowed - && shouldAccessNetworkAfterException(e); - } - } - aStaticDAVOptionsCache.addDAVOptions( aDAVOptions, - nLifeTime ); - } - break; - default: - { - SAL_WARN( "ucb.ucp.webdav", "OPTIONS - DAV_HTTP_ERROR, for URL <" << m_xIdentifier->getContentIdentifier() << ">, HTTP error: "<< e.getStatus() - << ", '" << e.getData() << "'" ); - aDAVOptions.setHttpResponseStatusCode( e.getStatus() ); - aDAVOptions.setHttpResponseStatusText( e.getData() ); - // cache it, so OPTIONS won't be called again, this URL does not support it - aStaticDAVOptionsCache.addDAVOptions( aDAVOptions, - m_nOptsCacheLifeNotImpl ); - } - break; - } - } - break; - // The 'DAVException::DAV_HTTP_REDIRECT' means we reached the maximum - // number of redirections, consider the resource type as UNKNOWN - // possibly a normal web site, not DAV - case DAVException::DAV_HTTP_REDIRECT: - default: - { - SAL_WARN( "ucb.ucp.webdav","OPTIONS - General DAVException (or max DAV_HTTP_REDIRECT reached) for URL <" << m_xIdentifier->getContentIdentifier() << ">, DAV ExceptionCode: " - << e.getError() << ", HTTP error: "<< e.getStatus() ); - aStaticDAVOptionsCache.addDAVOptions( aDAVOptions, - m_nOptsCacheLifeNotImpl ); - } - break; - } - } - } - else - { - // check current response status code, perhaps we need to set networkAccessAllowed - sal_uInt16 CachedResponseStatusCode = aDAVOptions.getHttpResponseStatusCode(); - if ( networkAccessAllowed != nullptr && - ( ( CachedResponseStatusCode == SC_NOT_FOUND ) || - ( CachedResponseStatusCode == SC_GONE ) || - ( CachedResponseStatusCode == USC_CONNECTION_TIMED_OUT ) || - ( CachedResponseStatusCode == USC_LOOKUP_FAILED ) || - ( CachedResponseStatusCode == USC_AUTH_FAILED ) || - ( CachedResponseStatusCode == USC_AUTHPROXY_FAILED ) - ) - ) - { - *networkAccessAllowed = false; - } - } - rDAVOptions = aDAVOptions; -} - - -//static -bool Content::isResourceAvailable( const css::uno::Reference< css::ucb::XCommandEnvironment >& xEnv, - const std::unique_ptr< DAVResourceAccess > & rResAccess, - DAVOptions& rDAVOptions ) -{ - std::vector< OUString > aHeaderNames; - DAVResource aResource; - - try - { - // To check for the physical URL resource availability, first - // try using a simple HEAD command - // if HEAD is successful, set element found, - rResAccess->HEAD( aHeaderNames, aResource, xEnv ); - rDAVOptions.setHttpResponseStatusCode( 0 ); - rDAVOptions.setHttpResponseStatusText( OUString() ); - return true; - } - catch ( DAVException const & e ) - { - if ( e.getError() == DAVException::DAV_HTTP_ERROR ) - { - if ( e.getStatus() == SC_NOT_IMPLEMENTED || - e.getStatus() == SC_METHOD_NOT_ALLOWED || - e.getStatus() == SC_NOT_FOUND ) - { - SAL_WARN( "ucb.ucp.webdav", "HEAD probably not implemented: fall back to a partial GET" ); - // set in cached OPTIONS "HEAD not implemented" - // so it won't be used again on this resource - rDAVOptions.setHeadAllowed( false ); - try - { - // do a GET with a payload of 0, the server does not - // support HEAD (or has HEAD disabled) - DAVRequestHeaders aPartialGet; - aPartialGet.emplace_back( - OUString( "Range" ), - OUString( "bytes=0-0" )); - - rResAccess->GET0( aPartialGet, - aHeaderNames, - aResource, - xEnv ); - return true; - } - catch ( DAVException const & ex ) - { - if ( ex.getError() == DAVException::DAV_HTTP_ERROR ) - { - rDAVOptions.setHttpResponseStatusCode( ex.getStatus() ); - rDAVOptions.setHttpResponseStatusText( ex.getData() ); - } - } - } - else - { - rDAVOptions.setHttpResponseStatusCode( e.getStatus() ); - rDAVOptions.setHttpResponseStatusText( e.getData() ); - } - } - return false; - } - catch ( ... ) - { - } - // set SC_NOT_IMPLEMENTED since at a minimum GET must be implemented in a basic Web server - rDAVOptions.setHttpResponseStatusCode( SC_NOT_IMPLEMENTED ); - rDAVOptions.setHttpResponseStatusText( OUString() ); - return false; -} - - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/ucb/source/ucp/webdav-neon/webdavcontent.hxx b/ucb/source/ucp/webdav-neon/webdavcontent.hxx deleted file mode 100644 index 74dfb1624b75..000000000000 --- a/ucb/source/ucp/webdav-neon/webdavcontent.hxx +++ /dev/null @@ -1,317 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -#pragma once - -#include <config_lgpl.h> -#include <memory> -#include <list> -#include <rtl/ref.hxx> -#include <com/sun/star/ucb/ContentCreationException.hpp> -#include <com/sun/star/ucb/XContentCreator.hpp> -#include <ucbhelper/contenthelper.hxx> -#include "DAVResourceAccess.hxx" -#include "PropertyMap.hxx" - -namespace com::sun::star::beans { - struct Property; - struct PropertyValue; -} - -namespace com::sun::star::io { - class XInputStream; -} - -namespace com::sun::star::sdbc { - class XRow; -} - -namespace com::sun::star::ucb { - struct OpenCommandArgument3; - struct PostCommandArgument2; - struct PropertyCommandArgument; - struct TransferInfo; -} - -namespace webdav_ucp -{ - - -// UNO service name for the content. -inline constexpr OUStringLiteral WEBDAV_CONTENT_SERVICE_NAME = u"com.sun.star.ucb.WebDAVContent"; - - -class ContentProvider; -class ContentProperties; -class CachableContentProperties; - -class Content : public ::ucbhelper::ContentImplHelper, - public css::ucb::XContentCreator -{ - enum ResourceType - { - UNKNOWN, // the type of the Web resource is unknown - NOT_FOUND, // the Web resource does not exists - FTP, // the Web resource exists but it's ftp - NON_DAV, // the Web resource exists but it's not DAV - DAV, // the type of the Web resource is DAV with lock/unlock available - DAV_NOLOCK // the type of the Web resource is DAV with no lock/unlock available - }; - - std::unique_ptr< DAVResourceAccess > m_xResAccess; - std::unique_ptr< CachableContentProperties > - m_xCachedProps; // locally cached props - OUString m_aEscapedTitle; - // resource type for general DAV methods - ResourceType m_eResourceType; - // resource type for general LOCK method only - ResourceType m_eResourceTypeForLocks; - ContentProvider* m_pProvider; // No need for a ref, base class holds object - bool m_bTransient; - bool m_bCollection; - bool m_bDidGetOrHead; - std::vector< OUString > m_aFailedPropNames; - // Options Cache lifetime - // for web site implementing OPTIONS, but not dav - sal_uInt32 m_nOptsCacheLifeImplWeb; - // for WebDAV site where OPTIONS is mandatory - sal_uInt32 m_nOptsCacheLifeDAV; - // same as above, but when the resource is locked by us - sal_uInt32 m_nOptsCacheLifeDAVLocked; -// For web site not implementing OPTIONS - // during this time we assume the site doesn't turn to WebDAV - // but remains a simple Web - sal_uInt32 m_nOptsCacheLifeNotImpl; - // When resource is not found - // may be the resource is unavailable only briefly? - // so better have this small - sal_uInt32 m_nOptsCacheLifeNotFound; - - void initOptsCacheLifeTime(); - -private: - virtual css::uno::Sequence< css::beans::Property > - getProperties( const css::uno::Reference< css::ucb::XCommandEnvironment > & xEnv ) override; - virtual css::uno::Sequence< css::ucb::CommandInfo > - getCommands( const css::uno::Reference< css::ucb::XCommandEnvironment > & xEnv ) override; - virtual OUString getParentURL() override; - - /// @throws css::uno::Exception - bool isFolder( const css::uno::Reference< css::ucb::XCommandEnvironment >& xEnv ); - - /// @throws css::uno::Exception - css::uno::Reference< css::sdbc::XRow > - getPropertyValues( const css::uno::Sequence< css::beans::Property >& rProperties, - const css::uno::Reference< css::ucb::XCommandEnvironment >& xEnv ); - - /// @throws css::uno::Exception - css::uno::Sequence< css::uno::Any > - setPropertyValues( const css::uno::Sequence< css::beans::PropertyValue >& rValues, - const css::uno::Reference< css::ucb::XCommandEnvironment >& xEnv ); - - typedef rtl::Reference< Content > ContentRef; - typedef std::vector< ContentRef > ContentRefList; - void queryChildren( ContentRefList& rChildren); - - bool - exchangeIdentity( const css::uno::Reference< css::ucb::XContentIdentifier >& xNewId ); - - OUString - getBaseURI( const std::unique_ptr< DAVResourceAccess > & rResAccess ); - - /// @throws css::uno::Exception - ResourceType - getResourceType( const css::uno::Reference< css::ucb::XCommandEnvironment >& xEnv ); - - /// @throws css::uno::Exception - ResourceType - getResourceType( const css::uno::Reference< css::ucb::XCommandEnvironment >& xEnv, - const std::unique_ptr< DAVResourceAccess > & rResAccess, - bool * networkAccessAllowed = nullptr); - - // Command "open" - /// @throws css::uno::Exception - css::uno::Any open( - const css::ucb::OpenCommandArgument3 & rArg, - const css::uno::Reference< css::ucb::XCommandEnvironment > & xEnv ); - - // Command "post" - /// @throws css::uno::Exception - void post( const css::ucb::PostCommandArgument2 & rArg, - const css::uno::Reference< css::ucb::XCommandEnvironment > & xEnv ); - - // Command "insert" - /// @throws css::uno::Exception - void insert( const css::uno::Reference< css::io::XInputStream > & xInputStream, - bool bReplaceExisting, - const css::uno::Reference< css::ucb::XCommandEnvironment >& Environment ); - - // Command "transfer" - /// @throws css::uno::Exception - void transfer( const css::ucb::TransferInfo & rArgs, - const css::uno::Reference< css::ucb::XCommandEnvironment >& Environment ); - - // Command "delete" - /// @throws css::uno::Exception - void destroy( bool bDeletePhysical ); - - // Command "lock" - /// @throws css::uno::Exception - void lock( const css::uno::Reference< css::ucb::XCommandEnvironment >& Environment ); - - // Command "unlock" - /// @throws css::uno::Exception - void unlock( const css::uno::Reference< css::ucb::XCommandEnvironment >& Environment ); - - css::uno::Any MapDAVException( const DAVException & e, - bool bWrite ); - /// @throws css::uno::Exception - void cancelCommandExecution( - const DAVException & e, - const css::uno::Reference< css::ucb::XCommandEnvironment > & xEnv, - bool bWrite = false ); - - static bool shouldAccessNetworkAfterException( const DAVException & e ); - - ResourceType resourceTypeForLocks( - const css::uno::Reference< css::ucb::XCommandEnvironment >& rEnvironment, - const std::unique_ptr< DAVResourceAccess > & rResAccess ); - - ResourceType resourceTypeForLocks( - const css::uno::Reference< css::ucb::XCommandEnvironment >& rEnvironment ); - - /// @throws css::beans::PropertyExistException - /// @throws css::beans::IllegalTypeException - /// @throws css::lang::IllegalArgumentException - /// @throws css::uno::RuntimeException - void addProperty( const css::ucb::PropertyCommandArgument &aCmdArg, - const css::uno::Reference< css::ucb::XCommandEnvironment >& Environment ); - - /// @throws css::beans::UnknownPropertyException - /// @throws css::beans::NotRemoveableException - /// @throws css::uno::RuntimeException - void removeProperty( const OUString& Name, - const css::uno::Reference< css::ucb::XCommandEnvironment >& Environment ); - -public: - /// @throws css::ucb::ContentCreationException - /// @throws css::uno::RuntimeException - Content( const css::uno::Reference< css::uno::XComponentContext >& rxContext, - ContentProvider* pProvider, - const css::uno::Reference< css::ucb::XContentIdentifier >& Identifier, - rtl::Reference< DAVSessionFactory > const & rSessionFactory ); - /// @throws css::ucb::ContentCreationException - /// @throws css::uno::RuntimeException - Content( const css::uno::Reference< css::uno::XComponentContext >& rxContext, - ContentProvider* pProvider, - const css::uno::Reference< css::ucb::XContentIdentifier >& Identifier, - rtl::Reference< DAVSessionFactory > const & rSessionFactory, - bool isCollection ); - virtual ~Content() override; - - // XInterface - virtual css::uno::Any SAL_CALL queryInterface( const css::uno::Type & rType ) override; - virtual void SAL_CALL acquire() - noexcept override; - virtual void SAL_CALL release() - noexcept override; - - // XTypeProvider - virtual css::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId() override; - virtual css::uno::Sequence< css::uno::Type > SAL_CALL getTypes() override; - - // XServiceInfo - virtual OUString SAL_CALL - getImplementationName() override; - - virtual css::uno::Sequence< OUString > SAL_CALL - getSupportedServiceNames() override; - - // XContent - virtual OUString SAL_CALL - getContentType() override; - - // XCommandProcessor - virtual css::uno::Any SAL_CALL - execute( const css::ucb::Command& aCommand, - sal_Int32 CommandId, - const css::uno::Reference< css::ucb::XCommandEnvironment >& Environment ) override; - virtual void SAL_CALL - abort( sal_Int32 CommandId ) override; - - // XPropertyContainer - virtual void SAL_CALL - addProperty( const OUString& Name, - sal_Int16 Attributes, - const css::uno::Any& DefaultValue ) override; - - virtual void SAL_CALL - removeProperty( const OUString& Name ) override; - - - // Additional interfaces - - - // XContentCreator - virtual css::uno::Sequence< css::ucb::ContentInfo > SAL_CALL - queryCreatableContentsInfo() override; - virtual css::uno::Reference< css::ucb::XContent > SAL_CALL - createNewContent( const css::ucb::ContentInfo& Info ) override; - - - // Non-interface methods. - - - DAVResourceAccess & getResourceAccess() { return *m_xResAccess; } - - // Called from resultset data supplier. - static css::uno::Reference< css::sdbc::XRow > - getPropertyValues( const css::uno::Reference< css::uno::XComponentContext >& rxContext, - const css::uno::Sequence< css::beans::Property >& rProperties, - const ContentProperties& rData, - const rtl::Reference< ::ucbhelper::ContentProviderImplHelper >& rProvider, - const OUString& rContentId ); - - // Use OPTIONS method to retrieve the type of the Web resource - /// @throws css::uno::Exception - void getResourceOptions( const css::uno::Reference< css::ucb::XCommandEnvironment >& xEnv, - DAVOptions& rDAVOptions, - const std::unique_ptr< DAVResourceAccess > & rResAccess, - bool * networkAccessAllowed = nullptr); - - static bool isResourceAvailable( const css::uno::Reference< css::ucb::XCommandEnvironment >& xEnv, - const std::unique_ptr< DAVResourceAccess > & rResAccess, - DAVOptions& rDAVOptions ); - - static void removeCachedPropertyNames( const OUString & rURL ); - -}; - -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/ucb/source/ucp/webdav-neon/webdavcontentcaps.cxx b/ucb/source/ucp/webdav-neon/webdavcontentcaps.cxx deleted file mode 100644 index f3e3abe8783d..000000000000 --- a/ucb/source/ucp/webdav-neon/webdavcontentcaps.cxx +++ /dev/null @@ -1,646 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -/************************************************************************** - TODO - ************************************************************************** - - *************************************************************************/ - -#include <memory> -#include <set> -#include <com/sun/star/beans/Property.hpp> -#include <com/sun/star/beans/PropertyAttribute.hpp> -#include <com/sun/star/beans/PropertyValue.hpp> -#include <com/sun/star/ucb/CommandInfo.hpp> -#include <com/sun/star/ucb/ContentInfo.hpp> -#include <com/sun/star/ucb/OpenCommandArgument2.hpp> -#include <com/sun/star/ucb/InsertCommandArgument.hpp> -#include <com/sun/star/ucb/PostCommandArgument2.hpp> -#include <com/sun/star/ucb/PropertyCommandArgument.hpp> -#include <com/sun/star/ucb/TransferInfo.hpp> -#include <com/sun/star/uno/Sequence.hxx> -#include <com/sun/star/util/DateTime.hpp> -#include <com/sun/star/ucb/Link.hpp> -#include <com/sun/star/ucb/Lock.hpp> -#include <com/sun/star/ucb/LockEntry.hpp> -#include "webdavcontent.hxx" -#include "webdavprovider.hxx" -#include "ContentProperties.hxx" -#include "PropfindCache.hxx" - -using namespace com::sun::star; -using namespace webdav_ucp; - - -// ContentProvider implementation. - - -void ContentProvider::getProperty( - const OUString & rPropName, beans::Property & rProp ) -{ - if ( !m_pProps ) - { - osl::MutexGuard aGuard( m_aMutex ); - if ( !m_pProps ) - { - m_pProps.reset( new PropertyMap ); - - - // Fill map of known properties... - - - // Mandatory UCB properties. - m_pProps->insert( - beans::Property( - "ContentType", - -1, - cppu::UnoType<OUString>::get(), - beans::PropertyAttribute::BOUND - | beans::PropertyAttribute::READONLY ) ); - - m_pProps->insert( - beans::Property( - "IsDocument", - -1, - cppu::UnoType<bool>::get(), - beans::PropertyAttribute::BOUND - | beans::PropertyAttribute::READONLY ) ); - - m_pProps->insert( - beans::Property( - "IsFolder", - -1, - cppu::UnoType<bool>::get(), - beans::PropertyAttribute::BOUND - | beans::PropertyAttribute::READONLY ) ); - - m_pProps->insert( - beans::Property( - "Title", - -1, - cppu::UnoType<OUString>::get(), - beans::PropertyAttribute::BOUND ) ); - - // Optional UCB properties. - - m_pProps->insert( - beans::Property( - "DateCreated", - -1, - cppu::UnoType<util::DateTime>::get(), - beans::PropertyAttribute::BOUND - | beans::PropertyAttribute::READONLY ) ); - - m_pProps->insert( - beans::Property( - "DateModified", - -1, - cppu::UnoType<util::DateTime>::get(), - beans::PropertyAttribute::BOUND - | beans::PropertyAttribute::READONLY ) ); - - m_pProps->insert( - beans::Property( - "MediaType", - -1, - cppu::UnoType<OUString>::get(), - beans::PropertyAttribute::BOUND - | beans::PropertyAttribute::READONLY ) ); - - m_pProps->insert( - beans::Property( - "Size", - -1, - cppu::UnoType<sal_Int64>::get(), - beans::PropertyAttribute::BOUND - | beans::PropertyAttribute::READONLY ) ); - - m_pProps->insert( - beans::Property( - "BaseURI", - -1, - cppu::UnoType<OUString>::get(), - beans::PropertyAttribute::BOUND - | beans::PropertyAttribute::READONLY ) ); - - m_pProps->insert( - beans::Property( - "CreatableContentsInfo", - -1, - cppu::UnoType< - uno::Sequence< ucb::ContentInfo >>::get(), - beans::PropertyAttribute::BOUND - | beans::PropertyAttribute::READONLY ) ); - - // Standard DAV properties. - - m_pProps->insert( - beans::Property( - DAVProperties::CREATIONDATE, - -1, - cppu::UnoType<OUString>::get(), - beans::PropertyAttribute::BOUND - | beans::PropertyAttribute::READONLY ) ); - - m_pProps->insert( - beans::Property( - DAVProperties::DISPLAYNAME, - -1, - cppu::UnoType<OUString>::get(), - beans::PropertyAttribute::BOUND ) ); - - m_pProps->insert( - beans::Property( - DAVProperties::GETCONTENTLANGUAGE, - -1, - cppu::UnoType<OUString>::get(), - beans::PropertyAttribute::BOUND - | beans::PropertyAttribute::READONLY ) ); - - m_pProps->insert( - beans::Property( - DAVProperties::GETCONTENTLENGTH, - -1, - cppu::UnoType<OUString>::get(), - beans::PropertyAttribute::BOUND - | beans::PropertyAttribute::READONLY ) ); - - m_pProps->insert( - beans::Property( - DAVProperties::GETCONTENTTYPE , - -1, - cppu::UnoType<OUString>::get(), - beans::PropertyAttribute::BOUND - | beans::PropertyAttribute::READONLY ) ); - - m_pProps->insert( - beans::Property( - DAVProperties::GETETAG, - -1, - cppu::UnoType<OUString>::get(), - beans::PropertyAttribute::BOUND - | beans::PropertyAttribute::READONLY ) ); - - m_pProps->insert( - beans::Property( - DAVProperties::GETLASTMODIFIED, - -1, - cppu::UnoType<OUString>::get(), - beans::PropertyAttribute::BOUND - | beans::PropertyAttribute::READONLY ) ); - - m_pProps->insert( - beans::Property( - DAVProperties::LOCKDISCOVERY, - -1, - cppu::UnoType< - uno::Sequence< ucb::Lock >>::get(), - beans::PropertyAttribute::BOUND - | beans::PropertyAttribute::READONLY ) ); - - m_pProps->insert( - beans::Property( - DAVProperties::RESOURCETYPE, - -1, - cppu::UnoType<OUString>::get(), - beans::PropertyAttribute::BOUND - | beans::PropertyAttribute::READONLY ) ); - - m_pProps->insert( - beans::Property( - DAVProperties::SOURCE, - -1, - cppu::UnoType<uno::Sequence< ucb::Link >>::get(), - beans::PropertyAttribute::BOUND ) ); - - m_pProps->insert( - beans::Property( - DAVProperties::SUPPORTEDLOCK, - -1, - cppu::UnoType<uno::Sequence< ucb::LockEntry >>::get(), - beans::PropertyAttribute::BOUND - | beans::PropertyAttribute::READONLY ) ); - - m_pProps->insert( - beans::Property( - DAVProperties::EXECUTABLE, - -1, - cppu::UnoType<OUString>::get(), - beans::PropertyAttribute::BOUND ) ); - } - } - - - // Lookup property. - - - beans::Property aProp; - aProp.Name = rPropName; - const PropertyMap::const_iterator it = m_pProps->find( aProp ); - if ( it != m_pProps->end() ) - { - rProp = *it; - } - else - { - // All unknown props are treated as: - rProp = beans::Property( - rPropName, - - 1, - cppu::UnoType<OUString>::get(), - beans::PropertyAttribute::BOUND ); - } -} - - -static PropertyNamesCache aStaticPropertyNamesCache; - -// static -void Content::removeCachedPropertyNames( const OUString & rURL ) -{ - aStaticPropertyNamesCache.removeCachedPropertyNames( rURL ); -} - -// Content implementation. - - -// virtual -uno::Sequence< beans::Property > Content::getProperties( - const uno::Reference< ucb::XCommandEnvironment > & xEnv ) -{ - bool bTransient; - std::unique_ptr< DAVResourceAccess > xResAccess; - std::unique_ptr< ContentProperties > xCachedProps; - rtl::Reference< ContentProvider > xProvider; - - { - osl::Guard< osl::Mutex > aGuard( m_aMutex ); - - bTransient = m_bTransient; - xResAccess.reset(new DAVResourceAccess(*m_xResAccess)); - if (m_xCachedProps) - xCachedProps.reset(new ContentProperties(*m_xCachedProps)); - xProvider.set( m_pProvider ); - } - - std::set< OUString > aPropSet; - - // No server access for just created (not yet committed) objects. - // Only a minimal set of properties supported at this stage. - if ( !bTransient ) - { - // Obtain all properties supported for this resource from server. - DAVOptions aDAVOptions; - getResourceOptions( xEnv, aDAVOptions, xResAccess ); - // only Class 1 is needed for PROPFIND - if ( aDAVOptions.isClass1() ) - { - try - { - std::vector< DAVResourceInfo > props; - OUString aTheURL( xResAccess->getURL() ); - PropertyNames aPropsNames( aTheURL ); - - if( !aStaticPropertyNamesCache.getCachedPropertyNames( aTheURL, aPropsNames ) ) - { - - xResAccess->PROPFIND( DAVZERO, props, xEnv ); - aPropsNames.setPropertiesNames( std::vector(props) ); - - aStaticPropertyNamesCache.addCachePropertyNames( aPropsNames ); - } - else - { - props = aPropsNames.getPropertiesNames(); - } - - // Note: vector should contain exactly one resource info, because - // we used a depth of DAVZERO for PROPFIND. - if (props.size() == 1) - { - aPropSet.insert( (*props.begin()).properties.begin(), - (*props.begin()).properties.end() ); - } - } - catch ( DAVException const & ) - { - } - } - } - - // Add DAV properties, map DAV properties to UCB properties. - bool bHasCreationDate = false; // creationdate <-> DateCreated - bool bHasGetLastModified = false; // getlastmodified <-> DateModified - bool bHasGetContentType = false; // getcontenttype <-> MediaType - bool bHasGetContentLength = false; // getcontentlength <-> Size - - bool bHasContentType = false; - bool bHasIsDocument = false; - bool bHasIsFolder = false; - bool bHasTitle = false; - bool bHasBaseURI = false; - bool bHasDateCreated = false; - bool bHasDateModified = false; - bool bHasMediaType = false; - bool bHasSize = false; - bool bHasCreatableInfos = false; - - { - for ( const auto& rProp : aPropSet ) - { - if ( !bHasCreationDate && - ( rProp == DAVProperties::CREATIONDATE ) ) - { - bHasCreationDate = true; - } - else if ( !bHasGetLastModified && - ( rProp == DAVProperties::GETLASTMODIFIED ) ) - { - bHasGetLastModified = true; - } - else if ( !bHasGetContentType && - ( rProp == DAVProperties::GETCONTENTTYPE ) ) - { - bHasGetContentType = true; - } - else if ( !bHasGetContentLength && - ( rProp == DAVProperties::GETCONTENTLENGTH ) ) - { - bHasGetContentLength = true; - } - else if ( !bHasContentType && rProp == "ContentType" ) - { - bHasContentType = true; - } - else if ( !bHasIsDocument && rProp == "IsDocument" ) - { - bHasIsDocument = true; - } - else if ( !bHasIsFolder && rProp == "IsFolder" ) - { - bHasIsFolder = true; - } - else if ( !bHasTitle && rProp == "Title" ) - { - bHasTitle = true; - } - else if ( !bHasBaseURI && rProp == "BaseURI" ) - { - bHasBaseURI = true; - } - else if ( !bHasDateCreated && rProp == "DateCreated" ) - { - bHasDateCreated = true; - } - else if ( !bHasDateModified && rProp == "DateModified" ) - { - bHasDateModified = true; - } - else if ( !bHasMediaType && rProp == "MediaType" ) - { - bHasMediaType = true; - } - else if ( !bHasSize && rProp == "Size" ) - { - bHasSize = true; - } - else if ( !bHasCreatableInfos && rProp == "CreatableContentsInfo" ) - { - bHasCreatableInfos = true; - } - } - } - - // Add mandatory properties. - if ( !bHasContentType ) - aPropSet.insert( - OUString( "ContentType" ) ); - - if ( !bHasIsDocument ) - aPropSet.insert( - OUString( "IsDocument" ) ); - - if ( !bHasIsFolder ) - aPropSet.insert( - OUString( "IsFolder" ) ); - - if ( !bHasTitle ) - { - // Always present since it can be calculated from content's URI. - aPropSet.insert( - OUString( "Title" ) ); - } - - // Add optional properties. - - if ( !bHasBaseURI ) - { - // Always present since it can be calculated from content's URI. - aPropSet.insert( - OUString( "BaseURI" ) ); - } - - if ( !bHasDateCreated && bHasCreationDate ) - aPropSet.insert( - OUString( "DateCreated" ) ); - - if ( !bHasDateModified && bHasGetLastModified ) - aPropSet.insert( - OUString( "DateModified" ) ); - - if ( !bHasMediaType && bHasGetContentType ) - aPropSet.insert( - OUString( "MediaType" ) ); - - if ( !bHasSize && bHasGetContentLength ) - aPropSet.insert( - OUString( "Size" ) ); - - if ( !bHasCreatableInfos ) - aPropSet.insert( - OUString( - "CreatableContentsInfo" ) ); - - // Add cached properties, if present and still missing. - if (xCachedProps) - { - const std::unique_ptr< PropertyValueMap > & xProps - = xCachedProps->getProperties(); - - for ( const auto& rEntry : *xProps ) - aPropSet.insert( rEntry.first ); - } - - // std::set -> uno::Sequence - sal_Int32 nCount = aPropSet.size(); - uno::Sequence< beans::Property > aProperties( nCount ); - auto aPropertiesRange = asNonConstRange(aProperties); - - sal_Int32 n = 0; - beans::Property aProp; - - for ( const auto& rProp : aPropSet ) - { - xProvider->getProperty( rProp, aProp ); - aPropertiesRange[ n++ ] = aProp; - } - - return aProperties; -} - - -// virtual -uno::Sequence< ucb::CommandInfo > Content::getCommands( - const uno::Reference< ucb::XCommandEnvironment > & xEnv ) -{ - osl::Guard< osl::Mutex > aGuard( m_aMutex ); - - uno::Sequence< ucb::CommandInfo > aCmdInfo{ - - - // Mandatory commands - - - ucb::CommandInfo( - "getCommandInfo", - -1, - cppu::UnoType<void>::get() ), - ucb::CommandInfo( - "getPropertySetInfo", - -1, - cppu::UnoType<void>::get() ), - ucb::CommandInfo( - "getPropertyValues", - -1, - cppu::UnoType<uno::Sequence< beans::Property >>::get() ), - ucb::CommandInfo( - "setPropertyValues", - -1, - cppu::UnoType<uno::Sequence< beans::PropertyValue >>::get() ), - - - // Optional standard commands - - - ucb::CommandInfo( - "delete", - -1, - cppu::UnoType<bool>::get() ), - ucb::CommandInfo( - "insert", - -1, - cppu::UnoType<ucb::InsertCommandArgument>::get() ), - ucb::CommandInfo( - "open", - -1, - cppu::UnoType<ucb::OpenCommandArgument2>::get() ), - - - // New commands - - - ucb::CommandInfo( - "post", - -1, - cppu::UnoType<ucb::PostCommandArgument2>::get() ), - ucb::CommandInfo( - "addProperty", - -1, - cppu::UnoType<ucb::PropertyCommandArgument>::get() ), - ucb::CommandInfo( - "removeProperty", - -1, - cppu::UnoType<OUString>::get() ), - }; - - bool bFolder = false; - - try - { - bFolder = isFolder( xEnv ); - } - catch ( uno::Exception const & ) - { - return aCmdInfo; - } - - ResourceType eType = resourceTypeForLocks( xEnv ); - bool bSupportsLocking = ( eType == NOT_FOUND || eType == DAV ); - - sal_Int32 nPos = aCmdInfo.getLength(); - sal_Int32 nMoreCmds = ( bFolder ? 2 : 0 ) + ( bSupportsLocking ? 2 : 0 ); - if ( nMoreCmds ) - aCmdInfo.realloc( nPos + nMoreCmds ); - else - return aCmdInfo; - - auto pCmdInfo = aCmdInfo.getArray(); - if ( bFolder ) - { - - // Optional standard commands - - - pCmdInfo[ nPos ] = - ucb::CommandInfo( - "transfer", - -1, - cppu::UnoType<ucb::TransferInfo>::get() ); - nPos++; - pCmdInfo[ nPos ] = - ucb::CommandInfo( - "createNewContent", - -1, - cppu::UnoType<ucb::ContentInfo>::get() ); - nPos++; - } - else - { - // no document-only commands at the moment. - } - - if ( bSupportsLocking ) - { - pCmdInfo[ nPos ] = - ucb::CommandInfo( - "lock", - -1, - cppu::UnoType<void>::get() ); - nPos++; - pCmdInfo[ nPos ] = - ucb::CommandInfo( - "unlock", - -1, - cppu::UnoType<void>::get() ); - nPos++; - } - return aCmdInfo; -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/ucb/source/ucp/webdav-neon/webdavdatasupplier.cxx b/ucb/source/ucp/webdav-neon/webdavdatasupplier.cxx deleted file mode 100644 index 6acadda6a6fd..000000000000 --- a/ucb/source/ucp/webdav-neon/webdavdatasupplier.cxx +++ /dev/null @@ -1,487 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - - -/************************************************************************** - TODO - ************************************************************************** - - *************************************************************************/ - -#include <sal/log.hxx> -#include <com/sun/star/ucb/IllegalIdentifierException.hpp> -#include <com/sun/star/ucb/OpenMode.hpp> -#include <com/sun/star/ucb/ResultSetException.hpp> -#include <ucbhelper/contentidentifier.hxx> -#include <ucbhelper/providerhelper.hxx> -#include <tools/diagnose_ex.h> -#include <memory> -#include <vector> -#include "webdavdatasupplier.hxx" -#include "webdavcontent.hxx" -#include "ContentProperties.hxx" -#include "NeonUri.hxx" - -using namespace com::sun::star; -using namespace webdav_ucp; - -namespace webdav_ucp -{ - - -// struct ResultListEntry. - -namespace { - -struct ResultListEntry -{ - OUString aId; - uno::Reference< ucb::XContentIdentifier > xId; - uno::Reference< ucb::XContent > xContent; - uno::Reference< sdbc::XRow > xRow; - std::shared_ptr<ContentProperties> const pData; - - explicit ResultListEntry(std::shared_ptr<ContentProperties> const& pEntry) - : pData(pEntry) - {} -}; - -} - -// ResultList. - - -typedef std::vector<std::unique_ptr<ResultListEntry>> ResultList; - - -// struct DataSupplier_Impl. - - -struct DataSupplier_Impl -{ - osl::Mutex m_aMutex; - ResultList m_Results; - rtl::Reference< Content > m_xContent; - uno::Reference< uno::XComponentContext > m_xContext; - sal_Int32 m_nOpenMode; - bool m_bCountFinal; - bool m_bThrowException; - - DataSupplier_Impl( - const uno::Reference< uno::XComponentContext >& rxContext, - const rtl::Reference< Content >& rContent, - sal_Int32 nOpenMode ) - : m_xContent( rContent ), m_xContext( rxContext ), m_nOpenMode( nOpenMode ), - m_bCountFinal( false ), m_bThrowException( false ) {} -}; - -} - - -// DataSupplier Implementation. - - -DataSupplier::DataSupplier( - const uno::Reference< uno::XComponentContext >& rxContext, - const rtl::Reference< Content >& rContent, - sal_Int32 nOpenMode ) -: m_pImpl( new DataSupplier_Impl( rxContext, rContent, nOpenMode ) ) -{ -} - - -// virtual -DataSupplier::~DataSupplier() -{ -} - - -// virtual -OUString DataSupplier::queryContentIdentifierString( sal_uInt32 nIndex ) -{ - osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex ); - - if (nIndex < m_pImpl->m_Results.size()) - { - OUString aId = m_pImpl->m_Results[ nIndex ]->aId; - if ( !aId.isEmpty() ) - { - // Already cached. - return aId; - } - } - - if ( getResult( nIndex ) ) - { - OUString aId = m_pImpl->m_xContent->getResourceAccess().getURL(); - - const ContentProperties& props(*(m_pImpl->m_Results[ nIndex ]->pData)); - - if ( ( aId.lastIndexOf( '/' ) + 1 ) != aId.getLength() ) - aId += "/"; - - aId += props.getEscapedTitle(); - - if ( props.isTrailingSlash() ) - aId += "/"; - - m_pImpl->m_Results[ nIndex ]->aId = aId; - return aId; - } - return OUString(); -} - - -// virtual -uno::Reference< ucb::XContentIdentifier > -DataSupplier::queryContentIdentifier( sal_uInt32 nIndex ) -{ - osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex ); - - if (nIndex < m_pImpl->m_Results.size()) - { - uno::Reference< ucb::XContentIdentifier > xId - = m_pImpl->m_Results[ nIndex ]->xId; - if ( xId.is() ) - { - // Already cached. - return xId; - } - } - - OUString aId = queryContentIdentifierString( nIndex ); - if ( !aId.isEmpty() ) - { - uno::Reference< ucb::XContentIdentifier > xId - = new ::ucbhelper::ContentIdentifier( aId ); - m_pImpl->m_Results[ nIndex ]->xId = xId; - return xId; - } - return uno::Reference< ucb::XContentIdentifier >(); -} - - -// virtual -uno::Reference< ucb::XContent > -DataSupplier::queryContent( sal_uInt32 nIndex ) -{ - osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex ); - - if (nIndex < m_pImpl->m_Results.size()) - { - uno::Reference< ucb::XContent > xContent - = m_pImpl->m_Results[ nIndex ]->xContent; - if ( xContent.is() ) - { - // Already cached. - return xContent; - } - } - - uno::Reference< ucb::XContentIdentifier > xId - = queryContentIdentifier( nIndex ); - if ( xId.is() ) - { - try - { - uno::Reference< ucb::XContent > xContent - = m_pImpl->m_xContent->getProvider()->queryContent( xId ); - m_pImpl->m_Results[ nIndex ]->xContent = xContent; - return xContent; - - } - catch ( ucb::IllegalIdentifierException& ) - { - } - } - return uno::Reference< ucb::XContent >(); -} - - -// virtual -bool DataSupplier::getResult( sal_uInt32 nIndex ) -{ - osl::ClearableGuard< osl::Mutex > aGuard( m_pImpl->m_aMutex ); - - if (nIndex < m_pImpl->m_Results.size()) - { - // Result already present. - return true; - } - - // Obtain values... - if ( getData() ) - { - if (nIndex < m_pImpl->m_Results.size()) - { - // Result already present. - return true; - } - } - - return false; -} - - -// virtual -sal_uInt32 DataSupplier::totalCount() -{ - // Obtain values... - getData(); - - return m_pImpl->m_Results.size(); -} - - -// virtual -sal_uInt32 DataSupplier::currentCount() -{ - return m_pImpl->m_Results.size(); -} - - -// virtual -bool DataSupplier::isCountFinal() -{ - return m_pImpl->m_bCountFinal; -} - - -// virtual -uno::Reference< sdbc::XRow > DataSupplier::queryPropertyValues( - sal_uInt32 nIndex ) -{ - osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex ); - - if (nIndex < m_pImpl->m_Results.size()) - { - uno::Reference< sdbc::XRow > xRow = m_pImpl->m_Results[ nIndex ]->xRow; - if ( xRow.is() ) - { - // Already cached. - return xRow; - } - } - - if ( getResult( nIndex ) ) - { - uno::Reference< sdbc::XRow > xRow - = Content::getPropertyValues( - m_pImpl->m_xContext, - getResultSet()->getProperties(), - *(m_pImpl->m_Results[ nIndex ]->pData), - m_pImpl->m_xContent->getProvider(), - queryContentIdentifierString( nIndex ) ); - m_pImpl->m_Results[ nIndex ]->xRow = xRow; - return xRow; - } - - return uno::Reference< sdbc::XRow >(); -} - - -// virtual -void DataSupplier::releasePropertyValues( sal_uInt32 nIndex ) -{ - osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex ); - - if (nIndex < m_pImpl->m_Results.size()) - m_pImpl->m_Results[ nIndex ]->xRow.clear(); -} - - -// virtual -void DataSupplier::close() -{ -} - - -// virtual -void DataSupplier::validate() -{ - if ( m_pImpl->m_bThrowException ) - throw ucb::ResultSetException(); -} - - -bool DataSupplier::getData() -{ - osl::ClearableGuard< osl::Mutex > aGuard( m_pImpl->m_aMutex ); - - if ( !m_pImpl->m_bCountFinal ) - { - std::vector< OUString > propertyNames; - ContentProperties::UCBNamesToDAVNames( - getResultSet()->getProperties(), propertyNames ); - - // Append "resourcetype", if not already present. It's value is - // needed to get a valid ContentProperties::pIsFolder value, which - // is needed for OpenMode handling. - - bool isNoResourceType = std::none_of(propertyNames.begin(), propertyNames.end(), - [](const OUString& rName) { return rName == DAVProperties::RESOURCETYPE; }); - - if ( isNoResourceType ) - propertyNames.push_back( DAVProperties::RESOURCETYPE ); - - std::vector< DAVResource > resources; - try - { - // propfind depth 1, get property values for parent AND for each - // child - m_pImpl->m_xContent->getResourceAccess() - .PROPFIND( DAVONE, - propertyNames, - resources, - getResultSet()->getEnvironment() ); -#if defined SAL_LOG_INFO - { - //print the resource for every URI returned - for ( const auto& rResource : resources ) - { - NeonUri aCurrURI( rResource.uri ); - OUString aCurrPath = aCurrURI.GetPath(); - aCurrPath = NeonUri::unescape( aCurrPath ); - SAL_INFO( "ucb.ucp.webdav", "getData() - resource URL: <" << rResource.uri << ">, unescaped to: <" << aCurrPath << "> )" ); - for ( const auto& rProp : rResource.properties ) - { - SAL_INFO( "ucb.ucp.webdav", "PROPFIND - property name: " << rProp.Name ); - } - } - } -#endif - } - catch ( DAVException & ) - { - TOOLS_WARN_EXCEPTION( "ucb.ucp.webdav", "Running PROPFIND: DAVException" ); - m_pImpl->m_bThrowException = true; - } - - if ( !m_pImpl->m_bThrowException ) - { - try - { - NeonUri aURI( - m_pImpl->m_xContent->getResourceAccess().getURL() ); - OUString aPath = aURI.GetPath(); - - if ( aPath.endsWith("/") ) - aPath = aPath.copy( 0, aPath.getLength() - 1 ); - - aPath = NeonUri::unescape( aPath ); - bool bFoundParent = false; - - for (DAVResource & rRes : resources) - { - // Filter parent, which is contained somewhere(!) in - // the vector. - if ( !bFoundParent ) - { - try - { - NeonUri aCurrURI( rRes.uri ); - OUString aCurrPath = aCurrURI.GetPath(); - if ( aCurrPath.endsWith("/") ) - aCurrPath - = aCurrPath.copy( - 0, - aCurrPath.getLength() - 1 ); - - aCurrPath = NeonUri::unescape( aCurrPath ); - if ( aPath == aCurrPath ) - { - bFoundParent = true; - continue; - } - } - catch ( DAVException const & ) - { - // do nothing, ignore error. continue. - } - } - - std::shared_ptr<ContentProperties> const - pContentProperties = std::make_shared<ContentProperties>(rRes); - - // Check resource against open mode. - switch ( m_pImpl->m_nOpenMode ) - { - case ucb::OpenMode::FOLDERS: - { - bool bFolder = false; - - const uno::Any & rValue - = pContentProperties->getValue( - "IsFolder" ); - rValue >>= bFolder; - - if ( !bFolder ) - continue; - - break; - } - - case ucb::OpenMode::DOCUMENTS: - { - bool bDocument = false; - - const uno::Any & rValue - = pContentProperties->getValue( - "IsDocument" ); - rValue >>= bDocument; - - if ( !bDocument ) - continue; - - break; - } - - case ucb::OpenMode::ALL: - default: - break; - } - - m_pImpl->m_Results.push_back( - std::make_unique<ResultListEntry>(pContentProperties)); - } - } - catch ( DAVException const & ) - { - } - } - - m_pImpl->m_bCountFinal = true; - - // Callback possible, because listeners may be informed! - aGuard.clear(); - getResultSet()->rowCountFinal(); - } - return !m_pImpl->m_bThrowException; -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/ucb/source/ucp/webdav-neon/webdavdatasupplier.hxx b/ucb/source/ucp/webdav-neon/webdavdatasupplier.hxx deleted file mode 100644 index 5c820364028c..000000000000 --- a/ucb/source/ucp/webdav-neon/webdavdatasupplier.hxx +++ /dev/null @@ -1,78 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -#pragma once - -#include <config_lgpl.h> -#include <memory> -#include <rtl/ref.hxx> -#include <ucbhelper/resultset.hxx> - -namespace webdav_ucp { - -struct DataSupplier_Impl; -class Content; - -class DataSupplier : public ucbhelper::ResultSetDataSupplier -{ - std::unique_ptr<DataSupplier_Impl> m_pImpl; - -private: - bool getData(); - -public: - DataSupplier( const css::uno::Reference< css::uno::XComponentContext >& rxContext, - const rtl::Reference< Content >& rContent, - sal_Int32 nOpenMode); - - virtual ~DataSupplier() override; - - virtual OUString queryContentIdentifierString( sal_uInt32 nIndex ) override; - virtual css::uno::Reference< css::ucb::XContentIdentifier > - queryContentIdentifier( sal_uInt32 nIndex ) override; - virtual css::uno::Reference< css::ucb::XContent > - queryContent( sal_uInt32 nIndex ) override; - - virtual bool getResult( sal_uInt32 nIndex ) override; - - virtual sal_uInt32 totalCount() override; - virtual sal_uInt32 currentCount() override; - virtual bool isCountFinal() override; - - virtual css::uno::Reference< css::sdbc::XRow > - queryPropertyValues( sal_uInt32 nIndex ) override; - virtual void releasePropertyValues( sal_uInt32 nIndex ) override; - - virtual void close() override; - - virtual void validate() override; -}; - -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/ucb/source/ucp/webdav-neon/webdavprovider.cxx b/ucb/source/ucp/webdav-neon/webdavprovider.cxx deleted file mode 100644 index 87dc8b03188b..000000000000 --- a/ucb/source/ucp/webdav-neon/webdavprovider.cxx +++ /dev/null @@ -1,189 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -#include <sal/config.h> - -#include <com/sun/star/ucb/IllegalIdentifierException.hpp> -#include <comphelper/processfactory.hxx> -#include <ucbhelper/contentidentifier.hxx> -#include <ucbhelper/macros.hxx> -#include <cppuhelper/queryinterface.hxx> -#include "webdavprovider.hxx" -#include "webdavcontent.hxx" - -#include <osl/mutex.hxx> -#include <tools/urlobj.hxx> - -using namespace com::sun::star; -using namespace webdav_ucp; - - -// ContentProvider Implementation. - - -ContentProvider::ContentProvider( - const uno::Reference< uno::XComponentContext >& rxContext ) -: ::ucbhelper::ContentProviderImplHelper( rxContext ), - m_xDAVSessionFactory( new DAVSessionFactory ) -{ -} - - -// virtual -ContentProvider::~ContentProvider() -{ -} - - -// XInterface methods. - -void SAL_CALL ContentProvider::acquire() - noexcept -{ - OWeakObject::acquire(); -} - -void SAL_CALL ContentProvider::release() - noexcept -{ - OWeakObject::release(); -} - -css::uno::Any SAL_CALL ContentProvider::queryInterface( const css::uno::Type & rType ) -{ - css::uno::Any aRet = cppu::queryInterface( rType, - static_cast< lang::XTypeProvider* >(this), - static_cast< lang::XServiceInfo* >(this), - static_cast< ucb::XContentProvider* >(this) - ); - return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType ); -} - -// XTypeProvider methods. - - -XTYPEPROVIDER_IMPL_3( ContentProvider, - lang::XTypeProvider, - lang::XServiceInfo, - ucb::XContentProvider ); - - -// XServiceInfo methods. - -OUString -ContentProvider::getImplementationName() -{ - return "com.sun.star.comp.WebDAVContentProvider"; -} - -css::uno::Sequence< OUString > -ContentProvider::getSupportedServiceNames() -{ - return { WEBDAV_CONTENT_PROVIDER_SERVICE_NAME }; -} - -sal_Bool -ContentProvider::supportsService(const OUString& s) -{ - return cppu::supportsService(this, s); -} - -// XContentProvider methods. - - -// virtual -uno::Reference< ucb::XContent > SAL_CALL -ContentProvider::queryContent( - const uno::Reference< - ucb::XContentIdentifier >& Identifier ) -{ - // Check URL scheme... - INetURLObject aURL( Identifier->getContentIdentifier() ); - - if ( aURL.isSchemeEqualTo( INetProtocol::NotValid ) ) - throw ucb::IllegalIdentifierException(); - - if ( !aURL.isAnyKnownWebDAVScheme() ) - throw ucb::IllegalIdentifierException(); - - uno::Reference< ucb::XContentIdentifier > xCanonicId; - - if (aURL.isSchemeEqualTo( INetProtocol::VndSunStarWebdav ) || - aURL.isSchemeEqualTo(DAV_URL_SCHEME) || - aURL.isSchemeEqualTo( WEBDAV_URL_SCHEME ) ) - { - aURL.changeScheme( INetProtocol::Http ); - xCanonicId = new ::ucbhelper::ContentIdentifier( aURL.getExternalURL() ); - } - else if ( aURL.isSchemeEqualTo( VNDSUNSTARWEBDAVS_URL_SCHEME ) || - aURL.isSchemeEqualTo( DAVS_URL_SCHEME ) || - aURL.isSchemeEqualTo( WEBDAVS_URL_SCHEME )) - { - aURL.changeScheme( INetProtocol::Https ); - xCanonicId = new ::ucbhelper::ContentIdentifier( aURL.getExternalURL() ); - } - else - { - xCanonicId = Identifier; - } - - osl::MutexGuard aGuard( m_aMutex ); - - // Check, if a content with given id already exists... - uno::Reference< ucb::XContent > xContent - = queryExistingContent( xCanonicId ); - if ( xContent.is() ) - return xContent; - - // Create a new content. - - try - { - xContent = new ::webdav_ucp::Content( - m_xContext, this, xCanonicId, m_xDAVSessionFactory ); - registerNewContent( xContent ); - } - catch ( ucb::ContentCreationException const & ) - { - throw ucb::IllegalIdentifierException(); - } - - if ( !xContent->getIdentifier().is() ) - throw ucb::IllegalIdentifierException(); - - return xContent; -} - -extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface* -ucb_webdav_neon_ContentProvider_get_implementation( - css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const&) -{ - return cppu::acquire(new ContentProvider(context)); -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/ucb/source/ucp/webdav-neon/webdavprovider.hxx b/ucb/source/ucp/webdav-neon/webdavprovider.hxx deleted file mode 100644 index 7aca1b48a2b9..000000000000 --- a/ucb/source/ucp/webdav-neon/webdavprovider.hxx +++ /dev/null @@ -1,105 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -#pragma once - -#include <memory> -#include <config_lgpl.h> -#include <rtl/ref.hxx> -#include <com/sun/star/beans/Property.hpp> -#include <com/sun/star/lang/XSingleServiceFactory.hpp> -#include "DAVSessionFactory.hxx" -#include <ucbhelper/providerhelper.hxx> -#include "PropertyMap.hxx" - -namespace webdav_ucp { - - -// UNO service name for the provider. This name will be used by the UCB to -// create instances of the provider. -inline constexpr OUStringLiteral WEBDAV_CONTENT_PROVIDER_SERVICE_NAME =u"com.sun.star.ucb.WebDAVContentProvider"; - -// URL scheme. This is the scheme the provider will be able to create -// contents for. The UCB will select the provider ( i.e. in order to create -// contents ) according to this scheme. -#define VNDSUNSTARWEBDAV_URL_SCHEME "vnd.sun.star.webdav" -#define VNDSUNSTARWEBDAVS_URL_SCHEME u"vnd.sun.star.webdavs" -inline constexpr OUStringLiteral HTTP_URL_SCHEME = u"http"; -inline constexpr OUStringLiteral HTTPS_URL_SCHEME = u"https"; -#define DAV_URL_SCHEME u"dav" -#define DAVS_URL_SCHEME u"davs" -#define WEBDAV_URL_SCHEME u"webdav" -#define WEBDAVS_URL_SCHEME u"webdavs" - -#define FTP_URL_SCHEME "ftp" - -#define HTTP_CONTENT_TYPE ("application/" + HTTP_URL_SCHEME + "-content") - -#define WEBDAV_CONTENT_TYPE HTTP_CONTENT_TYPE -inline constexpr OUStringLiteral WEBDAV_COLLECTION_TYPE = u"application/" VNDSUNSTARWEBDAV_URL_SCHEME "-collection"; - - -class ContentProvider : public ::ucbhelper::ContentProviderImplHelper -{ - rtl::Reference< DAVSessionFactory > m_xDAVSessionFactory; - std::unique_ptr<PropertyMap> m_pProps; - -public: - explicit ContentProvider( const css::uno::Reference< css::uno::XComponentContext >& rxContext ); - virtual ~ContentProvider() override; - - // XInterface - virtual css::uno::Any SAL_CALL queryInterface( const css::uno::Type & rType ) override; - virtual void SAL_CALL acquire() - noexcept override; - virtual void SAL_CALL release() - noexcept override; - - // XTypeProvider - virtual css::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId() override; - virtual css::uno::Sequence< css::uno::Type > SAL_CALL getTypes() override; - - // XServiceInfo - virtual OUString SAL_CALL getImplementationName() override; - virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override; - virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override; - - // XContentProvider - virtual css::uno::Reference< css::ucb::XContent > SAL_CALL - queryContent( const css::uno::Reference< css::ucb::XContentIdentifier >& Identifier ) override; - - - // Non-interface methods. - - void getProperty( const OUString & rPropName, - css::beans::Property & rProp ); -}; - -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/ucb/source/ucp/webdav-neon/webdavresultset.cxx b/ucb/source/ucp/webdav-neon/webdavresultset.cxx deleted file mode 100644 index be4fadc9bf39..000000000000 --- a/ucb/source/ucp/webdav-neon/webdavresultset.cxx +++ /dev/null @@ -1,86 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - - -/************************************************************************** - TODO - ************************************************************************** - - - This implementation is not a dynamic result set!!! It only implements - the necessary interfaces, but never recognizes/notifies changes!!! - - *************************************************************************/ -#include "webdavresultset.hxx" - -using namespace com::sun::star; -using namespace webdav_ucp; - - -// DynamicResultSet Implementation. - - -DynamicResultSet::DynamicResultSet( - const uno::Reference< uno::XComponentContext >& rxContext, - const rtl::Reference< Content >& rxContent, - const ucb::OpenCommandArgument2& rCommand, - const uno::Reference< ucb::XCommandEnvironment >& rxEnv ) -: ResultSetImplHelper( rxContext, rCommand ), - m_xContent( rxContent ), - m_xEnv( rxEnv ) -{ -} - - -// Non-interface methods. - - -void DynamicResultSet::initStatic() -{ - m_xResultSet1 - = new ::ucbhelper::ResultSet( m_xContext, - m_aCommand.Properties, - new DataSupplier( m_xContext, - m_xContent, - m_aCommand.Mode ), - m_xEnv ); -} - - -void DynamicResultSet::initDynamic() -{ - m_xResultSet1 - = new ::ucbhelper::ResultSet( m_xContext, - m_aCommand.Properties, - new DataSupplier( m_xContext, - m_xContent, - m_aCommand.Mode ), - m_xEnv ); - m_xResultSet2 = m_xResultSet1; -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/ucb/source/ucp/webdav-neon/webdavresultset.hxx b/ucb/source/ucp/webdav-neon/webdavresultset.hxx deleted file mode 100644 index c2f8e727ec04..000000000000 --- a/ucb/source/ucp/webdav-neon/webdavresultset.hxx +++ /dev/null @@ -1,57 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -#pragma once - -#include <config_lgpl.h> -#include <rtl/ref.hxx> -#include <ucbhelper/resultsethelper.hxx> -#include "webdavcontent.hxx" -#include "webdavdatasupplier.hxx" - -namespace webdav_ucp { - -class DynamicResultSet : public ::ucbhelper::ResultSetImplHelper -{ - rtl::Reference< Content > m_xContent; - css::uno::Reference< css::ucb::XCommandEnvironment > m_xEnv; - -private: - virtual void initStatic() override; - virtual void initDynamic() override; - -public: - DynamicResultSet( const css::uno::Reference< css::uno::XComponentContext >& rxContext, - const rtl::Reference< Content >& rxContent, - const css::ucb::OpenCommandArgument2& rCommand, - const css::uno::Reference< css::ucb::XCommandEnvironment >& rxEnv ); -}; - -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |