xref: /AOO41X/main/ucb/source/ucp/webdav/SerfPropPatchReqProcImpl.cxx (revision 8590a0fdd306f78ee72b863c64cbcf09c28509eb)
1*8590a0fdSAndre Fischer /**************************************************************
2*8590a0fdSAndre Fischer  *
3*8590a0fdSAndre Fischer  * Licensed to the Apache Software Foundation (ASF) under one
4*8590a0fdSAndre Fischer  * or more contributor license agreements.  See the NOTICE file
5*8590a0fdSAndre Fischer  * distributed with this work for additional information
6*8590a0fdSAndre Fischer  * regarding copyright ownership.  The ASF licenses this file
7*8590a0fdSAndre Fischer  * to you under the Apache License, Version 2.0 (the
8*8590a0fdSAndre Fischer  * "License"); you may not use this file except in compliance
9*8590a0fdSAndre Fischer  * with the License.  You may obtain a copy of the License at
10*8590a0fdSAndre Fischer  *
11*8590a0fdSAndre Fischer  *   http://www.apache.org/licenses/LICENSE-2.0
12*8590a0fdSAndre Fischer  *
13*8590a0fdSAndre Fischer  * Unless required by applicable law or agreed to in writing,
14*8590a0fdSAndre Fischer  * software distributed under the License is distributed on an
15*8590a0fdSAndre Fischer  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*8590a0fdSAndre Fischer  * KIND, either express or implied.  See the License for the
17*8590a0fdSAndre Fischer  * specific language governing permissions and limitations
18*8590a0fdSAndre Fischer  * under the License.
19*8590a0fdSAndre Fischer  *
20*8590a0fdSAndre Fischer  *************************************************************/
21*8590a0fdSAndre Fischer 
22*8590a0fdSAndre Fischer // MARKER(update_precomp.py): autogen include statement, do not remove
23*8590a0fdSAndre Fischer #include "precompiled_ucb.hxx"
24*8590a0fdSAndre Fischer 
25*8590a0fdSAndre Fischer #include <rtl/ustring.hxx>
26*8590a0fdSAndre Fischer #include <DAVProperties.hxx>
27*8590a0fdSAndre Fischer #include <UCBDeadPropertyValue.hxx>
28*8590a0fdSAndre Fischer 
29*8590a0fdSAndre Fischer #include <SerfPropPatchReqProcImpl.hxx>
30*8590a0fdSAndre Fischer #include <SerfTypes.hxx>
31*8590a0fdSAndre Fischer 
32*8590a0fdSAndre Fischer namespace http_dav_ucp
33*8590a0fdSAndre Fischer {
34*8590a0fdSAndre Fischer 
35*8590a0fdSAndre Fischer SerfPropPatchReqProcImpl::SerfPropPatchReqProcImpl( const char* inPath,
36*8590a0fdSAndre Fischer                                                     const std::vector< ProppatchValue > & inProperties )
37*8590a0fdSAndre Fischer     : SerfRequestProcessorImpl( inPath )
38*8590a0fdSAndre Fischer     , mpProperties( &inProperties )
39*8590a0fdSAndre Fischer {
40*8590a0fdSAndre Fischer }
41*8590a0fdSAndre Fischer 
42*8590a0fdSAndre Fischer SerfPropPatchReqProcImpl::~SerfPropPatchReqProcImpl()
43*8590a0fdSAndre Fischer {
44*8590a0fdSAndre Fischer }
45*8590a0fdSAndre Fischer 
46*8590a0fdSAndre Fischer #define PROPPATCH_HEADER "<?xml version=\"1.0\" encoding=\"utf-8\"?><propertyupdate xmlns=\"DAV:\">"
47*8590a0fdSAndre Fischer #define PROPPATCH_TRAILER "</propertyupdate>"
48*8590a0fdSAndre Fischer 
49*8590a0fdSAndre Fischer serf_bucket_t * SerfPropPatchReqProcImpl::createSerfRequestBucket( serf_request_t * inSerfRequest )
50*8590a0fdSAndre Fischer {
51*8590a0fdSAndre Fischer     serf_bucket_alloc_t* pSerfBucketAlloc = serf_request_get_alloc( inSerfRequest );
52*8590a0fdSAndre Fischer 
53*8590a0fdSAndre Fischer     // body bucket
54*8590a0fdSAndre Fischer     serf_bucket_t* body_bkt = 0;
55*8590a0fdSAndre Fischer     rtl::OUString aBodyText;
56*8590a0fdSAndre Fischer     {
57*8590a0fdSAndre Fischer         // create and fill body bucket with properties to be set or removed
58*8590a0fdSAndre Fischer         static const char* OpCodes[2] = { "set", "remove" };
59*8590a0fdSAndre Fischer         const int nPropCount = ( mpProperties != 0 )
60*8590a0fdSAndre Fischer                                ? mpProperties->size()
61*8590a0fdSAndre Fischer                                : 0;
62*8590a0fdSAndre Fischer         if ( nPropCount > 0 )
63*8590a0fdSAndre Fischer         {
64*8590a0fdSAndre Fischer             // <*operation code*><prop>
65*8590a0fdSAndre Fischer             ProppatchOperation lastOp = (*mpProperties)[ 0 ].operation;
66*8590a0fdSAndre Fischer             aBodyText += rtl::OUString::createFromAscii( "<" );
67*8590a0fdSAndre Fischer             aBodyText += rtl::OUString::createFromAscii( OpCodes[lastOp] );
68*8590a0fdSAndre Fischer             aBodyText += rtl::OUString::createFromAscii( "><prop>" );
69*8590a0fdSAndre Fischer 
70*8590a0fdSAndre Fischer             SerfPropName thePropName;
71*8590a0fdSAndre Fischer             for ( int n = 0; n < nPropCount; ++n )
72*8590a0fdSAndre Fischer             {
73*8590a0fdSAndre Fischer                 const ProppatchValue & rProperty = (*mpProperties)[ n ];
74*8590a0fdSAndre Fischer                 // split fullname into namespace and name!
75*8590a0fdSAndre Fischer                 DAVProperties::createSerfPropName( rProperty.name,
76*8590a0fdSAndre Fischer                                                    thePropName );
77*8590a0fdSAndre Fischer 
78*8590a0fdSAndre Fischer                 if ( rProperty.operation != lastOp )
79*8590a0fdSAndre Fischer                 {
80*8590a0fdSAndre Fischer                     // </prop></*last operation code*><*operation code><prop>
81*8590a0fdSAndre Fischer                     aBodyText += rtl::OUString::createFromAscii( "</prop></" );
82*8590a0fdSAndre Fischer                     aBodyText += rtl::OUString::createFromAscii( OpCodes[lastOp] );
83*8590a0fdSAndre Fischer                     aBodyText += rtl::OUString::createFromAscii( "><" );
84*8590a0fdSAndre Fischer                     aBodyText += rtl::OUString::createFromAscii( OpCodes[rProperty.operation] );
85*8590a0fdSAndre Fischer                     aBodyText += rtl::OUString::createFromAscii( "><prop>" );
86*8590a0fdSAndre Fischer                 }
87*8590a0fdSAndre Fischer 
88*8590a0fdSAndre Fischer                 // <*propname* xmlns="*propns*"
89*8590a0fdSAndre Fischer                 aBodyText += rtl::OUString::createFromAscii( "<" );
90*8590a0fdSAndre Fischer                 aBodyText += rtl::OUString::createFromAscii( thePropName.name );
91*8590a0fdSAndre Fischer                 aBodyText += rtl::OUString::createFromAscii( " xmlns=\"" );
92*8590a0fdSAndre Fischer                 aBodyText += rtl::OUString::createFromAscii( thePropName.nspace );
93*8590a0fdSAndre Fischer                 aBodyText += rtl::OUString::createFromAscii( "\"" );
94*8590a0fdSAndre Fischer 
95*8590a0fdSAndre Fischer                 if ( rProperty.operation == PROPSET )
96*8590a0fdSAndre Fischer                 {
97*8590a0fdSAndre Fischer                     // >*property value*</*propname*>
98*8590a0fdSAndre Fischer                     aBodyText += rtl::OUString::createFromAscii( ">" );
99*8590a0fdSAndre Fischer 
100*8590a0fdSAndre Fischer                     rtl::OUString aStringValue;
101*8590a0fdSAndre Fischer                     if ( DAVProperties::isUCBDeadProperty( thePropName ) )
102*8590a0fdSAndre Fischer                     {
103*8590a0fdSAndre Fischer                         UCBDeadPropertyValue::toXML( rProperty.value,
104*8590a0fdSAndre Fischer                                                      aStringValue );
105*8590a0fdSAndre Fischer                     }
106*8590a0fdSAndre Fischer                     else
107*8590a0fdSAndre Fischer                     {
108*8590a0fdSAndre Fischer                         rProperty.value >>= aStringValue;
109*8590a0fdSAndre Fischer                     }
110*8590a0fdSAndre Fischer                     aBodyText += aStringValue;
111*8590a0fdSAndre Fischer                     aBodyText += rtl::OUString::createFromAscii( "</" );
112*8590a0fdSAndre Fischer                     aBodyText += rtl::OUString::createFromAscii( thePropName.name );
113*8590a0fdSAndre Fischer                     aBodyText += rtl::OUString::createFromAscii( ">" );
114*8590a0fdSAndre Fischer                 }
115*8590a0fdSAndre Fischer                 else
116*8590a0fdSAndre Fischer                 {
117*8590a0fdSAndre Fischer                     // />
118*8590a0fdSAndre Fischer                     aBodyText += rtl::OUString::createFromAscii( "/>" );
119*8590a0fdSAndre Fischer                 }
120*8590a0fdSAndre Fischer 
121*8590a0fdSAndre Fischer                 lastOp = rProperty.operation;
122*8590a0fdSAndre Fischer             }
123*8590a0fdSAndre Fischer 
124*8590a0fdSAndre Fischer             // </prop></*last operation code*>
125*8590a0fdSAndre Fischer             aBodyText += rtl::OUString::createFromAscii( "</prop></" );
126*8590a0fdSAndre Fischer             aBodyText += rtl::OUString::createFromAscii( OpCodes[lastOp] );
127*8590a0fdSAndre Fischer             aBodyText += rtl::OUString::createFromAscii( ">" );
128*8590a0fdSAndre Fischer 
129*8590a0fdSAndre Fischer             // add PropPatch xml header in front
130*8590a0fdSAndre Fischer             aBodyText = rtl::OUString::createFromAscii( PROPPATCH_HEADER ) + aBodyText;
131*8590a0fdSAndre Fischer 
132*8590a0fdSAndre Fischer             // add PropPatch xml trailer at end
133*8590a0fdSAndre Fischer             aBodyText += rtl::OUString::createFromAscii( PROPPATCH_TRAILER );
134*8590a0fdSAndre Fischer 
135*8590a0fdSAndre Fischer             const char* pTestValue = rtl::OUStringToOString( aBodyText, RTL_TEXTENCODING_UTF8 );
136*8590a0fdSAndre Fischer             body_bkt = SERF_BUCKET_SIMPLE_STRING( rtl::OUStringToOString( aBodyText, RTL_TEXTENCODING_UTF8 ),
137*8590a0fdSAndre Fischer                                                   pSerfBucketAlloc );
138*8590a0fdSAndre Fischer         }
139*8590a0fdSAndre Fischer     }
140*8590a0fdSAndre Fischer 
141*8590a0fdSAndre Fischer     // create serf request
142*8590a0fdSAndre Fischer     serf_bucket_t *req_bkt = serf_request_bucket_request_create( inSerfRequest,
143*8590a0fdSAndre Fischer                                                                  "PROPPATCH",
144*8590a0fdSAndre Fischer                                                                  getPathStr(),
145*8590a0fdSAndre Fischer                                                                  body_bkt,
146*8590a0fdSAndre Fischer                                                                  serf_request_get_alloc( inSerfRequest ) );
147*8590a0fdSAndre Fischer 
148*8590a0fdSAndre Fischer     // TODO - correct header data
149*8590a0fdSAndre Fischer     // set request header fields
150*8590a0fdSAndre Fischer     serf_bucket_t* hdrs_bkt = serf_bucket_request_get_headers( req_bkt );
151*8590a0fdSAndre Fischer     serf_bucket_headers_setn( hdrs_bkt, "User-Agent", "www.openoffice.org/ucb/" );
152*8590a0fdSAndre Fischer     serf_bucket_headers_setn( hdrs_bkt, "Accept-Encoding", "gzip");
153*8590a0fdSAndre Fischer 
154*8590a0fdSAndre Fischer     // request specific header fields
155*8590a0fdSAndre Fischer     if ( body_bkt != 0 && aBodyText.getLength() > 0 )
156*8590a0fdSAndre Fischer     {
157*8590a0fdSAndre Fischer         serf_bucket_headers_setn( hdrs_bkt, "Content-Type", "application/xml" );
158*8590a0fdSAndre Fischer         serf_bucket_headers_setn( hdrs_bkt, "Content-Length",
159*8590a0fdSAndre Fischer                                   rtl::OUStringToOString( rtl::OUString::valueOf( aBodyText.getLength() ), RTL_TEXTENCODING_UTF8 ) );
160*8590a0fdSAndre Fischer     }
161*8590a0fdSAndre Fischer 
162*8590a0fdSAndre Fischer     return req_bkt;
163*8590a0fdSAndre Fischer }
164*8590a0fdSAndre Fischer 
165*8590a0fdSAndre Fischer 
166*8590a0fdSAndre Fischer bool SerfPropPatchReqProcImpl::processSerfResponseBucket( serf_request_t * /*inSerfRequest*/,
167*8590a0fdSAndre Fischer                                                          serf_bucket_t * inSerfResponseBucket,
168*8590a0fdSAndre Fischer                                                          apr_pool_t * /*inAprPool*/,
169*8590a0fdSAndre Fischer                                                          apr_status_t & outStatus )
170*8590a0fdSAndre Fischer {
171*8590a0fdSAndre Fischer     const char* data;
172*8590a0fdSAndre Fischer     apr_size_t len;
173*8590a0fdSAndre Fischer 
174*8590a0fdSAndre Fischer     while (1) {
175*8590a0fdSAndre Fischer         outStatus = serf_bucket_read(inSerfResponseBucket, 2048, &data, &len);
176*8590a0fdSAndre Fischer         if (SERF_BUCKET_READ_ERROR(outStatus))
177*8590a0fdSAndre Fischer         {
178*8590a0fdSAndre Fischer             return true;
179*8590a0fdSAndre Fischer         }
180*8590a0fdSAndre Fischer 
181*8590a0fdSAndre Fischer         /* are we done yet? */
182*8590a0fdSAndre Fischer         if (APR_STATUS_IS_EOF(outStatus))
183*8590a0fdSAndre Fischer         {
184*8590a0fdSAndre Fischer             outStatus = APR_EOF;
185*8590a0fdSAndre Fischer             return true;
186*8590a0fdSAndre Fischer         }
187*8590a0fdSAndre Fischer 
188*8590a0fdSAndre Fischer         /* have we drained the response so far? */
189*8590a0fdSAndre Fischer         if ( APR_STATUS_IS_EAGAIN( outStatus ) )
190*8590a0fdSAndre Fischer         {
191*8590a0fdSAndre Fischer             return false;
192*8590a0fdSAndre Fischer         }
193*8590a0fdSAndre Fischer     }
194*8590a0fdSAndre Fischer 
195*8590a0fdSAndre Fischer     /* NOTREACHED */
196*8590a0fdSAndre Fischer     return true;
197*8590a0fdSAndre Fischer }
198*8590a0fdSAndre Fischer 
199*8590a0fdSAndre Fischer } // namespace http_dav_ucp
200