Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*************************************************************************
3 : *
4 : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : *
6 : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : *
8 : * OpenOffice.org - a multi-platform office productivity suite
9 : *
10 : * This file is part of OpenOffice.org.
11 : *
12 : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : * it under the terms of the GNU Lesser General Public License version 3
14 : * only, as published by the Free Software Foundation.
15 : *
16 : * OpenOffice.org is distributed in the hope that it will be useful,
17 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : * GNU Lesser General Public License version 3 for more details
20 : * (a copy is included in the LICENSE file that accompanied this code).
21 : *
22 : * You should have received a copy of the GNU Lesser General Public License
23 : * version 3 along with OpenOffice.org. If not, see
24 : * <http://www.openoffice.org/license.html>
25 : * for a copy of the LGPLv3 License.
26 : *
27 : ************************************************************************/
28 :
29 :
30 : #include <string.h>
31 : #include <rtl/uri.hxx>
32 : #include <rtl/ustring.hxx>
33 : #include <rtl/ustrbuf.hxx>
34 : #include "ne_alloc.h"
35 : #include "NeonUri.hxx"
36 : #include "DAVException.hxx"
37 :
38 : #include "../inc/urihelper.hxx"
39 :
40 : using namespace webdav_ucp;
41 :
42 : # if defined __SUNPRO_CC
43 : // FIXME: not sure whether initializing a ne_uri statically is supposed to work
44 : // the string fields of ne_uri are char*, not const char*
45 : # pragma disable_warn
46 : # endif
47 :
48 : #if defined __GNUC__
49 : #define GCC_VERSION (__GNUC__ * 10000 \
50 : + __GNUC_MINOR__ * 100 \
51 : + __GNUC_PATCHLEVEL__)
52 : /* Diagnostics pragma was introduced with gcc-4.2.1 */
53 : #if GCC_VERSION >= 40201
54 : #pragma GCC diagnostic ignored "-Wwrite-strings"
55 : #endif
56 : #endif
57 :
58 : namespace {
59 :
60 : const ne_uri g_sUriDefaultsHTTP = { "http",
61 : NULL,
62 : NULL,
63 : DEFAULT_HTTP_PORT,
64 : NULL,
65 : NULL,
66 : NULL };
67 : const ne_uri g_sUriDefaultsHTTPS = { "https",
68 : NULL,
69 : NULL,
70 : DEFAULT_HTTPS_PORT,
71 : NULL,
72 : NULL,
73 : NULL };
74 : const ne_uri g_sUriDefaultsFTP = { "ftp",
75 : NULL,
76 : NULL,
77 : DEFAULT_FTP_PORT,
78 : NULL,
79 : NULL,
80 : NULL };
81 : } // namespace
82 :
83 : # if defined __SUNPRO_CC
84 : # pragma enable_warn
85 : #endif
86 :
87 : // -------------------------------------------------------------------
88 : // Constructor
89 : // -------------------------------------------------------------------
90 :
91 : namespace {
92 :
93 : //TODO! rtl::OString::matchIgnoreAsciiCaseAsciiL() missing
94 0 : inline bool matchIgnoreAsciiCase(rtl::OString const & rStr1,
95 : sal_Char const * pStr2,
96 : sal_Int32 nStr2Len) SAL_THROW(())
97 : {
98 : return
99 : rtl_str_shortenedCompareIgnoreAsciiCase_WithLength(
100 0 : rStr1.getStr(), rStr1.getLength(), pStr2, nStr2Len, nStr2Len)
101 0 : == 0;
102 : }
103 :
104 : }
105 :
106 0 : NeonUri::NeonUri( const ne_uri * inUri )
107 0 : throw ( DAVException )
108 : {
109 0 : if ( inUri == 0 )
110 0 : throw DAVException( DAVException::DAV_INVALID_ARG );
111 :
112 0 : char * uri = ne_uri_unparse( inUri );
113 :
114 0 : if ( uri == 0 )
115 0 : throw DAVException( DAVException::DAV_INVALID_ARG );
116 :
117 0 : init( rtl::OString( uri ), inUri );
118 0 : ne_free( uri );
119 :
120 0 : calculateURI();
121 0 : }
122 :
123 0 : NeonUri::NeonUri( const rtl::OUString & inUri )
124 0 : throw ( DAVException )
125 : {
126 0 : if ( inUri.isEmpty() )
127 0 : throw DAVException( DAVException::DAV_INVALID_ARG );
128 :
129 : // #i77023#
130 0 : rtl::OUString aEscapedUri( ucb_impl::urihelper::encodeURI( inUri ) );
131 :
132 : rtl::OString theInputUri(
133 0 : aEscapedUri.getStr(), aEscapedUri.getLength(), RTL_TEXTENCODING_UTF8 );
134 :
135 : ne_uri theUri;
136 0 : if ( ne_uri_parse( theInputUri.getStr(), &theUri ) != 0 )
137 : {
138 0 : ne_uri_free( &theUri );
139 0 : throw DAVException( DAVException::DAV_INVALID_ARG );
140 : }
141 :
142 0 : init( theInputUri, &theUri );
143 0 : ne_uri_free( &theUri );
144 :
145 0 : calculateURI();
146 0 : }
147 :
148 0 : void NeonUri::init( const rtl::OString & rUri, const ne_uri * pUri )
149 : {
150 : // Complete URI.
151 : const ne_uri * pUriDefs
152 : = matchIgnoreAsciiCase( rUri,
153 0 : RTL_CONSTASCII_STRINGPARAM( "ftp:" ) ) ?
154 : &g_sUriDefaultsFTP :
155 : matchIgnoreAsciiCase( rUri,
156 0 : RTL_CONSTASCII_STRINGPARAM( "https:" ) ) ?
157 : &g_sUriDefaultsHTTPS :
158 0 : &g_sUriDefaultsHTTP;
159 :
160 : mScheme = rtl::OStringToOUString(
161 : pUri->scheme ? pUri->scheme : pUriDefs->scheme,
162 0 : RTL_TEXTENCODING_UTF8 );
163 : mUserInfo = rtl::OStringToOUString(
164 : pUri->userinfo ? pUri->userinfo : pUriDefs->userinfo,
165 0 : RTL_TEXTENCODING_UTF8 );
166 : mHostName = rtl::OStringToOUString(
167 : pUri->host ? pUri->host : pUriDefs->host,
168 0 : RTL_TEXTENCODING_UTF8 );
169 0 : mPort = pUri->port > 0 ? pUri->port : pUriDefs->port;
170 : mPath = rtl::OStringToOUString(
171 : pUri->path ? pUri->path : pUriDefs->path,
172 0 : RTL_TEXTENCODING_UTF8 );
173 :
174 0 : if ( pUri->query )
175 : {
176 0 : mPath += rtl::OUString("?");
177 : mPath += rtl::OStringToOUString(
178 0 : pUri->query, RTL_TEXTENCODING_UTF8 );
179 : }
180 :
181 0 : if ( pUri->fragment )
182 : {
183 0 : mPath += rtl::OUString("#");
184 : mPath += rtl::OStringToOUString(
185 0 : pUri->fragment, RTL_TEXTENCODING_UTF8 );
186 : }
187 0 : }
188 :
189 : // -------------------------------------------------------------------
190 : // Destructor
191 : // -------------------------------------------------------------------
192 0 : NeonUri::~NeonUri( )
193 : {
194 0 : }
195 :
196 0 : void NeonUri::calculateURI ()
197 : {
198 0 : rtl::OUStringBuffer aBuf( mScheme );
199 0 : aBuf.appendAscii( "://" );
200 0 : if ( !mUserInfo.isEmpty() )
201 : {
202 : //TODO! differentiate between empty and missing userinfo
203 0 : aBuf.append( mUserInfo );
204 0 : aBuf.appendAscii( "@" );
205 : }
206 : // Is host a numeric IPv6 address?
207 0 : if ( ( mHostName.indexOf( ':' ) != -1 ) &&
208 0 : ( mHostName[ 0 ] != sal_Unicode( '[' ) ) )
209 : {
210 0 : aBuf.appendAscii( "[" );
211 0 : aBuf.append( mHostName );
212 0 : aBuf.appendAscii( "]" );
213 : }
214 : else
215 : {
216 0 : aBuf.append( mHostName );
217 : }
218 :
219 : // append port, but only, if not default port.
220 0 : bool bAppendPort = true;
221 0 : switch ( mPort )
222 : {
223 : case DEFAULT_HTTP_PORT:
224 0 : bAppendPort = mScheme != "http";
225 0 : break;
226 :
227 : case DEFAULT_HTTPS_PORT:
228 0 : bAppendPort = mScheme != "https";
229 0 : break;
230 :
231 : case DEFAULT_FTP_PORT:
232 0 : bAppendPort = mScheme != "ftp";
233 0 : break;
234 : }
235 0 : if ( bAppendPort )
236 : {
237 0 : aBuf.appendAscii( ":" );
238 0 : aBuf.append( rtl::OUString::valueOf( mPort ) );
239 : }
240 0 : aBuf.append( mPath );
241 :
242 0 : mURI = aBuf.makeStringAndClear();
243 0 : }
244 :
245 0 : ::rtl::OUString NeonUri::GetPathBaseName () const
246 : {
247 0 : sal_Int32 nPos = mPath.lastIndexOf ('/');
248 0 : sal_Int32 nTrail = 0;
249 0 : if (nPos == mPath.getLength () - 1)
250 : {
251 : // Trailing slash found. Skip.
252 0 : nTrail = 1;
253 0 : nPos = mPath.lastIndexOf ('/', nPos);
254 : }
255 0 : if (nPos != -1)
256 : {
257 : rtl::OUString aTemp(
258 0 : mPath.copy (nPos + 1, mPath.getLength () - nPos - 1 - nTrail) );
259 :
260 : // query, fragment present?
261 0 : nPos = aTemp.indexOf( '?' );
262 0 : if ( nPos == -1 )
263 0 : nPos = aTemp.indexOf( '#' );
264 :
265 0 : if ( nPos != -1 )
266 0 : aTemp = aTemp.copy( 0, nPos );
267 :
268 0 : return aTemp;
269 : }
270 : else
271 0 : return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM ("/"));
272 : }
273 :
274 0 : bool NeonUri::operator== ( const NeonUri & rOther ) const
275 : {
276 0 : return ( mURI == rOther.mURI );
277 : }
278 :
279 0 : ::rtl::OUString NeonUri::GetPathBaseNameUnescaped () const
280 : {
281 0 : return unescape( GetPathBaseName() );
282 : }
283 :
284 0 : void NeonUri::AppendPath (const rtl::OUString& rPath)
285 : {
286 0 : if (mPath.lastIndexOf ('/') != mPath.getLength () - 1)
287 0 : mPath += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM ("/"));
288 :
289 0 : mPath += rPath;
290 0 : calculateURI ();
291 0 : };
292 :
293 : // static
294 0 : rtl::OUString NeonUri::escapeSegment( const rtl::OUString& segment )
295 : {
296 : return rtl::Uri::encode( segment,
297 : rtl_UriCharClassPchar,
298 : rtl_UriEncodeIgnoreEscapes,
299 0 : RTL_TEXTENCODING_UTF8 );
300 : }
301 :
302 : // static
303 0 : rtl::OUString NeonUri::unescape( const rtl::OUString& segment )
304 : {
305 : return rtl::Uri::decode( segment,
306 : rtl_UriDecodeWithCharset,
307 0 : RTL_TEXTENCODING_UTF8 );
308 : }
309 :
310 : // static
311 0 : rtl::OUString NeonUri::makeConnectionEndPointString(
312 : const rtl::OUString & rHostName, int nPort )
313 : {
314 0 : rtl::OUStringBuffer aBuf;
315 :
316 : // Is host a numeric IPv6 address?
317 0 : if ( ( rHostName.indexOf( ':' ) != -1 ) &&
318 0 : ( rHostName[ 0 ] != sal_Unicode( '[' ) ) )
319 : {
320 0 : aBuf.appendAscii( "[" );
321 0 : aBuf.append( rHostName );
322 0 : aBuf.appendAscii( "]" );
323 : }
324 : else
325 : {
326 0 : aBuf.append( rHostName );
327 : }
328 :
329 0 : if ( ( nPort != DEFAULT_HTTP_PORT ) && ( nPort != DEFAULT_HTTPS_PORT ) )
330 : {
331 0 : aBuf.appendAscii( ":" );
332 0 : aBuf.append( rtl::OUString::valueOf( sal_Int32( nPort ) ) );
333 : }
334 0 : return aBuf.makeStringAndClear();
335 : }
336 :
337 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|