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 [PATCH] Basic apr_xml_parser
Date Mon, 06 Sep 2004 15:41:38 GMT

Here's a simple patch for starting the path to xml support.  
It compiles, but I'm hoping to get some suggestions on how 
this should interact with the rest of our API 
(especially Apache::Request). 

Right now all this does is parse the input
stream into an internal apr_xml_doc (which is only 
available after a full parse).  It will leave the req->body 
table empty.  Any ideas out there about how we should 
integrate the parsed doc into our Perl/C APIs?

Thanks!

Index: src/apreq_params.h
===================================================================
RCS file: /home/cvs/httpd-apreq-2/src/apreq_params.h,v
retrieving revision 1.37
diff -u -r1.37 apreq_params.h
--- src/apreq_params.h	31 Jul 2004 23:56:40 -0000	1.37
+++ src/apreq_params.h	6 Sep 2004 15:29:21 -0000
@@ -327,6 +327,19 @@
  */
 APREQ_DECLARE_PARSER(apreq_parse_multipart);
 
+
+
+/**
+ * application/xml expat-based parser. It will reject
+ * metabuckets, and it will parse until EOS appears.
+ * The parsed document isn't available until parsing has
+ * completed successfully.  The parser's ctx pointer may 
+ * be cast as (const apr_xml_doc **) to retrieve the 
+ * parsed document.  No table entries will be added to 
+ * req->body by this parser.
+ */
+APREQ_DECLARE_PARSER(apreq_parse_xml);
+
 /**
  * Construct a parser.
  *
Index: src/apreq_parsers.c
===================================================================
RCS file: /home/cvs/httpd-apreq-2/src/apreq_parsers.c,v
retrieving revision 1.61
diff -u -r1.61 apreq_parsers.c
--- src/apreq_parsers.c	9 Aug 2004 00:34:17 -0000	1.61
+++ src/apreq_parsers.c	6 Sep 2004 15:29:25 -0000
@@ -19,6 +19,7 @@
 #include "apr_lib.h"
 #include "apr_strings.h"
 #include "apr_strmatch.h"
+#include "apr_xml.h"
 
 #ifndef MAX
 #define MAX(A,B)  ( (A) > (B) ? (A) : (B) )
@@ -1106,4 +1107,88 @@
     apreq_log(APREQ_ERROR APR_EGENERAL, env, 
               "Uploads are disabled for this request.");
     return APR_EGENERAL;
+}
+
+
+/* XML parser */
+
+struct xml_ctx {
+    apr_xml_doc                 *doc;
+    apr_xml_parser              *xml_parser;
+    enum {
+        XML_INCOMPLETE,
+        XML_COMPLETE,
+        XML_ERROR
+    }                            status;
+};
+
+
+APREQ_DECLARE_PARSER(apreq_parse_xml)
+{
+    apr_pool_t *pool = apreq_env_pool(env);
+    struct xml_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->doc = NULL;
+        ctx->xml_parser = apr_xml_parser_create(pool);
+        ctx->status = XML_INCOMPLETE;
+    }
+    
+
+    PARSER_STATUS_CHECK(XML);
+
+    while (e != APR_BRIGADE_SENTINEL(bb))
+    {
+        const char *data;
+        apr_size_t dlen;
+
+        if (APR_BUCKET_IS_EOS(e)) {
+            s = apr_xml_parser_done(ctx->xml_parser, &ctx->doc);
+            if (s == APR_SUCCESS) {
+                ctx->status = XML_COMPLETE;
+                apr_bucket_delete(e);
+            }
+            else {
+                ctx->status = XML_ERROR;
+                apreq_log(APREQ_ERROR s, env, "apreq_parse_xml: "
+                          "apr_xml_parser_done failed");
+            }
+           return s;
+        }
+        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 = XML_ERROR;
+            apreq_log(APREQ_ERROR s, env, "apreq_parse_xml: "
+                      "apr_bucket_read failed");
+            return s;
+        }
+
+        s = apr_xml_parser_feed(ctx->xml_parser, data, dlen);
+
+        if (s == APR_SUCCESS) {
+            apr_bucket *f = e;
+            e = APR_BUCKET_NEXT(e);
+            apr_bucket_delete(f);
+            continue;
+        }
+        else {
+            ctx->status = XML_ERROR;
+            apreq_log(APREQ_ERROR s, env, "apreq_parse_xml: "
+                      "apr_xml_parser_feed failed");
+            return s;
+        }
+
+    }
+
+    return APR_INCOMPLETE;
+
 }

-- 
Joe Schaefer


Mime
View raw message