diff options
Diffstat (limited to 'ucb/source/ucp/webdav-curl/DAVProperties.cxx')
-rw-r--r-- | ucb/source/ucp/webdav-curl/DAVProperties.cxx | 202 |
1 files changed, 202 insertions, 0 deletions
diff --git a/ucb/source/ucp/webdav-curl/DAVProperties.cxx b/ucb/source/ucp/webdav-curl/DAVProperties.cxx new file mode 100644 index 000000000..8b3dce369 --- /dev/null +++ b/ucb/source/ucp/webdav-curl/DAVProperties.cxx @@ -0,0 +1,202 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include "DAVProperties.hxx" +#include <rtl/ustrbuf.hxx> +#include <o3tl/string_view.hxx> +#include <string.h> + +using namespace http_dav_ucp; + + +// static +void DAVProperties::createSerfPropName( ::std::u16string_view const rFullName, + SerfPropName & 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 + { + // this must not be a URI - WebDAVResponseParser must have converted it + // to the "<prop:" form above + assert(rFullName.find(':') == ::std::u16string_view::npos); + // Add our namespace to our own properties. + rName.nspace = "http://ucb.openoffice.org/dav/props/"; + rName.name + = strdup( OUStringToOString( rFullName, + RTL_TEXTENCODING_UTF8 ).getStr() ); + } +} + + +// static +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.getLength() ) + { + // 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::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))) + { + 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:"; + rFullName += aName; + rFullName += " xmlns:prop=\""; + rFullName += aNameSpace; + rFullName += "\">"; + } +} + + +// static +bool DAVProperties::isUCBDeadProperty( const SerfPropName & rName ) +{ + return ( rName.nspace && + ( rtl_str_compareIgnoreAsciiCase( + rName.nspace, "http://ucb.openoffice.org/dav/props/" ) + == 0 ) ); +} + +bool DAVProperties::isUCBSpecialProperty(const OUString& rFullName, OUString& rParsedName) +{ + sal_Int32 nLen = rFullName.getLength(); + if ( nLen <= 0 || + !rFullName.startsWith( "<prop:" ) || + !rFullName.endsWith( "\">" ) ) + return false; + + sal_Int32 nStart = RTL_CONSTASCII_LENGTH( "<prop:" ); + sal_Int32 nEnd = rFullName.indexOf( ' ', nStart ); + if ( nEnd == -1 ) + return false; + + OUString sPropName = rFullName.copy( nStart, nEnd - nStart ); + if ( !sPropName.getLength() ) + return false; + + // TODO skip whitespaces? + if ( !rFullName.match( "xmlns:prop=\"", ++nEnd ) ) + return false; + + nStart = nEnd + RTL_CONSTASCII_LENGTH( "xmlns:prop=\"" ); + nEnd = rFullName.indexOf( '"', nStart ); + if ( nEnd != nLen - RTL_CONSTASCII_LENGTH( "\">" ) ) + return false; + + OUString sNamesp = rFullName.copy( nStart, nEnd - nStart ); + if ( !( nLen = sNamesp.getLength() ) ) + return false; + + OUStringBuffer aBuff( sNamesp ); + if ( sNamesp[nLen - 1] != '/' ) + aBuff.append( '/' ); + aBuff.append( sPropName ); + rParsedName = aBuff.makeStringAndClear(); + + return rParsedName.getLength(); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |