1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 // MARKER(update_precomp.py): autogen include statement, do not remove
23 #include "precompiled_ucb.hxx"
24 
25 #include <SerfPostReqProcImpl.hxx>
26 
27 #include <serf.h>
28 
29 using namespace com::sun::star;
30 
31 namespace http_dav_ucp
32 {
33 
34 SerfPostReqProcImpl::SerfPostReqProcImpl( const char* inPath,
35                                           const char* inData,
36                                           apr_size_t inDataLen,
37                                           const char* inContentType,
38                                           const char* inReferer,
39                                           const com::sun::star::uno::Reference< SerfInputStream > & xioInStrm )
40     : SerfRequestProcessorImpl( inPath )
41     , mpPostData( inData )
42     , mnPostDataLen( inDataLen )
43     , mpContentType( inContentType )
44     , mpReferer( inReferer )
45     , xInputStream( xioInStrm )
46     , xOutputStream()
47 {
48 }
49 
50 SerfPostReqProcImpl::SerfPostReqProcImpl( const char* inPath,
51                                           const char* inData,
52                                           apr_size_t inDataLen,
53                                           const char* inContentType,
54                                           const char* inReferer,
55                                           const com::sun::star::uno::Reference< com::sun::star::io::XOutputStream > & xioOutStrm )
56     : SerfRequestProcessorImpl( inPath )
57     , mpPostData( inData )
58     , mnPostDataLen( inDataLen )
59     , mpContentType( inContentType )
60     , mpReferer( inReferer )
61     , xInputStream()
62     , xOutputStream( xioOutStrm )
63 {
64 }
65 
66 SerfPostReqProcImpl::~SerfPostReqProcImpl()
67 {
68 }
69 
70 serf_bucket_t * SerfPostReqProcImpl::createSerfRequestBucket( serf_request_t * inSerfRequest )
71 {
72     serf_bucket_alloc_t* pSerfBucketAlloc = serf_request_get_alloc( inSerfRequest );
73 
74     // create body bucket
75     serf_bucket_t* body_bkt = 0;
76     if ( mpPostData != 0 && mnPostDataLen > 0 )
77     {
78         body_bkt = SERF_BUCKET_SIMPLE_STRING_LEN( mpPostData, mnPostDataLen, pSerfBucketAlloc );
79     }
80 
81     // create serf request
82     serf_bucket_t *req_bkt = serf_request_bucket_request_create( inSerfRequest,
83                                                                  "POST",
84                                                                  getPathStr(),
85                                                                  body_bkt,
86                                                                  serf_request_get_alloc( inSerfRequest ) );
87 
88     // TODO - correct headers
89     // set request header fields
90     serf_bucket_t* hdrs_bkt = serf_bucket_request_get_headers( req_bkt );
91     serf_bucket_headers_setn( hdrs_bkt, "User-Agent", "www.openoffice.org/ucb/" );
92     serf_bucket_headers_setn( hdrs_bkt, "Accept-Encoding", "gzip");
93 
94     // request specific header fields
95     if ( body_bkt != 0 )
96     {
97         serf_bucket_headers_setn( hdrs_bkt, "Content-Length",
98                                   rtl::OUStringToOString( rtl::OUString::valueOf( (sal_Int32)mnPostDataLen ), RTL_TEXTENCODING_UTF8 ) );
99     }
100     if ( mpContentType != 0 )
101     {
102         serf_bucket_headers_setn( hdrs_bkt, "Content-Type", mpContentType );
103     }
104     if ( mpReferer != 0 )
105     {
106         serf_bucket_headers_setn( hdrs_bkt, "Referer", mpReferer );
107     }
108 
109     return req_bkt;
110 }
111 
112 
113 bool SerfPostReqProcImpl::processSerfResponseBucket( serf_request_t * /*inSerfRequest*/,
114                                                     serf_bucket_t * inSerfResponseBucket,
115                                                     apr_pool_t * /*inAprPool*/,
116                                                     apr_status_t & outStatus )
117 {
118     const char* data;
119     apr_size_t len;
120 
121     while (1) {
122         outStatus = serf_bucket_read(inSerfResponseBucket, 8096, &data, &len);
123         if (SERF_BUCKET_READ_ERROR(outStatus))
124         {
125             return true;
126         }
127 
128         if ( len > 0 )
129         {
130             if ( xInputStream.is() )
131             {
132                 xInputStream->AddToStream( data, len );
133             }
134             else if ( xOutputStream.is() )
135             {
136                 const uno::Sequence< sal_Int8 > aDataSeq( (sal_Int8 *)data, len );
137                 xOutputStream->writeBytes( aDataSeq );
138             }
139         }
140 
141         /* are we done yet? */
142         if (APR_STATUS_IS_EOF(outStatus))
143         {
144             outStatus = APR_EOF;
145             return true;
146         }
147 
148         /* have we drained the response so far? */
149         if ( APR_STATUS_IS_EAGAIN( outStatus ) )
150         {
151             return false;
152         }
153     }
154 
155     /* NOTREACHED */
156     return true;
157 }
158 
159 } // namespace http_dav_ucp
160