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 #ifndef INCLUDED_CURLREQUEST_HXX 23 #define INCLUDED_CURLREQUEST_HXX 24 25 #include <vector> 26 #include "DAVException.hxx" 27 #include <com/sun/star/io/XOutputStream.hpp> 28 #include "CurlInputStream.hxx" 29 #include "CurlTypes.hxx" 30 #include "CurlUri.hxx" 31 #include <curl/curl.h> 32 33 namespace http_dav_ucp 34 { 35 36 /* Since Curl persists all settings for the duration of 37 * the CURL* structure, and we need some of them to only last for 38 * the duration of a request, use this class to reset the short-lived 39 * settings at the end of each request using RAII, and to capture 40 * some results in a convenient format. 41 * 42 * Features are opt-in to their non-default values. 43 * 44 * External pointers (CURL*, request body, etc.) are only shared with us, 45 * never copied, temporarily used by us, and never belong to us. 46 */ 47 class CurlRequest 48 { 49 public: 50 class Header 51 { 52 public: 53 rtl::OString name; 54 rtl::OString value; 55 }; 56 57 CurlRequest( CURL *curl ); 58 ~CurlRequest(); 59 60 // Request setup methods: 61 void addHeader( const rtl::OString &name, const rtl::OString &value ) throw (DAVException); 62 void setRequestBody( const char *body, size_t size ); isChunkedEncoding()63 bool isChunkedEncoding() { return useChunkedEncoding; } setChunkedEncoding(bool isChunkedEncoding)64 void setChunkedEncoding( bool isChunkedEncoding ) { useChunkedEncoding = isChunkedEncoding; } 65 void saveResponseBodyTo( const com::sun::star::uno::Reference< com::sun::star::io::XOutputStream > & xOutputStream ); 66 void setProvideCredentialsCallback( 67 bool (*provideCredsCallback)(long statusCode, void *userdata) throw (DAVException), 68 void *credsUserdata ); 69 70 // Requests 71 CURLcode copy( CurlUri uri, rtl::OUString path ) throw(DAVException); 72 CURLcode delete_( CurlUri uri, rtl::OUString path ) throw(DAVException); 73 CURLcode get( CurlUri uri, rtl::OUString path ) throw(DAVException); 74 CURLcode head( CurlUri uri, rtl::OUString path ) throw(DAVException); 75 CURLcode lock( CurlUri uri, rtl::OUString path ) throw(DAVException); 76 CURLcode mkcol( CurlUri uri, rtl::OUString path ) throw(DAVException); 77 CURLcode move( CurlUri uri, rtl::OUString path ) throw(DAVException); 78 CURLcode post( CurlUri uri, rtl::OUString path ) throw(DAVException); 79 CURLcode propfind( CurlUri uri, rtl::OUString path ) throw(DAVException); 80 CURLcode proppatch( CurlUri uri, rtl::OUString path ) throw(DAVException); 81 CURLcode put( CurlUri uri, rtl::OUString path ) throw(DAVException); 82 CURLcode unlock( CurlUri uri, rtl::OUString path ) throw(DAVException); 83 84 // Response methods: getStatusCode()85 int getStatusCode() { return statusCode; } getReasonPhrase()86 rtl::OString& getReasonPhrase() { return reasonPhrase; } 87 // TODO: a multimap would be O(n * log(m)) instead of O(n * m) getResponseHeaders()88 std::vector<Header>& getResponseHeaders() { return responseHeaders; } 89 const Header *findResponseHeader( const rtl::OString &name ); getResponseBody()90 com::sun::star::uno::Reference < CurlInputStream > getResponseBody() { return responseBodyInputStream; } 91 92 private: 93 CurlRequest( const CurlRequest &curlRequest ); // No copy constructor. 94 void setURI( CurlUri uri, rtl::OUString path ) throw (DAVException); 95 CURLcode perform() throw (DAVException); 96 97 static int Curl_SeekCallback(void *userp, curl_off_t offset, int origin); 98 99 static size_t Curl_SendMoreBody( char *buffer, size_t size, size_t nitems, void *userdata ); 100 size_t curlSendMoreBody( char *buffer, size_t len ); 101 102 static size_t Curl_HeaderReceived( char *buffer, size_t size, size_t nitems, void *userdata ); 103 void curlHeaderReceived( const char *buffer, size_t len ); 104 105 static size_t Curl_MoreBodyReceived( char *buffer, size_t size, size_t nitems, void *userdata ); 106 void curlMoreBodyReceived( const char *buffer, size_t len ); 107 108 CURL *curl; 109 CURLU *curlUrl; 110 111 // Request values: 112 curl_slist *requestHeaders; 113 const char *requestBody; 114 size_t requestBodyOffset; 115 size_t requestBodySize; 116 bool useChunkedEncoding; 117 bool (*provideCredentialsCallback)( long statusCode, void *userdata ) throw (DAVException); 118 void *provideCredentialsUserdata; 119 120 // Response values: 121 rtl::OString reasonPhrase; 122 int statusCode; 123 std::vector<Header> responseHeaders; 124 com::sun::star::uno::Reference < CurlInputStream > responseBodyInputStream; 125 com::sun::star::uno::Reference< com::sun::star::io::XOutputStream > xOutputStream; 126 }; 127 128 } // namespace http_dav_ucp 129 130 #endif // INCLUDED_CURLREQUEST_HXX