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 : #include "sal/config.h"
30 :
31 : #include <string.h>
32 : #include <rtl/uri.hxx>
33 : #include <rtl/ustring.hxx>
34 : #include <rtl/ustrbuf.hxx>
35 : #include "ne_alloc.h"
36 : #include "NeonUri.hxx"
37 : #include "DAVException.hxx"
38 :
39 : #include "../inc/urihelper.hxx"
40 :
41 : using namespace webdav_ucp;
42 :
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 :
46 : #ifdef __GNUC__
47 : #pragma GCC diagnostic ignored "-Wwrite-strings"
48 : #endif
49 :
50 : namespace {
51 :
52 : const ne_uri g_sUriDefaultsHTTP = { const_cast<char *>("http"),
53 : NULL,
54 : NULL,
55 : DEFAULT_HTTP_PORT,
56 : NULL,
57 : NULL,
58 : NULL };
59 : const ne_uri g_sUriDefaultsHTTPS = { const_cast<char *>("https"),
60 : NULL,
61 : NULL,
62 : DEFAULT_HTTPS_PORT,
63 : NULL,
64 : NULL,
65 : NULL };
66 : const ne_uri g_sUriDefaultsFTP = { const_cast<char *>("ftp"),
67 : NULL,
68 : NULL,
69 : DEFAULT_FTP_PORT,
70 : NULL,
71 : NULL,
72 : NULL };
73 : } // namespace
74 :
75 0 : NeonUri::NeonUri( const ne_uri * inUri )
76 0 : throw ( DAVException )
77 : {
78 0 : if ( inUri == 0 )
79 0 : throw DAVException( DAVException::DAV_INVALID_ARG );
80 :
81 0 : char * uri = ne_uri_unparse( inUri );
82 :
83 0 : if ( uri == 0 )
84 0 : throw DAVException( DAVException::DAV_INVALID_ARG );
85 :
86 0 : init( OString( uri ), inUri );
87 0 : ne_free( uri );
88 :
89 0 : calculateURI();
90 0 : }
91 :
92 1 : NeonUri::NeonUri( const OUString & inUri )
93 1 : throw ( DAVException )
94 : {
95 1 : if ( inUri.isEmpty() )
96 0 : throw DAVException( DAVException::DAV_INVALID_ARG );
97 :
98 : // #i77023#
99 1 : OUString aEscapedUri( ucb_impl::urihelper::encodeURI( inUri ) );
100 :
101 : OString theInputUri(
102 2 : aEscapedUri.getStr(), aEscapedUri.getLength(), RTL_TEXTENCODING_UTF8 );
103 :
104 : ne_uri theUri;
105 1 : if ( ne_uri_parse( theInputUri.getStr(), &theUri ) != 0 )
106 : {
107 0 : ne_uri_free( &theUri );
108 0 : throw DAVException( DAVException::DAV_INVALID_ARG );
109 : }
110 :
111 1 : init( theInputUri, &theUri );
112 1 : ne_uri_free( &theUri );
113 :
114 2 : calculateURI();
115 1 : }
116 :
117 1 : void NeonUri::init( const OString & rUri, const ne_uri * pUri )
118 : {
119 : // Complete URI.
120 : const ne_uri * pUriDefs
121 1 : = rUri.matchIgnoreAsciiCase( "ftp:" ) ?
122 : &g_sUriDefaultsFTP :
123 1 : rUri.matchIgnoreAsciiCase( "https:" ) ?
124 : &g_sUriDefaultsHTTPS :
125 2 : &g_sUriDefaultsHTTP;
126 :
127 2 : mScheme = OStringToOUString(
128 : pUri->scheme ? pUri->scheme : pUriDefs->scheme,
129 1 : RTL_TEXTENCODING_UTF8 );
130 2 : mUserInfo = OStringToOUString(
131 : pUri->userinfo ? pUri->userinfo : pUriDefs->userinfo,
132 1 : RTL_TEXTENCODING_UTF8 );
133 2 : mHostName = OStringToOUString(
134 : pUri->host ? pUri->host : pUriDefs->host,
135 1 : RTL_TEXTENCODING_UTF8 );
136 1 : mPort = pUri->port > 0 ? pUri->port : pUriDefs->port;
137 2 : mPath = OStringToOUString(
138 : pUri->path ? pUri->path : pUriDefs->path,
139 1 : RTL_TEXTENCODING_UTF8 );
140 :
141 1 : if ( pUri->query )
142 : {
143 0 : mPath += "?" + OStringToOUString( pUri->query, RTL_TEXTENCODING_UTF8 );
144 : }
145 :
146 1 : if ( pUri->fragment )
147 : {
148 0 : mPath += "#" + OStringToOUString( pUri->fragment, RTL_TEXTENCODING_UTF8 );
149 : }
150 1 : }
151 :
152 1 : NeonUri::~NeonUri( )
153 : {
154 1 : }
155 :
156 1 : void NeonUri::calculateURI ()
157 : {
158 1 : OUStringBuffer aBuf( mScheme );
159 1 : aBuf.appendAscii( "://" );
160 1 : if ( !mUserInfo.isEmpty() )
161 : {
162 : //TODO! differentiate between empty and missing userinfo
163 0 : aBuf.append( mUserInfo );
164 0 : aBuf.appendAscii( "@" );
165 : }
166 : // Is host a numeric IPv6 address?
167 1 : if ( ( mHostName.indexOf( ':' ) != -1 ) &&
168 0 : ( mHostName[ 0 ] != '[' ) )
169 : {
170 0 : aBuf.appendAscii( "[" );
171 0 : aBuf.append( mHostName );
172 0 : aBuf.appendAscii( "]" );
173 : }
174 : else
175 : {
176 1 : aBuf.append( mHostName );
177 : }
178 :
179 : // append port, but only, if not default port.
180 1 : bool bAppendPort = true;
181 1 : switch ( mPort )
182 : {
183 : case DEFAULT_HTTP_PORT:
184 1 : bAppendPort = mScheme != "http";
185 1 : break;
186 :
187 : case DEFAULT_HTTPS_PORT:
188 0 : bAppendPort = mScheme != "https";
189 0 : break;
190 :
191 : case DEFAULT_FTP_PORT:
192 0 : bAppendPort = mScheme != "ftp";
193 0 : break;
194 : }
195 1 : if ( bAppendPort )
196 : {
197 0 : aBuf.appendAscii( ":" );
198 0 : aBuf.append( OUString::number( mPort ) );
199 : }
200 1 : aBuf.append( mPath );
201 :
202 1 : mURI = aBuf.makeStringAndClear();
203 1 : }
204 :
205 1 : OUString NeonUri::GetPathBaseName () const
206 : {
207 1 : sal_Int32 nPos = mPath.lastIndexOf ('/');
208 1 : sal_Int32 nTrail = 0;
209 1 : if (nPos == mPath.getLength () - 1)
210 : {
211 : // Trailing slash found. Skip.
212 1 : nTrail = 1;
213 1 : nPos = mPath.lastIndexOf ('/', nPos);
214 : }
215 1 : if (nPos != -1)
216 : {
217 : OUString aTemp(
218 1 : mPath.copy (nPos + 1, mPath.getLength () - nPos - 1 - nTrail) );
219 :
220 : // query, fragment present?
221 1 : nPos = aTemp.indexOf( '?' );
222 1 : if ( nPos == -1 )
223 1 : nPos = aTemp.indexOf( '#' );
224 :
225 1 : if ( nPos != -1 )
226 0 : aTemp = aTemp.copy( 0, nPos );
227 :
228 1 : return aTemp;
229 : }
230 : else
231 0 : return OUString("/");
232 : }
233 :
234 0 : bool NeonUri::operator== ( const NeonUri & rOther ) const
235 : {
236 0 : return ( mURI == rOther.mURI );
237 : }
238 :
239 0 : OUString NeonUri::GetPathBaseNameUnescaped () const
240 : {
241 0 : return unescape( GetPathBaseName() );
242 : }
243 :
244 0 : void NeonUri::AppendPath (const OUString& rPath)
245 : {
246 0 : if (mPath.lastIndexOf ('/') != mPath.getLength () - 1)
247 0 : mPath += "/";
248 :
249 0 : mPath += rPath;
250 0 : calculateURI ();
251 0 : };
252 :
253 : // static
254 0 : OUString NeonUri::escapeSegment( const OUString& segment )
255 : {
256 : return rtl::Uri::encode( segment,
257 : rtl_UriCharClassPchar,
258 : rtl_UriEncodeIgnoreEscapes,
259 0 : RTL_TEXTENCODING_UTF8 );
260 : }
261 :
262 : // static
263 0 : OUString NeonUri::unescape( const OUString& segment )
264 : {
265 : return rtl::Uri::decode( segment,
266 : rtl_UriDecodeWithCharset,
267 0 : RTL_TEXTENCODING_UTF8 );
268 : }
269 :
270 : // static
271 0 : OUString NeonUri::makeConnectionEndPointString(
272 : const OUString & rHostName, int nPort )
273 : {
274 0 : OUStringBuffer aBuf;
275 :
276 : // Is host a numeric IPv6 address?
277 0 : if ( ( rHostName.indexOf( ':' ) != -1 ) &&
278 0 : ( rHostName[ 0 ] != '[' ) )
279 : {
280 0 : aBuf.appendAscii( "[" );
281 0 : aBuf.append( rHostName );
282 0 : aBuf.appendAscii( "]" );
283 : }
284 : else
285 : {
286 0 : aBuf.append( rHostName );
287 : }
288 :
289 0 : if ( ( nPort != DEFAULT_HTTP_PORT ) && ( nPort != DEFAULT_HTTPS_PORT ) )
290 : {
291 0 : aBuf.appendAscii( ":" );
292 0 : aBuf.append( OUString::number( nPort ) );
293 : }
294 0 : return aBuf.makeStringAndClear();
295 : }
296 :
297 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|