Update build revision
[shibboleth/cpp-xmltooling.git] / xmltooling / util / CurlURLInputStream.h
index a1a6035..c149951 100644 (file)
-/*\r
- * Licensed to the Apache Software Foundation (ASF) under one or more\r
- * contributor license agreements.  See the NOTICE file distributed with\r
- * this work for additional information regarding copyright ownership.\r
- * The ASF licenses this file to You under the Apache License, Version 2.0\r
- * (the "License"); you may not use this file except in compliance with\r
- * the License.  You may obtain a copy of the License at\r
- * \r
- *      http://www.apache.org/licenses/LICENSE-2.0\r
- * \r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-/*\r
- * $Id: CurlURLInputStream.hpp 527149 2007-04-10 14:56:39Z amassari $\r
- */\r
-\r
-#if !defined(XERCESC_INCLUDE_GUARD_CURLURLINPUTSTREAM_HPP)\r
-#define XERCESC_INCLUDE_GUARD_CURLURLINPUTSTREAM_HPP\r
-\r
-#include <curl/curl.h>\r
-#include <curl/multi.h>\r
-#include <curl/easy.h>\r
-\r
-#include <xercesc/util/XMLURL.hpp>\r
-#include <xercesc/util/XMLExceptMsgs.hpp>\r
-#include <xercesc/util/Janitor.hpp>\r
-#include <xercesc/util/BinInputStream.hpp>\r
-#include <xercesc/util/XMLNetAccessor.hpp>\r
-\r
-namespace xmltooling {\r
-\r
-//\r
-// This class implements the BinInputStream interface specified by the XML\r
-// parser.\r
-//\r
-\r
-class XMLTOOL_DLLLOCAL CurlURLInputStream : public BinInputStream\r
-{\r
-public :\r
-    CurlURLInputStream(const XMLURL&  urlSource, const XMLNetHTTPInfo* httpInfo=0);\r
-    ~CurlURLInputStream();\r
-\r
-    unsigned int curPos() const;\r
-    unsigned int readBytes\r
-    (\r
-                XMLByte* const  toFill\r
-        , const unsigned int    maxToRead\r
-    );\r
-\r
-\r
-private :\r
-    // -----------------------------------------------------------------------\r
-    //  Unimplemented constructors and operators\r
-    // -----------------------------------------------------------------------\r
-    CurlURLInputStream(const CurlURLInputStream&);\r
-    CurlURLInputStream& operator=(const CurlURLInputStream&);\r
-    \r
-    static size_t staticWriteCallback(char *buffer,\r
-                                      size_t size,\r
-                                      size_t nitems,\r
-                                      void *outstream);\r
-    size_t writeCallback(                        char *buffer,\r
-                                      size_t size,\r
-                                      size_t nitems);\r
-\r
-\r
-    // -----------------------------------------------------------------------\r
-    //  Private data members\r
-    //\r
-    //  fSocket\r
-    //      The socket representing the connection to the remote file.\r
-    //  fBytesProcessed\r
-    //      Its a rolling count of the number of bytes processed off this\r
-    //      input stream.\r
-    //  fBuffer\r
-    //      Holds the http header, plus the first part of the actual\r
-    //      data.  Filled at the time the stream is opened, data goes\r
-    //      out to user in response to readBytes().\r
-    //  fBufferPos, fBufferEnd\r
-    //      Pointers into fBuffer, showing start and end+1 of content\r
-    //      that readBytes must return.\r
-    // -----------------------------------------------------------------------\r
-       \r
-    CURLM*                             fMulti;\r
-    CURL*                              fEasy;\r
-    \r
-    MemoryManager*      fMemoryManager;\r
-    \r
-    XMLURL                             fURLSource;\r
-    ArrayJanitor<char> fURL;\r
-    \r
-    unsigned long       fTotalBytesRead;\r
-    XMLByte*                   fWritePtr;\r
-    unsigned long              fBytesRead;\r
-    unsigned long              fBytesToRead;\r
-    bool                               fDataAvailable;\r
-    \r
-    // Overflow buffer for when curl writes more data to us\r
-    // than we've asked for.\r
-    XMLByte                            fBuffer[CURL_MAX_WRITE_SIZE];\r
-    XMLByte*                   fBufferHeadPtr;\r
-    XMLByte*                   fBufferTailPtr;\r
-    \r
-}; // CurlURLInputStream\r
-\r
-\r
-inline unsigned int\r
-CurlURLInputStream::curPos() const\r
-{\r
-    return fTotalBytesRead;\r
-}\r
-\r
-};\r
-\r
-#endif // CURLURLINPUTSTREAM_HPP\r
-\r
+/**
+ * Licensed to the University Corporation for Advanced Internet
+ * Development, Inc. (UCAID) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for
+ * additional information regarding copyright ownership.
+ *
+ * UCAID licenses this file to you under the Apache License,
+ * Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the
+ * License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied. See the License for the specific
+ * language governing permissions and limitations under the License.
+ */
+
+/**
+ * @file xmltooling/util/CurlURLInputStream.h
+ *
+ * Asynchronous use of curl to fetch data from a URL.
+ */
+
+#if !defined(__xmltooling_curlinstr_h__) && !defined(XMLTOOLING_LITE)
+#define __xmltooling_curlinstr_h__
+
+#include <xmltooling/logging.h>
+
+#include <string>
+#include <vector>
+#include <curl/curl.h>
+#include <xercesc/util/BinInputStream.hpp>
+
+namespace xmltooling {
+
+    /**
+     * Adapted from Xerces-C as a more advanced input stream implementation
+     * for subsequent use in parsing remote documents.
+     */
+    class XMLTOOL_API CurlURLInputStream : public xercesc::BinInputStream
+    {
+    public :
+        /**
+         * Constructor.
+         *
+         * @param url       the URL of the resource to fetch
+         * @param cacheTag  optional pointer to string used for cache management
+         */
+        CurlURLInputStream(const char* url, std::string* cacheTag=nullptr);
+
+        /**
+         * Constructor.
+         *
+         * @param url       the URL of the resource to fetch
+         * @param cacheTag  optional pointer to string used for cache management
+         */
+        CurlURLInputStream(const XMLCh* url, std::string* cacheTag=nullptr);
+
+        /**
+         * Constructor taking a DOM element supporting the following content:
+         * 
+         * <dl>
+         *  <dt>uri | url</dt>
+         *  <dd>identifies the remote resource</dd>
+         *  <dt>verifyHost</dt>
+         *  <dd>true iff name of host should be matched against TLS/SSL certificate</dd>
+         *  <dt>TransportOption elements, like so:</dt>
+         *  <dd>&lt;TransportOption provider="CURL" option="150"&gt;0&lt;/TransportOption&gt;</dd>
+         * </dl>
+         * 
+         * @param e         DOM to supply configuration
+         * @param cacheTag  optional pointer to string used for cache management
+         */
+        CurlURLInputStream(const xercesc::DOMElement* e, std::string* cacheTag=nullptr);
+
+        ~CurlURLInputStream();
+
+#ifdef XMLTOOLING_XERCESC_64BITSAFE
+        XMLFilePos
+#else
+        unsigned int
+#endif
+        curPos() const {
+            return fTotalBytesRead;
+        }
+
+#ifdef XMLTOOLING_XERCESC_INPUTSTREAM_HAS_CONTENTTYPE
+        const XMLCh* getContentType() const {
+            return fContentType;
+        }
+#endif
+
+        xsecsize_t readBytes(XMLByte* const toFill, const xsecsize_t maxToRead);
+
+        /**
+         * Access the OpenSSL context options in place for this object.
+         *
+         * @return bitmask suitable for use with SSL_CTX_set_options
+         */
+        int getOpenSSLOps() const {
+            return fOpenSSLOps;
+        }
+
+    private :
+        CurlURLInputStream(const CurlURLInputStream&);
+        CurlURLInputStream& operator=(const CurlURLInputStream&);
+
+        // libcurl callbacks for data read/write
+        static size_t staticWriteCallback(char *buffer, size_t size, size_t nitems, void *outstream);
+        size_t writeCallback(char *buffer, size_t size, size_t nitems);
+
+        void init(const xercesc::DOMElement* e=nullptr);
+        bool readMore(int *runningHandles);
+
+        logging::Category&  fLog;
+        std::string*        fCacheTag;
+        std::string         fURL;
+        std::vector<std::string>    fSavedOptions;
+        int                 fOpenSSLOps;
+
+        CURLM*              fMulti;
+        CURL*               fEasy;
+        struct curl_slist*  fHeaders;
+
+        unsigned long       fTotalBytesRead;
+        XMLByte*            fWritePtr;
+        xsecsize_t          fBytesRead;
+        xsecsize_t          fBytesToRead;
+        bool                fDataAvailable;
+
+        // Overflow buffer for when curl writes more data to us
+        // than we've asked for.
+        XMLByte*            fBuffer;
+        XMLByte*            fBufferHeadPtr;
+        XMLByte*            fBufferTailPtr;
+        size_t              fBufferSize;
+
+        XMLCh*              fContentType;
+        long                fStatusCode;
+
+        char                fError[CURL_ERROR_SIZE];
+    };
+};
+
+#endif // __xmltooling_curlinstr_h__