LibreOffice Module ucb (master)  1
SerfSession.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include <vector>
21 #include <string.h>
22 #include <sal/log.hxx>
24 #include <comphelper/sequence.hxx>
26 
27 #include "AprEnv.hxx"
28 #include <apr_strings.h>
29 
30 #include "DAVAuthListener.hxx"
31 #include "SerfSession.hxx"
32 #include "SerfUri.hxx"
33 #include "SerfRequestProcessor.hxx"
34 #include "SerfCallbacks.hxx"
35 #include "SerfInputStream.hxx"
36 
37 #include <com/sun/star/xml/crypto/SEInitializer.hpp>
38 #include <com/sun/star/xml/crypto/XSecurityEnvironment.hpp>
39 #include <com/sun/star/security/XCertificate.hpp>
40 #include <com/sun/star/security/CertificateValidity.hpp>
41 #include <com/sun/star/security/CertificateContainerStatus.hpp>
42 #include <com/sun/star/security/CertificateContainer.hpp>
43 #include <com/sun/star/security/XCertificateContainer.hpp>
44 #include <com/sun/star/security/CertAltNameEntry.hpp>
45 #include <com/sun/star/security/XSanExtension.hpp>
46 #include <com/sun/star/io/NotConnectedException.hpp>
47 #include <com/sun/star/io/BufferSizeExceededException.hpp>
48 #include <com/sun/star/io/IOException.hpp>
49 #define OID_SUBJECT_ALTERNATIVE_NAME "2.5.29.17"
50 
51 #include <com/sun/star/ucb/Lock.hpp>
52 #include <com/sun/star/xml/crypto/XSEInitializer.hpp>
53 
54 using namespace com::sun::star;
55 using namespace http_dav_ucp;
56 
57 // Constructor
58 
59 SerfSession::SerfSession(
60  const rtl::Reference< DAVSessionFactory > & rSessionFactory,
61  const OUString& inUri,
62  const ucbhelper::InternetProxyDecider & rProxyDecider )
63  : DAVSession( rSessionFactory )
64  , m_aMutex()
65  , m_aUri( inUri )
66  , m_aProxyName()
67  , m_nProxyPort( 0 )
68  , m_pSerfConnection( nullptr )
69  , m_pSerfContext( nullptr )
70  , m_bIsHeadRequestInProgress( false )
71  , m_bUseChunkedEncoding( false )
72  , m_bNoOfTransferEncodingSwitches( 0 )
73  , m_rProxyDecider( rProxyDecider )
74  , m_aEnv()
75 {
76  m_pSerfContext = serf_context_create( getAprPool() );
77 
78  m_pSerfBucket_Alloc = serf_bucket_allocator_create( getAprPool(), nullptr, nullptr );
79 }
80 
81 
82 // Destructor
83 
85 {
86  if ( m_pSerfConnection )
87  {
88  serf_connection_close( m_pSerfConnection );
89  m_pSerfConnection = nullptr;
90  }
91 }
92 
93 
95 {
96  osl::Guard< osl::Mutex > theGuard( m_aMutex );
97  m_aEnv = rEnv;
98  Init();
99 }
100 
101 
103 {
104  osl::Guard< osl::Mutex > theGuard( m_aMutex );
105 
106  bool bCreateNewSession = false;
107 
108  if ( m_pSerfConnection == nullptr )
109  {
110  const ucbhelper::InternetProxyServer & rProxyCfg = getProxySettings();
111 
112  m_aProxyName = rProxyCfg.aName;
113  m_nProxyPort = rProxyCfg.nPort;
114 
115  // Not yet initialized. Create new session.
116  bCreateNewSession = true;
117  }
118  else
119  {
120  const ucbhelper::InternetProxyServer & rProxyCfg = getProxySettings();
121 
122  if ( ( rProxyCfg.aName != m_aProxyName )
123  || ( rProxyCfg.nPort != m_nProxyPort ) )
124  {
125  m_aProxyName = rProxyCfg.aName;
126  m_nProxyPort = rProxyCfg.nPort;
127 
128  // new session needed, destroy old first
129  serf_connection_close( m_pSerfConnection );
130  m_pSerfConnection = nullptr;
131  bCreateNewSession = true;
132  }
133  }
134 
135  if ( bCreateNewSession )
136  {
137  // TODO - close_connection callback
138  apr_status_t status = serf_connection_create2( &m_pSerfConnection,
140  m_aUri.getAprUri(),
141  Serf_ConnectSetup, this,
142  nullptr /* close connection callback */, nullptr /* close connection baton */,
143  getAprPool() );
144 
145  if ( m_pSerfConnection == nullptr ||status != APR_SUCCESS )
146  {
149  }
150 
151  // Register the session with the lock store
152 // m_aSerfLockStore.registerSession( m_pSerfConnection );
153 
154  if ( m_aProxyName.getLength() )
155  {
156  apr_sockaddr_t *proxy_address = nullptr;
157  status = apr_sockaddr_info_get( &proxy_address,
158  OUStringToOString( m_aProxyName, RTL_TEXTENCODING_UTF8 ).getStr(),
159  APR_UNSPEC,
160  static_cast<apr_port_t>(m_nProxyPort),
161  0, getAprPool() );
162 
163  if ( status != APR_SUCCESS )
164  {
167  }
168 
169  serf_config_proxy( m_pSerfContext, proxy_address );
170  }
171 
172 
173  serf_config_credentials_callback( m_pSerfContext, Serf_Credentials );
174 
176  }
177 }
178 
180 {
182 }
183 
184 serf_bucket_alloc_t* SerfSession::getSerfBktAlloc()
185 {
186  return m_pSerfBucket_Alloc;
187 }
188 
190 {
191  return m_pSerfContext;
192 }
193 
194 serf_connection_t* SerfSession::getSerfConnection()
195 {
196  return m_pSerfConnection;
197 }
198 
200 {
202 }
203 
205 {
206  return m_aUri.GetScheme().equalsIgnoreAsciiCase( "https" );
207 }
208 
210 {
211  return m_aUri.getAprUri().hostinfo;
212 }
213 
214 
215 // virtual
216 bool SerfSession::CanUse( const OUString & inUri )
217 {
218  try
219  {
220  SerfUri theUri( inUri );
221  if ( ( theUri.GetPort() == m_aUri.GetPort() ) &&
222  ( theUri.GetHost() == m_aUri.GetHost() ) &&
223  ( theUri.GetScheme() == m_aUri.GetScheme() ) )
224  {
225  return true;
226  }
227  }
228  catch ( DAVException const & )
229  {
230  return false;
231  }
232  return false;
233 }
234 
235 
236 // virtual
238 {
239  Init();
240  return ( m_aProxyName.getLength() > 0 );
241 }
242 
243 apr_status_t SerfSession::setupSerfConnection( apr_socket_t * inAprSocket,
244  serf_bucket_t **outSerfInputBucket,
245  serf_bucket_t **outSerfOutputBucket,
246  apr_pool_t* /*inAprPool*/ )
247 {
248  serf_bucket_t *tmpInputBkt;
249  tmpInputBkt = serf_context_bucket_socket_create( getSerfContext(),
250  inAprSocket,
251  getSerfBktAlloc() );
252 
253  if ( isSSLNeeded() )
254  {
255  tmpInputBkt = serf_bucket_ssl_decrypt_create( tmpInputBkt,
256  nullptr,
257  getSerfBktAlloc() );
261  serf_ssl_server_cert_chain_callback_set(
262  serf_bucket_ssl_decrypt_context_get(tmpInputBkt),
263  nullptr,
265  this);
266  serf_ssl_set_hostname( serf_bucket_ssl_decrypt_context_get( tmpInputBkt ),
267  getHostinfo() );
268 
269  *outSerfOutputBucket = serf_bucket_ssl_encrypt_create( *outSerfOutputBucket,
270  serf_bucket_ssl_decrypt_context_get( tmpInputBkt ),
271  getSerfBktAlloc() );
272  }
273 
274  *outSerfInputBucket = tmpInputBkt;
275 
276  return APR_SUCCESS;
277 }
278 
279 apr_status_t SerfSession::provideSerfCredentials( bool bGiveProvidedCredentialsASecondTry,
280  char ** outUsername,
281  char ** outPassword,
282  serf_request_t * /*inRequest*/,
283  int /*inCode*/,
284  const char *inAuthProtocol,
285  const char *inRealm,
286  apr_pool_t *inAprPool )
287 {
289  if ( !pListener )
290  {
291  // abort
292  return SERF_ERROR_AUTHN_FAILED;
293  }
294 
295  OUString theUserName;
296  OUString thePassWord;
297  try
298  {
299  SerfUri uri( getRequestEnvironment().m_aRequestURI );
300  OUString aUserInfo( uri.GetUserInfo() );
301  if ( aUserInfo.getLength() )
302  {
303  sal_Int32 nPos = aUserInfo.indexOf( '@' );
304  if ( nPos == -1 )
305  {
306  theUserName = aUserInfo;
307  }
308  else
309  {
310  theUserName = aUserInfo.copy( 0, nPos );
311  thePassWord = aUserInfo.copy( nPos + 1 );
312  }
313  }
314  }
315  catch ( DAVException const & )
316  {
317  // abort
318  return SERF_ERROR_AUTHN_FAILED;
319  }
320 
321  const bool bCanUseSystemCreds = ( ( strcasecmp( inAuthProtocol, "NTLM" ) == 0 ) ||
322  ( strcasecmp( inAuthProtocol, "Negotiate" ) == 0 ) );
323 
324  int theRetVal = pListener->authenticate( OUString::createFromAscii( inRealm ),
325  getHostName(),
326  theUserName,
327  thePassWord,
328  bCanUseSystemCreds,
329  bGiveProvidedCredentialsASecondTry );
330 
331  if ( theRetVal == 0 )
332  {
333  *outUsername = apr_pstrdup( inAprPool, OUStringToOString( theUserName, RTL_TEXTENCODING_UTF8 ).getStr() );
334  *outPassword = apr_pstrdup( inAprPool, OUStringToOString( thePassWord, RTL_TEXTENCODING_UTF8 ).getStr() );
335  }
336 
337  return theRetVal != 0 ? SERF_ERROR_AUTHN_FAILED : APR_SUCCESS;
338 }
339 
341  int,
342  const serf_ssl_certificate_t * const * pCertificateChainBase64Encoded,
343  int nCertificateChainLength)
344 {
345  // Check arguments.
346  if (pCertificateChainBase64Encoded == nullptr || nCertificateChainLength<=0)
347  {
348  assert(pCertificateChainBase64Encoded != nullptr);
349  assert(nCertificateChainLength>0);
350  return SERF_SSL_CERT_UNKNOWN_FAILURE;
351  }
352 
353  // When called from SerfLockStore::~SerfLockStore(),
354  // css::xml::crypto::SEInitializer::create() will fail
355  // but we want to send unlock commands anyway,
356  // so just ignore certificates and return here.
357  if (apr_environment::AprEnv::getAprEnv()->getSerfLockStore()->finishing())
358  return APR_SUCCESS;
359 
360  // Create some crypto objects to decode and handle the base64
361  // encoded certificate chain.
362  uno::Reference< security::XCertificateContainer > xCertificateContainer;
363  uno::Reference< xml::crypto::XXMLSecurityContext > xSecurityContext;
364  uno::Reference< xml::crypto::XSecurityEnvironment > xSecurityEnv;
365  try
366  {
367  css::uno::Reference< css::uno::XComponentContext > xContext =
368  ::comphelper::getProcessComponentContext();
369  // Create a certificate container.
370  xCertificateContainer = security::CertificateContainer::create( xContext );
371 
372  css::uno::Reference< css::xml::crypto::XSEInitializer > xSEInitializer =
373  css::xml::crypto::SEInitializer::create( xContext );
374 
375  xSecurityContext = xSEInitializer->createSecurityContext( OUString() );
376  if (xSecurityContext.is())
377  xSecurityEnv = xSecurityContext->getSecurityEnvironment();
378 
379  if ( ! xSecurityContext.is() || ! xSecurityEnv.is())
380  {
381  // Do we have to dispose xSEInitializer or xCertificateContainer?
382  return SERF_SSL_CERT_UNKNOWN_FAILURE;
383  }
384  }
385  catch ( uno::Exception const &)
386  {
387  return SERF_SSL_CERT_UNKNOWN_FAILURE;
388  }
389 
390  // Decode the server certificate.
391  const char* sBase64EncodedServerCertificate (
392  serf_ssl_cert_export(
393  pCertificateChainBase64Encoded[0],
394  getAprPool()));
395  uno::Reference< security::XCertificate > xServerCertificate(
396  xSecurityEnv->createCertificateFromAscii(
397  OUString::createFromAscii(sBase64EncodedServerCertificate)));
398  if ( ! xServerCertificate.is())
399  return SERF_SSL_CERT_UNKNOWN_FAILURE;
400 
401  // Get the subject from the server certificate.
402  OUString sServerCertificateSubject (xServerCertificate->getSubjectName());
403  sal_Int32 nIndex = 0;
404  while (nIndex >= 0)
405  {
406  const OUString sToken (sServerCertificateSubject.getToken(0, ',', nIndex));
407  if (sToken.startsWith("CN="))
408  {
409  sServerCertificateSubject = sToken.copy(3);
410  break;
411  }
412  else if (sToken.startsWith(" CN="))
413  {
414  sServerCertificateSubject = sToken.copy(4);
415  break;
416  }
417  }
418 
419  // When the certificate container already contains a (trusted)
420  // entry for the server then we do not have to authenticate any
421  // certificate.
422  const security::CertificateContainerStatus eStatus (
423  xCertificateContainer->hasCertificate(
424  getHostName(), sServerCertificateSubject ) );
425  if (eStatus != security::CertificateContainerStatus_NOCERT)
426  {
427  return eStatus == security::CertificateContainerStatus_TRUSTED
428  ? APR_SUCCESS
429  : SERF_SSL_CERT_UNKNOWN_FAILURE;
430  }
431 
432  // The shortcut failed, so try to verify the whole chain. This is
433  // done outside the isDomainMatch() block because the result is
434  // used by the interaction handler.
435  std::vector< uno::Reference< security::XCertificate > > aChain;
436  for (nIndex = 1; nIndex < nCertificateChainLength; ++nIndex)
437  {
438  const char* sBase64EncodedCertificate (
439  serf_ssl_cert_export(
440  pCertificateChainBase64Encoded[nIndex],
441  getAprPool()));
442  uno::Reference< security::XCertificate > xCertificate(
443  xSecurityEnv->createCertificateFromAscii(
444  OUString::createFromAscii(sBase64EncodedCertificate)));
445  if ( ! xCertificate.is())
446  return SERF_SSL_CERT_UNKNOWN_FAILURE;
447  aChain.push_back(xCertificate);
448  }
449  const sal_Int64 nVerificationResult (xSecurityEnv->verifyCertificate(
450  xServerCertificate,
452 
453  // When the certificate matches the host name then we can use the
454  // result of the verification.
455  bool bHostnameMatchesCertHostnames = false;
456  {
457  uno::Sequence< uno::Reference< security::XCertificateExtension > > extensions = xServerCertificate->getExtensions();
458  uno::Sequence< security::CertAltNameEntry > altNames;
459  for (sal_Int32 i = 0 ; i < extensions.getLength(); ++i)
460  {
461  uno::Reference< security::XCertificateExtension >element = extensions[i];
462 
463  const OString aId ( reinterpret_cast<const sal_Char *>(const_cast<const signed char *>(element->getExtensionId().getArray())), element->getExtensionId().getLength());
464  if ( aId.equals( OID_SUBJECT_ALTERNATIVE_NAME ) )
465  {
466  uno::Reference< security::XSanExtension > sanExtension ( element, uno::UNO_QUERY );
467  altNames = sanExtension->getAlternativeNames();
468  break;
469  }
470  }
471 
472  uno::Sequence< OUString > certHostNames(altNames.getLength() + 1);
473  certHostNames[0] = sServerCertificateSubject;
474  for( int n = 0; n < altNames.getLength(); ++n )
475  {
476  if (altNames[n].Type == security::ExtAltNameType_DNS_NAME)
477  {
478  altNames[n].Value >>= certHostNames[n+1];
479  }
480  }
481 
482  for ( int i = 0; i < certHostNames.getLength() && !bHostnameMatchesCertHostnames; ++i )
483  {
484  bHostnameMatchesCertHostnames = isDomainMatch( certHostNames[i] );
485  }
486 
487  }
488  if ( bHostnameMatchesCertHostnames )
489  {
490 
491  if (nVerificationResult == 0)
492  {
493  // Certificate (chain) is valid.
494  xCertificateContainer->addCertificate(getHostName(), sServerCertificateSubject, true);
495  return APR_SUCCESS;
496  }
497  else if ((nVerificationResult & security::CertificateValidity::CHAIN_INCOMPLETE) != 0)
498  {
499  // We do not have enough information for verification,
500  // neither automatically (as we just discovered) nor
501  // manually (so there is no point in showing any dialog.)
502  return SERF_SSL_CERT_UNKNOWN_FAILURE;
503  }
504  else if ((nVerificationResult &
505  (security::CertificateValidity::INVALID | security::CertificateValidity::REVOKED)) != 0)
506  {
507  // Certificate (chain) is invalid.
508  xCertificateContainer->addCertificate(getHostName(), sServerCertificateSubject, false);
509  return SERF_SSL_CERT_UNKNOWN_FAILURE;
510  }
511  else
512  {
513  // For all other we have to ask the user.
514  }
515  }
516 
517  // We have not been able to automatically verify (or falsify) the
518  // certificate chain. To resolve this we have to ask the user.
519  const uno::Reference< ucb::XCommandEnvironment > xEnv( getRequestEnvironment().m_xEnv );
520  if ( xEnv.is() )
521  {
522  uno::Reference< task::XInteractionHandler > xIH( xEnv->getInteractionHandler() );
523  if ( xIH.is() )
524  {
527  static_cast<sal_Int32>(nVerificationResult), xServerCertificate, getHostName() ) );
528  xIH->handle( xRequest.get() );
529 
531  = xRequest->getSelection();
532 
533  if ( xSelection.is() )
534  {
535  uno::Reference< task::XInteractionApprove > xApprove( xSelection.get(), uno::UNO_QUERY );
536  if ( xApprove.is() )
537  {
538  xCertificateContainer->addCertificate( getHostName(), sServerCertificateSubject, true );
539  return APR_SUCCESS;
540  }
541  else
542  {
543  // Don't trust cert
544  xCertificateContainer->addCertificate( getHostName(), sServerCertificateSubject, false );
545  return SERF_SSL_CERT_UNKNOWN_FAILURE;
546  }
547  }
548  }
549  else
550  {
551  // Don't trust cert
552  xCertificateContainer->addCertificate( getHostName(), sServerCertificateSubject, false );
553  return SERF_SSL_CERT_UNKNOWN_FAILURE;
554  }
555  }
556 
557  return SERF_SSL_CERT_UNKNOWN_FAILURE;
558 }
559 
560 serf_bucket_t* SerfSession::acceptSerfResponse( serf_request_t * inSerfRequest,
561  serf_bucket_t * inSerfStreamBucket,
562  apr_pool_t* /*inAprPool*/ )
563 {
564  // get the per-request bucket allocator
565  serf_bucket_alloc_t* SerfBktAlloc = serf_request_get_alloc( inSerfRequest );
566 
567  // create a barrier bucket so the response doesn't eat us!
568  serf_bucket_t *responseBkt = serf_bucket_barrier_create( inSerfStreamBucket,
569  SerfBktAlloc );
570 
571  // create response bucket
572  responseBkt = serf_bucket_response_create( responseBkt,
573  SerfBktAlloc );
574 
575  if ( isHeadRequestInProgress() )
576  {
577  // advise the response bucket that this was from a HEAD request and that it should not expect to see a response body.
578  serf_bucket_response_set_head( responseBkt );
579  }
580 
581  return responseBkt;
582 }
583 
585 {
586  return new SerfRequestProcessor( *this,
587  inPath,
589 }
590 
591 
592 // PROPFIND - allprop & named
593 
594 void SerfSession::PROPFIND( const OUString & inPath,
595  const Depth inDepth,
596  const std::vector< OUString > & inPropNames,
597  std::vector< DAVResource > & ioResources,
598  const DAVRequestEnvironment & rEnv )
599 {
600  osl::Guard< osl::Mutex > theGuard( m_aMutex );
601 
602  Init( rEnv );
603 
604  apr_status_t status = APR_SUCCESS;
605  std::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) );
606  aReqProc->processPropFind( inDepth,
607  inPropNames,
608  ioResources,
609  status );
610 
611  if ( status == APR_SUCCESS &&
612  aReqProc->mpDAVException == nullptr &&
613  ioResources.empty() )
614  {
616  throw DAVException( DAVException::DAV_HTTP_ERROR, inPath, APR_EGENERAL );
617  }
618  HandleError( aReqProc );
619 }
620 
621 
622 // PROPFIND - propnames
623 
624 void SerfSession::PROPFIND( const OUString & inPath,
625  const Depth inDepth,
626  std::vector< DAVResourceInfo > & ioResInfo,
627  const DAVRequestEnvironment & rEnv )
628 {
629  osl::Guard< osl::Mutex > theGuard( m_aMutex );
630 
631  Init( rEnv );
632 
633  apr_status_t status = APR_SUCCESS;
634  std::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) );
635  aReqProc->processPropFind( inDepth,
636  ioResInfo,
637  status );
638 
639  if ( status == APR_SUCCESS &&
640  aReqProc->mpDAVException == nullptr &&
641  ioResInfo.empty() )
642  {
644  throw DAVException( DAVException::DAV_HTTP_ERROR, inPath, APR_EGENERAL );
645  }
646  HandleError( aReqProc );
647 }
648 
649 
650 // PROPPATCH
651 
652 void SerfSession::PROPPATCH( const OUString & inPath,
653  const std::vector< ProppatchValue > & inValues,
654  const DAVRequestEnvironment & rEnv )
655 {
656  osl::Guard< osl::Mutex > theGuard( m_aMutex );
657 
658  Init( rEnv );
659 
660  apr_status_t status = APR_SUCCESS;
661  std::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) );
662  aReqProc->processPropPatch( inValues,
663  status );
664 
665  HandleError( aReqProc );
666 }
667 
668 
669 // HEAD
670 
671 void SerfSession::HEAD( const OUString & inPath,
672  const std::vector< OUString > & inHeaderNames,
673  DAVResource & ioResource,
674  const DAVRequestEnvironment & rEnv )
675 {
676  osl::Guard< osl::Mutex > theGuard( m_aMutex );
677 
678  Init( rEnv );
679 
681 
682  std::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) );
683  ioResource.uri = inPath;
684  ioResource.properties.clear();
685  apr_status_t status = APR_SUCCESS;
686  aReqProc->processHead( inHeaderNames,
687  ioResource,
688  status );
689 
691 
692  HandleError( aReqProc );
693 }
694 
695 
696 // GET
697 
698 uno::Reference< io::XInputStream >
699 SerfSession::GET( const OUString & inPath,
700  const DAVRequestEnvironment & rEnv )
701 {
702  osl::Guard< osl::Mutex > theGuard( m_aMutex );
703 
704  Init( rEnv );
705 
707  apr_status_t status = APR_SUCCESS;
708  std::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) );
709  aReqProc->processGet( xInputStream,
710  status );
711 
712  HandleError( aReqProc );
713 
714  return uno::Reference< io::XInputStream >( xInputStream.get() );
715 }
716 
717 
718 // GET
719 
720 void SerfSession::GET( const OUString & inPath,
721  uno::Reference< io::XOutputStream > & ioOutputStream,
722  const DAVRequestEnvironment & rEnv )
723 {
724  osl::Guard< osl::Mutex > theGuard( m_aMutex );
725 
726  Init( rEnv );
727 
728  apr_status_t status = APR_SUCCESS;
729  std::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) );
730  aReqProc->processGet( ioOutputStream,
731  status );
732 
733  HandleError( aReqProc );
734 }
735 
736 
737 // GET
738 
739 uno::Reference< io::XInputStream >
740 SerfSession::GET( const OUString & inPath,
741  const std::vector< OUString > & inHeaderNames,
742  DAVResource & ioResource,
743  const DAVRequestEnvironment & rEnv )
744 {
745  osl::Guard< osl::Mutex > theGuard( m_aMutex );
746 
747  Init( rEnv );
748 
749  std::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) );
751  ioResource.uri = inPath;
752  ioResource.properties.clear();
753  apr_status_t status = APR_SUCCESS;
754  aReqProc->processGet( xInputStream,
755  inHeaderNames,
756  ioResource,
757  status );
758 
759  HandleError( aReqProc );
760 
761  return uno::Reference< io::XInputStream >( xInputStream.get() );
762 }
763 
764 
765 // GET
766 
767 void SerfSession::GET( const OUString & inPath,
768  uno::Reference< io::XOutputStream > & ioOutputStream,
769  const std::vector< OUString > & inHeaderNames,
770  DAVResource & ioResource,
771  const DAVRequestEnvironment & rEnv )
772 {
773  osl::Guard< osl::Mutex > theGuard( m_aMutex );
774 
775  Init( rEnv );
776 
777  std::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) );
778  ioResource.uri = inPath;
779  ioResource.properties.clear();
780  apr_status_t status = APR_SUCCESS;
781  aReqProc->processGet( ioOutputStream,
782  inHeaderNames,
783  ioResource,
784  status );
785 
786  HandleError( aReqProc );
787 }
788 
789 
790 // PUT
791 
792 void SerfSession::PUT( const OUString & inPath,
793  const uno::Reference< io::XInputStream > & inInputStream,
794  const DAVRequestEnvironment & rEnv )
795 {
796  osl::Guard< osl::Mutex > theGuard( m_aMutex );
797 
798  Init( rEnv );
799 
800  std::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) );
801  uno::Sequence< sal_Int8 > aDataToSend;
802  if ( !getDataFromInputStream( inInputStream, aDataToSend, false ) )
804  apr_status_t status = APR_SUCCESS;
805  aReqProc->processPut( reinterpret_cast< const char * >( aDataToSend.getConstArray() ),
806  aDataToSend.getLength(),
807  status );
808 
809  HandleError( aReqProc );
810 }
811 
812 
813 // POST
814 
815 uno::Reference< io::XInputStream >
816 SerfSession::POST( const OUString & inPath,
817  const OUString & rContentType,
818  const OUString & rReferer,
819  const uno::Reference< io::XInputStream > & inInputStream,
820  const DAVRequestEnvironment & rEnv )
821 {
822  osl::Guard< osl::Mutex > theGuard( m_aMutex );
823 
824  uno::Sequence< sal_Int8 > aDataToSend;
825  if ( !getDataFromInputStream( inInputStream, aDataToSend, true ) )
826  {
828  }
829 
830  Init( rEnv );
831 
832  std::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) );
834  apr_status_t status = APR_SUCCESS;
835  aReqProc->processPost( reinterpret_cast< const char * >( aDataToSend.getConstArray() ),
836  aDataToSend.getLength(),
837  rContentType,
838  rReferer,
839  xInputStream,
840  status );
841 
842  HandleError( aReqProc );
843  return uno::Reference< io::XInputStream >( xInputStream.get() );
844 }
845 
846 
847 // POST
848 
849 void SerfSession::POST( const OUString & inPath,
850  const OUString & rContentType,
851  const OUString & rReferer,
852  const uno::Reference< io::XInputStream > & inInputStream,
853  uno::Reference< io::XOutputStream > & oOutputStream,
854  const DAVRequestEnvironment & rEnv )
855 {
856  osl::Guard< osl::Mutex > theGuard( m_aMutex );
857 
858  uno::Sequence< sal_Int8 > aDataToSend;
859  if ( !getDataFromInputStream( inInputStream, aDataToSend, true ) )
860  {
862  }
863 
864  Init( rEnv );
865 
866  std::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) );
867  apr_status_t status = APR_SUCCESS;
868  aReqProc->processPost( reinterpret_cast< const char * >( aDataToSend.getConstArray() ),
869  aDataToSend.getLength(),
870  rContentType,
871  rReferer,
872  oOutputStream,
873  status );
874 
875  HandleError( aReqProc );
876 }
877 
878 
879 // MKCOL
880 
881 void SerfSession::MKCOL( const OUString & inPath,
882  const DAVRequestEnvironment & rEnv )
883 {
884  osl::Guard< osl::Mutex > theGuard( m_aMutex );
885 
886  Init( rEnv );
887 
888  std::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) );
889  apr_status_t status = APR_SUCCESS;
890  aReqProc->processMkCol( status );
891 
892  HandleError( aReqProc );
893 }
894 
895 
896 // COPY
897 
898 void SerfSession::COPY( const OUString & inSourceURL,
899  const OUString & inDestinationURL,
900  const DAVRequestEnvironment & rEnv,
901  bool inOverWrite )
902 {
903  osl::Guard< osl::Mutex > theGuard( m_aMutex );
904 
905  Init( rEnv );
906 
907  SerfUri theSourceUri( inSourceURL );
908  std::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( theSourceUri.GetPath() ) );
909  apr_status_t status = APR_SUCCESS;
910  aReqProc->processCopy( inDestinationURL, inOverWrite, status );
911 
912  HandleError( aReqProc );
913 }
914 
915 
916 // MOVE
917 
918 void SerfSession::MOVE( const OUString & inSourceURL,
919  const OUString & inDestinationURL,
920  const DAVRequestEnvironment & rEnv,
921  bool inOverWrite )
922 {
923  osl::Guard< osl::Mutex > theGuard( m_aMutex );
924 
925  Init( rEnv );
926 
927  SerfUri theSourceUri( inSourceURL );
928  std::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( theSourceUri.GetPath() ) );
929  apr_status_t status = APR_SUCCESS;
930  aReqProc->processMove( inDestinationURL, inOverWrite, status );
931 
932  HandleError( aReqProc );
933 }
934 
935 
936 // DESTROY
937 
938 void SerfSession::DESTROY( const OUString & inPath,
939  const DAVRequestEnvironment & rEnv )
940 {
941  osl::Guard< osl::Mutex > theGuard( m_aMutex );
942 
943  Init( rEnv );
944 
945  std::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) );
946  apr_status_t status = APR_SUCCESS;
947  aReqProc->processDelete( status );
948 
949  HandleError( aReqProc );
950 }
951 
952 
953 /*
954 namespace
955 {
956  sal_Int32 lastChanceToSendRefreshRequest( TimeValue const & rStart,
957  int timeout )
958  {
959  TimeValue aEnd;
960  osl_getSystemTime( &aEnd );
961 
962  // Try to estimate a safe absolute time for sending the
963  // lock refresh request.
964  sal_Int32 lastChanceToSendRefreshRequest = -1;
965  if ( timeout != NE_TIMEOUT_INFINITE )
966  {
967  sal_Int32 calltime = aEnd.Seconds - rStart.Seconds;
968  if ( calltime <= timeout )
969  {
970  lastChanceToSendRefreshRequest
971  = aEnd.Seconds + timeout - calltime;
972  }
973  else
974  {
975  SAL_INFO("ucb.ucp.webdav", "No chance to refresh lock before timeout!" );
976  }
977  }
978  return lastChanceToSendRefreshRequest;
979  }
980 
981 } // namespace
982 */
983 
984 // LOCK (set new lock)
985 
986 void SerfSession::LOCK( const OUString & inPath,
987  ucb::Lock & rLock,
988  const DAVRequestEnvironment & rEnv )
989 {
990  osl::Guard< osl::Mutex > theGuard( m_aMutex );
991 
992  Init( rEnv );
993 
994  std::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) );
995  aReqProc->processLock( rLock );
996 
997  HandleError( aReqProc );
998 }
999 
1000 
1001 // LOCK (refresh existing lock)
1002 
1003 sal_Int64 SerfSession::LOCK( const OUString & /*inPath*/,
1004  sal_Int64 nTimeout,
1005  const DAVRequestEnvironment & /*rEnv*/ )
1006 {
1007  osl::Guard< osl::Mutex > theGuard( m_aMutex );
1008 
1009  return nTimeout;
1010  /*
1011  // Try to get the neon lock from lock store
1012  SerfLock * theLock
1013  = m_aSerfLockStore.findByUri( makeAbsoluteURL( inPath ) );
1014  if ( !theLock )
1015  throw DAVException( DAVException::DAV_NOT_LOCKED );
1016 
1017  Init( rEnv );
1018 
1019  // refresh existing lock.
1020  theLock->timeout = static_cast< long >( nTimeout );
1021 
1022  TimeValue startCall;
1023  osl_getSystemTime( &startCall );
1024 
1025  int theRetVal = ne_lock_refresh( m_pHttpSession, theLock );
1026 
1027  if ( theRetVal == NE_OK )
1028  {
1029  m_aSerfLockStore.updateLock( theLock,
1030  lastChanceToSendRefreshRequest(
1031  startCall, theLock->timeout ) );
1032  }
1033 
1034  HandleError( theRetVal, inPath, rEnv );
1035 
1036  return theLock->timeout;
1037  */
1038 }
1039 
1040 
1041 // LOCK (refresh existing lock)
1042 
1043 bool SerfSession::LOCK( const OUString& rLock,
1044  sal_Int32 *plastChanceToSendRefreshRequest )
1045 {
1046  osl::Guard< osl::Mutex > theGuard( m_aMutex );
1047 
1048  std::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( rLock ) );
1049  aReqProc->processLock( ucb::Lock(), plastChanceToSendRefreshRequest );
1050 
1051  try
1052  {
1053  HandleError( aReqProc );
1054  SAL_INFO("ucb.ucp.webdav", "Refreshing LOCK of " << rLock << " succeeded." );
1055  return true;
1056  }
1057  catch(...)
1058  {
1059  SAL_INFO("ucb.ucp.webdav", "Refreshing LOCK of " << rLock << " failed!" );
1060  return false;
1061  }
1062 }
1063 
1064 
1065 // UNLOCK
1066 
1067 void SerfSession::UNLOCK( const OUString & inPath,
1068  const DAVRequestEnvironment & rEnv )
1069 {
1070  osl::Guard< osl::Mutex > theGuard( m_aMutex );
1071 
1072  Init( rEnv );
1073 
1074  std::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) );
1075  aReqProc->processUnlock();
1076 
1077  try
1078  {
1079  HandleError( aReqProc );
1080  SAL_INFO("ucb.ucp.webdav", "UNLOCK of " << inPath << " succeeded." );
1082  }
1083  catch(...)
1084  {
1085  SAL_INFO("ucb.ucp.webdav", "UNLOCK of " << inPath << " failed!" );
1086  }
1087 }
1088 
1089 
1090 // UNLOCK
1091 
1092 void SerfSession::UNLOCK( const OUString& rLock )
1093 {
1094  osl::Guard< osl::Mutex > theGuard( m_aMutex );
1095 
1096  std::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( rLock ) );
1097  aReqProc->processUnlock();
1098 
1099  try
1100  {
1101  HandleError( aReqProc );
1102  SAL_INFO("ucb.ucp.webdav", "UNLOCK of " << rLock << " succeeded." );
1103  }
1104  catch(...)
1105  {
1106  SAL_INFO("ucb.ucp.webdav", "UNLOCK of " << rLock << " failed!" );
1107  }
1108 }
1109 
1110 
1112 {
1113  // 11.11.09 (tkr): The following code lines causing crashes if
1114  // closing a ongoing connection. It turned out that this existing
1115  // solution doesn't work in multi-threading environments.
1116  // So I disabled them in 3.2. . Issue #73893# should fix it in OOo 3.3.
1117  //if ( m_pHttpSession )
1118  // ne_close_connection( m_pHttpSession );
1119 }
1120 
1121 
1123 {
1124  if ( m_aUri.GetScheme() == "http" || m_aUri.GetScheme() == "https" )
1125  {
1127  m_aUri.GetHost(),
1128  m_aUri.GetPort() );
1129  }
1130  else
1131  {
1132  // TODO: figure out, if this case can occur
1134  OUString() /* not used */,
1135  -1 /* not used */ );
1136  }
1137 }
1138 
1139 /*
1140 
1141 namespace {
1142 
1143 bool containsLocktoken( const uno::Sequence< ucb::Lock > & rLocks,
1144  const char * token )
1145 {
1146  for ( sal_Int32 n = 0; n < rLocks.getLength(); ++n )
1147  {
1148  const uno::Sequence< OUString > & rTokens
1149  = rLocks[ n ].LockTokens;
1150  for ( sal_Int32 m = 0; m < rTokens.getLength(); ++m )
1151  {
1152  if ( rTokens[ m ].equalsAscii( token ) )
1153  return true;
1154  }
1155  }
1156  return false;
1157 }
1158 
1159 } // namespace
1160 */
1161 
1162 
1163 bool SerfSession::removeExpiredLocktoken( const OUString & /*inURL*/,
1164  const DAVRequestEnvironment & /*rEnv*/ )
1165 {
1166  return true;
1167  /*
1168  SerfLock * theLock = m_aSerfLockStore.findByUri( inURL );
1169  if ( !theLock )
1170  return false;
1171 
1172  // do a lockdiscovery to check whether this lock is still valid.
1173  try
1174  {
1175  // @@@ Alternative: use ne_lock_discover() => less overhead
1176 
1177  std::vector< DAVResource > aResources;
1178  std::vector< OUString > aPropNames;
1179  aPropNames.push_back( DAVProperties::LOCKDISCOVERY );
1180 
1181  PROPFIND( rEnv.m_aRequestURI, DAVZERO, aPropNames, aResources, rEnv );
1182 
1183  if ( aResources.empty() )
1184  return false;
1185 
1186  std::vector< DAVPropertyValue >::const_iterator it
1187  = aResources[ 0 ].properties.begin();
1188  std::vector< DAVPropertyValue >::const_iterator end
1189  = aResources[ 0 ].properties.end();
1190 
1191  while ( it != end )
1192  {
1193  if ( (*it).Name.equals( DAVProperties::LOCKDISCOVERY ) )
1194  {
1195  uno::Sequence< ucb::Lock > aLocks;
1196  if ( !( (*it).Value >>= aLocks ) )
1197  return false;
1198 
1199  if ( !containsLocktoken( aLocks, theLock->token ) )
1200  {
1201  // expired!
1202  break;
1203  }
1204 
1205  // still valid.
1206  return false;
1207  }
1208  ++it;
1209  }
1210 
1211  // No lockdiscovery prop in propfind result / locktoken not found
1212  // in propfind result -> not locked
1213  SAL_INFO("ucb.ucp.webdav", "SerfSession::removeExpiredLocktoken: Removing "
1214  " expired lock token for " << inURL << ". token: " << theLock->token );
1215 
1216  m_aSerfLockStore.removeLock( theLock );
1217  ne_lock_destroy( theLock );
1218  return true;
1219  }
1220  catch ( DAVException const & )
1221  {
1222  }
1223  return false;
1224  */
1225 }
1226 
1227 
1228 // HandleError
1229 // Common Error Handler
1230 
1231 void SerfSession::HandleError( std::shared_ptr<SerfRequestProcessor> rReqProc )
1232 {
1234 
1235  if ( rReqProc->mpDAVException )
1236  {
1237  DAVException* mpDAVExp( rReqProc->mpDAVException );
1238 
1239  serf_connection_reset( getSerfConnection() );
1240 
1241  if ( mpDAVExp->getStatus() == 413 &&
1243  {
1246  }
1247 
1248  throw DAVException( mpDAVExp->getError(),
1249  mpDAVExp->getData(),
1250  mpDAVExp->getStatus() );
1251  }
1252 
1253  /*
1254  // Map error code to DAVException.
1255  switch ( nError )
1256  {
1257  case NE_OK:
1258  return;
1259 
1260  case NE_ERROR: // Generic error
1261  {
1262  OUString aText = OUString::createFromAscii(
1263  ne_get_error( m_pHttpSession ) );
1264 
1265  sal_uInt16 code = makeStatusCode( aText );
1266 
1267  if ( code == SC_LOCKED )
1268  {
1269  if ( m_aSerfLockStore.findByUri(
1270  makeAbsoluteURL( inPath ) ) == 0 )
1271  {
1272  // locked by 3rd party
1273  throw DAVException( DAVException::DAV_LOCKED );
1274  }
1275  else
1276  {
1277  // locked by ourself
1278  throw DAVException( DAVException::DAV_LOCKED_SELF );
1279  }
1280  }
1281 
1282  // Special handling for 400 and 412 status codes, which may indicate
1283  // that a lock previously obtained by us has been released meanwhile
1284  // by the server. Unfortunately, RFC is not clear at this point,
1285  // thus server implementations behave different...
1286  else if ( code == SC_BAD_REQUEST || code == SC_PRECONDITION_FAILED )
1287  {
1288  if ( removeExpiredLocktoken( makeAbsoluteURL( inPath ), rEnv ) )
1289  throw DAVException( DAVException::DAV_LOCK_EXPIRED );
1290  }
1291 
1292  throw DAVException( DAVException::DAV_HTTP_ERROR, aText, code );
1293  }
1294  case NE_LOOKUP: // Name lookup failed.
1295  throw DAVException( DAVException::DAV_HTTP_LOOKUP,
1296  SerfUri::makeConnectionEndPointString(
1297  m_aHostName, m_nPort ) );
1298 
1299  case NE_AUTH: // User authentication failed on server
1300  throw DAVException( DAVException::DAV_HTTP_AUTH,
1301  SerfUri::makeConnectionEndPointString(
1302  m_aHostName, m_nPort ) );
1303 
1304  case NE_PROXYAUTH: // User authentication failed on proxy
1305  throw DAVException( DAVException::DAV_HTTP_AUTHPROXY,
1306  SerfUri::makeConnectionEndPointString(
1307  m_aProxyName, m_nProxyPort ) );
1308 
1309  case NE_CONNECT: // Could not connect to server
1310  throw DAVException( DAVException::DAV_HTTP_CONNECT,
1311  SerfUri::makeConnectionEndPointString(
1312  m_aHostName, m_nPort ) );
1313 
1314  case NE_TIMEOUT: // Connection timed out
1315  throw DAVException( DAVException::DAV_HTTP_TIMEOUT,
1316  SerfUri::makeConnectionEndPointString(
1317  m_aHostName, m_nPort ) );
1318 
1319  case NE_FAILED: // The precondition failed
1320  throw DAVException( DAVException::DAV_HTTP_FAILED,
1321  SerfUri::makeConnectionEndPointString(
1322  m_aHostName, m_nPort ) );
1323 
1324  case NE_RETRY: // Retry request (ne_end_request ONLY)
1325  throw DAVException( DAVException::DAV_HTTP_RETRY,
1326  SerfUri::makeConnectionEndPointString(
1327  m_aHostName, m_nPort ) );
1328 
1329  case NE_REDIRECT:
1330  {
1331  SerfUri aUri( ne_redirect_location( m_pHttpSession ) );
1332  throw DAVException(
1333  DAVException::DAV_HTTP_REDIRECT, aUri.GetURI() );
1334  }
1335  default:
1336  {
1337  SAL_INFO("ucb.ucp.webdav", "SerfSession::HandleError : Unknown Serf error code!" );
1338  throw DAVException( DAVException::DAV_HTTP_ERROR,
1339  OUString::createFromAscii(
1340  ne_get_error( m_pHttpSession ) ) );
1341  }
1342  }
1343  */
1344 }
1345 
1346 
1347 // static
1348 bool
1350  const uno::Reference< io::XInputStream > & xStream,
1351  uno::Sequence< sal_Int8 > & rData,
1352  bool bAppendTrailingZeroByte )
1353 {
1354  if ( xStream.is() )
1355  {
1356  uno::Reference< io::XSeekable > xSeekable( xStream, uno::UNO_QUERY );
1357  if ( xSeekable.is() )
1358  {
1359  try
1360  {
1361  sal_Int32 nSize
1362  = sal::static_int_cast<sal_Int32>(xSeekable->getLength());
1363  sal_Int32 nRead
1364  = xStream->readBytes( rData, nSize );
1365 
1366  if ( nRead == nSize )
1367  {
1368  if ( bAppendTrailingZeroByte )
1369  {
1370  rData.realloc( nSize + 1 );
1371  rData[ nSize ] = sal_Int8( 0 );
1372  }
1373  return true;
1374  }
1375  }
1376  catch ( io::NotConnectedException const & )
1377  {
1378  // readBytes
1379  }
1380  catch ( io::BufferSizeExceededException const & )
1381  {
1382  // readBytes
1383  }
1384  catch ( io::IOException const & )
1385  {
1386  // getLength, readBytes
1387  }
1388  }
1389  else
1390  {
1391  try
1392  {
1393  uno::Sequence< sal_Int8 > aBuffer;
1394  sal_Int32 nPos = 0;
1395 
1396  sal_Int32 nRead = xStream->readSomeBytes( aBuffer, 65536 );
1397  while ( nRead > 0 )
1398  {
1399  if ( rData.getLength() < ( nPos + nRead ) )
1400  rData.realloc( nPos + nRead );
1401 
1402  aBuffer.realloc( nRead );
1403  memcpy( rData.getArray() + nPos, aBuffer.getConstArray(), nRead );
1404  nPos += nRead;
1405 
1406  aBuffer.realloc( 0 );
1407  nRead = xStream->readSomeBytes( aBuffer, 65536 );
1408  }
1409 
1410  if ( bAppendTrailingZeroByte )
1411  {
1412  rData.realloc( nPos + 1 );
1413  rData[ nPos ] = sal_Int8( 0 );
1414  }
1415  return true;
1416  }
1417  catch ( io::NotConnectedException const & )
1418  {
1419  // readBytes
1420  }
1421  catch ( io::BufferSizeExceededException const & )
1422  {
1423  // readBytes
1424  }
1425  catch ( io::IOException const & )
1426  {
1427  // readBytes
1428  }
1429  }
1430  }
1431  return false;
1432 }
1433 
1434 
1435 bool
1436 SerfSession::isDomainMatch( const OUString & certHostName )
1437 {
1438  OUString hostName = getHostName();
1439 
1440  if (hostName.equalsIgnoreAsciiCase( certHostName ) )
1441  return true;
1442 
1443  if ( certHostName.startsWith( "*" ) &&
1444  hostName.getLength() >= certHostName.getLength() )
1445  {
1446  OUString cmpStr = certHostName.copy( 1 );
1447 
1448  if ( hostName.matchIgnoreAsciiCase(
1449  cmpStr, hostName.getLength() - cmpStr.getLength() ) )
1450  return true;
1451  }
1452  return false;
1453 }
1454 
1455 /*
1456 
1457 OUString SerfSession::makeAbsoluteURL( OUString const & rURL ) const
1458 {
1459  try
1460  {
1461  // Is URL relative or already absolute?
1462  if ( rURL[ 0 ] != '/' )
1463  {
1464  // absolute.
1465  return OUString( rURL );
1466  }
1467  else
1468  {
1469  ne_uri aUri;
1470  memset( &aUri, 0, sizeof( aUri ) );
1471 
1472  ne_fill_server_uri( m_pHttpSession, &aUri );
1473  aUri.path
1474  = ne_strdup( OUStringToOString(
1475  rURL, RTL_TEXTENCODING_UTF8 ).getStr() );
1476  SerfUri aSerfUri( &aUri );
1477  ne_uri_free( &aUri );
1478  return aSerfUri.GetURI();
1479  }
1480  }
1481  catch ( DAVException const & )
1482  {
1483  }
1484  // error.
1485  return OUString();
1486 }
1487 */
1488 
1489 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Type
http_dav_ucp::SerfLockStore * getSerfLockStore()
Definition: AprEnv.cxx:57
::osl::Mutex m_aMutex
const ExceptionCode & getError() const
virtual void COPY(const OUString &inSourceURL, const OUString &inDestinationURL, const DAVRequestEnvironment &rEnv, bool inOverWrite=false) override
ucbhelper::InternetProxyServer getProxySettings() const
serf_context_t * getSerfContext()
virtual int authenticate(const OUString &inRealm, const OUString &inHostName, OUString &inoutUserName, OUString &outPassWord, bool bCanUseSystemCredentials, bool bUsePreviousCredentials=true)=0
signed char sal_Int8
const OUString & getHostName() const
apr_status_t Serf_CertificateChainValidation(void *pSerfSession, int nFailures, int, const serf_ssl_certificate_t *const *pCertificateChainBase64Encoded, apr_size_t nCertificateChainLength)
static bool removeExpiredLocktoken(const OUString &inURL, const DAVRequestEnvironment &rEnv)
virtual void HEAD(const OUString &inPath, const std::vector< OUString > &inHeaderNames, DAVResource &ioResource, const DAVRequestEnvironment &rEnv) override
apr_status_t verifySerfCertificateChain(int nFailures, const serf_ssl_certificate_t *const *pCertificateChainBase64Encoded, int nCertificateChainLength)
const OUString & getData() const
#define OID_SUBJECT_ALTERNATIVE_NAME
Definition: SerfSession.cxx:49
apr_status_t setupSerfConnection(apr_socket_t *inAprSocket, serf_bucket_t **outSerfInputBucket, serf_bucket_t **outSerfOutputBucket, apr_pool_t *inAprPool)
static bool getDataFromInputStream(const css::uno::Reference< css::io::XInputStream > &xStream, css::uno::Sequence< sal_Int8 > &rData, bool bAppendTrailingZeroByte)
virtual void PROPFIND(const OUString &inPath, const Depth inDepth, const std::vector< OUString > &inPropNames, std::vector< DAVResource > &ioResources, const DAVRequestEnvironment &rEnv) override
apr_status_t Serf_ConnectSetup(apr_socket_t *skt, serf_bucket_t **read_bkt, serf_bucket_t **write_bkt, void *setup_baton, apr_pool_t *pool)
const OUString & GetHost() const
Definition: SerfUri.hxx:73
apr_status_t Serf_Credentials(char **username, char **password, serf_request_t *request, void *baton, int code, const char *authn_type, const char *realm, apr_pool_t *pool)
serf_bucket_t * acceptSerfResponse(serf_request_t *inSerfRequest, serf_bucket_t *inSerfStreamBucket, apr_pool_t *inAprPool)
sal_Int16 m_bNoOfTransferEncodingSwitches
Definition: SerfSession.hxx:59
OUString makeConnectionEndPointString() const
Definition: SerfUri.hxx:96
sal_Int32 GetPort() const
Definition: SerfUri.hxx:75
serf_bucket_alloc_t * getSerfBktAlloc()
apr_uri_t & getAprUri()
Definition: SerfUri.hxx:63
virtual void DESTROY(const OUString &inPath, const DAVRequestEnvironment &rEnv) override
apr_status_t provideSerfCredentials(bool bGiveProvidedCredentialsASecondTry, char **outUsername, char **outPassword, serf_request_t *inRequest, int inCode, const char *inAuthProtocol, const char *inRealm, apr_pool_t *inAprPool)
serf_context_t * m_pSerfContext
Definition: SerfSession.hxx:55
static AprEnv * getAprEnv()
Definition: AprEnv.cxx:45
serf_connection_t * getSerfConnection()
virtual void abort() override
int i
virtual void PROPPATCH(const OUString &inPath, const std::vector< ProppatchValue > &inValues, const DAVRequestEnvironment &rEnv) override
void HandleError(std::shared_ptr< SerfRequestProcessor > rReqProc)
const OUString & GetPath() const
Definition: SerfUri.hxx:77
DAVRequestEnvironment m_aEnv
Definition: SerfSession.hxx:63
void removeLock(const OUString &rLock)
apr_pool_t * getAprPool()
Definition: AprEnv.cxx:52
OString OUStringToOString(const OUString &str, ConnectionSettings const *settings)
static apr_pool_t * getAprPool()
serf_bucket_alloc_t * m_pSerfBucket_Alloc
Definition: SerfSession.hxx:56
virtual void MOVE(const OUString &inSourceURL, const OUString &inDestinationURL, const DAVRequestEnvironment &rEnv, bool inOverWrite=false) override
virtual ~SerfSession() override
Definition: SerfSession.cxx:84
const OUString & GetUserInfo() const
Definition: SerfUri.hxx:71
css::uno::Sequence< DstElementType > containerToSequence(const SrcType &i_Container)
virtual css::uno::Reference< css::io::XInputStream > POST(const OUString &inPath, const OUString &rContentType, const OUString &rReferer, const css::uno::Reference< css::io::XInputStream > &inInputStream, const DAVRequestEnvironment &rEnv) override
virtual css::uno::Reference< css::io::XInputStream > GET(const OUString &inPath, const DAVRequestEnvironment &rEnv) override
#define SAL_INFO(area, stream)
rtl::Reference< DAVAuthListener > m_xAuthListener
virtual void PUT(const OUString &inPath, const css::uno::Reference< css::io::XInputStream > &inInputStream, const DAVRequestEnvironment &rEnv) override
std::vector< DAVPropertyValue > properties
Definition: DAVResource.hxx:44
virtual void LOCK(const OUString &inURL, css::ucb::Lock &inLock, const DAVRequestEnvironment &rEnv) override
const ucbhelper::InternetProxyDecider & m_rProxyDecider
Definition: SerfSession.hxx:61
virtual void UNLOCK(const OUString &inURL, const DAVRequestEnvironment &rEnv) override
virtual bool CanUse(const OUString &inUri) override
serf_connection_t * m_pSerfConnection
Definition: SerfSession.hxx:54
sal_uInt16 getStatus() const
const DAVRequestEnvironment & getRequestEnvironment() const
bool isDomainMatch(const OUString &certHostName)
virtual bool UsesProxy() override
sal_Int32 nPos
SerfRequestProcessor * createReqProc(const OUString &inPath)
const OUString & GetScheme() const
Definition: SerfUri.hxx:69
InternetProxyServer getProxy(const OUString &rProtocol, const OUString &rHost, sal_Int32 nPort) const
virtual void MKCOL(const OUString &inPath, const DAVRequestEnvironment &rEnv) override