blob: f7930494a2208b6d660b5d0bc06ea2fbd02c2c2e [file] [log] [blame]
/**************************************************************
*
* 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
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_ucb.hxx"
#include <string.h>
#include <rtl/uri.hxx>
#include <rtl/ustring.hxx>
#include <rtl/ustrbuf.hxx>
#include "SerfUri.hxx"
#include "DAVException.hxx"
#include "AprEnv.hxx"
#include "../inc/urihelper.hxx"
using namespace http_dav_ucp;
# if defined __SUNPRO_CC
# pragma enable_warn
#endif
// -------------------------------------------------------------------
// Constructor
// -------------------------------------------------------------------
namespace {
inline bool matchIgnoreAsciiCase(rtl::OString const & rStr1,
sal_Char const * pStr2,
sal_Int32 nStr2Len) SAL_THROW(())
{
return
rtl_str_shortenedCompareIgnoreAsciiCase_WithLength(
rStr1.getStr(), rStr1.getLength(), pStr2, nStr2Len, nStr2Len)
== 0;
}
}
SerfUri::SerfUri( const apr_uri_t * inUri )
throw ( DAVException )
: mAprUri( *inUri )
, mURI()
, mScheme()
, mUserInfo()
, mHostName()
, mPort()
, mPath()
{
if ( inUri == 0 )
throw DAVException( DAVException::DAV_INVALID_ARG );
char * uri = apr_uri_unparse( apr_environment::AprEnv::getAprEnv()->getAprPool(), &mAprUri, 0 );
if ( uri == 0 )
throw DAVException( DAVException::DAV_INVALID_ARG );
init( &mAprUri );
calculateURI();
}
SerfUri::SerfUri( const rtl::OUString & inUri )
throw ( DAVException )
: mAprUri()
, mURI()
, mScheme()
, mUserInfo()
, mHostName()
, mPort()
, mPath()
{
if ( inUri.getLength() <= 0 )
throw DAVException( DAVException::DAV_INVALID_ARG );
// #i77023#
rtl::OUString aEscapedUri( ucb_impl::urihelper::encodeURI( inUri ) );
rtl::OString theInputUri(
aEscapedUri.getStr(), aEscapedUri.getLength(), RTL_TEXTENCODING_UTF8 );
if ( apr_uri_parse( apr_environment::AprEnv::getAprEnv()->getAprPool(),
theInputUri.getStr(), &mAprUri ) != APR_SUCCESS )
{
throw DAVException( DAVException::DAV_INVALID_ARG );
}
if ( !mAprUri.port )
{
mAprUri.port = apr_uri_port_of_scheme( mAprUri.scheme );
}
if ( !mAprUri.path )
{
mAprUri.path = "/";
}
init( &mAprUri );
calculateURI();
}
void SerfUri::init( const apr_uri_t * pUri )
{
mScheme = rtl::OStringToOUString( pUri->scheme, RTL_TEXTENCODING_UTF8 );
mUserInfo = rtl::OStringToOUString( pUri->user, RTL_TEXTENCODING_UTF8 );
mHostName = rtl::OStringToOUString( pUri->hostname, RTL_TEXTENCODING_UTF8 );
mPort = pUri->port;
mPath = rtl::OStringToOUString( pUri->path, RTL_TEXTENCODING_UTF8 );
if ( pUri->query )
{
mPath += rtl::OUString::createFromAscii( "?" );
mPath += rtl::OStringToOUString( pUri->query, RTL_TEXTENCODING_UTF8 );
}
if ( pUri->fragment )
{
mPath += rtl::OUString::createFromAscii( "#" );
mPath += rtl::OStringToOUString( pUri->fragment, RTL_TEXTENCODING_UTF8 );
}
}
SerfUri::~SerfUri( )
{
}
void SerfUri::calculateURI ()
{
rtl::OUStringBuffer aBuf( mScheme );
aBuf.appendAscii( "://" );
if ( mUserInfo.getLength() > 0 )
{
aBuf.append( mUserInfo );
aBuf.appendAscii( "@" );
}
// Is host a numeric IPv6 address?
if ( ( mHostName.indexOf( ':' ) != -1 ) &&
( mHostName[ 0 ] != sal_Unicode( '[' ) ) )
{
aBuf.appendAscii( "[" );
aBuf.append( mHostName );
aBuf.appendAscii( "]" );
}
else
{
aBuf.append( mHostName );
}
// append port, but only, if not default port.
bool bAppendPort = true;
switch ( mPort )
{
case DEFAULT_HTTP_PORT:
bAppendPort = !mScheme.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "http" ) );
break;
case DEFAULT_HTTPS_PORT:
bAppendPort = !mScheme.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "https" ) );
break;
}
if ( bAppendPort )
{
aBuf.appendAscii( ":" );
aBuf.append( rtl::OUString::valueOf( mPort ) );
}
aBuf.append( mPath );
mURI = aBuf.makeStringAndClear();
}
::rtl::OUString SerfUri::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)
{
rtl::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 rtl::OUString::createFromAscii ("/");
}
bool SerfUri::operator== ( const SerfUri & rOther ) const
{
return ( mURI == rOther.mURI );
}
::rtl::OUString SerfUri::GetPathBaseNameUnescaped () const
{
return unescape( GetPathBaseName() );
}
void SerfUri::AppendPath (const rtl::OUString& rPath)
{
if (mPath.lastIndexOf ('/') != mPath.getLength () - 1)
mPath += rtl::OUString::createFromAscii ("/");
mPath += rPath;
calculateURI ();
};
// static
rtl::OUString SerfUri::escapeSegment( const rtl::OUString& segment )
{
return rtl::Uri::encode( segment,
rtl_UriCharClassPchar,
rtl_UriEncodeIgnoreEscapes,
RTL_TEXTENCODING_UTF8 );
}
// static
rtl::OUString SerfUri::unescape( const rtl::OUString& segment )
{
return rtl::Uri::decode( segment,
rtl_UriDecodeWithCharset,
RTL_TEXTENCODING_UTF8 );
}
// static
rtl::OUString SerfUri::makeConnectionEndPointString(
const rtl::OUString & rHostName, int nPort )
{
rtl::OUStringBuffer aBuf;
// Is host a numeric IPv6 address?
if ( ( rHostName.indexOf( ':' ) != -1 ) &&
( rHostName[ 0 ] != sal_Unicode( '[' ) ) )
{
aBuf.appendAscii( "[" );
aBuf.append( rHostName );
aBuf.appendAscii( "]" );
}
else
{
aBuf.append( rHostName );
}
if ( ( nPort != DEFAULT_HTTP_PORT ) && ( nPort != DEFAULT_HTTPS_PORT ) )
{
aBuf.appendAscii( ":" );
aBuf.append( rtl::OUString::valueOf( sal_Int32( nPort ) ) );
}
return aBuf.makeStringAndClear();
}