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 #ifndef INCLUDED_UCB_SOURCE_UCP_WEBDAV_NEON_NEONSESSION_HXX
30 #define INCLUDED_UCB_SOURCE_UCP_WEBDAV_NEON_NEONSESSION_HXX
31 
32 #include <config_lgpl.h>
33 #include <vector>
34 #include <osl/mutex.hxx>
35 #include "DAVSession.hxx"
36 #include "NeonTypes.hxx"
37 #include "NeonLockStore.hxx"
38 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
39 
40 namespace ucbhelper { class ProxyDecider; }
41 
42 namespace webdav_ucp
43 {
44 
45 // A DAVSession implementation using the neon/expat library
46 class NeonSession : public DAVSession
47 {
48 private:
49     osl::Mutex        m_aMutex;
50     OUString     m_aScheme;
51     OUString     m_aHostName;
52     OUString     m_aProxyName;
53     sal_Int32         m_nPort;
54     sal_Int32         m_nProxyPort;
55     css::uno::Sequence< css::beans::NamedValue > const m_aFlags;
56     HttpSession *     m_pHttpSession;
57     bool m_bNeedNewSession = false; // Something happened that could invalidate m_pHttpSession
58     void * const      m_pRequestData;
59     const ucbhelper::InternetProxyDecider & m_rProxyDecider;
60 
61     // @@@ This should really be per-request data. But Neon currently
62     // (0.23.5) has no interface for passing per-request user data.
63     // Theoretically, a NeonSession instance could handle multiple requests
64     // at a time --currently it doesn't. Thus this is not an issue at the
65     // moment.
66     DAVRequestEnvironment m_aEnv;
67 
68     static bool          m_bGlobalsInited;
69     static NeonLockStore m_aNeonLockStore;
70 
71 protected:
72     virtual ~NeonSession() override;
73 
74 public:
75     /// @throws std::exception
76     NeonSession( const rtl::Reference< DAVSessionFactory > & rSessionFactory,
77                  const OUString& inUri,
78                  const css::uno::Sequence< css::beans::NamedValue >& rFlags,
79                  const ucbhelper::InternetProxyDecider & rProxyDecider );
80 
81     // DAVSession methods
82     virtual bool CanUse( const OUString & inPath,
83                          const css::uno::Sequence< css::beans::NamedValue >& rFlags ) override;
84 
85     virtual bool UsesProxy() override;
86 
getRequestEnvironment() const87     const DAVRequestEnvironment & getRequestEnvironment() const
88     { return m_aEnv; }
89 
90     virtual void
91     OPTIONS( const OUString & inPath,
92              DAVOptions& rOptions, // contains the name+values
93              const DAVRequestEnvironment & rEnv ) override;
94 
95     // allprop & named
96     virtual void
97     PROPFIND( const OUString & inPath,
98               const Depth inDepth,
99               const std::vector< OUString > & inPropNames,
100               std::vector< DAVResource > & ioResources,
101               const DAVRequestEnvironment & rEnv ) override;
102 
103     // propnames
104     virtual void
105     PROPFIND( const OUString & inPath,
106               const Depth inDepth,
107               std::vector< DAVResourceInfo >& ioResInfo,
108               const DAVRequestEnvironment & rEnv ) override;
109 
110     virtual void
111     PROPPATCH( const OUString & inPath,
112                const std::vector< ProppatchValue > & inValues,
113                const DAVRequestEnvironment & rEnv ) override;
114 
115     virtual void
116     HEAD( const OUString &  inPath,
117           const std::vector< OUString > & inHeaderNames,
118           DAVResource & ioResource,
119           const DAVRequestEnvironment & rEnv ) override;
120 
121     virtual css::uno::Reference< css::io::XInputStream >
122     GET( const OUString & inPath,
123          const DAVRequestEnvironment & rEnv ) override;
124 
125     virtual void
126     GET( const OUString & inPath,
127          css::uno::Reference< css::io::XOutputStream > &  ioOutputStream,
128          const DAVRequestEnvironment & rEnv ) override;
129 
130     virtual css::uno::Reference< css::io::XInputStream >
131     GET( const OUString & inPath,
132          const std::vector< OUString > & inHeaderNames,
133          DAVResource & ioResource,
134          const DAVRequestEnvironment & rEnv ) override;
135 
136     virtual void
137     GET0( const OUString & inPath,
138          const std::vector< OUString > & inHeaderNames,
139          DAVResource & ioResource,
140          const DAVRequestEnvironment & rEnv ) override;
141 
142     virtual void
143     GET( const OUString & inPath,
144          css::uno::Reference< css::io::XOutputStream > & ioOutputStream,
145          const std::vector< OUString > & inHeaderNames,
146          DAVResource & ioResource,
147          const DAVRequestEnvironment & rEnv ) override;
148 
149     virtual void
150     PUT( const OUString & inPath,
151          const css::uno::Reference< css::io::XInputStream > & inInputStream,
152          const DAVRequestEnvironment & rEnv ) override;
153 
154     virtual css::uno::Reference< css::io::XInputStream >
155     POST( const OUString & inPath,
156           const OUString & rContentType,
157           const OUString & rReferer,
158           const css::uno::Reference< css::io::XInputStream > & inInputStream,
159           const DAVRequestEnvironment & rEnv ) override;
160 
161     virtual void
162     POST( const OUString & inPath,
163           const OUString & rContentType,
164           const OUString & rReferer,
165           const css::uno::Reference< css::io::XInputStream > & inInputStream,
166           css::uno::Reference< css::io::XOutputStream > & oOutputStream,
167           const DAVRequestEnvironment & rEnv ) override;
168 
169     virtual void
170     MKCOL( const OUString & inPath,
171            const DAVRequestEnvironment & rEnv ) override;
172 
173     virtual void
174     COPY( const OUString & inSourceURL,
175           const OUString & inDestinationURL,
176           const DAVRequestEnvironment & rEnv,
177           bool inOverWrite ) override;
178 
179     virtual void
180     MOVE( const OUString & inSourceURL,
181           const OUString & inDestinationURL,
182           const DAVRequestEnvironment & rEnv,
183           bool inOverWrite ) override;
184 
185     virtual void DESTROY( const OUString & inPath,
186                           const DAVRequestEnvironment & rEnv ) override;
187 
188     // set new lock.
189     virtual void LOCK( const OUString & inURL,
190                        css::ucb::Lock & inLock,
191                        const DAVRequestEnvironment & rEnv ) override;
192 
193     virtual void UNLOCK( const OUString & inURL,
194                          const DAVRequestEnvironment & rEnv ) override;
195 
196     // helpers
197     virtual void abort() override;
198 
getHostName() const199     const OUString & getHostName() const { return m_aHostName; }
200 
getComponentContext() const201     ::uno::Reference< ::uno::XComponentContext > const & getComponentContext() const
202     { return m_xFactory->getComponentContext(); }
203 
getRequestData() const204     const void * getRequestData() const { return m_pRequestData; }
205 
206     bool isDomainMatch( const OUString& certHostName );
207 
208     int CertificationNotify(const ne_ssl_certificate *cert);
209 
210     int NeonAuth(const char* inAuthProtocol, const char* inRealm,
211                  int attempt, char* inoutUserName, char * inoutPassWord);
212 
213     void PreSendRequest(ne_request* req, ne_buffer* headers);
214 
215 private:
216     friend class NeonLockStore;
217 
218     /// @throws css::uno::RuntimeException
219     void Init();
220 
221     /// @throws css::uno::RuntimeException
222     void Init( const DAVRequestEnvironment & rEnv );
223 
224     // ret: true => retry request.
225     /// @throws std::exception
226     void HandleError( int nError,
227                       const OUString & inPath,
228                       const DAVRequestEnvironment & rEnv );
229 
230     ucbhelper::InternetProxyServer getProxySettings() const;
231 
232     bool removeExpiredLocktoken( const OUString & inURL,
233                                  const DAVRequestEnvironment & rEnv );
234 
235     // refresh lock, called by NeonLockStore::refreshLocks
236     bool LOCK( NeonLock * pLock,
237                sal_Int32 & rlastChanceToSendRefreshRequest );
238 
239     // unlock, called by NeonLockStore::~NeonLockStore
240     bool UNLOCK( NeonLock * pLock );
241 
242     // low level GET implementation, used by public GET implementations
243     static int GET( ne_session * sess,
244                     const char * uri,
245                     ne_block_reader reader,
246                     bool getheaders,
247                     void * userdata );
248 
249     // low level GET implementation, used by public GET implementations
250     // used as a HEAD substitute when head is not available
251     static int GET0( ne_session * sess,
252                      const char * uri,
253                      bool getheaders,
254                      void * userdata );
255 
256     // Buffer-based PUT implementation. Neon only has file descriptor-
257     // based API.
258     static int PUT( ne_session * sess,
259                     const char * uri,
260                     const char * buffer,
261                     size_t size );
262 
263     // Buffer-based POST implementation. Neon only has file descriptor-
264     // based API.
265     int POST( ne_session * sess,
266               const char * uri,
267               const char * buffer,
268               ne_block_reader reader,
269               void * userdata,
270               const OUString & rContentType,
271               const OUString & rReferer );
272 
273     // Helper: XInputStream -> Sequence< sal_Int8 >
274     static bool getDataFromInputStream(
275         const css::uno::Reference< css::io::XInputStream > & xStream,
276         css::uno::Sequence< sal_Int8 > & rData,
277         bool bAppendTrailingZeroByte );
278 
279     OUString makeAbsoluteURL( OUString const & rURL ) const;
280 };
281 
282 osl::Mutex& getGlobalNeonMutex();
283 
284 } // namespace webdav_ucp
285 
286 #endif // INCLUDED_UCB_SOURCE_UCP_WEBDAV_NEON_NEONSESSION_HXX
287 
288 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
289