xref: /trunk/main/ucb/source/ucp/webdav/CurlSession.hxx (revision 91144cd0085a7583d2099b982122deb2184ab956)
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 <com/sun/star/security/CertificateContainer.hpp>
41 #include <com/sun/star/security/XCertificateContainer.hpp>
42 #include <com/sun/star/xml/crypto/XSecurityEnvironment.hpp>
43 #include <com/sun/star/xml/crypto/XXMLSecurityContext.hpp>
44 #include <curl/curl.h>
45 #include <openssl/ssl.h>
46 
47 namespace ucbhelper { class ProxyDecider; }
48 
49 namespace http_dav_ucp
50 {
51 
52 // -------------------------------------------------------------------
53 // CurlSession
54 // A DAVSession implementation using the Curl library
55 // -------------------------------------------------------------------
56 
57 class CurlSession : public DAVSession
58 {
59 private:
60     osl::Mutex                      m_aMutex;
61     ::comphelper::ComponentContext  m_aContext;
62     ::comphelper::EventLogger       m_aLogger;
63 
64     CurlUri                 m_aUri;
65 
66     rtl::OUString           m_aProxyName;
67     sal_Int32               m_nProxyPort;
68     // The server, according RFC7231
69     // http://tools.ietf.org/html/rfc7231#section-7.4.2
70     rtl::OString            m_aServerHeaderField;
71 
72     CURL*                   m_pCurl;
73     bool                    m_bUseChunkedEncoding;
74     bool                    m_bTransferEncodingSwitched;
75 
76     const ucbhelper::InternetProxyDecider & m_rProxyDecider;
77 
78     DAVRequestEnvironment m_aEnv;
79 
80     static CurlLockStore m_aCurlLockStore;
81 
82     ::com::sun::star::uno::Reference< ::com::sun::star::security::XCertificateContainer > m_xCertificateContainer;
83     ::com::sun::star::uno::Reference< ::com::sun::star::xml::crypto::XXMLSecurityContext > m_xSecurityContext;
84     ::com::sun::star::uno::Reference< ::com::sun::star::xml::crypto::XSecurityEnvironment > m_xSecurityEnv;
85 
86     bool isSSLNeeded();
87 
88 
89     rtl::OUString           composeCurrentUri( const rtl::OUString & inPath );
90     void                    addEnvironmentRequestHeaders( CurlRequest &curlRequest,
91                                                           const DAVRequestEnvironment &env );
92     void                    processResponse( CurlRequest &curlRequest,
93                                              CURLcode curlCode );
94 
95     static CURLcode         Curl_SSLContextCallback( CURL *curl,
96                                                      void *ssl_ctx,
97                                                      void *userptr );
98     static int              OPENSSL_VerifyCertificate( X509_STORE_CTX *x509_ctx, void *arg );
99     int                     verifyServerX509Certificate( X509_STORE_CTX *x509StoreContext );
100     int                     verifyCertificateChain (
101                                 std::vector< uno::Sequence< sal_Int8 > > &asn1DerCertificates );
102 
103     static int              Curl_DebugCallback( CURL *,
104                                                 curl_infotype type,
105                                                 unsigned char *data,
106                                                 size_t size,
107                                                 void* userdata );
108     int                     curlDebugOutput( curl_infotype type, char *data, int size );
109 
110     static bool             Curl_ProvideCredentials( long statusCode,
111                                                      void *userdata );
112     bool                    provideCredentials( const DAVRequestEnvironment &env,
113                                                 CurlRequest &request,
114                                                 long statusCode );
115 
116 protected:
117     virtual ~CurlSession();
118 
119 public:
120     CurlSession( const rtl::Reference< DAVSessionFactory > & rSessionFactory,
121                  const rtl::OUString& inUri,
122                  const ucbhelper::InternetProxyDecider & rProxyDecider );
123 
124     // DAVSession methods
125     virtual sal_Bool CanUse( const ::rtl::OUString & inUri );
126 
127     virtual sal_Bool UsesProxy();
128 
getRequestEnvironment() const129     const DAVRequestEnvironment & getRequestEnvironment() const
130     { return m_aEnv; }
131 
132     // allprop & named
133     virtual void
134     PROPFIND( const ::rtl::OUString & inPath,
135               const Depth inDepth,
136               const std::vector< ::rtl::OUString > & inPropNames,
137               std::vector< DAVResource > & ioResources,
138               const DAVRequestEnvironment & rEnv );
139 
140     // propnames
141     virtual void
142     PROPFIND( const ::rtl::OUString & inPath,
143               const Depth inDepth,
144               std::vector< DAVResourceInfo >& ioResInfo,
145               const DAVRequestEnvironment & rEnv );
146 
147     virtual void
148     PROPPATCH( const ::rtl::OUString & inPath,
149                const std::vector< ProppatchValue > & inValues,
150                const DAVRequestEnvironment & rEnv );
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 
158     virtual com::sun::star::uno::Reference< com::sun::star::io::XInputStream >
159     GET( const ::rtl::OUString & inPath,
160          const DAVRequestEnvironment & rEnv );
161 
162     virtual void
163     GET( const ::rtl::OUString & inPath,
164          com::sun::star::uno::Reference<
165              com::sun::star::io::XOutputStream > &  ioOutputStream,
166          const DAVRequestEnvironment & rEnv );
167 
168     virtual com::sun::star::uno::Reference< com::sun::star::io::XInputStream >
169     GET( const ::rtl::OUString & inPath,
170          const std::vector< ::rtl::OUString > & inHeaderNames,
171          DAVResource & ioResource,
172          const DAVRequestEnvironment & rEnv );
173 
174     virtual void
175     GET( const ::rtl::OUString & inPath,
176          com::sun::star::uno::Reference<
177              com::sun::star::io::XOutputStream > & ioOutputStream,
178          const std::vector< ::rtl::OUString > & inHeaderNames,
179          DAVResource & ioResource,
180          const DAVRequestEnvironment & rEnv );
181 
182     virtual void
183     PUT( const ::rtl::OUString & inPath,
184          const com::sun::star::uno::Reference<
185              com::sun::star::io::XInputStream > & inInputStream,
186          const DAVRequestEnvironment & rEnv );
187 
188     virtual com::sun::star::uno::Reference< com::sun::star::io::XInputStream >
189     POST( const rtl::OUString & inPath,
190           const rtl::OUString & rContentType,
191           const rtl::OUString & rReferer,
192           const com::sun::star::uno::Reference<
193               com::sun::star::io::XInputStream > & inInputStream,
194           const DAVRequestEnvironment & rEnv );
195 
196     virtual void
197     POST( const rtl::OUString & inPath,
198           const rtl::OUString & rContentType,
199           const rtl::OUString & rReferer,
200           const com::sun::star::uno::Reference<
201               com::sun::star::io::XInputStream > & inInputStream,
202           com::sun::star::uno::Reference<
203               com::sun::star::io::XOutputStream > & oOutputStream,
204           const DAVRequestEnvironment & rEnv );
205 
206     virtual void
207     MKCOL( const ::rtl::OUString & inPath,
208            const DAVRequestEnvironment & rEnv );
209 
210     virtual void
211     COPY( const ::rtl::OUString & inSourceURL,
212           const ::rtl::OUString & inDestinationURL,
213           const DAVRequestEnvironment & rEnv,
214           sal_Bool inOverWrite );
215 
216     virtual void
217     MOVE( const ::rtl::OUString & inSourceURL,
218           const ::rtl::OUString & inDestinationURL,
219           const DAVRequestEnvironment & rEnv,
220           sal_Bool inOverWrite );
221 
222     virtual void DESTROY( const ::rtl::OUString & inPath,
223                           const DAVRequestEnvironment & rEnv );
224 
225     // set new lock.
226     virtual void LOCK( const ::rtl::OUString & inURL,
227                        com::sun::star::ucb::Lock & inLock,
228                        const DAVRequestEnvironment & rEnv );
229 
230     // refresh existing lock.
231     virtual sal_Int64 LOCK( const ::rtl::OUString & inURL,
232                             sal_Int64 nTimeout,
233                             const DAVRequestEnvironment & rEnv );
234 
235     virtual void UNLOCK( const ::rtl::OUString & inURL,
236                          const DAVRequestEnvironment & rEnv );
237 
238     // helpers
239     virtual void abort();
240 
getHostName() const241     const rtl::OUString & getHostName() const { return m_aUri.GetHost(); }
getPort() const242     int getPort() const { return m_aUri.GetPort(); }
243 
getMSF()244     const ::uno::Reference< ::lang::XMultiServiceFactory > getMSF()
245     { return m_xFactory->getServiceFactory(); }
246 
247     sal_Bool isDomainMatch( rtl::OUString certHostName );
248 
getServerHeaderField()249     const rtl::OString & getServerHeaderField() { return m_aServerHeaderField; };
250 
251 private:
252     friend class CurlLockStore;
253 
254     void Init( void );
255 
256     void Init( const DAVRequestEnvironment & rEnv );
257 
258     const ucbhelper::InternetProxyServer & getProxySettings() const;
259 
260     void propfind( CurlRequest &curlRequest,
261                    const rtl::OUString &inPath,
262                    const Depth inDepth,
263                    const std::vector< ::rtl::OUString > * propNames,
264                    const bool onlyPropertyNames,
265                    const DAVRequestEnvironment & rEnv );
266 
267     bool removeExpiredLocktoken( const rtl::OUString & inURL,
268                                  const DAVRequestEnvironment & rEnv );
269 
270     // refresh lock, called by CurlLockStore::refreshLocks
271     bool LOCK( CurlLock * pLock,
272                sal_Int32 & rlastChanceToSendRefreshRequest );
273 
274     // unlock, called by CurlLockStore::~CurlLockStore
275     bool UNLOCK( CurlLock * pLock );
276 
277     /*
278     // low level GET implementation, used by public GET implementations
279     static int GET( CurlConnection * sess,
280                     const char * uri,
281                     //ne_block_reader reader,
282                     bool getheaders,
283                     void * userdata );
284 
285     // Buffer-based PUT implementation. Serf only has file descriptor-
286     // based API.
287     static int PUT( CurlConnection * sess,
288                     const char * uri,
289                     const char * buffer,
290                     size_t size );
291 
292     // Buffer-based POST implementation. Serf only has file descriptor-
293     // based API.
294     int POST( CurlConnection * sess,
295               const char * uri,
296               const char * buffer,
297               //ne_block_reader reader,
298               void * userdata,
299               const rtl::OUString & rContentType,
300               const rtl::OUString & rReferer );
301     */
302 
303     // Helper: XInputStream -> Sequence< sal_Int8 >
304     static bool getDataFromInputStream(
305         const com::sun::star::uno::Reference<
306             com::sun::star::io::XInputStream > & xStream,
307         com::sun::star::uno::Sequence< sal_Int8 > & rData,
308         bool bAppendTrailingZeroByte );
309 
310     /*
311     rtl::OUString makeAbsoluteURL( rtl::OUString const & rURL ) const;
312     */
313 };
314 
315 } // namespace http_dav_ucp
316 
317 #endif // INCLUDED_CURLSESSION_HXX
318