18590a0fdSAndre Fischer /**************************************************************
28590a0fdSAndre Fischer *
38590a0fdSAndre Fischer * Licensed to the Apache Software Foundation (ASF) under one
48590a0fdSAndre Fischer * or more contributor license agreements. See the NOTICE file
58590a0fdSAndre Fischer * distributed with this work for additional information
68590a0fdSAndre Fischer * regarding copyright ownership. The ASF licenses this file
78590a0fdSAndre Fischer * to you under the Apache License, Version 2.0 (the
88590a0fdSAndre Fischer * "License"); you may not use this file except in compliance
98590a0fdSAndre Fischer * with the License. You may obtain a copy of the License at
108590a0fdSAndre Fischer *
118590a0fdSAndre Fischer * http://www.apache.org/licenses/LICENSE-2.0
128590a0fdSAndre Fischer *
138590a0fdSAndre Fischer * Unless required by applicable law or agreed to in writing,
148590a0fdSAndre Fischer * software distributed under the License is distributed on an
158590a0fdSAndre Fischer * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
168590a0fdSAndre Fischer * KIND, either express or implied. See the License for the
178590a0fdSAndre Fischer * specific language governing permissions and limitations
188590a0fdSAndre Fischer * under the License.
198590a0fdSAndre Fischer *
208590a0fdSAndre Fischer *************************************************************/
218590a0fdSAndre Fischer
228590a0fdSAndre Fischer // MARKER(update_precomp.py): autogen include statement, do not remove
238590a0fdSAndre Fischer #include "precompiled_ucb.hxx"
248590a0fdSAndre Fischer
258590a0fdSAndre Fischer #include <string.h>
268590a0fdSAndre Fischer #include <rtl/uri.hxx>
278590a0fdSAndre Fischer #include <rtl/ustring.hxx>
288590a0fdSAndre Fischer #include <rtl/ustrbuf.hxx>
298590a0fdSAndre Fischer #include "SerfUri.hxx"
308590a0fdSAndre Fischer #include "DAVException.hxx"
31*c1c10f68SAriel Constenla-Haile #include "AprEnv.hxx"
328590a0fdSAndre Fischer
338590a0fdSAndre Fischer #include "../inc/urihelper.hxx"
348590a0fdSAndre Fischer
358590a0fdSAndre Fischer using namespace http_dav_ucp;
368590a0fdSAndre Fischer
378590a0fdSAndre Fischer # if defined __SUNPRO_CC
388590a0fdSAndre Fischer # pragma enable_warn
398590a0fdSAndre Fischer #endif
408590a0fdSAndre Fischer
418590a0fdSAndre Fischer // -------------------------------------------------------------------
428590a0fdSAndre Fischer // Constructor
438590a0fdSAndre Fischer // -------------------------------------------------------------------
448590a0fdSAndre Fischer
458590a0fdSAndre Fischer namespace {
468590a0fdSAndre Fischer
matchIgnoreAsciiCase(rtl::OString const & rStr1,sal_Char const * pStr2,sal_Int32 nStr2Len)478590a0fdSAndre Fischer inline bool matchIgnoreAsciiCase(rtl::OString const & rStr1,
488590a0fdSAndre Fischer sal_Char const * pStr2,
498590a0fdSAndre Fischer sal_Int32 nStr2Len) SAL_THROW(())
508590a0fdSAndre Fischer {
518590a0fdSAndre Fischer return
528590a0fdSAndre Fischer rtl_str_shortenedCompareIgnoreAsciiCase_WithLength(
538590a0fdSAndre Fischer rStr1.getStr(), rStr1.getLength(), pStr2, nStr2Len, nStr2Len)
548590a0fdSAndre Fischer == 0;
558590a0fdSAndre Fischer }
568590a0fdSAndre Fischer
578590a0fdSAndre Fischer }
588590a0fdSAndre Fischer
SerfUri(const apr_uri_t * inUri)598590a0fdSAndre Fischer SerfUri::SerfUri( const apr_uri_t * inUri )
608590a0fdSAndre Fischer throw ( DAVException )
618590a0fdSAndre Fischer : mAprUri( *inUri )
628590a0fdSAndre Fischer , mURI()
638590a0fdSAndre Fischer , mScheme()
648590a0fdSAndre Fischer , mUserInfo()
658590a0fdSAndre Fischer , mHostName()
668590a0fdSAndre Fischer , mPort()
678590a0fdSAndre Fischer , mPath()
688590a0fdSAndre Fischer {
698590a0fdSAndre Fischer if ( inUri == 0 )
708590a0fdSAndre Fischer throw DAVException( DAVException::DAV_INVALID_ARG );
718590a0fdSAndre Fischer
728590a0fdSAndre Fischer char * uri = apr_uri_unparse( apr_environment::AprEnv::getAprEnv()->getAprPool(), &mAprUri, 0 );
738590a0fdSAndre Fischer
748590a0fdSAndre Fischer if ( uri == 0 )
758590a0fdSAndre Fischer throw DAVException( DAVException::DAV_INVALID_ARG );
768590a0fdSAndre Fischer
778590a0fdSAndre Fischer init( &mAprUri );
788590a0fdSAndre Fischer
798590a0fdSAndre Fischer calculateURI();
808590a0fdSAndre Fischer }
818590a0fdSAndre Fischer
SerfUri(const rtl::OUString & inUri)828590a0fdSAndre Fischer SerfUri::SerfUri( const rtl::OUString & inUri )
838590a0fdSAndre Fischer throw ( DAVException )
848590a0fdSAndre Fischer : mAprUri()
858590a0fdSAndre Fischer , mURI()
868590a0fdSAndre Fischer , mScheme()
878590a0fdSAndre Fischer , mUserInfo()
888590a0fdSAndre Fischer , mHostName()
898590a0fdSAndre Fischer , mPort()
908590a0fdSAndre Fischer , mPath()
918590a0fdSAndre Fischer {
928590a0fdSAndre Fischer if ( inUri.getLength() <= 0 )
938590a0fdSAndre Fischer throw DAVException( DAVException::DAV_INVALID_ARG );
948590a0fdSAndre Fischer
958590a0fdSAndre Fischer // #i77023#
968590a0fdSAndre Fischer rtl::OUString aEscapedUri( ucb_impl::urihelper::encodeURI( inUri ) );
978590a0fdSAndre Fischer
988590a0fdSAndre Fischer rtl::OString theInputUri(
998590a0fdSAndre Fischer aEscapedUri.getStr(), aEscapedUri.getLength(), RTL_TEXTENCODING_UTF8 );
1008590a0fdSAndre Fischer
1018590a0fdSAndre Fischer if ( apr_uri_parse( apr_environment::AprEnv::getAprEnv()->getAprPool(),
1028590a0fdSAndre Fischer theInputUri.getStr(), &mAprUri ) != APR_SUCCESS )
1038590a0fdSAndre Fischer {
1048590a0fdSAndre Fischer throw DAVException( DAVException::DAV_INVALID_ARG );
1058590a0fdSAndre Fischer }
1068590a0fdSAndre Fischer if ( !mAprUri.port )
1078590a0fdSAndre Fischer {
1088590a0fdSAndre Fischer mAprUri.port = apr_uri_port_of_scheme( mAprUri.scheme );
1098590a0fdSAndre Fischer }
1108590a0fdSAndre Fischer if ( !mAprUri.path )
1118590a0fdSAndre Fischer {
1128590a0fdSAndre Fischer mAprUri.path = "/";
1138590a0fdSAndre Fischer }
1148590a0fdSAndre Fischer
1158590a0fdSAndre Fischer init( &mAprUri );
1168590a0fdSAndre Fischer
1178590a0fdSAndre Fischer calculateURI();
1188590a0fdSAndre Fischer }
1198590a0fdSAndre Fischer
init(const apr_uri_t * pUri)1208590a0fdSAndre Fischer void SerfUri::init( const apr_uri_t * pUri )
1218590a0fdSAndre Fischer {
1228590a0fdSAndre Fischer mScheme = rtl::OStringToOUString( pUri->scheme, RTL_TEXTENCODING_UTF8 );
1238590a0fdSAndre Fischer mUserInfo = rtl::OStringToOUString( pUri->user, RTL_TEXTENCODING_UTF8 );
1248590a0fdSAndre Fischer mHostName = rtl::OStringToOUString( pUri->hostname, RTL_TEXTENCODING_UTF8 );
1258590a0fdSAndre Fischer mPort = pUri->port;
1268590a0fdSAndre Fischer mPath = rtl::OStringToOUString( pUri->path, RTL_TEXTENCODING_UTF8 );
1278590a0fdSAndre Fischer
1288590a0fdSAndre Fischer if ( pUri->query )
1298590a0fdSAndre Fischer {
1308590a0fdSAndre Fischer mPath += rtl::OUString::createFromAscii( "?" );
1318590a0fdSAndre Fischer mPath += rtl::OStringToOUString( pUri->query, RTL_TEXTENCODING_UTF8 );
1328590a0fdSAndre Fischer }
1338590a0fdSAndre Fischer
1348590a0fdSAndre Fischer if ( pUri->fragment )
1358590a0fdSAndre Fischer {
1368590a0fdSAndre Fischer mPath += rtl::OUString::createFromAscii( "#" );
1378590a0fdSAndre Fischer mPath += rtl::OStringToOUString( pUri->fragment, RTL_TEXTENCODING_UTF8 );
1388590a0fdSAndre Fischer }
1398590a0fdSAndre Fischer }
1408590a0fdSAndre Fischer
~SerfUri()1418590a0fdSAndre Fischer SerfUri::~SerfUri( )
1428590a0fdSAndre Fischer {
1438590a0fdSAndre Fischer }
1448590a0fdSAndre Fischer
calculateURI()1458590a0fdSAndre Fischer void SerfUri::calculateURI ()
1468590a0fdSAndre Fischer {
1478590a0fdSAndre Fischer rtl::OUStringBuffer aBuf( mScheme );
1488590a0fdSAndre Fischer aBuf.appendAscii( "://" );
1498590a0fdSAndre Fischer if ( mUserInfo.getLength() > 0 )
1508590a0fdSAndre Fischer {
1518590a0fdSAndre Fischer aBuf.append( mUserInfo );
1528590a0fdSAndre Fischer aBuf.appendAscii( "@" );
1538590a0fdSAndre Fischer }
1548590a0fdSAndre Fischer // Is host a numeric IPv6 address?
1558590a0fdSAndre Fischer if ( ( mHostName.indexOf( ':' ) != -1 ) &&
1568590a0fdSAndre Fischer ( mHostName[ 0 ] != sal_Unicode( '[' ) ) )
1578590a0fdSAndre Fischer {
1588590a0fdSAndre Fischer aBuf.appendAscii( "[" );
1598590a0fdSAndre Fischer aBuf.append( mHostName );
1608590a0fdSAndre Fischer aBuf.appendAscii( "]" );
1618590a0fdSAndre Fischer }
1628590a0fdSAndre Fischer else
1638590a0fdSAndre Fischer {
1648590a0fdSAndre Fischer aBuf.append( mHostName );
1658590a0fdSAndre Fischer }
1668590a0fdSAndre Fischer
1678590a0fdSAndre Fischer // append port, but only, if not default port.
1688590a0fdSAndre Fischer bool bAppendPort = true;
1698590a0fdSAndre Fischer switch ( mPort )
1708590a0fdSAndre Fischer {
1718590a0fdSAndre Fischer case DEFAULT_HTTP_PORT:
1728590a0fdSAndre Fischer bAppendPort = !mScheme.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "http" ) );
1738590a0fdSAndre Fischer break;
1748590a0fdSAndre Fischer
1758590a0fdSAndre Fischer case DEFAULT_HTTPS_PORT:
1768590a0fdSAndre Fischer bAppendPort = !mScheme.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "https" ) );
1778590a0fdSAndre Fischer break;
1788590a0fdSAndre Fischer }
1798590a0fdSAndre Fischer if ( bAppendPort )
1808590a0fdSAndre Fischer {
1818590a0fdSAndre Fischer aBuf.appendAscii( ":" );
1828590a0fdSAndre Fischer aBuf.append( rtl::OUString::valueOf( mPort ) );
1838590a0fdSAndre Fischer }
1848590a0fdSAndre Fischer aBuf.append( mPath );
1858590a0fdSAndre Fischer
1868590a0fdSAndre Fischer mURI = aBuf.makeStringAndClear();
1878590a0fdSAndre Fischer }
1888590a0fdSAndre Fischer
GetPathBaseName() const1898590a0fdSAndre Fischer ::rtl::OUString SerfUri::GetPathBaseName () const
1908590a0fdSAndre Fischer {
1918590a0fdSAndre Fischer sal_Int32 nPos = mPath.lastIndexOf ('/');
1928590a0fdSAndre Fischer sal_Int32 nTrail = 0;
1938590a0fdSAndre Fischer if (nPos == mPath.getLength () - 1)
1948590a0fdSAndre Fischer {
1958590a0fdSAndre Fischer // Trailing slash found. Skip.
1968590a0fdSAndre Fischer nTrail = 1;
1978590a0fdSAndre Fischer nPos = mPath.lastIndexOf ('/', nPos);
1988590a0fdSAndre Fischer }
1998590a0fdSAndre Fischer if (nPos != -1)
2008590a0fdSAndre Fischer {
2018590a0fdSAndre Fischer rtl::OUString aTemp(
2028590a0fdSAndre Fischer mPath.copy (nPos + 1, mPath.getLength () - nPos - 1 - nTrail) );
2038590a0fdSAndre Fischer
2048590a0fdSAndre Fischer // query, fragment present?
2058590a0fdSAndre Fischer nPos = aTemp.indexOf( '?' );
2068590a0fdSAndre Fischer if ( nPos == -1 )
2078590a0fdSAndre Fischer nPos = aTemp.indexOf( '#' );
2088590a0fdSAndre Fischer
2098590a0fdSAndre Fischer if ( nPos != -1 )
2108590a0fdSAndre Fischer aTemp = aTemp.copy( 0, nPos );
2118590a0fdSAndre Fischer
2128590a0fdSAndre Fischer return aTemp;
2138590a0fdSAndre Fischer }
2148590a0fdSAndre Fischer else
2158590a0fdSAndre Fischer return rtl::OUString::createFromAscii ("/");
2168590a0fdSAndre Fischer }
2178590a0fdSAndre Fischer
operator ==(const SerfUri & rOther) const2188590a0fdSAndre Fischer bool SerfUri::operator== ( const SerfUri & rOther ) const
2198590a0fdSAndre Fischer {
2208590a0fdSAndre Fischer return ( mURI == rOther.mURI );
2218590a0fdSAndre Fischer }
2228590a0fdSAndre Fischer
GetPathBaseNameUnescaped() const2238590a0fdSAndre Fischer ::rtl::OUString SerfUri::GetPathBaseNameUnescaped () const
2248590a0fdSAndre Fischer {
2258590a0fdSAndre Fischer return unescape( GetPathBaseName() );
2268590a0fdSAndre Fischer }
2278590a0fdSAndre Fischer
AppendPath(const rtl::OUString & rPath)2288590a0fdSAndre Fischer void SerfUri::AppendPath (const rtl::OUString& rPath)
2298590a0fdSAndre Fischer {
2308590a0fdSAndre Fischer if (mPath.lastIndexOf ('/') != mPath.getLength () - 1)
2318590a0fdSAndre Fischer mPath += rtl::OUString::createFromAscii ("/");
2328590a0fdSAndre Fischer
2338590a0fdSAndre Fischer mPath += rPath;
2348590a0fdSAndre Fischer calculateURI ();
2358590a0fdSAndre Fischer };
2368590a0fdSAndre Fischer
2378590a0fdSAndre Fischer // static
escapeSegment(const rtl::OUString & segment)2388590a0fdSAndre Fischer rtl::OUString SerfUri::escapeSegment( const rtl::OUString& segment )
2398590a0fdSAndre Fischer {
2408590a0fdSAndre Fischer return rtl::Uri::encode( segment,
2418590a0fdSAndre Fischer rtl_UriCharClassPchar,
2428590a0fdSAndre Fischer rtl_UriEncodeIgnoreEscapes,
2438590a0fdSAndre Fischer RTL_TEXTENCODING_UTF8 );
2448590a0fdSAndre Fischer }
2458590a0fdSAndre Fischer
2468590a0fdSAndre Fischer // static
unescape(const rtl::OUString & segment)2478590a0fdSAndre Fischer rtl::OUString SerfUri::unescape( const rtl::OUString& segment )
2488590a0fdSAndre Fischer {
2498590a0fdSAndre Fischer return rtl::Uri::decode( segment,
2508590a0fdSAndre Fischer rtl_UriDecodeWithCharset,
2518590a0fdSAndre Fischer RTL_TEXTENCODING_UTF8 );
2528590a0fdSAndre Fischer }
2538590a0fdSAndre Fischer
2548590a0fdSAndre Fischer // static
makeConnectionEndPointString(const rtl::OUString & rHostName,int nPort)2558590a0fdSAndre Fischer rtl::OUString SerfUri::makeConnectionEndPointString(
2568590a0fdSAndre Fischer const rtl::OUString & rHostName, int nPort )
2578590a0fdSAndre Fischer {
2588590a0fdSAndre Fischer rtl::OUStringBuffer aBuf;
2598590a0fdSAndre Fischer
2608590a0fdSAndre Fischer // Is host a numeric IPv6 address?
2618590a0fdSAndre Fischer if ( ( rHostName.indexOf( ':' ) != -1 ) &&
2628590a0fdSAndre Fischer ( rHostName[ 0 ] != sal_Unicode( '[' ) ) )
2638590a0fdSAndre Fischer {
2648590a0fdSAndre Fischer aBuf.appendAscii( "[" );
2658590a0fdSAndre Fischer aBuf.append( rHostName );
2668590a0fdSAndre Fischer aBuf.appendAscii( "]" );
2678590a0fdSAndre Fischer }
2688590a0fdSAndre Fischer else
2698590a0fdSAndre Fischer {
2708590a0fdSAndre Fischer aBuf.append( rHostName );
2718590a0fdSAndre Fischer }
2728590a0fdSAndre Fischer
2738590a0fdSAndre Fischer if ( ( nPort != DEFAULT_HTTP_PORT ) && ( nPort != DEFAULT_HTTPS_PORT ) )
2748590a0fdSAndre Fischer {
2758590a0fdSAndre Fischer aBuf.appendAscii( ":" );
2768590a0fdSAndre Fischer aBuf.append( rtl::OUString::valueOf( sal_Int32( nPort ) ) );
2778590a0fdSAndre Fischer }
2788590a0fdSAndre Fischer return aBuf.makeStringAndClear();
2798590a0fdSAndre Fischer }
2808590a0fdSAndre Fischer
281