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