1251881Speter/* 2251881Speter * getdate.c : entry point for get_dated_revision for ra_serf 3251881Speter * 4251881Speter * ==================================================================== 5251881Speter * Licensed to the Apache Software Foundation (ASF) under one 6251881Speter * or more contributor license agreements. See the NOTICE file 7251881Speter * distributed with this work for additional information 8251881Speter * regarding copyright ownership. The ASF licenses this file 9251881Speter * to you under the Apache License, Version 2.0 (the 10251881Speter * "License"); you may not use this file except in compliance 11251881Speter * with the License. You may obtain a copy of the License at 12251881Speter * 13251881Speter * http://www.apache.org/licenses/LICENSE-2.0 14251881Speter * 15251881Speter * Unless required by applicable law or agreed to in writing, 16251881Speter * software distributed under the License is distributed on an 17251881Speter * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 18251881Speter * KIND, either express or implied. See the License for the 19251881Speter * specific language governing permissions and limitations 20251881Speter * under the License. 21251881Speter * ==================================================================== 22251881Speter */ 23251881Speter 24251881Speter 25251881Speter 26251881Speter#include <apr_uri.h> 27251881Speter#include <serf.h> 28251881Speter 29251881Speter#include "svn_pools.h" 30251881Speter#include "svn_ra.h" 31251881Speter#include "svn_time.h" 32251881Speter#include "svn_xml.h" 33251881Speter 34251881Speter#include "private/svn_dav_protocol.h" 35251881Speter 36251881Speter#include "svn_private_config.h" 37251881Speter 38251881Speter#include "../libsvn_ra/ra_loader.h" 39251881Speter 40251881Speter#include "ra_serf.h" 41251881Speter 42251881Speter 43251881Speter/* 44251881Speter * This enum represents the current state of our XML parsing for a REPORT. 45251881Speter */ 46251881Speterenum date_state_e { 47299742Sdim INITIAL = XML_STATE_INITIAL, 48251881Speter REPORT, 49251881Speter VERSION_NAME 50251881Speter}; 51251881Speter 52251881Speter 53251881Spetertypedef struct date_context_t { 54251881Speter /* The time asked about. */ 55251881Speter apr_time_t time; 56251881Speter 57251881Speter /* What was the youngest revision at that time? */ 58251881Speter svn_revnum_t *revision; 59251881Speter 60251881Speter} date_context_t; 61251881Speter 62251881Speter#define D_ "DAV:" 63251881Speter#define S_ SVN_XML_NAMESPACE 64251881Speterstatic const svn_ra_serf__xml_transition_t date_ttable[] = { 65251881Speter { INITIAL, S_, "dated-rev-report", REPORT, 66251881Speter FALSE, { NULL }, FALSE }, 67251881Speter 68251881Speter { REPORT, D_, SVN_DAV__VERSION_NAME, VERSION_NAME, 69251881Speter TRUE, { NULL }, TRUE }, 70251881Speter 71251881Speter { 0 } 72251881Speter}; 73251881Speter 74251881Speter 75251881Speter/* Conforms to svn_ra_serf__xml_closed_t */ 76251881Speterstatic svn_error_t * 77251881Speterdate_closed(svn_ra_serf__xml_estate_t *xes, 78251881Speter void *baton, 79251881Speter int leaving_state, 80251881Speter const svn_string_t *cdata, 81251881Speter apr_hash_t *attrs, 82251881Speter apr_pool_t *scratch_pool) 83251881Speter{ 84251881Speter date_context_t *date_ctx = baton; 85299742Sdim apr_int64_t rev; 86251881Speter 87251881Speter SVN_ERR_ASSERT(leaving_state == VERSION_NAME); 88251881Speter SVN_ERR_ASSERT(cdata != NULL); 89251881Speter 90299742Sdim SVN_ERR(svn_cstring_atoi64(&rev, cdata->data)); 91251881Speter 92299742Sdim *date_ctx->revision = (svn_revnum_t)rev; 93299742Sdim 94251881Speter return SVN_NO_ERROR; 95251881Speter} 96251881Speter 97251881Speter 98251881Speter/* Implements svn_ra_serf__request_body_delegate_t */ 99251881Speterstatic svn_error_t * 100251881Spetercreate_getdate_body(serf_bucket_t **body_bkt, 101251881Speter void *baton, 102251881Speter serf_bucket_alloc_t *alloc, 103299742Sdim apr_pool_t *pool /* request pool */, 104299742Sdim apr_pool_t *scratch_pool) 105251881Speter{ 106251881Speter serf_bucket_t *buckets; 107251881Speter date_context_t *date_ctx = baton; 108251881Speter 109251881Speter buckets = serf_bucket_aggregate_create(alloc); 110251881Speter 111251881Speter svn_ra_serf__add_open_tag_buckets(buckets, alloc, "S:dated-rev-report", 112251881Speter "xmlns:S", SVN_XML_NAMESPACE, 113251881Speter "xmlns:D", "DAV:", 114299742Sdim SVN_VA_NULL); 115251881Speter 116251881Speter svn_ra_serf__add_tag_buckets(buckets, 117251881Speter "D:" SVN_DAV__CREATIONDATE, 118251881Speter svn_time_to_cstring(date_ctx->time, pool), 119251881Speter alloc); 120251881Speter 121251881Speter svn_ra_serf__add_close_tag_buckets(buckets, alloc, "S:dated-rev-report"); 122251881Speter 123251881Speter *body_bkt = buckets; 124251881Speter return SVN_NO_ERROR; 125251881Speter} 126251881Speter 127251881Spetersvn_error_t * 128251881Spetersvn_ra_serf__get_dated_revision(svn_ra_session_t *ra_session, 129251881Speter svn_revnum_t *revision, 130251881Speter apr_time_t tm, 131251881Speter apr_pool_t *pool) 132251881Speter{ 133251881Speter date_context_t *date_ctx; 134251881Speter svn_ra_serf__session_t *session = ra_session->priv; 135251881Speter svn_ra_serf__handler_t *handler; 136251881Speter svn_ra_serf__xml_context_t *xmlctx; 137251881Speter const char *report_target; 138251881Speter 139251881Speter date_ctx = apr_palloc(pool, sizeof(*date_ctx)); 140251881Speter date_ctx->time = tm; 141251881Speter date_ctx->revision = revision; 142251881Speter 143299742Sdim SVN_ERR(svn_ra_serf__report_resource(&report_target, session, pool)); 144251881Speter 145251881Speter xmlctx = svn_ra_serf__xml_context_create(date_ttable, 146251881Speter NULL, date_closed, NULL, 147251881Speter date_ctx, 148251881Speter pool); 149299742Sdim handler = svn_ra_serf__create_expat_handler(session, xmlctx, NULL, pool); 150251881Speter 151251881Speter handler->method = "REPORT"; 152251881Speter handler->path = report_target; 153251881Speter handler->body_type = "text/xml"; 154251881Speter 155251881Speter handler->body_delegate = create_getdate_body; 156251881Speter handler->body_delegate_baton = date_ctx; 157251881Speter 158251881Speter *date_ctx->revision = SVN_INVALID_REVNUM; 159251881Speter 160299742Sdim SVN_ERR(svn_ra_serf__context_run_one(handler, pool)); 161251881Speter 162299742Sdim if (handler->sline.code != 200) 163299742Sdim return svn_error_trace(svn_ra_serf__unexpected_status(handler)); 164253734Speter 165299742Sdim if (!SVN_IS_VALID_REVNUM(*revision)) 166299742Sdim return svn_error_create(SVN_ERR_RA_DAV_PROPS_NOT_FOUND, NULL, 167299742Sdim _("The REPORT response did not include " 168299742Sdim "the requested properties")); 169253734Speter 170253734Speter return SVN_NO_ERROR; 171251881Speter} 172