1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: NeonUri.cxx,v $
10 * $Revision: 1.25.16.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_ucb.hxx"
35 #include <rtl/uri.hxx>
36 #include <rtl/ustring.hxx>
37 #include <rtl/ustrbuf.hxx>
38 #include "NeonUri.hxx"
39 #include "DAVException.hxx"
41 #include "../inc/urihelper.hxx"
43 using namespace webdav_ucp
;
46 char *host
, *userinfo
;
48 char *path
, *query
, *fragment
;
50 # if defined __SUNPRO_CC
51 // FIXME: not sure whether initializing a ne_uri statically is supposed to work
52 // the string fields of ne_uri are char*, not const char*
57 #define GCC_VERSION (__GNUC__ * 10000 \
58 + __GNUC_MINOR__ * 100 \
59 + __GNUC_PATCHLEVEL__)
60 /* Diagnostics pragma was introduced with gcc-4.2.1 */
61 #if GCC_VERSION > 40201
62 #pragma GCC diagnostic ignored "-Wwrite-strings"
68 const ne_uri g_sUriDefaultsHTTP
= { "http",
69 #if NEON_VERSION >= 0x0260
74 #if NEON_VERSION >= 0x0260
79 const ne_uri g_sUriDefaultsHTTPS
= { "https",
80 #if NEON_VERSION >= 0x0260
85 #if NEON_VERSION >= 0x0260
90 const ne_uri g_sUriDefaultsFTP
= { "ftp",
91 #if NEON_VERSION >= 0x0260
96 #if NEON_VERSION >= 0x0260
103 # if defined __SUNPRO_CC
107 // -------------------------------------------------------------------
109 // -------------------------------------------------------------------
113 //TODO! rtl::OString::matchIgnoreAsciiCaseAsciiL() missing
114 inline bool matchIgnoreAsciiCase(rtl::OString
const & rStr1
,
115 sal_Char
const * pStr2
,
116 sal_Int32 nStr2Len
) SAL_THROW(())
119 rtl_str_shortenedCompareIgnoreAsciiCase_WithLength(
120 rStr1
.getStr(), rStr1
.getLength(), pStr2
, nStr2Len
, nStr2Len
)
126 NeonUri::NeonUri( const ne_uri
* inUri
)
127 throw ( DAVException
)
130 throw DAVException( DAVException::DAV_INVALID_ARG
);
132 char * uri
= ne_uri_unparse( inUri
);
135 throw DAVException( DAVException::DAV_INVALID_ARG
);
137 init( rtl::OString( uri
), inUri
);
143 NeonUri::NeonUri( const rtl::OUString
& inUri
)
144 throw ( DAVException
)
146 if ( inUri
.getLength() <= 0 )
147 throw DAVException( DAVException::DAV_INVALID_ARG
);
150 rtl::OUString
aEscapedUri( ucb_impl::urihelper::encodeURI( inUri
) );
152 rtl::OString
theInputUri(
153 aEscapedUri
.getStr(), aEscapedUri
.getLength(), RTL_TEXTENCODING_UTF8
);
156 if ( ne_uri_parse( theInputUri
.getStr(), &theUri
) != 0 )
158 ne_uri_free( &theUri
);
159 throw DAVException( DAVException::DAV_INVALID_ARG
);
162 init( theInputUri
, &theUri
);
163 ne_uri_free( &theUri
);
168 void NeonUri::init( const rtl::OString
& rUri
, const ne_uri
* pUri
)
171 const ne_uri
* pUriDefs
172 = matchIgnoreAsciiCase( rUri
,
173 RTL_CONSTASCII_STRINGPARAM( "ftp:" ) ) ?
175 matchIgnoreAsciiCase( rUri
,
176 RTL_CONSTASCII_STRINGPARAM( "https:" ) ) ?
177 &g_sUriDefaultsHTTPS
:
180 mScheme
= rtl::OStringToOUString(
181 pUri
->scheme
? pUri
->scheme
: pUriDefs
->scheme
,
182 RTL_TEXTENCODING_UTF8
);
183 mUserInfo
= rtl::OStringToOUString(
184 #if NEON_VERSION >= 0x0260
185 pUri
->userinfo
? pUri
->userinfo
: pUriDefs
->userinfo
,
187 pUri
->authinfo
? pUri
->authinfo
: pUriDefs
->authinfo
,
189 RTL_TEXTENCODING_UTF8
);
190 mHostName
= rtl::OStringToOUString(
191 pUri
->host
? pUri
->host
: pUriDefs
->host
,
192 RTL_TEXTENCODING_UTF8
);
193 mPort
= pUri
->port
> 0 ? pUri
->port
: pUriDefs
->port
;
194 mPath
= rtl::OStringToOUString(
195 pUri
->path
? pUri
->path
: pUriDefs
->path
,
196 RTL_TEXTENCODING_UTF8
);
198 #if NEON_VERSION >= 0x0260
201 mPath
+= rtl::OUString::createFromAscii( "?" );
202 mPath
+= rtl::OStringToOUString(
203 pUri
->query
, RTL_TEXTENCODING_UTF8
);
206 if ( pUri
->fragment
)
208 mPath
+= rtl::OUString::createFromAscii( "#" );
209 mPath
+= rtl::OStringToOUString(
210 pUri
->fragment
, RTL_TEXTENCODING_UTF8
);
215 // -------------------------------------------------------------------
217 // -------------------------------------------------------------------
222 void NeonUri::calculateURI ()
224 rtl::OUStringBuffer
aBuf( mScheme
);
225 aBuf
.appendAscii( "://" );
226 if ( mUserInfo
.getLength() > 0 )
228 //TODO! differentiate between empty and missing userinfo
229 aBuf
.append( mUserInfo
);
230 aBuf
.appendAscii( "@" );
232 // Is host a numeric IPv6 address?
233 if ( ( mHostName
.indexOf( ':' ) != -1 ) &&
234 ( mHostName
[ 0 ] != sal_Unicode( '[' ) ) )
236 aBuf
.appendAscii( "[" );
237 aBuf
.append( mHostName
);
238 aBuf
.appendAscii( "]" );
242 aBuf
.append( mHostName
);
245 // append port, but only, if not default port.
246 bool bAppendPort
= true;
249 case DEFAULT_HTTP_PORT
:
251 = !mScheme
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "http" ) );
254 case DEFAULT_HTTPS_PORT
:
256 = !mScheme
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "https" ) );
259 case DEFAULT_FTP_PORT
:
261 = !mScheme
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "ftp" ) );
266 aBuf
.appendAscii( ":" );
267 aBuf
.append( rtl::OUString::valueOf( mPort
) );
269 aBuf
.append( mPath
);
271 mURI
= aBuf
.makeStringAndClear();
274 ::rtl::OUString
NeonUri::GetPathBaseName () const
276 sal_Int32 nPos
= mPath
.lastIndexOf ('/');
277 sal_Int32 nTrail
= 0;
278 if (nPos
== mPath
.getLength () - 1)
280 // Trailing slash found. Skip.
282 nPos
= mPath
.lastIndexOf ('/', nPos
);
287 mPath
.copy (nPos
+ 1, mPath
.getLength () - nPos
- 1 - nTrail
) );
289 // query, fragment present?
290 nPos
= aTemp
.indexOf( '?' );
292 nPos
= aTemp
.indexOf( '#' );
295 aTemp
= aTemp
.copy( 0, nPos
);
300 return rtl::OUString::createFromAscii ("/");
303 bool NeonUri::operator== ( const NeonUri
& rOther
) const
305 return ( mURI
== rOther
.mURI
);
308 ::rtl::OUString
NeonUri::GetPathBaseNameUnescaped () const
310 return unescape( GetPathBaseName() );
313 void NeonUri::AppendPath (const rtl::OUString
& rPath
)
315 if (mPath
.lastIndexOf ('/') != mPath
.getLength () - 1)
316 mPath
+= rtl::OUString::createFromAscii ("/");
323 rtl::OUString
NeonUri::escapeSegment( const rtl::OUString
& segment
)
325 return rtl::Uri::encode( segment
,
326 rtl_UriCharClassPchar
,
327 rtl_UriEncodeIgnoreEscapes
,
328 RTL_TEXTENCODING_UTF8
);
332 rtl::OUString
NeonUri::unescape( const rtl::OUString
& segment
)
334 return rtl::Uri::decode( segment
,
335 rtl_UriDecodeWithCharset
,
336 RTL_TEXTENCODING_UTF8
);
340 rtl::OUString
NeonUri::makeConnectionEndPointString(
341 const rtl::OUString
& rHostName
, int nPort
)
343 rtl::OUStringBuffer aBuf
;
345 // Is host a numeric IPv6 address?
346 if ( ( rHostName
.indexOf( ':' ) != -1 ) &&
347 ( rHostName
[ 0 ] != sal_Unicode( '[' ) ) )
349 aBuf
.appendAscii( "[" );
350 aBuf
.append( rHostName
);
351 aBuf
.appendAscii( "]" );
355 aBuf
.append( rHostName
);
358 if ( ( nPort
!= DEFAULT_HTTP_PORT
) && ( nPort
!= DEFAULT_HTTPS_PORT
) )
360 aBuf
.appendAscii( ":" );
361 aBuf
.append( rtl::OUString::valueOf( sal_Int32( nPort
) ) );
363 return aBuf
.makeStringAndClear();