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 <SerfHeadReqProcImpl.hxx>
26 
27 using namespace com::sun::star;
28 
29 namespace http_dav_ucp
30 {
31 
32 SerfHeadReqProcImpl::SerfHeadReqProcImpl( const char* inPath,
33                                          const std::vector< ::rtl::OUString > & inHeaderNames,
34                                          DAVResource & ioResource )
35     : SerfRequestProcessorImpl( inPath )
36     , mpHeaderNames( &inHeaderNames )
37     , mpResource( &ioResource )
38 {
39 }
40 
41 SerfHeadReqProcImpl::~SerfHeadReqProcImpl()
42 {
43 }
44 
45 serf_bucket_t * SerfHeadReqProcImpl::createSerfRequestBucket( serf_request_t * inSerfRequest )
46 {
47     serf_bucket_alloc_t* pSerfBucketAlloc = serf_request_get_alloc( inSerfRequest );
48 
49     // create serf request
50     serf_bucket_t *req_bkt = serf_request_bucket_request_create( inSerfRequest,
51                                                                  "HEAD",
52                                                                  getPathStr(),
53                                                                  0,
54                                                                  serf_request_get_alloc( inSerfRequest ) );
55 
56     // TODO - correct headers
57     // set request header fields
58     serf_bucket_t* hdrs_bkt = serf_bucket_request_get_headers( req_bkt );
59     serf_bucket_headers_setn( hdrs_bkt, "User-Agent", "www.openoffice.org/ucb/" );
60     serf_bucket_headers_setn( hdrs_bkt, "Accept-Encoding", "gzip");
61 
62     return req_bkt;
63 }
64 
65 namespace
66 {
67     apr_status_t Serf_ProcessResponseHeader( void* inUserData,
68                                              const char* inHeaderName,
69                                              const char* inHeaderValue )
70     {
71         SerfHeadReqProcImpl* pReqProcImpl = static_cast< SerfHeadReqProcImpl* >( inUserData );
72         pReqProcImpl->processSingleResponseHeader( inHeaderName,
73                                                    inHeaderValue );
74 
75         return APR_SUCCESS;
76     }
77 } // end of anonymous namespace
78 
79 bool SerfHeadReqProcImpl::processSerfResponseBucket( serf_request_t * /*inSerfRequest*/,
80                                                      serf_bucket_t * inSerfResponseBucket,
81                                                      apr_pool_t * /*inAprPool*/,
82                                                      apr_status_t & outStatus )
83 {
84     const char* data;
85     apr_size_t len;
86 
87     serf_bucket_t* SerfHeaderBucket = serf_bucket_response_get_headers( inSerfResponseBucket );
88 
89     while ( SerfHeaderBucket )
90     {
91         outStatus = serf_bucket_read(SerfHeaderBucket, 8096, &data, &len);
92         if (SERF_BUCKET_READ_ERROR(outStatus))
93         {
94             return true;
95         }
96 
97         /* are we done yet? */
98         if (APR_STATUS_IS_EOF(outStatus))
99         {
100             // read response header, if requested
101             if ( mpHeaderNames != 0 && mpResource != 0 )
102             {
103                 serf_bucket_t* SerfHeaderBucket = serf_bucket_response_get_headers( inSerfResponseBucket );
104                 if ( SerfHeaderBucket != 0 )
105                 {
106                     serf_bucket_headers_do( SerfHeaderBucket,
107                                             Serf_ProcessResponseHeader,
108                                             this );
109                 }
110             }
111 
112             outStatus = APR_EOF;
113             return true;
114         }
115 
116         /* have we drained the response so far? */
117         if ( APR_STATUS_IS_EAGAIN( outStatus ) )
118         {
119             return false;
120         }
121     }
122 
123     return true;
124 }
125 
126 void SerfHeadReqProcImpl::processSingleResponseHeader( const char* inHeaderName,
127                                                        const char* inHeaderValue )
128 {
129     rtl::OUString aHeaderName( rtl::OUString::createFromAscii( inHeaderName ) );
130 
131     bool bStoreHeaderField = false;
132 
133     if ( mpHeaderNames->size() == 0 )
134     {
135         // store all header fields
136         bStoreHeaderField = true;
137     }
138     else
139     {
140         // store only header fields which are requested
141         std::vector< ::rtl::OUString >::const_iterator it( mpHeaderNames->begin() );
142         const std::vector< ::rtl::OUString >::const_iterator end( mpHeaderNames->end() );
143 
144         while ( it != end )
145         {
146             // header names are case insensitive
147             if ( (*it).equalsIgnoreAsciiCase( aHeaderName ) )
148             {
149                 bStoreHeaderField = true;
150                 break;
151             }
152             else
153             {
154                 ++it;
155             }
156         }
157     }
158 
159     if ( bStoreHeaderField )
160     {
161         DAVPropertyValue thePropertyValue;
162         thePropertyValue.IsCaseSensitive = false;
163         thePropertyValue.Name = aHeaderName;
164         thePropertyValue.Value <<= rtl::OUString::createFromAscii( inHeaderValue );
165         mpResource->properties.push_back( thePropertyValue );
166     }
167 }
168 
169 } // namespace http_dav_ucp
170