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;
   }