cURL / Mailing Lists / curl-library / Single Mail

curl-library

[PATCH] xmlIO HTTPS handler using libcurl

From: joel reed <joelwreed_at_gmail.com>
Date: Tue, 13 Mar 2007 22:27:53 -0400

The attached patch adds an optional libxml xmlIO handler for HTTPS using
libcurl. (CC'ing libcurl list as an FYI.)

It is currently OFF by default, since it adds a dependency on libcurl.

If you'd like to try it out, first make sure your curl is compiled with
SSL support, e.g.:

    curl-config --feature | grep SSL

That should output "SSL"

If you're libcurl looks good, then to apply & enable https support in
libxml2, do something like:

    cd /usr/local/src/libxml2-2.6.27
    patch -p1 < ~/https-v1.diff
    aclocal && autoconf && automake
    ./configure --with-https=yes && make && make install

Implementation notes:

1) curlhttps.c currently does:

    curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
    curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0);

    which disables certificate verfication.
        
    any ideas on howto do a libxml configuration api for this?

2) If their is interest in adding this to libxml, I'd be glad to write
some test cases (right now my proprietary app is a good enough test case
for me personally) but to do some testcases, I'd need an SSL enabled web
site. Could xmlsoft.org host some xml files via https? Any other ideas
on how to set this up?

3) diffstat:

   libxml-2.0.pc.in | 2
   libxml2-2.6.27/Makefile.am | 8 -
   libxml2-2.6.27/config.h.in | 3
   libxml2-2.6.27/configure.in | 30 +++
   libxml2-2.6.27/curlhttps.c | 198
++++++++++++++++++++++++++
   libxml2-2.6.27/include/libxml/curlhttps.h | 36 ++++
   libxml2-2.6.27/include/libxml/parser.h | 1
   libxml2-2.6.27/include/libxml/xmlversion.h.in | 9 +
   libxml2-2.6.27/parser.c | 6
   libxml2-2.6.27/win32/Makefile.bcb | 8 +
   libxml2-2.6.27/win32/Makefile.mingw | 8 +
   libxml2-2.6.27/win32/Makefile.msvc | 8 +
   libxml2-2.6.27/win32/configure.js | 8 +
   libxml2-2.6.27/xmlIO.c | 8 +
   libxml2-2.6.27/xmllint.c | 1
   15 files changed, 329 insertions(+), 5 deletions(-)

Comments? Suggestions?

jr

diff -up -urN libxml2-2.6.27-orig/config.h.in libxml2-2.6.27/config.h.in
--- libxml2-2.6.27-orig/config.h.in 2006-10-25 10:47:22.000000000 -0400
+++ libxml2-2.6.27/config.h.in 2007-03-13 11:07:31.000000000 -0400
@@ -94,6 +94,9 @@
 /* Define to 1 if you have the `isnand' function. */
 #undef HAVE_ISNAND
 
+/* Define if libcurl library is available. */
+#undef HAVE_LIBCURL
+
 /* Define if history library is there (-lhistory) */
 #undef HAVE_LIBHISTORY
 
diff -up -urN libxml2-2.6.27-orig/configure.in libxml2-2.6.27/configure.in
--- libxml2-2.6.27-orig/configure.in 2006-10-25 10:46:05.000000000 -0400
+++ libxml2-2.6.27/configure.in 2007-03-13 11:06:36.000000000 -0400
@@ -91,6 +91,8 @@ AC_ARG_WITH(html-subdir, AC_HELP_STRING(
 AC_SUBST(HTML_DIR)
 AC_ARG_WITH(http,
 [ --with-http add the HTTP support (on)])
+AC_ARG_WITH(https,
+[ --with-https add the HTTPS support (off)])
 AC_ARG_WITH(iconv,
 [ --with-iconv[[=DIR]] add ICONV support (on)])
 AC_ARG_WITH(iso8859x,
@@ -960,6 +962,34 @@ fi
 AC_SUBST(WITH_HTTP)
 AC_SUBST(HTTP_OBJ)
 
+WITH_HTTPS=0
+HTTPS_OBJ=
+CURL_CFLAGS=""
+CURL_LIBS=""
+
+if test "$with_https" != "no" ; then
+ AC_PATH_PROG(CURL_CONFIG, curl-config, no)
+ if test "$CURL_CONFIG" != "no" ; then
+ CURL_HAS_SSL=`curl-config --feature | grep SSL`
+ if test "$CURL_HAS_SSL" == "SSL" ; then
+ CURL_CFLAGS=`$CURL_CONFIG --cflags`
+ CURL_LIBS=`$CURL_CONFIG --libs`
+ AC_DEFINE(HAVE_LIBCURL, 1, [Define if libcurl library is available.])
+ WITH_HTTPS=1
+ HTTPS_OBJ=curlhttps.o
+ echo Enabled HTTPS support.
+ else
+ echo libcurl does not have SSL support. libxml https NOT enabled.
+ fi
+ else
+ echo curl-config not found. libxml https NOT enabled.
+ fi
+fi
+AC_SUBST(WITH_HTTPS)
+AC_SUBST(HTTPS_OBJ)
+AC_SUBST(CURL_CFLAGS)
+AC_SUBST(CURL_LIBS)
+
 if test "$with_legacy" = "no" ; then
     echo Disabling deprecated APIs
     WITH_LEGACY=0
diff -up -urN libxml2-2.6.27-orig/include/libxml/curlhttps.h libxml2-2.6.27/include/libxml/curlhttps.h
--- libxml2-2.6.27-orig/include/libxml/curlhttps.h 1969-12-31 19:00:00.000000000 -0500
+++ libxml2-2.6.27/include/libxml/curlhttps.h 2007-03-13 11:02:08.000000000 -0400
@@ -0,0 +1,36 @@
+/*
+ * Summary: xmlIO HTTPS implementation
+ * Description: xmlIO HTTPS implementation allowing to fetch resources
+ * like external subset.
+ *
+ * Copy: See Copyright for the status of this software.
+ *
+ * Author: Joel W. Reed
+ */
+
+#ifndef __CURL_HTTPS_H__
+#define __CURL_HTTPS_H__
+
+#include <libxml/xmlversion.h>
+
+#ifdef LIBXML_HTTPS_ENABLED
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+XMLPUBFUN int XMLCALL
+ xmlIOHTTPSMatch (const char * URI);
+XMLPUBFUN void * XMLCALL
+ xmlIOHTTPSOpen (const char *URL);
+XMLPUBFUN int XMLCALL
+ xmlIOHTTPSRead (void *ctx,
+ char *dest,
+ int len);
+XMLPUBFUN int XMLCALL
+ xmlIOHTTPSClose (void *ctx);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LIBXML_HTTPS_ENABLED */
+#endif /* __CURL_HTTPS_H__ */
diff -up -urN libxml2-2.6.27-orig/include/libxml/parser.h libxml2-2.6.27/include/libxml/parser.h
--- libxml2-2.6.27-orig/include/libxml/parser.h 2006-07-13 02:25:52.000000000 -0400
+++ libxml2-2.6.27/include/libxml/parser.h 2007-03-13 10:32:44.000000000 -0400
@@ -1207,6 +1207,7 @@ typedef enum {
     XML_WITH_DEBUG_MEM = 29,
     XML_WITH_DEBUG_RUN = 30,
     XML_WITH_ZLIB = 31,
+ XML_WITH_HTTPS = 32,
     XML_WITH_NONE = 99999 /* just to be sure of allocation size */
 } xmlFeature;
 
diff -up -urN libxml2-2.6.27-orig/include/libxml/xmlversion.h.in libxml2-2.6.27/include/libxml/xmlversion.h.in
--- libxml2-2.6.27-orig/include/libxml/xmlversion.h.in 2006-10-11 15:28:04.000000000 -0400
+++ libxml2-2.6.27/include/libxml/xmlversion.h.in 2007-03-13 10:31:17.000000000 -0400
@@ -178,6 +178,15 @@ XMLPUBFUN void XMLCALL xmlCheckVersion(i
 #endif
 
 /**
+ * LIBXML_HTTPS_ENABLED:
+ *
+ * Whether the HTTPS support is configured in
+ */
+#if @WITH_HTTPS@
+#define LIBXML_HTTPS_ENABLED
+#endif
+
+/**
  * LIBXML_VALID_ENABLED:
  *
  * Whether the DTD validation support is configured in
diff -up -urN libxml2-2.6.27-orig/Makefile.am libxml2-2.6.27/Makefile.am
--- libxml2-2.6.27-orig/Makefile.am 2005-12-06 17:20:12.000000000 -0500
+++ libxml2-2.6.27/Makefile.am 2007-03-13 11:04:23.000000000 -0400
@@ -4,7 +4,7 @@ SUBDIRS = include . doc example xstc @PY
 
 DIST_SUBDIRS = include . doc example python xstc
 
-INCLUDES = -I$(top_builddir)/include -I_at_srcdir@/include @THREAD_CFLAGS@ @Z_CFLAGS@
+INCLUDES = -I$(top_builddir)/include -I_at_srcdir@/include @THREAD_CFLAGS@ @Z_CFLAGS@ @CURL_CFLAGS@
 
 noinst_PROGRAMS=testSchemas testRelax testSAX testHTML testXPath testURI \
                 testThreads testC14N testAutomata testRegexp \
@@ -15,7 +15,7 @@ bin_PROGRAMS = xmllint xmlcatalog
 bin_SCRIPTS=xml2-config
 
 lib_LTLIBRARIES = libxml2.la
-libxml2_la_LIBADD = @THREAD_LIBS@ @Z_LIBS@ $(ICONV_LIBS) @M_LIBS@ @WIN32_EXTRA_LIBADD@
+libxml2_la_LIBADD = @THREAD_LIBS@ @Z_LIBS@ $(ICONV_LIBS) @M_LIBS@ @CURL_LIBS@ @WIN32_EXTRA_LIBADD@
 
 libxml2_la_LDFLAGS = @CYGWIN_EXTRA_LDFLAGS@ @WIN32_EXTRA_LDFLAGS@ -version-info @LIBXML_VERSION_INFO@ @MODULE_PLATFORM_LIBS@
 
@@ -23,7 +23,7 @@ if WITH_TRIO_SOURCES
 libxml2_la_SOURCES = SAX.c entities.c encoding.c error.c parserInternals.c \
                 parser.c tree.c hash.c list.c xmlIO.c xmlmemory.c uri.c \
                 valid.c xlink.c HTMLparser.c HTMLtree.c debugXML.c xpath.c \
- xpointer.c xinclude.c nanohttp.c nanoftp.c DOCBparser.c \
+ xpointer.c xinclude.c nanohttp.c nanoftp.c curlhttps.c DOCBparser.c \
                 catalog.c globals.c threads.c c14n.c xmlstring.c \
                 xmlregexp.c xmlschemas.c xmlschemastypes.c xmlunicode.c \
                 triostr.c trio.c xmlreader.c relaxng.c dict.c SAX2.c \
@@ -33,7 +33,7 @@ else
 libxml2_la_SOURCES = SAX.c entities.c encoding.c error.c parserInternals.c \
                 parser.c tree.c hash.c list.c xmlIO.c xmlmemory.c uri.c \
                 valid.c xlink.c HTMLparser.c HTMLtree.c debugXML.c xpath.c \
- xpointer.c xinclude.c nanohttp.c nanoftp.c DOCBparser.c \
+ xpointer.c xinclude.c nanohttp.c nanoftp.c curlhttps.c DOCBparser.c \
                 catalog.c globals.c threads.c c14n.c xmlstring.c \
                 xmlregexp.c xmlschemas.c xmlschemastypes.c xmlunicode.c \
                 xmlreader.c relaxng.c dict.c SAX2.c \
diff -up -urN libxml2-2.6.27-orig/parser.c libxml2-2.6.27/parser.c
--- libxml2-2.6.27-orig/parser.c 2006-10-17 10:28:27.000000000 -0400
+++ libxml2-2.6.27/parser.c 2007-03-13 10:32:00.000000000 -0400
@@ -687,6 +687,12 @@ xmlHasFeature(xmlFeature feature)
 #else
             return(0);
 #endif
+ case XML_WITH_HTTPS:
+#ifdef LIBXML_HTTPS_ENABLED
+ return(1);
+#else
+ return(0);
+#endif
         case XML_WITH_VALID:
 #ifdef LIBXML_VALID_ENABLED
             return(1);
diff -up -urN libxml2-2.6.27-orig/win32/configure.js libxml2-2.6.27/win32/configure.js
--- libxml2-2.6.27-orig/win32/configure.js 2005-12-15 06:10:52.000000000 -0500
+++ libxml2-2.6.27/win32/configure.js 2007-03-13 12:59:34.000000000 -0400
@@ -32,6 +32,7 @@ var withTrio = false;
 var withThreads = "native";
 var withFtp = true;
 var withHttp = true;
+var withHttps = false;
 var withHtml = true;
 var withC14n = true;
 var withCatalog = true;
@@ -115,6 +116,7 @@ function usage()
         txt += " threads: Enable thread safety [no|ctls|native|posix] (" + (withThreads) + ") \n";
         txt += " ftp: Enable FTP client (" + (withFtp? "yes" : "no") + ")\n";
         txt += " http: Enable HTTP client (" + (withHttp? "yes" : "no") + ")\n";
+ txt += " https: Enable HTTPS client (" + (withHttps? "yes" : "no") + ")\n";
         txt += " html: Enable HTML processor (" + (withHtml? "yes" : "no") + ")\n";
         txt += " c14n: Enable C14N support (" + (withC14n? "yes" : "no") + ")\n";
         txt += " catalog: Enable catalog support (" + (withCatalog? "yes" : "no") + ")\n";
@@ -223,6 +225,7 @@ function discoverVersion()
         vf.WriteLine("WITH_THREADS=" + withThreads);
         vf.WriteLine("WITH_FTP=" + (withFtp? "1" : "0"));
         vf.WriteLine("WITH_HTTP=" + (withHttp? "1" : "0"));
+ vf.WriteLine("WITH_HTTPS=" + (withHttps? "1" : "0"));
         vf.WriteLine("WITH_HTML=" + (withHtml? "1" : "0"));
         vf.WriteLine("WITH_C14N=" + (withC14n? "1" : "0"));
         vf.WriteLine("WITH_CATALOG=" + (withCatalog? "1" : "0"));
@@ -300,6 +303,8 @@ function configureLibxml()
                         of.WriteLine(s.replace(/\@WITH_FTP\@/, withFtp? "1" : "0"));
                 } else if (s.search(/\@WITH_HTTP\@/) != -1) {
                         of.WriteLine(s.replace(/\@WITH_HTTP\@/, withHttp? "1" : "0"));
+ } else if (s.search(/\@WITH_HTTPS\@/) != -1) {
+ of.WriteLine(s.replace(/\@WITH_HTTPS\@/, withHttps? "1" : "0"));
                 } else if (s.search(/\@WITH_HTML\@/) != -1) {
                         of.WriteLine(s.replace(/\@WITH_HTML\@/, withHtml? "1" : "0"));
                 } else if (s.search(/\@WITH_C14N\@/) != -1) {
@@ -443,6 +448,8 @@ for (i = 0; (i < WScript.Arguments.lengt
                         withFtp = strToBool(arg.substring(opt.length + 1, arg.length));
                 else if (opt == "http")
                         withHttp = strToBool(arg.substring(opt.length + 1, arg.length));
+ else if (opt == "https")
+ withHttps = strToBool(arg.substring(opt.length + 1, arg.length));
                 else if (opt == "html")
                         withHtml = strToBool(arg.substring(opt.length + 1, arg.length));
                 else if (opt == "c14n")
@@ -629,6 +636,7 @@ txtOut += " Trio: " + boolT
 txtOut += " Thread safety: " + withThreads + "\n";
 txtOut += " FTP client: " + boolToStr(withFtp) + "\n";
 txtOut += " HTTP client: " + boolToStr(withHttp) + "\n";
+txtOut += " HTTPS client: " + boolToStr(withHttps) + "\n";
 txtOut += " HTML processor: " + boolToStr(withHtml) + "\n";
 txtOut += " C14N support: " + boolToStr(withC14n) + "\n";
 txtOut += " Catalog support: " + boolToStr(withCatalog) + "\n";
diff -up -urN libxml2-2.6.27-orig/win32/Makefile.bcb libxml2-2.6.27/win32/Makefile.bcb
--- libxml2-2.6.27-orig/win32/Makefile.bcb 2006-03-09 03:39:59.000000000 -0500
+++ libxml2-2.6.27/win32/Makefile.bcb 2007-03-13 14:14:42.000000000 -0400
@@ -68,6 +68,9 @@ CFLAGS = $(CFLAGS) -DHAVE_PTHREAD_H
 !if "$(WITH_ZLIB)" == "1"
 CFLAGS = $(CFLAGS) -DHAVE_ZLIB_H
 !endif
+!if "$(WITH_HTTPS)" == "1"
+CFLAGS = $(CFLAGS) -DCURL_STATICLIB
+!endif
 
 # The linker and its options.
 LD = ilink32.exe
@@ -92,6 +95,9 @@ LIBS = $(LIBS) iconvomf.lib
 !if "$(WITH_ZLIB)" == "1"
 LIBS = $(LIBS) zlibomf.lib
 !endif
+!if "$(WITH_HTTPS)" == "1"
+LIBS = $(LIBS) libcurl.lib ssleay32.lib libeay32.lib user32.lib advapi32.lib winmm.lib gdi32.lib
+!endif
 !if "$(WITH_THREADS)" == "posix"
 LIBS = $(LIBS) pthreadVC.lib
 !endif
@@ -130,6 +136,7 @@ XML_OBJS = $(XML_INTDIR)\c14n.obj\
         $(XML_INTDIR)\list.obj\
         $(XML_INTDIR)\nanoftp.obj\
         $(XML_INTDIR)\nanohttp.obj\
+ $(XML_INTDIR)\curlhttps.obj\
         $(XML_INTDIR)\parser.obj\
         $(XML_INTDIR)\parserInternals.obj\
         $(XML_INTDIR)\pattern.obj\
@@ -175,6 +182,7 @@ XML_OBJS_A = $(XML_INTDIR_A)\c14n.obj\
         $(XML_INTDIR_A)\list.obj\
         $(XML_INTDIR_A)\nanoftp.obj\
         $(XML_INTDIR_A)\nanohttp.obj\
+ $(XML_INTDIR_A)\curlhttps.obj\
         $(XML_INTDIR_A)\parser.obj\
         $(XML_INTDIR_A)\parserInternals.obj\
         $(XML_INTDIR_A)\pattern.obj\
diff -up -urN libxml2-2.6.27-orig/win32/Makefile.mingw libxml2-2.6.27/win32/Makefile.mingw
--- libxml2-2.6.27-orig/win32/Makefile.mingw 2006-02-03 04:42:26.000000000 -0500
+++ libxml2-2.6.27/win32/Makefile.mingw 2007-03-13 14:14:50.000000000 -0400
@@ -60,6 +60,9 @@ endif
 ifeq ($(WITH_ZLIB),1)
 CFLAGS += -DHAVE_ZLIB_H
 endif
+ifeq ($(WITH_HTTPS),1)
+CFLAGS += -DCURL_STATICLIB
+endif
 
 # The linker and its options.
 LD = gcc.exe
@@ -81,6 +84,9 @@ endif
 ifeq ($(WITH_ZLIB),1)
 LIBS += -lzdll
 endif
+ifeq ($(WITH_HTTPS),1)
+LIBS += -leay32 -lcurl -lssleay32 -luser32 -ladvapi32 -lwinmm -lgdi32
+endif
 ifeq ($(WITH_THREADS),posix)
 LIBS += -lpthreadGC
 endif
@@ -120,6 +126,7 @@ XML_OBJS = $(XML_INTDIR)/c14n.o\
         $(XML_INTDIR)/list.o\
         $(XML_INTDIR)/nanoftp.o\
         $(XML_INTDIR)/nanohttp.o\
+ $(XML_INTDIR)/curlhttps.o\
         $(XML_INTDIR)/parser.o\
         $(XML_INTDIR)/parserInternals.o\
         $(XML_INTDIR)/pattern.o\
@@ -167,6 +174,7 @@ XML_OBJS_A = $(XML_INTDIR_A)/c14n.o\
         $(XML_INTDIR_A)/list.o\
         $(XML_INTDIR_A)/nanoftp.o\
         $(XML_INTDIR_A)/nanohttp.o\
+ $(XML_INTDIR_A)/curlhttps.o\
         $(XML_INTDIR_A)/parser.o\
         $(XML_INTDIR_A)/parserInternals.o\
         $(XML_INTDIR_A)/pattern.o\
diff -up -urN libxml2-2.6.27-orig/win32/Makefile.msvc libxml2-2.6.27/win32/Makefile.msvc
--- libxml2-2.6.27-orig/win32/Makefile.msvc 2006-02-03 04:42:26.000000000 -0500
+++ libxml2-2.6.27/win32/Makefile.msvc 2007-03-13 14:14:37.000000000 -0400
@@ -56,6 +56,9 @@ CFLAGS = $(CFLAGS) /D "HAVE_PTHREAD_H"
 !if "$(WITH_ZLIB)" == "1"
 CFLAGS = $(CFLAGS) /D "HAVE_ZLIB_H"
 !endif
+!if "$(WITH_HTTPS)" == "1"
+CFLAGS = $(CFLAGS) /D "CURL_STATICLIB"
+!endif
 
 # The linker and its options.
 LD = link.exe
@@ -65,6 +68,9 @@ LIBS =
 !if "$(WITH_FTP)" == "1" || "$(WITH_HTTP)" == "1"
 LIBS = $(LIBS) wsock32.lib
 !endif
+!if "$(WITH_HTTPS)" == "1"
+LIBS = $(LIBS) libcurl.lib ssleay32.lib libeay32.lib user32.lib advapi32.lib winmm.lib gdi32.lib
+!endif
 !if "$(WITH_ICONV)" == "1"
 LIBS = $(LIBS) iconv.lib
 !endif
@@ -109,6 +115,7 @@ XML_OBJS = $(XML_INTDIR)\c14n.obj\
         $(XML_INTDIR)\list.obj\
         $(XML_INTDIR)\nanoftp.obj\
         $(XML_INTDIR)\nanohttp.obj\
+ $(XML_INTDIR)\curlhttps.obj\
         $(XML_INTDIR)\parser.obj\
         $(XML_INTDIR)\parserInternals.obj\
         $(XML_INTDIR)\pattern.obj\
@@ -154,6 +161,7 @@ XML_OBJS_A = $(XML_INTDIR_A)\c14n.obj\
         $(XML_INTDIR_A)\list.obj\
         $(XML_INTDIR_A)\nanoftp.obj\
         $(XML_INTDIR_A)\nanohttp.obj\
+ $(XML_INTDIR_A)\curlhttps.obj\
         $(XML_INTDIR_A)\parser.obj\
         $(XML_INTDIR_A)\parserInternals.obj\
         $(XML_INTDIR_A)\pattern.obj\
diff -up -urN libxml2-2.6.27-orig/xmlIO.c libxml2-2.6.27/xmlIO.c
--- libxml2-2.6.27-orig/xmlIO.c 2006-10-13 06:27:09.000000000 -0400
+++ libxml2-2.6.27/xmlIO.c 2007-03-13 11:29:43.000000000 -0400
@@ -87,6 +87,9 @@
 #ifdef LIBXML_CATALOG_ENABLED
 #include <libxml/catalog.h>
 #endif
+#ifdef LIBXML_HTTPS_ENABLED
+#include <libxml/curlhttps.h>
+#endif
 #include <libxml/globals.h>
 
 /* #define VERBOSE_FAILURE */
@@ -2126,6 +2129,11 @@ xmlRegisterDefaultInputCallbacks(void) {
                               xmlIOHTTPRead, xmlIOHTTPClose);
 #endif /* LIBXML_HTTP_ENABLED */
 
+#ifdef LIBXML_HTTPS_ENABLED
+ xmlRegisterInputCallbacks(xmlIOHTTPSMatch, xmlIOHTTPSOpen,
+ xmlIOHTTPSRead, xmlIOHTTPSClose);
+#endif /* LIBXML_HTTP_ENABLED */
+
 #ifdef LIBXML_FTP_ENABLED
     xmlRegisterInputCallbacks(xmlIOFTPMatch, xmlIOFTPOpen,
                               xmlIOFTPRead, xmlIOFTPClose);
diff -up -urN libxml2-2.6.27-orig/xmllint.c libxml2-2.6.27/xmllint.c
--- libxml2-2.6.27-orig/xmllint.c 2006-10-18 17:21:50.000000000 -0400
+++ libxml2-2.6.27/xmllint.c 2007-03-13 10:31:00.000000000 -0400
@@ -2782,6 +2782,7 @@ static void showVersion(const char *name
     if (xmlHasFeature(XML_WITH_SAX1)) fprintf(stderr, "SAXv1 ");
     if (xmlHasFeature(XML_WITH_FTP)) fprintf(stderr, "FTP ");
     if (xmlHasFeature(XML_WITH_HTTP)) fprintf(stderr, "HTTP ");
+ if (xmlHasFeature(XML_WITH_HTTPS)) fprintf(stderr, "HTTPS ");
     if (xmlHasFeature(XML_WITH_VALID)) fprintf(stderr, "DTDValid ");
     if (xmlHasFeature(XML_WITH_HTML)) fprintf(stderr, "HTML ");
     if (xmlHasFeature(XML_WITH_LEGACY)) fprintf(stderr, "Legacy ");
--- libxml2-2.6.27-orig/libxml-2.0.pc.in 2006-10-11 08:27:12.000000000 -0400
+++ libxml2-2.6.27/libxml-2.0.pc.in 2007-03-13 15:08:23.000000000 -0400
@@ -9,5 +9,5 @@ Version: @VERSION@
 Description: libXML library version2.
 Requires:
 Libs: -L${libdir} -lxml2
-Libs.private: @THREAD_LIBS@ @Z_LIBS@ @ICONV_LIBS@ @M_LIBS@ @LIBS@
+Libs.private: @THREAD_LIBS@ @Z_LIBS@ @ICONV_LIBS@ @M_LIBS@ @CURL_LIBS@ @LIBS@
 Cflags: @XML_INCLUDEDIR@ @XML_CFLAGS@
--- /dev/null 2007-03-02 14:19:00.000000000 -0500
+++ libxml2-2.6.27/curlhttps.c 2007-03-13 21:56:59.000000000 -0400
@@ -0,0 +1,198 @@
+/*
+ * curlhttps.c: xmlIO handler for https via libcurl
+ *
+ * See Copyright for the status of this software.
+ *
+ * joelwreed_at_gmail.com
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+#include <libxml/xinclude.h>
+#include <libxml/xmlIO.h>
+
+#ifdef LIBXML_HTTPS_ENABLED
+
+#include <libxml/curlhttps.h>
+#include <curl/curl.h>
+
+#if defined(WIN32)
+#pragma comment(lib, "libcurl.lib")
+#pragma comment(lib, "libeay32.lib")
+#pragma comment(lib, "ssleay32.lib")
+#pragma comment(lib, "gdi32.lib")
+#pragma comment(lib, "winmm.lib")
+#pragma comment(lib, "advapi32.lib")
+#pragma comment(lib, "user32.lib")
+#endif
+
+typedef struct _xmlIOHTTPSReadCtxt
+{
+ CURL *curl;
+ xmlChar* uri;
+ char *buffer;
+ int sizeBuffer;
+ int sizeRead;
+} xmlIOHTTPSReadCtxt;
+
+static int xmlIOHTTPSInitialized = 0;
+
+static size_t
+xmlIOHTTPSReceiveData(void *ptr, size_t size, size_t nmemb, void *c)
+{
+ int len_received;
+ xmlIOHTTPSReadCtxt *context;
+
+ if (c == NULL) return(-1);
+ context = (xmlIOHTTPSReadCtxt*) c;
+
+ len_received = size * nmemb;
+ context->buffer = xmlMemRealloc(context->buffer,
+ context->sizeBuffer + len_received + 1);
+
+ if (context->buffer) {
+ memcpy(&(context->buffer[context->sizeBuffer]), ptr, len_received);
+ context->sizeBuffer += len_received;
+ context->buffer[context->sizeBuffer] = 0;
+ }
+
+ return len_received;
+
+}
+
+/**
+ * xmlIOHTTPSMatch:
+ * @URI: an URI to test
+ *
+ * Check for an https: query
+ *
+ * Returns 1 if yes and 0 if another Input module should be used
+ */
+int
+xmlIOHTTPSMatch(const char * URI) {
+ if ((URI != NULL) && (!strncmp(URI, "https:", 6)))
+ return(1);
+ return(0);
+}
+
+/**
+ * xmlIOHTTPSOpen:
+ * @URI: an URI to open
+ *
+ * Returns an Input context or NULL in case or error
+ */
+void *
+xmlIOHTTPSOpen(const char * URI) {
+ xmlIOHTTPSReadCtxt* context;
+
+ if ((URI == NULL) || (strncmp(URI, "https:", 6)))
+ return(NULL);
+
+ if (!xmlIOHTTPSInitialized) {
+ curl_global_init(CURL_GLOBAL_ALL);
+ xmlIOHTTPSInitialized = 1;
+ }
+
+ context = (xmlIOHTTPSReadCtxt*) xmlMalloc(sizeof(xmlIOHTTPSReadCtxt));
+ if (context == NULL) {
+ xmlGenericError(xmlGenericErrorContext,
+ "creating HTTPS input context");
+ return (NULL);
+ }
+
+ (void) memset(context, 0, sizeof(xmlIOHTTPSReadCtxt));
+
+ context->uri = (char *) xmlStrdup((const xmlChar *)URI);
+ if (context->uri == NULL) {
+ xmlGenericError(xmlGenericErrorContext,
+ "copying URI");
+ xmlFree(context);
+ return (NULL);
+ }
+
+ context->curl = curl_easy_init();
+ curl_easy_setopt(context->curl, CURLOPT_URL, context->uri);
+ context->buffer = NULL;
+ context->sizeBuffer = 0;
+
+#ifdef DEBUG_HTTPS
+ curl_easy_setopt(context->curl, CURLOPT_VERBOSE, 1);
+#endif
+
+ curl_easy_setopt(context->curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
+ curl_easy_setopt(context->curl, CURLOPT_SSL_VERIFYPEER, 0);
+ curl_easy_setopt(context->curl, CURLOPT_SSL_VERIFYHOST, 0);
+ curl_easy_setopt(context->curl, CURLOPT_WRITEFUNCTION, xmlIOHTTPSReceiveData);
+ curl_easy_setopt(context->curl, CURLOPT_WRITEDATA, context);
+
+ return context;
+}
+
+/**
+ * xmlIOHTTPSClose:
+ * @c: the read context
+ *
+ * Close the https: query handler
+ *
+ * Returns 0 or -1 in case of error
+ */
+int
+xmlIOHTTPSClose(void * c) {
+ xmlIOHTTPSReadCtxt *context;
+ if (c == NULL) return(-1);
+
+ context = (xmlIOHTTPSReadCtxt*) c;
+ curl_easy_cleanup(context->curl);
+
+ if (context->uri != NULL)
+ xmlFree(context->uri);
+
+ if (context->buffer != NULL)
+ xmlMemFree(context->buffer);
+
+ xmlFree(context);
+
+ return(0);
+}
+
+/**
+ * xmlIOHTTPSRead:
+ * @c: the read context
+ * @buffer: where to store data
+ * @len: number of bytes to read
+ *
+ * Implement an https: query read.
+ *
+ * Returns the number of bytes read or -1 in case of error
+ */
+int
+xmlIOHTTPSRead(void * c, char * buffer, int len) {
+ int bytesToRead;
+ xmlIOHTTPSReadCtxt *context;
+ CURLcode res;
+
+ if (c == NULL) return(-1);
+ context = (xmlIOHTTPSReadCtxt*) c;
+
+ if (context->buffer == NULL) {
+ res = curl_easy_perform(context->curl);
+ if (res != CURLE_OK) {
+ xmlGenericError(xmlGenericErrorContext,
+ "xmlIOHTTPSRead: %s\n", curl_easy_strerror(res));
+
+ return -1;
+ }
+ }
+
+ bytesToRead = len < (context->sizeBuffer - context->sizeRead) ?
+ len : (context->sizeBuffer - context->sizeRead);
+
+ memcpy(buffer, &(context->buffer[context->sizeRead]), bytesToRead);
+ context->sizeRead += bytesToRead;
+
+ return bytesToRead;
+}
+
+#endif
Received on 2007-03-14