]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Feature #1005: libxml2 as ESI parser
authorhno <>
Fri, 10 Dec 2004 07:49:53 +0000 (07:49 +0000)
committerhno <>
Fri, 10 Dec 2004 07:49:53 +0000 (07:49 +0000)
by jojo@fistofbenztown.de (Joachim Bauch)

Todo: With this is becomes an apparent need to modularize the ESI parsers
slightly to allow the user to select which ESI parsers to build.

CONTRIBUTORS
configure.in
src/ESILibxml2Parser.cc [new file with mode: 0644]
src/ESILibxml2Parser.h [new file with mode: 0644]
src/ESIParser.cc
src/Makefile.am
src/cf.data.pre

index c367455f028b8d10c73605c2ab9525515085f273..d16511eed7ee738d26452d97cf564fc93e865aea 100644 (file)
@@ -91,5 +91,6 @@ and ideas to make this software available.
        Leeann Bent <lbent@cs.ucsd.edu>
        Bruce Murphy <pack-squid@rattus.net>
        Francis Daly <francis@daoine.org>
+       Joachim Bauch <jojo@fistofbenztown.de>
 
        Duane Wessels <wessels@squid-cache.org>
index 3986ebaa94625cf4817362a7dc5f77cb7a0d0a15..84c08494113d72aa71ff7dc35cfc39803066da09 100644 (file)
@@ -3,7 +3,7 @@ dnl  Configuration input file for Squid
 dnl
 dnl  Duane Wessels, wessels@nlanr.net, February 1996 (autoconf v2.9)
 dnl
-dnl  $Id: configure.in,v 1.362 2004/10/20 22:41:03 hno Exp $
+dnl  $Id: configure.in,v 1.363 2004/12/10 00:49:53 hno Exp $
 dnl
 dnl
 dnl
@@ -13,7 +13,7 @@ AC_CONFIG_SRCDIR([src/main.cc])
 AC_CONFIG_AUX_DIR(cfgaux)
 AM_INIT_AUTOMAKE(squid, 3.0-PRE3-CVS)
 AM_CONFIG_HEADER(include/autoconf.h)
-AC_REVISION($Revision: 1.362 $)dnl
+AC_REVISION($Revision: 1.363 $)dnl
 AC_PREFIX_DEFAULT(/usr/local/squid)
 AM_MAINTAINER_MODE
 
@@ -562,7 +562,7 @@ AC_CACHE_CHECK(whether to enable ESI,ac_cv_use_esi, ac_cv_use_esi=no)
 if test "$ac_cv_use_esi" = "yes" ; then
   AC_DEFINE(ESI,1,[Compile the ESI processor and Surrogate header support])
   AM_CONDITIONAL(USE_ESI, true)
-  XTRA_LIBS="$XTRA_LIBS -lexpat"
+  XTRA_LIBS="$XTRA_LIBS -lexpat -lxml2"
 else
   AC_DEFINE(ESI,0,[Compile the ESI processor and Surrogate header support])
 fi
diff --git a/src/ESILibxml2Parser.cc b/src/ESILibxml2Parser.cc
new file mode 100644 (file)
index 0000000..293d414
--- /dev/null
@@ -0,0 +1,154 @@
+/*
+ * $Id: ESILibxml2Parser.cc,v 1.1 2004/12/10 00:49:53 hno Exp $
+ *
+ * AUTHOR: Joachim Bauch (mail@joachim-bauch.de)
+ *
+ * SQUID Web Proxy Cache          http://www.squid-cache.org/
+ * ----------------------------------------------------------
+ *
+ *  Squid is the result of efforts by numerous individuals from
+ *  the Internet community; see the CONTRIBUTORS file for full
+ *  details.   Many organizations have provided support for Squid's
+ *  development; see the SPONSORS file for full details.  Squid is
+ *  Copyrighted (C) 2001 by the Regents of the University of
+ *  California; see the COPYRIGHT file for full details.  Squid
+ *  incorporates software developed and/or copyrighted by other
+ *  sources; see the CREDITS file for full details.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *  
+ *  This program is distributed in the hope that it will be useful,
+ ;  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *  
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
+ *
+ */
+
+/*
+ * The ESI Libxml2 parser is Copyright (c) 2004 by Joachim Bauch
+ * http://www.joachim-bauch.de
+ * mail@joachim-bauch.de
+ */
+
+#include "squid.h"
+#include "ESILibxml2Parser.h"
+
+#ifdef sprintf
+// ugly, but needed to use correct sprintf function below
+#undef sprintf
+#endif
+
+#include <stdio.h>
+
+// the global document that will store the resolved entity
+// definitions
+static htmlDocPtr entity_doc = NULL;
+
+// the SAX callback functions
+void esi_startElementSAXFunc(void * ctx, const xmlChar * name, const xmlChar ** atts)
+{
+    int count=0;
+    xmlChar **tmp = (xmlChar **)atts;
+
+    while (tmp && *tmp != NULL) {
+        count++;
+        tmp++;
+    }
+
+    // we increased on every key and value
+    count /= 2;
+
+    ESILibxml2Parser *p = (ESILibxml2Parser *)ctx;
+
+    p->getClient()->start((const char *)name, (const char **)atts, count);
+}
+
+void esi_endElementSAXFunc(void * ctx, const xmlChar * name)
+{
+    ESILibxml2Parser *p = (ESILibxml2Parser *)ctx;
+    p->getClient()->end((const char *)name);
+}
+
+void esi_commentSAXFunc(void * ctx, const xmlChar * value)
+{
+    ESILibxml2Parser *p = (ESILibxml2Parser *)ctx;
+    p->getClient()->parserComment((const char *)value);
+}
+
+void esi_charactersSAXFunc(void *ctx, const xmlChar *ch, int len)
+{
+    ESILibxml2Parser *p = (ESILibxml2Parser *)ctx;
+    p->getClient()->parserDefault((const char *)ch, len);
+}
+
+xmlEntityPtr esi_getEntitySAXFunc(void * ctx,  const xmlChar * name)
+{
+    xmlEntityPtr res = xmlGetDocEntity(entity_doc, name);
+
+    if (res == NULL) {
+        const htmlEntityDesc *ent = htmlEntityLookup(name);
+
+        if (ent != NULL) {
+            char tmp[32];
+            sprintf(tmp, "&#%d;", ent->value);
+            res = xmlAddDocEntity(entity_doc, (const xmlChar *)name, XML_INTERNAL_GENERAL_ENTITY, NULL, NULL, (const xmlChar *)tmp);
+        }
+    }
+
+    return res;
+}
+
+ESILibxml2Parser::ESILibxml2Parser(ESIParserClient *aClient) : theClient (aClient)
+{
+    xmlSAXHandler sax;
+    htmlDefaultSAXHandlerInit();
+    memset(&sax, 0, sizeof(sax));
+    sax.startElement = esi_startElementSAXFunc;
+    sax.endElement = esi_endElementSAXFunc;
+    sax.comment = esi_commentSAXFunc;
+    sax.characters = esi_charactersSAXFunc;
+    sax.getEntity = esi_getEntitySAXFunc;
+
+    /* TODO: grab the document encoding from the headers */
+    parser = xmlCreatePushParserCtxt(&sax, static_cast<void *>(this), NULL, 0, NULL);
+    xmlSetFeature(parser, "substitute entities", 0);
+
+    if (entity_doc == NULL)
+        entity_doc = htmlNewDoc(NULL, NULL);
+}
+
+ESILibxml2Parser::~ESILibxml2Parser()
+{
+    xmlFreeParserCtxt(parser);
+    parser = NULL;
+}
+
+bool
+ESILibxml2Parser::parse(char const *dataToParse, size_t const lengthOfData, bool const endOfStream)
+{
+    return (xmlParseChunk(parser, dataToParse, lengthOfData, endOfStream) == 0);
+}
+
+size_t
+ESILibxml2Parser::lineNumber() const
+{
+    return xmlSAX2GetLineNumber(parser);
+}
+
+char const *
+ESILibxml2Parser::errorString() const
+{
+    xmlErrorPtr error = xmlGetLastError();
+
+    if (error == NULL)
+        return NULL;
+
+    return error->message;
+}
diff --git a/src/ESILibxml2Parser.h b/src/ESILibxml2Parser.h
new file mode 100644 (file)
index 0000000..b1b7094
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * $Id: ESILibxml2Parser.h,v 1.1 2004/12/10 00:49:53 hno Exp $
+ *
+ * AUTHOR: Joachim Bauch (mail@joachim-bauch.de)
+ *
+ * SQUID Web Proxy Cache          http://www.squid-cache.org/
+ * ----------------------------------------------------------
+ *
+ *  Squid is the result of efforts by numerous individuals from
+ *  the Internet community; see the CONTRIBUTORS file for full
+ *  details.   Many organizations have provided support for Squid's
+ *  development; see the SPONSORS file for full details.  Squid is
+ *  Copyrighted (C) 2001 by the Regents of the University of
+ *  California; see the COPYRIGHT file for full details.  Squid
+ *  incorporates software developed and/or copyrighted by other
+ *  sources; see the CREDITS file for full details.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *  
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *  
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
+ *
+ */
+
+/*
+ * The ESI Libxml2 parser is Copyright (c) 2004 by Joachim Bauch
+ * http://www.joachim-bauch.de
+ * mail@joachim-bauch.de
+ */
+
+#ifndef SQUID_ESILIBXML2PARSER_H
+#define SQUID_ESILIBXML2PARSER_H
+
+#include "ESIParser.h"
+// workaround for definition of "free" that prevents include of
+// parser.h from libxml2 without errors
+#ifdef free
+#define OLD_FREE free
+#undef free
+#endif
+#include <libxml/parser.h>
+#include <libxml/HTMLparser.h>
+#include <libxml/HTMLtree.h>
+
+#ifdef OLD_FREE
+#define free OLD_FREE
+#endif
+
+class ESILibxml2Parser : public ESIParser
+{
+
+public:
+    ESILibxml2Parser(ESIParserClient *);
+    ~ESILibxml2Parser();
+    /* true on success */
+    bool parse(char const *dataToParse, size_t const lengthOfData, bool const endOfStream);
+    size_t lineNumber() const;
+    char const * errorString() const;
+
+    ESIParserClient *getClient() { return theClient; }
+
+private:
+    mutable xmlParserCtxtPtr parser; /* our parser */
+
+    ESIParserClient *theClient;
+};
+
+#endif /* SQUID_ESILIBXML2PARSER_H */
index aa433cad45b0957f9e66ff061184a97ca6f0591e..d31e5d7b64828ab0e0eb1b2f99b80aae4d72da45 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: ESIParser.cc,v 1.1 2003/03/10 04:56:35 robertc Exp $
+ * $Id: ESIParser.cc,v 1.2 2004/12/10 00:49:53 hno Exp $
  *
  * DEBUG: section 86    ESI processing
  * AUTHOR: Robert Collins
 #include "ESIParser.h"
 #include "ESIExpatParser.h"
 #include "ESICustomParser.h"
+#include "ESILibxml2Parser.h"
 
 char *ESIParser::Type = NULL;
 
 ESIParser::Pointer
 ESIParser::NewParser(ESIParserClient *aClient)
 {
+    if (!strcasecmp("libxml2", Type))
+        return new ESILibxml2Parser (aClient);
+
     if (!strcasecmp("expat", Type))
         return new ESIExpatParser (aClient);
 
index 449c1567255e4da9afef3c383511daeaaa1e6c65..38bf75acd3b9a57a657eec05312f3c6696c088de 100644 (file)
@@ -1,7 +1,7 @@
 #
 #  Makefile for the Squid Object Cache server
 #
-#  $Id: Makefile.am,v 1.95 2004/10/25 12:40:20 hno Exp $
+#  $Id: Makefile.am,v 1.96 2004/12/10 00:49:53 hno Exp $
 #
 #  Uncomment and customize the following to suit your needs:
 #
@@ -75,6 +75,8 @@ ESI_ALL_SOURCE = \
        ESIInclude.cc \
        ESIInclude.h \
        ESILiteral.h \
+       ESILibxml2Parser.cc \
+       ESILibxml2Parser.h \
        ESIParser.cc \
        ESIParser.h \
        ESISegment.cc \
@@ -165,7 +167,7 @@ AM_CXXFLAGS = @SQUID_CXXFLAGS@
 
 SUBDIRS                = fs repl auth
 
-INCLUDES        = -I. -I$(srcdir) -I$(top_builddir)/include -I$(top_srcdir)/include -I$(top_srcdir)/lib/libTrie/include
+INCLUDES        = -I/usr/include/libxml2 -I. -I$(srcdir) -I$(top_builddir)/include -I$(top_srcdir)/include -I$(top_srcdir)/lib/libTrie/include
 
 EXTRA_PROGRAMS = \
        unlinkd \
index 467f12cd85ad81eb64e8a94490a88b6d5e21751c..ceb7cf8dd536b77376bc86f0b6a0970a73b5cf88 100644 (file)
@@ -1,6 +1,6 @@
 
 #
-# $Id: cf.data.pre,v 1.363 2004/12/08 00:24:42 hno Exp $
+# $Id: cf.data.pre,v 1.364 2004/12/10 00:49:54 hno Exp $
 #
 #
 # SQUID Web Proxy Cache          http://www.squid-cache.org/
@@ -3006,7 +3006,7 @@ DOC_END
 
 NAME: esi_parser
 IFDEF: ESI
-COMMENT: expat|custom
+COMMENT: libxml2|expat|custom
 TYPE: string
 LOC: ESIParser::Type
 DEFAULT: custom
@@ -4147,7 +4147,7 @@ DOC_START
 DOC_END
 
 NAME: mcast_miss_ttl
-IFDEF: MULTICAST_MISS_TTL
+IFDEF: MULTICAST_MISS_STREAM
 TYPE: ushort
 LOC: Config.mcast_miss.ttl
 DEFAULT: 16