httpd-apreq-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Joe Schaefer <joe+gm...@sunstarsys.com>
Subject Re: [PATCH] Basic apr_xml_parser
Date Tue, 07 Sep 2004 15:36:29 GMT
Joe Schaefer <joe+gmane@sunstarsys.com> writes:

> I don't see any harm in having two xml parsers (at least for the time
> being), so I'll see if I can put together a patch for libxml2 to see
> what folks want to do with it.

Here's the patch against current-cvs.  You'll need to rerun
buildconf to test it out.

Index: acinclude.m4
===================================================================
RCS file: /home/cvs/httpd-apreq-2/acinclude.m4,v
retrieving revision 1.30
diff -u -r1.30 acinclude.m4
--- acinclude.m4	7 Aug 2004 04:51:29 -0000	1.30
+++ acinclude.m4	7 Sep 2004 15:31:47 -0000
@@ -15,6 +15,9 @@
         AC_ARG_WITH(apache2-src,
                 AC_HELP_STRING([--with-apache2-src],[path to httpd-2 source]),
                 [APACHE2_SRC=$withval],[APACHE2_SRC=""])
+        AC_ARG_WITH(xml2-config,
+                AC_HELP_STRING([--with-xml2-config],[path to libxml2's xml2-config]),
+                [XML2_CONFIG=$withval],[XML2_CONFIG=""])
 
         prereq_check="$PERL build/version_check.pl"
 
@@ -66,6 +69,17 @@
             AC_MSG_ERROR([Bad libaprutil version])
         fi
 
+        if test -z "$XML2_CONFIG"; then
+            AC_PATH_PROG([XML2_CONFIG], [xml2-config], [not found])
+            if test "$XML2_CONFIG" = "not found"; then
+                AC_MSG_ERROR([xml2-config not in PATH - please configure with --with-xml2-config=/path/to/xml2-config])
+            fi
+        fi
+
+        if test -z "`$prereq_check libxml2 $XML2_CONFIG`"; then
+            AC_MSG_ERROR([Bad libxml2 version from `$XML2_CONFIG --version`])
+        fi
+
         if test "x$PERL_GLUE" != "xno"; then
             if test -z "`$prereq_check perl $PERL`"; then
                 AC_MSG_ERROR([Bad perl version])
@@ -143,6 +157,10 @@
            done
         fi
 
+        CPPFLAGS="$CPPFLAGS "`$XML2_CONFIG --cflags`
+        XML2_LDLIBS=`$XML2_CONFIG --libs`
+        XML2_LTLIBS=`$XML2_CONFIG --libtool-libs`
+
         get_version="$abs_srcdir/build/get-version.sh"
         version_hdr="$abs_srcdir/src/apreq_version.h"
 
@@ -183,6 +201,9 @@
         AC_SUBST(APR_LA)
         AC_SUBST(APU_LA)
         AC_SUBST(PERL)
+        AC_SUBST(XML2_LTLIBS)
+        AC_SUBST(XML2_LDLIBS)
+
 ])
 
 dnl APR_CONFIG_NICE(filename)
cvs server: Diffing build
Index: build/version_check.pl
===================================================================
RCS file: /home/cvs/httpd-apreq-2/build/version_check.pl,v
retrieving revision 1.18
diff -u -r1.18 version_check.pl
--- build/version_check.pl	29 Jul 2004 16:22:31 -0000	1.18
+++ build/version_check.pl	7 Sep 2004 15:31:47 -0000
@@ -55,6 +55,7 @@
                     apu => { version => "0.9.4",   test => \&gnu_version,
                              comment => "bundled with apache2 2.0.46"    },
                    perl => { version => "5.6.1",   test => \&gnu_version },
+                libxml2 => { version => "2.2.0",   test => \&gnu_version },
             );
 
 my %perl_glue = (
Index: src/Makefile.am
===================================================================
RCS file: /home/cvs/httpd-apreq-2/src/Makefile.am,v
retrieving revision 1.22
diff -u -r1.22 Makefile.am
--- src/Makefile.am	25 Jul 2004 21:18:30 -0000	1.22
+++ src/Makefile.am	7 Sep 2004 15:31:47 -0000
@@ -1,5 +1,5 @@
 INCLUDES = @APR_INCLUDES@ @APU_INCLUDES@
-LIBS = @APR_LTLIBS@ @APU_LTLIBS@
+LIBS = @APR_LTLIBS@ @APU_LTLIBS@ @XML2_LTLIBS@
 LDFLAGS = @APR_LDFLAGS@ @APU_LDFLAGS@
 EXTRA_DIST = groups.dox.in
 BUILT_SOURCES= @APR_LA@ @APU_LA@
Index: src/apreq_params.h
===================================================================
RCS file: /home/cvs/httpd-apreq-2/src/apreq_params.h,v
retrieving revision 1.38
diff -u -r1.38 apreq_params.h
--- src/apreq_params.h	6 Sep 2004 21:21:06 -0000	1.38
+++ src/apreq_params.h	7 Sep 2004 15:31:48 -0000
@@ -340,6 +340,9 @@
  */
 APREQ_DECLARE_PARSER(apreq_parse_xml);
 
+
+APREQ_DECLARE_PARSER(apreq_parse_libxml2);
+
 /**
  * Construct a parser.
  *
Index: src/apreq_parsers.c
===================================================================
RCS file: /home/cvs/httpd-apreq-2/src/apreq_parsers.c,v
retrieving revision 1.62
diff -u -r1.62 apreq_parsers.c
--- src/apreq_parsers.c	6 Sep 2004 21:21:06 -0000	1.62
+++ src/apreq_parsers.c	7 Sep 2004 15:31:51 -0000
@@ -20,6 +20,9 @@
 #include "apr_strings.h"
 #include "apr_strmatch.h"
 #include "apr_xml.h"
+#include "libxml/parser.h"
+#include "libxml/tree.h"
+#include "apr_pools.h"
 
 #ifndef MAX
 #define MAX(A,B)  ( (A) > (B) ? (A) : (B) )
@@ -1187,6 +1190,100 @@
             return s;
         }
 
+    }
+
+    return APR_INCOMPLETE;
+
+}
+
+
+/* libxml2 parser */
+
+static apr_status_t libxml2_parser_cleanup(void *data)
+{
+    xmlParserCtxtPtr ctxt = data;
+    xmlDocPtr doc = ctxt->myDoc;
+    xmlFreeParserCtxt(ctxt);
+    if (doc)
+        xmlFreeDoc(doc);
+    return APR_SUCCESS;
+}
+
+struct libxml2_ctx {
+    xmlParserCtxtPtr         parser_ctx;
+
+    enum {
+        LIBXML2_INCOMPLETE,
+        LIBXML2_COMPLETE,
+        LIBXML2_ERROR
+    }                            status;
+
+};
+
+APREQ_DECLARE_PARSER(apreq_parse_libxml2)
+{
+    apr_pool_t *pool = apreq_env_pool(env);
+    struct libxml2_ctx *ctx = parser->ctx;
+    apr_status_t s = APR_SUCCESS;
+    apr_bucket *e = APR_BRIGADE_FIRST(bb);
+
+    if (ctx == NULL) {
+        parser->ctx = ctx = apr_palloc(pool, sizeof *ctx);
+        ctx->parser_ctx = xmlCreatePushParserCtxt(NULL,NULL,NULL,0,NULL);
+        if (ctx->parser_ctx) {
+            ctx->status = LIBXML2_INCOMPLETE;
+            apr_pool_cleanup_register(pool, ctx->parser_ctx, 
+                                      libxml2_parser_cleanup, 
+                                      libxml2_parser_cleanup);
+        }
+        else
+            ctx->status = LIBXML2_ERROR;
+    }
+    
+
+    PARSER_STATUS_CHECK(LIBXML2);
+
+    while (e != APR_BRIGADE_SENTINEL(bb))
+    {
+        const char *data;
+        apr_size_t dlen;
+
+        if (APR_BUCKET_IS_EOS(e)) {
+            xmlParseChunk(ctx->parser_ctx, NULL, 0, 1);
+            if (ctx->parser_ctx->wellFormed) {
+                ctx->status = LIBXML2_COMPLETE;
+                apr_bucket_delete(e);
+                return APR_SUCCESS;
+            }
+            else {
+                ctx->status = LIBXML2_ERROR;
+                apreq_log(APREQ_ERROR s, env, "apreq_parse_libxml2: "
+                          "final xmlParseChunk call failed");
+                return APR_EGENERAL;
+           }
+         }
+        else if (APR_BUCKET_IS_METADATA(e)) {
+            e = APR_BUCKET_NEXT(e);
+            continue;
+        }
+
+        s = apr_bucket_read(e, &data, &dlen, APR_BLOCK_READ);
+
+        if (s != APR_SUCCESS) {
+            ctx->status = LIBXML2_ERROR;
+            apreq_log(APREQ_ERROR s, env, "apreq_parse_libxml2: "
+                      "apr_bucket_read failed");
+            return s;
+        }
+
+        xmlParseChunk(ctx->parser_ctx, data, dlen, 0);
+        /*XXX check parser_ctx for failure */
+
+        do {
+            apr_bucket *f = e;
+            e = APR_BUCKET_NEXT(e);
+            apr_bucket_delete(f);
+        } while (0);
     }
 
     return APR_INCOMPLETE;
Index: src/apreq_version.h
===================================================================
RCS file: /home/cvs/httpd-apreq-2/src/apreq_version.h,v
retrieving revision 1.24
diff -u -r1.24 apreq_version.h
--- src/apreq_version.h	8 Aug 2004 18:42:06 -0000	1.24
+++ src/apreq_version.h	7 Sep 2004 15:31:51 -0000
@@ -61,7 +61,7 @@
 #define APREQ_MINOR_VERSION       0
 
 /** patch level */
-#define APREQ_PATCH_VERSION      20
+#define APREQ_PATCH_VERSION      21
 
 /** 
  *  This symbol is defined for internal, "development" copies of libapreq.
cvs server: Diffing t
Index: t/Makefile.am
===================================================================
RCS file: /home/cvs/httpd-apreq-2/t/Makefile.am,v
retrieving revision 1.19
diff -u -r1.19 Makefile.am
--- t/Makefile.am	16 Jul 2004 17:12:37 -0000	1.19
+++ t/Makefile.am	7 Sep 2004 15:31:51 -0000
@@ -1,5 +1,5 @@
 INCLUDES = -I../src @APR_INCLUDES@ @APU_INCLUDES@
-LIBS = ../src/libapreq2.la @APR_LTLIBS@ @APU_LTLIBS@
+LIBS = ../src/libapreq2.la @APR_LTLIBS@ @APU_LTLIBS@ @XML2_LTLIBS@
 LDFLAGS = @APR_LDFLAGS@ @APU_LDFLAGS@
 
 noinst_LIBRARIES = libapreq2_tests.a
Index: t/parsers.c
===================================================================
RCS file: /home/cvs/httpd-apreq-2/t/parsers.c,v
retrieving revision 1.21
diff -u -r1.21 parsers.c
--- t/parsers.c	6 Sep 2004 21:21:06 -0000	1.21
+++ t/parsers.c	7 Sep 2004 15:31:52 -0000
@@ -20,6 +20,7 @@
 #include "apreq_params.h"
 #include "apr_strings.h"
 #include "apr_xml.h"
+#include "libxml/parser.h"
 
 #define CRLF "\015\012"
 
@@ -46,6 +47,15 @@
 "  </params>"
 "</methodCall>";
 
+static char libxml2_data[] =
+"<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n"
+"<methodCall>\n"
+"  <methodName>foo.bar</methodName>\n"
+"  <params>\n"
+"    <param><value><int>1</int></value></param>\n"
+"  </params>\n"
+"</methodCall>\n";
+
 
 extern apr_bucket_brigade *bb;
 extern apr_table_t *table;
@@ -233,6 +243,39 @@
 
 }
 
+
+static void parse_libxml2(CuTest *tc)
+{
+    xmlChar *val;
+    int vlen;
+    apr_status_t rv;
+    xmlParserCtxtPtr ctxt;
+    xmlDocPtr doc;
+    apreq_request_t *req = apreq_request(APREQ_XML_ENCTYPE, "");
+    apr_bucket_brigade *bb = apr_brigade_create(p, 
+                                   apr_bucket_alloc_create(p));
+    apr_bucket *e = apr_bucket_immortal_create(libxml2_data,
+                                                   strlen(libxml2_data),
+                                                   bb->bucket_alloc);
+
+    CuAssertPtrNotNull(tc, req);
+    APR_BRIGADE_INSERT_HEAD(bb, e);
+    APR_BRIGADE_INSERT_TAIL(bb, apr_bucket_eos_create(bb->bucket_alloc));
+
+    req->body = NULL;
+    req->parser = apreq_make_parser(p, APREQ_XML_ENCTYPE, 
+                                    apreq_parse_libxml2, NULL, NULL);
+    rv = apreq_parse_request(req,bb);
+    CuAssertIntEquals(tc, APR_SUCCESS, rv);
+    ctxt = *(xmlParserCtxtPtr *)req->parser->ctx;
+    doc = ctxt->myDoc;
+    CuAssertPtrNotNull(tc, doc);
+    xmlDocDumpFormatMemory(doc, &val, &vlen, 1);
+    CuAssertIntEquals(tc, strlen(libxml2_data), vlen);
+    CuAssertStrEquals(tc, libxml2_data, (char *)val);
+}
+
+
 CuSuite *testparser(void)
 {
     CuSuite *suite = CuSuiteNew("Parsers");
@@ -240,6 +283,7 @@
     SUITE_ADD_TEST(suite, parse_multipart);
     SUITE_ADD_TEST(suite, parse_disable_uploads);
     SUITE_ADD_TEST(suite, parse_xml);
+    SUITE_ADD_TEST(suite, parse_libxml2);
     return suite;
 }
 


-- 
Joe Schaefer


Mime
View raw message