LibreOffice Module ucb (master)  1
SerfPropPatchReqProcImpl.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 <rtl/ustring.hxx>
21 #include <rtl/ustrbuf.hxx>
22 #include "DAVProperties.hxx"
23 #include "UCBDeadPropertyValue.hxx"
24 
26 
27 namespace http_dav_ucp
28 {
29 
31  const DAVRequestHeaders& inRequestHeaders,
32  const std::vector< ProppatchValue > & inProperties )
33  : SerfRequestProcessorImpl( inPath, inRequestHeaders )
34  , mpProperties( &inProperties )
35 {
36 }
37 
39 {
40 }
41 
42 #define PROPPATCH_HEADER "<?xml version=\"1.0\" encoding=\"utf-8\"?><propertyupdate xmlns=\"DAV:\">"
43 #define PROPPATCH_TRAILER "</propertyupdate>"
44 
45 serf_bucket_t * SerfPropPatchReqProcImpl::createSerfRequestBucket( serf_request_t * inSerfRequest )
46 {
47  serf_bucket_alloc_t* pSerfBucketAlloc = serf_request_get_alloc( inSerfRequest );
48 
49  // body bucket
50  serf_bucket_t* body_bkt = nullptr;
51  OString aBodyText;
52  {
53  // create and fill body bucket with properties to be set or removed
54  static const struct
55  {
56  const char *str;
57  sal_Int32 len;
58  }
59  OpCode [] = {
60  { RTL_CONSTASCII_STRINGPARAM( "set" ) },
61  { RTL_CONSTASCII_STRINGPARAM( "remove" ) }
62  };
63  const int nPropCount = ( mpProperties != nullptr )
64  ? mpProperties->size()
65  : 0;
66  if ( nPropCount > 0 )
67  {
68  OUStringBuffer aBuffer;
69  // add PropPatch xml header in front
70  aBuffer.append( PROPPATCH_HEADER );
71 
72  // <*operation code*><prop>
73 
74  ProppatchOperation lastOp = (*mpProperties)[ 0 ].operation;
75  aBuffer.append( "<" );
76  aBuffer.appendAscii( OpCode[lastOp].str, OpCode[lastOp].len );
77  aBuffer.append( "><prop>" );
78 
79  SerfPropName thePropName;
80  for ( int n = 0; n < nPropCount; ++n )
81  {
82  const ProppatchValue & rProperty = (*mpProperties)[ n ];
83  // split fullname into namespace and name!
85  thePropName );
86 
87  if ( rProperty.operation != lastOp )
88  {
89  // </prop></*last operation code*><*operation code><prop>
90  aBuffer.append( "</prop></" );
91  aBuffer.appendAscii( OpCode[lastOp].str, OpCode[lastOp].len );
92  aBuffer.append( "><" );
93  aBuffer.appendAscii( OpCode[rProperty.operation].str, OpCode[rProperty.operation].len );
94  aBuffer.append( "><prop>" );
95  }
96 
97  // <*propname* xmlns="*propns*"
98  aBuffer.append( "<" );
99  aBuffer.appendAscii( thePropName.name );
100  aBuffer.append( " xmlns=\"" );
101  aBuffer.appendAscii( thePropName.nspace );
102  aBuffer.append( "\"" );
103 
104  if ( rProperty.operation == PROPSET )
105  {
106  // >*property value*</*propname*>
107  aBuffer.append( ">" );
108 
109  OUString aStringValue;
110  if ( DAVProperties::isUCBDeadProperty( thePropName ) )
111  {
113  aStringValue );
114  }
115  else
116  {
117  rProperty.value >>= aStringValue;
118  }
119  aBuffer.append( aStringValue );
120  aBuffer.append( "</" );
121  aBuffer.appendAscii( thePropName.name );
122  aBuffer.append( ">" );
123  }
124  else
125  {
126  aBuffer.append( "/>" );
127  }
128 
129  lastOp = rProperty.operation;
130  }
131 
132  // </prop></*last operation code*>
133  aBuffer.append( "</prop></" );
134  aBuffer.appendAscii( OpCode[lastOp].str, OpCode[lastOp].len );
135  aBuffer.append( ">" );
136 
137  // add PropPatch xml trailer at end
138  aBuffer.append( PROPPATCH_TRAILER );
139 
140  aBodyText = OUStringToOString( aBuffer.makeStringAndClear(), RTL_TEXTENCODING_UTF8 );
141  body_bkt = serf_bucket_simple_copy_create( aBodyText.getStr(),
142  aBodyText.getLength(),
143  pSerfBucketAlloc );
144  }
145  }
146 
147  // create serf request
148  serf_bucket_t *req_bkt = serf_request_bucket_request_create( inSerfRequest,
149  "PROPPATCH",
150  getPathStr(),
151  body_bkt,
152  pSerfBucketAlloc ) ;
153  handleChunkedEncoding(req_bkt, aBodyText.getLength());
154 
155  // set request header fields
156  serf_bucket_t* hdrs_bkt = serf_bucket_request_get_headers( req_bkt );
157  if (hdrs_bkt != nullptr)
158  {
159  // general header fields provided by caller
160  setRequestHeaders( hdrs_bkt );
161 
162  // request specific header fields
163  if ( body_bkt != nullptr && aBodyText.getLength() > 0 )
164  {
165  serf_bucket_headers_set( hdrs_bkt, "Content-Type", "application/xml" );
166  }
167  }
168  else
169  {
170  assert(!"Headers Bucket missing");
171  }
172 
173  return req_bkt;
174 }
175 
177  apr_size_t /*len*/ )
178 {
179  // nothing to do;
180 }
181 
182 void SerfPropPatchReqProcImpl::handleEndOfResponseData( serf_bucket_t * /*inSerfResponseBucket*/ )
183 {
184  // nothing to do;
185 }
186 
187 } // namespace http_dav_ucp
188 
189 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
std::vector< DAVRequestHeader > DAVRequestHeaders
virtual serf_bucket_t * createSerfRequestBucket(serf_request_t *inSerfRequest) override
ProppatchOperation operation
Definition: DAVTypes.hxx:66
void setRequestHeaders(serf_bucket_t *inoutSerfHeaderBucket)
virtual void handleEndOfResponseData(serf_bucket_t *inSerfResponseBucket) override
#define PROPPATCH_HEADER
virtual void processChunkOfResponseData(const char *data, apr_size_t len) override
OpCode
void handleChunkedEncoding(serf_bucket_t *pRequestBucket, apr_int64_t nLength) const
Turn chunked encoding on or off, depending on the result of useChunkedEncoding(). ...
static bool isUCBDeadProperty(const SerfPropName &rName)
SerfPropPatchReqProcImpl(const char *inPath, const DAVRequestHeaders &inRequestHeaders, const std::vector< ProppatchValue > &inProperties)
static void createSerfPropName(const OUString &rFullName, SerfPropName &rName)
const std::vector< ProppatchValue > * mpProperties
static bool toXML(const css::uno::Any &rInData, OUString &rOutData)
OString OUStringToOString(const OUString &str, ConnectionSettings const *settings)
#define PROPPATCH_TRAILER