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_SERFSESSION_HXX
25 #define INCLUDED_SERFSESSION_HXX
26 
27 #include <vector>
28 #include <boost/shared_ptr.hpp>
29 #include <osl/mutex.hxx>
30 #include "DAVResource.hxx"
31 #include "DAVSession.hxx"
32 #include "SerfTypes.hxx"
33 #include "SerfLockStore.hxx"
34 #include "SerfUri.hxx"
35 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
36 
37 namespace ucbhelper { class ProxyDecider; }
38 
39 namespace http_dav_ucp
40 {
41 
42 class SerfRequestProcessor;
43 
44 // -------------------------------------------------------------------
45 // SerfSession
46 // A DAVSession implementation using the neon/expat library
47 // -------------------------------------------------------------------
48 
49 class SerfSession : public DAVSession
50 {
51 private:
52     osl::Mutex              m_aMutex;
53 
54     SerfUri                 m_aUri;
55 
56     rtl::OUString           m_aProxyName;
57     sal_Int32               m_nProxyPort;
58     // The server, according RFC7231
59     // http://tools.ietf.org/html/rfc7231#section-7.4.2
60     rtl::OUString           m_aServerHeaderField;
61 
62     SerfConnection*         m_pSerfConnection;
63     serf_context_t*         m_pSerfContext;
64     serf_bucket_alloc_t*    m_pSerfBucket_Alloc;
65     bool                    m_bIsHeadRequestInProgress;
66     bool                    m_bUseChunkedEncoding;
67     sal_Int16               m_bNoOfTransferEncodingSwitches;
68 
69     const ucbhelper::InternetProxyDecider & m_rProxyDecider;
70 
71     DAVRequestEnvironment m_aEnv;
72 
73     static SerfLockStore m_aSerfLockStore;
74 
75     char* getHostinfo();
76     bool isSSLNeeded();
77 
78     SerfRequestProcessor*   createReqProc( const rtl::OUString & inPath );
79 
80     rtl::OUString           composeCurrentUri( const rtl::OUString & inPath );
81 
82 protected:
83     virtual ~SerfSession();
84 
85 public:
86     SerfSession( const rtl::Reference< DAVSessionFactory > & rSessionFactory,
87                  const rtl::OUString& inUri,
88                  const ucbhelper::InternetProxyDecider & rProxyDecider )
89         throw ( DAVException );
90 
91     // Serf library callbacks
92     apr_status_t setupSerfConnection( apr_socket_t * inAprSocket,
93                                       serf_bucket_t **outSerfInputBucket,
94                                       serf_bucket_t **outSerfOutputBucket,
95                                       apr_pool_t* inAprPool );
96 
97     apr_status_t provideSerfCredentials( bool bGiveProvidedCredentialsASecondTry,
98                                          char ** outUsername,
99                                          char ** outPassword,
100                                          serf_request_t * inRequest,
101                                          int inCode,
102                                          const char *inAuthProtocol,
103                                          const char *inRealm,
104                                          apr_pool_t *inAprPool );
105 
106     apr_status_t verifySerfCertificateChain (
107         int nFailures,
108         const serf_ssl_certificate_t * const * pCertificateChainBase64Encoded,
109         int nCertificateChainLength);
110 
111     serf_bucket_t* acceptSerfResponse( serf_request_t * inSerfRequest,
112                                        serf_bucket_t * inSerfStreamBucket,
113                                        apr_pool_t* inAprPool );
114 
115     // Serf-related data structures
116     apr_pool_t* getAprPool();
117     serf_bucket_alloc_t* getSerfBktAlloc();
118     serf_context_t* getSerfContext();
119     SerfConnection* getSerfConnection();
120 
121     // DAVSession methods
122     virtual sal_Bool CanUse( const ::rtl::OUString & inUri );
123 
124     virtual sal_Bool UsesProxy();
125 
getRequestEnvironment() const126     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     bool isHeadRequestInProgress();
160 
161     virtual com::sun::star::uno::Reference< com::sun::star::io::XInputStream >
162     GET( const ::rtl::OUString & inPath,
163          const DAVRequestEnvironment & rEnv )
164         throw ( DAVException );
165 
166     virtual void
167     GET( const ::rtl::OUString & inPath,
168          com::sun::star::uno::Reference<
169              com::sun::star::io::XOutputStream > &  ioOutputStream,
170          const DAVRequestEnvironment & rEnv )
171         throw ( DAVException );
172 
173     virtual com::sun::star::uno::Reference< com::sun::star::io::XInputStream >
174     GET( const ::rtl::OUString & inPath,
175          const std::vector< ::rtl::OUString > & inHeaderNames,
176          DAVResource & ioResource,
177          const DAVRequestEnvironment & rEnv )
178         throw ( DAVException );
179 
180     virtual void
181     GET( const ::rtl::OUString & inPath,
182          com::sun::star::uno::Reference<
183              com::sun::star::io::XOutputStream > & ioOutputStream,
184          const std::vector< ::rtl::OUString > & inHeaderNames,
185          DAVResource & ioResource,
186          const DAVRequestEnvironment & rEnv )
187         throw ( DAVException );
188 
189     virtual void
190     PUT( const ::rtl::OUString & inPath,
191          const com::sun::star::uno::Reference<
192              com::sun::star::io::XInputStream > & inInputStream,
193          const DAVRequestEnvironment & rEnv )
194         throw ( DAVException );
195 
196     virtual com::sun::star::uno::Reference< com::sun::star::io::XInputStream >
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           const DAVRequestEnvironment & rEnv )
203         throw ( DAVException );
204 
205     virtual void
206     POST( const rtl::OUString & inPath,
207           const rtl::OUString & rContentType,
208           const rtl::OUString & rReferer,
209           const com::sun::star::uno::Reference<
210               com::sun::star::io::XInputStream > & inInputStream,
211           com::sun::star::uno::Reference<
212               com::sun::star::io::XOutputStream > & oOutputStream,
213           const DAVRequestEnvironment & rEnv )
214         throw ( DAVException );
215 
216     virtual void
217     MKCOL( const ::rtl::OUString & inPath,
218            const DAVRequestEnvironment & rEnv )
219         throw ( DAVException );
220 
221     virtual void
222     COPY( const ::rtl::OUString & inSourceURL,
223           const ::rtl::OUString & inDestinationURL,
224           const DAVRequestEnvironment & rEnv,
225           sal_Bool inOverWrite )
226         throw ( DAVException );
227 
228     virtual void
229     MOVE( const ::rtl::OUString & inSourceURL,
230           const ::rtl::OUString & inDestinationURL,
231           const DAVRequestEnvironment & rEnv,
232           sal_Bool inOverWrite )
233         throw ( DAVException );
234 
235     virtual void DESTROY( const ::rtl::OUString & inPath,
236                           const DAVRequestEnvironment & rEnv )
237         throw ( DAVException );
238 
239     // set new lock.
240     virtual void LOCK( const ::rtl::OUString & inURL,
241                        com::sun::star::ucb::Lock & inLock,
242                        const DAVRequestEnvironment & rEnv )
243         throw ( DAVException );
244 
245     // refresh existing lock.
246     virtual sal_Int64 LOCK( const ::rtl::OUString & inURL,
247                             sal_Int64 nTimeout,
248                             const DAVRequestEnvironment & rEnv )
249         throw ( DAVException );
250 
251     virtual void UNLOCK( const ::rtl::OUString & inURL,
252                          const DAVRequestEnvironment & rEnv )
253         throw ( DAVException );
254 
255     // helpers
256     virtual void abort()
257         throw ( DAVException );
258 
getHostName() const259     const rtl::OUString & getHostName() const { return m_aUri.GetHost(); }
getPort() const260     int getPort() const { return m_aUri.GetPort(); }
261 
getMSF()262     const ::uno::Reference< ::lang::XMultiServiceFactory > getMSF()
263     { return m_xFactory->getServiceFactory(); }
264 
265     sal_Bool isDomainMatch( rtl::OUString certHostName );
266 
getServerHeaderField()267     const rtl::OUString & getServerHeaderField() { return m_aServerHeaderField; };
268 
setServerHeaderField(rtl::OUString aServerHeaderField)269     void setServerHeaderField( rtl::OUString aServerHeaderField ) { m_aServerHeaderField = aServerHeaderField; };
270 
271 private:
272     friend class SerfLockStore;
273 
274     void Init( void )
275         throw ( DAVException );
276 
277     void Init( const DAVRequestEnvironment & rEnv )
278         throw ( DAVException );
279 
280     void HandleError( boost::shared_ptr<SerfRequestProcessor> rReqProc )
281         throw ( DAVException );
282 
283     const ucbhelper::InternetProxyServer & getProxySettings() const;
284 
285     bool removeExpiredLocktoken( const rtl::OUString & inURL,
286                                  const DAVRequestEnvironment & rEnv );
287 
288     // refresh lock, called by SerfLockStore::refreshLocks
289     bool LOCK( SerfLock * pLock,
290                sal_Int32 & rlastChanceToSendRefreshRequest );
291 
292     // unlock, called by SerfLockStore::~SerfLockStore
293     bool UNLOCK( SerfLock * pLock );
294 
295     /*
296     // low level GET implementation, used by public GET implementations
297     static int GET( SerfConnection * 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( SerfConnection * 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( SerfConnection * 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_SERFSESSION_HXX
336