You are viewing a plain text version of this content. The canonical link for it is here.
Posted to apreq-cvs@httpd.apache.org by jo...@apache.org on 2004/09/06 23:21:06 UTC
cvs commit: httpd-apreq-2/t parsers.c
joes 2004/09/06 14:21:06
Modified: . CHANGES
src apreq_params.h apreq_parsers.c
t parsers.c
Log:
Add apreq_parse_xml parser.
Revision Changes Path
1.65 +4 -0 httpd-apreq-2/CHANGES
Index: CHANGES
===================================================================
RCS file: /home/cvs/httpd-apreq-2/CHANGES,v
retrieving revision 1.64
retrieving revision 1.65
diff -u -r1.64 -r1.65
--- CHANGES 30 Aug 2004 16:25:56 -0000 1.64
+++ CHANGES 6 Sep 2004 21:21:06 -0000 1.65
@@ -5,6 +5,10 @@
@section v2_05 Changes with libapreq2-2.05
+- C API [joes]
+ Add apreq_parse_xml parser, which is a simple wrapper
+ around APR's expat-based apr_xml_parser.
+
@section v2_04_dev Changes with libapreq2-2.04-dev (released August 30, 2004)
1.38 +13 -0 httpd-apreq-2/src/apreq_params.h
Index: apreq_params.h
===================================================================
RCS file: /home/cvs/httpd-apreq-2/src/apreq_params.h,v
retrieving revision 1.37
retrieving revision 1.38
diff -u -r1.37 -r1.38
--- apreq_params.h 31 Jul 2004 23:56:40 -0000 1.37
+++ apreq_params.h 6 Sep 2004 21:21:06 -0000 1.38
@@ -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.
*
1.62 +85 -0 httpd-apreq-2/src/apreq_parsers.c
Index: apreq_parsers.c
===================================================================
RCS file: /home/cvs/httpd-apreq-2/src/apreq_parsers.c,v
retrieving revision 1.61
retrieving revision 1.62
diff -u -r1.61 -r1.62
--- apreq_parsers.c 9 Aug 2004 00:34:17 -0000 1.61
+++ apreq_parsers.c 6 Sep 2004 21:21:06 -0000 1.62
@@ -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;
+
}
1.21 +43 -0 httpd-apreq-2/t/parsers.c
Index: parsers.c
===================================================================
RCS file: /home/cvs/httpd-apreq-2/t/parsers.c,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -r1.20 -r1.21
--- parsers.c 9 Aug 2004 00:34:17 -0000 1.20
+++ parsers.c 6 Sep 2004 21:21:06 -0000 1.21
@@ -19,6 +19,7 @@
#include "apreq.h"
#include "apreq_params.h"
#include "apr_strings.h"
+#include "apr_xml.h"
#define CRLF "\015\012"
@@ -36,6 +37,16 @@
"... contents of file1.txt ..." CRLF CRLF
"--AaB03x--" CRLF;
+static char xml_data[] =
+"<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>" /* length == 42 */
+"<methodCall>"
+" <methodName>foo.bar</methodName>"
+" <params>"
+" <param><value><int>1</int></value></param>"
+" </params>"
+"</methodCall>";
+
+
extern apr_bucket_brigade *bb;
extern apr_table_t *table;
@@ -190,6 +201,37 @@
CuAssertPtrEquals(tc, NULL, val);
}
+static void parse_xml(CuTest *tc)
+{
+ const char *val;
+ apr_size_t vlen;
+ apr_status_t rv;
+ int ns_map = 0;
+ apr_xml_doc *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(xml_data,
+ strlen(xml_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_xml, NULL, NULL);
+ rv = apreq_parse_request(req,bb);
+ CuAssertIntEquals(tc, APR_SUCCESS, rv);
+ doc = *(apr_xml_doc **)req->parser->ctx;
+ CuAssertPtrNotNull(tc, doc);
+ apr_xml_to_text(p, doc->root, APR_XML_X2T_FULL,
+ doc->namespaces, &ns_map, &val, &vlen);
+ CuAssertIntEquals(tc, strlen(xml_data), vlen + 42);
+ CuAssertStrEquals(tc, xml_data + 43, val);
+
+}
CuSuite *testparser(void)
{
@@ -197,6 +239,7 @@
SUITE_ADD_TEST(suite, parse_urlencoded);
SUITE_ADD_TEST(suite, parse_multipart);
SUITE_ADD_TEST(suite, parse_disable_uploads);
+ SUITE_ADD_TEST(suite, parse_xml);
return suite;
}