LibreOffice Module ucb (master)  1
NeonHeadRequest.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
3  *
4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5  *
6  * Copyright 2000, 2010 Oracle and/or its affiliates.
7  *
8  * OpenOffice.org - a multi-platform office productivity suite
9  *
10  * This file is part of OpenOffice.org.
11  *
12  * OpenOffice.org is free software: you can redistribute it and/or modify
13  * it under the terms of the GNU Lesser General Public License version 3
14  * only, as published by the Free Software Foundation.
15  *
16  * OpenOffice.org is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU Lesser General Public License version 3 for more details
20  * (a copy is included in the LICENSE file that accompanied this code).
21  *
22  * You should have received a copy of the GNU Lesser General Public License
23  * version 3 along with OpenOffice.org. If not, see
24  * <http://www.openoffice.org/license.html>
25  * for a copy of the LGPLv3 License.
26  *
27  ************************************************************************/
28 
29 #include <osl/mutex.hxx>
30 #include <sal/log.hxx>
31 #include "NeonHeadRequest.hxx"
32 #include "NeonSession.hxx"
33 
34 using namespace webdav_ucp;
35 using namespace com::sun::star;
36 
37 namespace {
38 
39 void process_headers( ne_request * req,
40  DAVResource & rResource,
41  const std::vector< OUString > & rHeaderNames )
42 {
43  void * cursor = nullptr;
44  const char * name, *value;
45 
46 #if defined SAL_LOG_INFO
47  {
48  for ( const auto& rHeader : rHeaderNames )
49  {
50  SAL_INFO( "ucb.ucp.webdav", "HEAD - requested header: " << rHeader );
51  }
52  }
53 #endif
54  while ( ( cursor = ne_response_header_iterate( req, cursor,
55  &name, &value ) ) != nullptr ) {
56  // The HTTP header `field-name` must be a `token`, which can only contain a subset of ASCII;
57  // assume that Neon will already have rejected any invalid data, so that it is guaranteed
58  // that `name` is ASCII-only:
59  OUString aHeaderName( OUString::createFromAscii( name ) );
60  // The HTTP header `field-value` may contain obsolete (as per RFC 7230) `obs-text` non-ASCII
61  // %x80-FF octets, lets preserve them as individual characters in `aHeaderValue` by treating
62  // `value` as ISO 8859-1:
63  OUString aHeaderValue(value, strlen(value), RTL_TEXTENCODING_ISO_8859_1);
64 
65  SAL_INFO( "ucb.ucp.webdav", "HEAD - received header: " << aHeaderName << ":" << aHeaderValue);
66 
67  // Note: Empty vector means that all headers are requested.
68  bool bIncludeIt = rHeaderNames.empty();
69 
70  if ( !bIncludeIt )
71  {
72  // Check whether this header was requested.
73  auto it = std::find_if(rHeaderNames.begin(), rHeaderNames.end(),
74  [&aHeaderName](const OUString& rName) {
75  // header names are case insensitive
76  return rName.equalsIgnoreAsciiCase( aHeaderName );
77  });
78 
79  if ( it != rHeaderNames.end() )
80  {
81  aHeaderName = *it;
82  bIncludeIt = true;
83  }
84  }
85 
86  if ( bIncludeIt )
87  {
88  // Create & set the PropertyValue
89  DAVPropertyValue thePropertyValue;
90  // header names are case insensitive, so are the
91  // corresponding property names
92  thePropertyValue.Name = aHeaderName.toAsciiLowerCase();
93  thePropertyValue.IsCaseSensitive = false;
94  thePropertyValue.Value <<= aHeaderValue;
95 
96  // Add the newly created PropertyValue
97  rResource.properties.push_back( thePropertyValue );
98  }
99  }
100 }
101 
102 } // namespace
103 
105  const OUString & inPath,
106  const std::vector< OUString > &
107  inHeaderNames,
108  DAVResource & ioResource,
109  int & nError )
110 {
111  ioResource.uri = inPath;
112  ioResource.properties.clear();
113 
114  // Create and dispatch HEAD request. Install catcher for all response
115  // header fields.
116  ne_request * req = ne_request_create( inSession,
117  "HEAD",
119  inPath,
120  RTL_TEXTENCODING_UTF8 ).getStr() );
121 
122  {
123  osl::Guard< osl::Mutex > theGlobalGuard(getGlobalNeonMutex());
124  nError = ne_request_dispatch( req );
125  }
126 
127  process_headers( req, ioResource, inHeaderNames );
128 
129  if ( nError == NE_OK && ne_get_status( req )->klass != 2 )
130  nError = NE_ERROR;
131 
132  ne_request_destroy( req );
133 }
134 
136 {
137 }
138 
139 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
ne_session HttpSession
Definition: NeonTypes.hxx:47
NeonHeadRequest(HttpSession *inSession, const OUString &inPath, const std::vector< OUString > &inHeaderNames, DAVResource &ioResource, int &nError)
osl::Mutex & getGlobalNeonMutex()
OString OUStringToOString(const OUString &str, ConnectionSettings const *settings)
std::vector< DAVPropertyValue > properties
#define SAL_INFO(area, stream)
const char * name
Any value