Rework support for libcurl-based input to parser.
[shibboleth/cpp-xmltooling.git] / xmltooling / util / CurlURLInputStream.h
1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements.  See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License.  You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17
18 /**
19  * @file xmltooling/util/CurlURLInputStream.h
20  *
21  * Asynchronous use of curl to fetch data from a URL.
22  */
23
24 #if !defined(__xmltooling_curlinstr_h__) && !defined(XMLTOOLING_LITE)
25 #define __xmltooling_curlinstr_h__
26
27 #include <xmltooling/logging.h>
28
29 #include <curl/curl.h>
30 #include <xercesc/util/BinInputStream.hpp>
31
32 namespace xmltooling {
33
34     /**
35      * Adapted from Xerces-C as a more advanced input stream implementation
36      * for subsequent use in parsing remote documents.
37      */
38     class XMLTOOL_API CurlURLInputStream : public xercesc::BinInputStream
39     {
40     public :
41         /**
42          * Constructor.
43          *
44          * @param url   the URL of the resource to fetch
45          */
46         CurlURLInputStream(const char* url);
47
48         /**
49          * Constructor.
50          *
51          * @param url   the URL of the resource to fetch
52          */
53         CurlURLInputStream(const XMLCh* url);
54
55         /**
56          * Constructor taking a DOM element supporting the following content:
57          * 
58          * <dl>
59          *  <dt>uri | url</dt>
60          *  <dd>identifies the remote resource</dd>
61          *  <dt>verifyHost</dt>
62          *  <dd>true iff name of host should be matched against TLS/SSL certificate</dd>
63          *  <dt>TransportOption elements, like so:</dt>
64          *  <dd>&lt;TransportOption provider="CURL" option="150"&gt;0&lt;/TransportOption&gt;</dd>
65          * </dl>
66          * 
67          * @param e     DOM to supply configuration
68          */
69         CurlURLInputStream(const xercesc::DOMElement* e);
70
71         ~CurlURLInputStream();
72
73 #ifdef XMLTOOLING_XERCESC_64BITSAFE
74         XMLFilePos
75 #else
76         unsigned int
77 #endif
78         curPos() const {
79             return fTotalBytesRead;
80         }
81
82 #ifdef XMLTOOLING_XERCESC_INPUTSTREAM_HAS_CONTENTTYPE
83         const XMLCh* getContentType() const {
84             return fContentType;
85         }
86 #endif
87
88         xsecsize_t readBytes(XMLByte* const toFill, const xsecsize_t maxToRead);
89
90     private :
91         CurlURLInputStream(const CurlURLInputStream&);
92         CurlURLInputStream& operator=(const CurlURLInputStream&);
93
94         // libcurl callbacks for data read/write
95         static size_t staticWriteCallback(char *buffer, size_t size, size_t nitems, void *outstream);
96         size_t writeCallback(char *buffer, size_t size, size_t nitems);
97
98         void init(const xercesc::DOMElement* e=NULL);
99         bool readMore(int *runningHandles);
100
101         logging::Category&  fLog;\r
102         std::string         fURL;\r
103
104         CURLM*              fMulti;
105         CURL*               fEasy;
106
107         unsigned long       fTotalBytesRead;
108         XMLByte*            fWritePtr;
109         xsecsize_t          fBytesRead;
110         xsecsize_t          fBytesToRead;
111         bool                fDataAvailable;
112
113         // Overflow buffer for when curl writes more data to us
114         // than we've asked for.
115         XMLByte             fBuffer[CURL_MAX_WRITE_SIZE];
116         XMLByte*            fBufferHeadPtr;
117         XMLByte*            fBufferTailPtr;
118
119         XMLCh*              fContentType;
120
121         char                fError[CURL_ERROR_SIZE];
122     };
123 };
124
125 #endif // __xmltooling_curlinstr_h__