/* Create a status parser attached to the request REQ. Detected errors will be returned there. */ static void multistatus_parser_create(svn_ra_neon__request_t *req) { multistatus_baton_t *b = apr_pcalloc(req->pool, sizeof(*b)); /* Create a parser, attached to REQ. (Ignore the return value.) */ svn_ra_neon__xml_parser_create(req, ne_accept_207, start_207_element, svn_ra_neon__xml_collect_cdata, end_207_element, b); b->cdata = svn_stringbuf_create("", req->pool); b->description = svn_stringbuf_create("", req->pool); b->req = req; b->propname = svn_stringbuf_create("", req->pool); b->propstat_description = svn_stringbuf_create("", req->pool); }
svn_error_t * svn_ra_neon__exchange_capabilities(svn_ra_neon__session_t *ras, apr_pool_t *pool) { svn_ra_neon__request_t* req; svn_error_t *err = SVN_NO_ERROR; ne_xml_parser *parser = NULL; options_ctx_t oc = { 0 }; const char *msg; int status_code; oc.pool = pool; oc.cdata = svn_stringbuf_create("", pool); req = svn_ra_neon__request_create(ras, "OPTIONS", ras->url->data, pool); /* ### Use a symbolic name somewhere for this MIME type? */ ne_add_request_header(req->ne_req, "Content-Type", "text/xml"); /* Create a parser to read the normal response body */ parser = svn_ra_neon__xml_parser_create(req, ne_accept_2xx, start_element, svn_ra_neon__xml_collect_cdata, end_element, &oc); /* Run the request and get the resulting status code. */ if ((err = svn_ra_neon__request_dispatch(&status_code, req, NULL, "<?xml version=\"1.0\" " "encoding=\"utf-8\"?>" "<D:options xmlns:D=\"DAV:\">" "<D:activity-collection-set/>" "</D:options>", 200, 0, pool))) goto cleanup; /* Was there an XML parse error somewhere? */ msg = ne_xml_get_error(parser); if (msg && *msg) { err = svn_error_createf(SVN_ERR_RA_DAV_REQUEST_FAILED, NULL, _("The %s request returned invalid XML " "in the response: %s (%s)"), "OPTIONS", msg, ras->url->data); goto cleanup; } /* We asked for, and therefore expect, to have found an activity collection in the response. */ if (oc.activity_coll == NULL) { err = svn_error_create(SVN_ERR_RA_DAV_OPTIONS_REQ_FAILED, NULL, _("The OPTIONS response did not include the " "requested activity-collection-set; this often " "means that the URL is not WebDAV-enabled")); goto cleanup; } ras->act_coll = apr_pstrdup(ras->pool, oc.activity_coll->data); parse_capabilities(req->ne_req, ras, pool); cleanup: svn_ra_neon__request_destroy(req); return err; }
/* See doc string for svn_ra_neon__parsed_request. */ static svn_error_t * parsed_request(svn_ra_neon__request_t *req, svn_ra_neon__session_t *ras, const char *method, const char *url, const char *body, apr_file_t *body_file, void set_parser(ne_xml_parser *parser, void *baton), svn_ra_neon__startelm_cb_t startelm_cb, svn_ra_neon__cdata_cb_t cdata_cb, svn_ra_neon__endelm_cb_t endelm_cb, void *baton, apr_hash_t *extra_headers, int *status_code, svn_boolean_t spool_response, apr_pool_t *pool) { ne_xml_parser *success_parser = NULL; spool_reader_baton_t spool_reader_baton; if (body == NULL) SVN_ERR(svn_ra_neon__set_neon_body_provider(req, body_file)); /* ### use a symbolic name somewhere for this MIME type? */ ne_add_request_header(req->ne_req, "Content-Type", "text/xml"); /* create a parser to read the normal response body */ success_parser = svn_ra_neon__xml_parser_create(req, NULL, startelm_cb, cdata_cb, endelm_cb, baton); /* if our caller is interested in having access to this parser, call the SET_PARSER callback with BATON. */ if (set_parser != NULL) set_parser(success_parser, baton); /* Register the "main" accepter and body-reader with the request -- the one to use when the HTTP status is 2XX. If we are spooling the response to disk first, we use our custom spool reader. */ if (spool_response) { /* Blow the temp-file away as soon as we eliminate the entire request */ SVN_ERR(svn_io_open_unique_file3(&spool_reader_baton.spool_file, &spool_reader_baton.spool_file_name, NULL, svn_io_file_del_on_pool_cleanup, req->pool, pool)); spool_reader_baton.req = req; svn_ra_neon__add_response_body_reader(req, ne_accept_2xx, spool_reader, &spool_reader_baton); } else attach_ne_body_reader(req, ne_accept_2xx, cancellation_callback, get_cancellation_baton(req, ne_xml_parse_v, success_parser, pool)); /* run the request and get the resulting status code. */ SVN_ERR(svn_ra_neon__request_dispatch( status_code, req, extra_headers, body, (strcmp(method, "PROPFIND") == 0) ? 207 : 200, 0, pool)); if (spool_response) { /* All done with the temporary file we spooled the response into. */ (void) apr_file_close(spool_reader_baton.spool_file); /* The success parser may set an error value in req->err */ SVN_RA_NEON__REQ_ERR (req, parse_spool_file(ras, spool_reader_baton.spool_file_name, success_parser, req->pool)); if (req->err) { svn_error_compose(req->err, svn_error_createf (SVN_ERR_RA_DAV_REQUEST_FAILED, NULL, _("Error reading spooled %s request response"), method)); return req->err; } } SVN_ERR(svn_ra_neon__check_parse_error(method, success_parser, url)); return SVN_NO_ERROR; }