1251881Speter/* 2251881Speter * getlocationsegments.c : entry point for get_location_segments 3251881Speter * RA functions for ra_serf 4251881Speter * 5251881Speter * ==================================================================== 6251881Speter * Licensed to the Apache Software Foundation (ASF) under one 7251881Speter * or more contributor license agreements. See the NOTICE file 8251881Speter * distributed with this work for additional information 9251881Speter * regarding copyright ownership. The ASF licenses this file 10251881Speter * to you under the Apache License, Version 2.0 (the 11251881Speter * "License"); you may not use this file except in compliance 12251881Speter * with the License. You may obtain a copy of the License at 13251881Speter * 14251881Speter * http://www.apache.org/licenses/LICENSE-2.0 15251881Speter * 16251881Speter * Unless required by applicable law or agreed to in writing, 17251881Speter * software distributed under the License is distributed on an 18251881Speter * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 19251881Speter * KIND, either express or implied. See the License for the 20251881Speter * specific language governing permissions and limitations 21251881Speter * under the License. 22251881Speter * ==================================================================== 23251881Speter */ 24251881Speter 25251881Speter 26251881Speter 27251881Speter#include <apr_uri.h> 28251881Speter#include <serf.h> 29251881Speter 30251881Speter#include "svn_hash.h" 31251881Speter#include "svn_pools.h" 32251881Speter#include "svn_ra.h" 33251881Speter#include "svn_xml.h" 34251881Speter#include "svn_path.h" 35251881Speter#include "svn_private_config.h" 36251881Speter#include "../libsvn_ra/ra_loader.h" 37251881Speter 38251881Speter#include "ra_serf.h" 39251881Speter 40251881Speter 41251881Speter 42251881Spetertypedef struct gls_context_t { 43251881Speter /* parameters set by our caller */ 44251881Speter svn_revnum_t peg_revision; 45251881Speter svn_revnum_t start_rev; 46251881Speter svn_revnum_t end_rev; 47251881Speter const char *path; 48251881Speter 49251881Speter /* location segment callback function/baton */ 50251881Speter svn_location_segment_receiver_t receiver; 51251881Speter void *receiver_baton; 52251881Speter 53251881Speter} gls_context_t; 54251881Speter 55299742Sdimenum locseg_state_e { 56299742Sdim INITIAL = XML_STATE_INITIAL, 57251881Speter REPORT, 58251881Speter SEGMENT 59251881Speter}; 60251881Speter 61251881Speter#define D_ "DAV:" 62251881Speter#define S_ SVN_XML_NAMESPACE 63251881Speterstatic const svn_ra_serf__xml_transition_t gls_ttable[] = { 64251881Speter { INITIAL, S_, "get-location-segments-report", REPORT, 65251881Speter FALSE, { NULL }, FALSE }, 66251881Speter 67251881Speter { REPORT, S_, "location-segment", SEGMENT, 68251881Speter FALSE, { "?path", "range-start", "range-end", NULL }, TRUE }, 69251881Speter 70251881Speter { 0 } 71251881Speter}; 72251881Speter 73251881Speter 74251881Speter/* Conforms to svn_ra_serf__xml_closed_t */ 75251881Speterstatic svn_error_t * 76251881Spetergls_closed(svn_ra_serf__xml_estate_t *xes, 77251881Speter void *baton, 78251881Speter int leaving_state, 79251881Speter const svn_string_t *cdata, 80251881Speter apr_hash_t *attrs, 81251881Speter apr_pool_t *scratch_pool) 82251881Speter{ 83251881Speter gls_context_t *gls_ctx = baton; 84251881Speter const char *path; 85251881Speter const char *start_str; 86251881Speter const char *end_str; 87299742Sdim apr_int64_t start_val; 88299742Sdim apr_int64_t end_val; 89251881Speter svn_location_segment_t segment; 90251881Speter 91251881Speter SVN_ERR_ASSERT(leaving_state == SEGMENT); 92251881Speter 93251881Speter path = svn_hash_gets(attrs, "path"); 94251881Speter start_str = svn_hash_gets(attrs, "range-start"); 95251881Speter end_str = svn_hash_gets(attrs, "range-end"); 96251881Speter 97251881Speter /* The transition table said these must exist. */ 98251881Speter SVN_ERR_ASSERT(start_str && end_str); 99251881Speter 100299742Sdim SVN_ERR(svn_cstring_atoi64(&start_val, start_str)); 101299742Sdim SVN_ERR(svn_cstring_atoi64(&end_val, end_str)); 102299742Sdim 103251881Speter segment.path = path; /* may be NULL */ 104299742Sdim segment.range_start = (svn_revnum_t)start_val; 105299742Sdim segment.range_end = (svn_revnum_t)end_val; 106251881Speter SVN_ERR(gls_ctx->receiver(&segment, gls_ctx->receiver_baton, scratch_pool)); 107251881Speter 108251881Speter return SVN_NO_ERROR; 109251881Speter} 110251881Speter 111251881Speter 112251881Speter/* Implements svn_ra_serf__request_body_delegate_t */ 113251881Speterstatic svn_error_t * 114251881Spetercreate_gls_body(serf_bucket_t **body_bkt, 115251881Speter void *baton, 116251881Speter serf_bucket_alloc_t *alloc, 117299742Sdim apr_pool_t *pool /* request pool */, 118299742Sdim apr_pool_t *scratch_pool) 119251881Speter{ 120251881Speter serf_bucket_t *buckets; 121251881Speter gls_context_t *gls_ctx = baton; 122251881Speter 123251881Speter buckets = serf_bucket_aggregate_create(alloc); 124251881Speter 125251881Speter svn_ra_serf__add_open_tag_buckets(buckets, alloc, 126251881Speter "S:get-location-segments", 127251881Speter "xmlns:S", SVN_XML_NAMESPACE, 128299742Sdim SVN_VA_NULL); 129251881Speter 130251881Speter svn_ra_serf__add_tag_buckets(buckets, 131251881Speter "S:path", gls_ctx->path, 132251881Speter alloc); 133251881Speter 134251881Speter svn_ra_serf__add_tag_buckets(buckets, 135251881Speter "S:peg-revision", 136251881Speter apr_ltoa(pool, gls_ctx->peg_revision), 137251881Speter alloc); 138251881Speter 139251881Speter svn_ra_serf__add_tag_buckets(buckets, 140251881Speter "S:start-revision", 141251881Speter apr_ltoa(pool, gls_ctx->start_rev), 142251881Speter alloc); 143251881Speter 144251881Speter svn_ra_serf__add_tag_buckets(buckets, 145251881Speter "S:end-revision", 146251881Speter apr_ltoa(pool, gls_ctx->end_rev), 147251881Speter alloc); 148251881Speter 149251881Speter svn_ra_serf__add_close_tag_buckets(buckets, alloc, 150251881Speter "S:get-location-segments"); 151251881Speter 152251881Speter *body_bkt = buckets; 153251881Speter return SVN_NO_ERROR; 154251881Speter} 155251881Speter 156251881Spetersvn_error_t * 157251881Spetersvn_ra_serf__get_location_segments(svn_ra_session_t *ra_session, 158251881Speter const char *path, 159251881Speter svn_revnum_t peg_revision, 160251881Speter svn_revnum_t start_rev, 161251881Speter svn_revnum_t end_rev, 162251881Speter svn_location_segment_receiver_t receiver, 163251881Speter void *receiver_baton, 164251881Speter apr_pool_t *pool) 165251881Speter{ 166251881Speter gls_context_t *gls_ctx; 167251881Speter svn_ra_serf__session_t *session = ra_session->priv; 168251881Speter svn_ra_serf__handler_t *handler; 169251881Speter svn_ra_serf__xml_context_t *xmlctx; 170251881Speter const char *req_url; 171251881Speter svn_error_t *err; 172251881Speter 173251881Speter gls_ctx = apr_pcalloc(pool, sizeof(*gls_ctx)); 174251881Speter gls_ctx->path = path; 175251881Speter gls_ctx->peg_revision = peg_revision; 176251881Speter gls_ctx->start_rev = start_rev; 177251881Speter gls_ctx->end_rev = end_rev; 178251881Speter gls_ctx->receiver = receiver; 179251881Speter gls_ctx->receiver_baton = receiver_baton; 180251881Speter 181251881Speter SVN_ERR(svn_ra_serf__get_stable_url(&req_url, NULL /* latest_revnum */, 182299742Sdim session, NULL /* url */, peg_revision, 183251881Speter pool, pool)); 184251881Speter 185251881Speter xmlctx = svn_ra_serf__xml_context_create(gls_ttable, 186251881Speter NULL, gls_closed, NULL, 187251881Speter gls_ctx, 188251881Speter pool); 189299742Sdim handler = svn_ra_serf__create_expat_handler(session, xmlctx, NULL, pool); 190251881Speter 191251881Speter handler->method = "REPORT"; 192251881Speter handler->path = req_url; 193251881Speter handler->body_delegate = create_gls_body; 194251881Speter handler->body_delegate_baton = gls_ctx; 195251881Speter handler->body_type = "text/xml"; 196251881Speter 197251881Speter err = svn_ra_serf__context_run_one(handler, pool); 198251881Speter 199299742Sdim if (!err) 200299742Sdim { 201299742Sdim err = svn_ra_serf__error_on_status(handler->sline, 202299742Sdim handler->path, 203299742Sdim handler->location); 204299742Sdim } 205251881Speter 206251881Speter if (err && (err->apr_err == SVN_ERR_UNSUPPORTED_FEATURE)) 207251881Speter return svn_error_create(SVN_ERR_RA_NOT_IMPLEMENTED, err, NULL); 208251881Speter 209251881Speter return svn_error_trace(err); 210251881Speter} 211