1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 #ifndef INCLUDED_CURLSESSION_HXX 25 #define INCLUDED_CURLSESSION_HXX 26 27 #include <vector> 28 #include <boost/shared_ptr.hpp> 29 #include <osl/mutex.hxx> 30 #include <comphelper/componentcontext.hxx> 31 #include <comphelper/logging.hxx> 32 #include "DAVResource.hxx" 33 #include "DAVSession.hxx" 34 #include "CurlTypes.hxx" 35 #include "CurlRequest.hxx" 36 #include "CurlLockStore.hxx" 37 #include "CurlUri.hxx" 38 #include "CurlInputStream.hxx" 39 #include <com/sun/star/lang/XMultiServiceFactory.hpp> 40 #include <curl/curl.h> 41 #include <openssl/ssl.h> 42 43 namespace ucbhelper { class ProxyDecider; } 44 45 namespace http_dav_ucp 46 { 47 48 // ------------------------------------------------------------------- 49 // CurlSession 50 // A DAVSession implementation using the Curl library 51 // ------------------------------------------------------------------- 52 53 class CurlSession : public DAVSession 54 { 55 private: 56 osl::Mutex m_aMutex; 57 ::comphelper::ComponentContext m_aContext; 58 ::comphelper::EventLogger m_aLogger; 59 60 CurlUri m_aUri; 61 62 rtl::OUString m_aProxyName; 63 sal_Int32 m_nProxyPort; 64 // The server, according RFC7231 65 // http://tools.ietf.org/html/rfc7231#section-7.4.2 66 rtl::OString m_aServerHeaderField; 67 68 CURL* m_pCurl; 69 bool m_bUseChunkedEncoding; 70 bool m_bTransferEncodingSwitched; 71 72 const ucbhelper::InternetProxyDecider & m_rProxyDecider; 73 74 DAVRequestEnvironment m_aEnv; 75 76 static CurlLockStore m_aCurlLockStore; 77 78 bool isSSLNeeded(); 79 80 81 rtl::OUString composeCurrentUri( const rtl::OUString & inPath ); 82 void addEnvironmentRequestHeaders( CurlRequest &curlRequest, 83 const DAVRequestEnvironment &env ) 84 throw ( DAVException ); 85 void processResponse( CurlRequest &curlRequest, 86 CURLcode curlCode ) 87 throw ( DAVException ); 88 89 static CURLcode Curl_SSLContextCallback( CURL *curl, 90 void *ssl_ctx, 91 void *userptr ); 92 static int OPENSSL_ValidateServerCertificate( int preverify_ok, 93 X509_STORE_CTX *x509_ctx ); 94 int validateServerX509Certificate( X509_STORE_CTX *x509StoreContext, 95 int preverifyOk ); 96 int verifyCertificateChain ( 97 std::vector< uno::Sequence< sal_Int8 > > &asn1DerCertificates ); 98 99 static int Curl_DebugCallback( CURL *, 100 curl_infotype type, 101 unsigned char *data, 102 size_t size, 103 void* userdata ); 104 int curlDebugOutput( curl_infotype type, char *data, int size ); 105 106 static bool Curl_ProvideCredentials( long statusCode, 107 void *userdata ) throw (DAVException); 108 bool provideCredentials( const DAVRequestEnvironment &env, 109 CurlRequest &request, 110 long statusCode ) throw (DAVException); 111 112 protected: 113 virtual ~CurlSession(); 114 115 public: 116 CurlSession( const rtl::Reference< DAVSessionFactory > & rSessionFactory, 117 const rtl::OUString& inUri, 118 const ucbhelper::InternetProxyDecider & rProxyDecider ) 119 throw ( DAVException ); 120 121 // DAVSession methods 122 virtual sal_Bool CanUse( const ::rtl::OUString & inUri ); 123 124 virtual sal_Bool UsesProxy(); 125 126 const DAVRequestEnvironment & getRequestEnvironment() const 127 { return m_aEnv; } 128 129 // allprop & named 130 virtual void 131 PROPFIND( const ::rtl::OUString & inPath, 132 const Depth inDepth, 133 const std::vector< ::rtl::OUString > & inPropNames, 134 std::vector< DAVResource > & ioResources, 135 const DAVRequestEnvironment & rEnv ) 136 throw ( DAVException ); 137 138 // propnames 139 virtual void 140 PROPFIND( const ::rtl::OUString & inPath, 141 const Depth inDepth, 142 std::vector< DAVResourceInfo >& ioResInfo, 143 const DAVRequestEnvironment & rEnv ) 144 throw ( DAVException ); 145 146 virtual void 147 PROPPATCH( const ::rtl::OUString & inPath, 148 const std::vector< ProppatchValue > & inValues, 149 const DAVRequestEnvironment & rEnv ) 150 throw ( DAVException ); 151 152 virtual void 153 HEAD( const ::rtl::OUString & inPath, 154 const std::vector< ::rtl::OUString > & inHeaderNames, 155 DAVResource & ioResource, 156 const DAVRequestEnvironment & rEnv ) 157 throw ( DAVException ); 158 159 virtual com::sun::star::uno::Reference< com::sun::star::io::XInputStream > 160 GET( const ::rtl::OUString & inPath, 161 const DAVRequestEnvironment & rEnv ) 162 throw ( DAVException ); 163 164 virtual void 165 GET( const ::rtl::OUString & inPath, 166 com::sun::star::uno::Reference< 167 com::sun::star::io::XOutputStream > & ioOutputStream, 168 const DAVRequestEnvironment & rEnv ) 169 throw ( DAVException ); 170 171 virtual com::sun::star::uno::Reference< com::sun::star::io::XInputStream > 172 GET( const ::rtl::OUString & inPath, 173 const std::vector< ::rtl::OUString > & inHeaderNames, 174 DAVResource & ioResource, 175 const DAVRequestEnvironment & rEnv ) 176 throw ( DAVException ); 177 178 virtual void 179 GET( const ::rtl::OUString & inPath, 180 com::sun::star::uno::Reference< 181 com::sun::star::io::XOutputStream > & ioOutputStream, 182 const std::vector< ::rtl::OUString > & inHeaderNames, 183 DAVResource & ioResource, 184 const DAVRequestEnvironment & rEnv ) 185 throw ( DAVException ); 186 187 virtual void 188 PUT( const ::rtl::OUString & inPath, 189 const com::sun::star::uno::Reference< 190 com::sun::star::io::XInputStream > & inInputStream, 191 const DAVRequestEnvironment & rEnv ) 192 throw ( DAVException ); 193 194 virtual com::sun::star::uno::Reference< com::sun::star::io::XInputStream > 195 POST( const rtl::OUString & inPath, 196 const rtl::OUString & rContentType, 197 const rtl::OUString & rReferer, 198 const com::sun::star::uno::Reference< 199 com::sun::star::io::XInputStream > & inInputStream, 200 const DAVRequestEnvironment & rEnv ) 201 throw ( DAVException ); 202 203 virtual void 204 POST( const rtl::OUString & inPath, 205 const rtl::OUString & rContentType, 206 const rtl::OUString & rReferer, 207 const com::sun::star::uno::Reference< 208 com::sun::star::io::XInputStream > & inInputStream, 209 com::sun::star::uno::Reference< 210 com::sun::star::io::XOutputStream > & oOutputStream, 211 const DAVRequestEnvironment & rEnv ) 212 throw ( DAVException ); 213 214 virtual void 215 MKCOL( const ::rtl::OUString & inPath, 216 const DAVRequestEnvironment & rEnv ) 217 throw ( DAVException ); 218 219 virtual void 220 COPY( const ::rtl::OUString & inSourceURL, 221 const ::rtl::OUString & inDestinationURL, 222 const DAVRequestEnvironment & rEnv, 223 sal_Bool inOverWrite ) 224 throw ( DAVException ); 225 226 virtual void 227 MOVE( const ::rtl::OUString & inSourceURL, 228 const ::rtl::OUString & inDestinationURL, 229 const DAVRequestEnvironment & rEnv, 230 sal_Bool inOverWrite ) 231 throw ( DAVException ); 232 233 virtual void DESTROY( const ::rtl::OUString & inPath, 234 const DAVRequestEnvironment & rEnv ) 235 throw ( DAVException ); 236 237 // set new lock. 238 virtual void LOCK( const ::rtl::OUString & inURL, 239 com::sun::star::ucb::Lock & inLock, 240 const DAVRequestEnvironment & rEnv ) 241 throw ( DAVException ); 242 243 // refresh existing lock. 244 virtual sal_Int64 LOCK( const ::rtl::OUString & inURL, 245 sal_Int64 nTimeout, 246 const DAVRequestEnvironment & rEnv ) 247 throw ( DAVException ); 248 249 virtual void UNLOCK( const ::rtl::OUString & inURL, 250 const DAVRequestEnvironment & rEnv ) 251 throw ( DAVException ); 252 253 // helpers 254 virtual void abort() 255 throw ( DAVException ); 256 257 const rtl::OUString & getHostName() const { return m_aUri.GetHost(); } 258 int getPort() const { return m_aUri.GetPort(); } 259 260 const ::uno::Reference< ::lang::XMultiServiceFactory > getMSF() 261 { return m_xFactory->getServiceFactory(); } 262 263 sal_Bool isDomainMatch( rtl::OUString certHostName ); 264 265 const rtl::OString & getServerHeaderField() { return m_aServerHeaderField; }; 266 267 private: 268 friend class CurlLockStore; 269 270 void Init( void ) 271 throw ( DAVException ); 272 273 void Init( const DAVRequestEnvironment & rEnv ) 274 throw ( DAVException ); 275 276 const ucbhelper::InternetProxyServer & getProxySettings() const; 277 278 void propfind( CurlRequest &curlRequest, 279 const rtl::OUString &inPath, 280 const Depth inDepth, 281 const std::vector< ::rtl::OUString > * propNames, 282 const bool onlyPropertyNames, 283 const DAVRequestEnvironment & rEnv ); 284 285 bool removeExpiredLocktoken( const rtl::OUString & inURL, 286 const DAVRequestEnvironment & rEnv ); 287 288 // refresh lock, called by CurlLockStore::refreshLocks 289 bool LOCK( CurlLock * pLock, 290 sal_Int32 & rlastChanceToSendRefreshRequest ); 291 292 // unlock, called by CurlLockStore::~CurlLockStore 293 bool UNLOCK( CurlLock * pLock ); 294 295 /* 296 // low level GET implementation, used by public GET implementations 297 static int GET( CurlConnection * sess, 298 const char * uri, 299 //ne_block_reader reader, 300 bool getheaders, 301 void * userdata ); 302 303 // Buffer-based PUT implementation. Serf only has file descriptor- 304 // based API. 305 static int PUT( CurlConnection * sess, 306 const char * uri, 307 const char * buffer, 308 size_t size ); 309 310 // Buffer-based POST implementation. Serf only has file descriptor- 311 // based API. 312 int POST( CurlConnection * sess, 313 const char * uri, 314 const char * buffer, 315 //ne_block_reader reader, 316 void * userdata, 317 const rtl::OUString & rContentType, 318 const rtl::OUString & rReferer ); 319 */ 320 321 // Helper: XInputStream -> Sequence< sal_Int8 > 322 static bool getDataFromInputStream( 323 const com::sun::star::uno::Reference< 324 com::sun::star::io::XInputStream > & xStream, 325 com::sun::star::uno::Sequence< sal_Int8 > & rData, 326 bool bAppendTrailingZeroByte ); 327 328 /* 329 rtl::OUString makeAbsoluteURL( rtl::OUString const & rURL ) const; 330 */ 331 }; 332 333 } // namespace http_dav_ucp 334 335 #endif // INCLUDED_CURLSESSION_HXX 336