diff options
Diffstat (limited to 'ucb/source/ucp/webdav-neon/NeonUri.cxx')
-rw-r--r-- | ucb/source/ucp/webdav-neon/NeonUri.cxx | 291 |
1 files changed, 291 insertions, 0 deletions
diff --git a/ucb/source/ucp/webdav-neon/NeonUri.cxx b/ucb/source/ucp/webdav-neon/NeonUri.cxx new file mode 100644 index 000000000..c1c263421 --- /dev/null +++ b/ucb/source/ucp/webdav-neon/NeonUri.cxx @@ -0,0 +1,291 @@ +/* -*- 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"), + nullptr, + nullptr, + DEFAULT_HTTP_PORT, + nullptr, + nullptr, + nullptr }; +const ne_uri g_sUriDefaultsHTTPS = { const_cast<char *>("https"), + nullptr, + nullptr, + DEFAULT_HTTPS_PORT, + nullptr, + nullptr, + nullptr }; +const ne_uri g_sUriDefaultsFTP = { const_cast<char *>("ftp"), + nullptr, + nullptr, + DEFAULT_FTP_PORT, + nullptr, + 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( OUString::number( 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 (const OUString& 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( OUString::number( nPort ) ); + } + return aBuf.makeStringAndClear(); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |