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