static svn_error_t * svn_ra_local__get_file_revs(svn_ra_session_t *session, const char *path, svn_revnum_t start, svn_revnum_t end, svn_boolean_t include_merged_revisions, svn_file_rev_handler_t handler, void *handler_baton, apr_pool_t *pool) { svn_ra_local__session_baton_t *sess = session->priv; const char *abs_path = svn_path_join(sess->fs_path->data, path, pool); return svn_repos_get_file_revs2(sess->repos, abs_path, start, end, include_merged_revisions, NULL, NULL, handler, handler_baton, pool); }
svn_error_t * svn_repos_get_file_revs(svn_repos_t *repos, const char *path, svn_revnum_t start, svn_revnum_t end, svn_repos_authz_func_t authz_read_func, void *authz_read_baton, svn_repos_file_rev_handler_t handler, void *handler_baton, apr_pool_t *pool) { svn_file_rev_handler_t handler2; void *handler2_baton; svn_compat_wrap_file_rev_handler(&handler2, &handler2_baton, handler, handler_baton, pool); return svn_repos_get_file_revs2(repos, path, start, end, FALSE, authz_read_func, authz_read_baton, handler2, handler2_baton, pool); }
/* Respond to a client request for a REPORT of type file-revs-report for the RESOURCE. Get request body from DOC and send result to OUTPUT. */ dav_error * dav_svn__file_revs_report(const dav_resource *resource, const apr_xml_doc *doc, ap_filter_t *output) { svn_error_t *serr; dav_error *derr = NULL; apr_xml_elem *child; int ns; struct file_rev_baton frb; dav_svn__authz_read_baton arb; const char *abs_path = NULL; /* These get determined from the request document. */ svn_revnum_t start = SVN_INVALID_REVNUM; svn_revnum_t end = SVN_INVALID_REVNUM; svn_boolean_t include_merged_revisions = FALSE; /* off by default */ /* Construct the authz read check baton. */ arb.r = resource->info->r; arb.repos = resource->info->repos; /* Sanity check. */ if (!resource->info->repos_path) return dav_svn__new_error(resource->pool, HTTP_BAD_REQUEST, 0, "The request does not specify a repository path"); ns = dav_svn__find_ns(doc->namespaces, SVN_XML_NAMESPACE); /* ### This is done on other places, but the document element is in this namespace, so is this necessary at all? */ if (ns == -1) { return dav_svn__new_error_tag(resource->pool, HTTP_BAD_REQUEST, 0, "The request does not contain the 'svn:' " "namespace, so it is not going to have " "certain required elements.", SVN_DAV_ERROR_NAMESPACE, SVN_DAV_ERROR_TAG); } /* Get request information. */ for (child = doc->root->first_child; child != NULL; child = child->next) { /* if this element isn't one of ours, then skip it */ if (child->ns != ns) continue; if (strcmp(child->name, "start-revision") == 0) start = SVN_STR_TO_REV(dav_xml_get_cdata(child, resource->pool, 1)); else if (strcmp(child->name, "end-revision") == 0) end = SVN_STR_TO_REV(dav_xml_get_cdata(child, resource->pool, 1)); else if (strcmp(child->name, "include-merged-revisions") == 0) include_merged_revisions = TRUE; /* presence indicates positivity */ else if (strcmp(child->name, "path") == 0) { const char *rel_path = dav_xml_get_cdata(child, resource->pool, 0); if ((derr = dav_svn__test_canonical(rel_path, resource->pool))) return derr; /* Force REL_PATH to be a relative path, not an fspath. */ rel_path = svn_relpath_canonicalize(rel_path, resource->pool); /* Append the REL_PATH to the base FS path to get an absolute repository path. */ abs_path = svn_fspath__join(resource->info->repos_path, rel_path, resource->pool); } /* else unknown element; skip it */ } /* Check that all parameters are present and valid. */ if (! abs_path) return dav_svn__new_error_tag(resource->pool, HTTP_BAD_REQUEST, 0, "Not all parameters passed.", SVN_DAV_ERROR_NAMESPACE, SVN_DAV_ERROR_TAG); frb.bb = apr_brigade_create(resource->pool, output->c->bucket_alloc); frb.output = output; frb.needs_header = TRUE; frb.svndiff_version = resource->info->svndiff_version; frb.compression_level = dav_svn__get_compression_level(resource->info->r); /* file_rev_handler will send header first time it is called. */ /* Get the revisions and send them. */ serr = svn_repos_get_file_revs2(resource->info->repos->repos, abs_path, start, end, include_merged_revisions, dav_svn__authz_read_func(&arb), &arb, file_rev_handler, &frb, resource->pool); if (serr) { /* We don't 'goto cleanup' because ap_fflush() tells httpd to write the HTTP headers out, and that includes whatever r->status is at that particular time. When we call dav_svn__convert_err(), we don't immediately set r->status right then, so r->status remains 0, hence HTTP status 200 would be misleadingly returned. */ return (dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR, serr->message, resource->pool)); } if ((serr = maybe_send_header(&frb))) { derr = dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR, "Error beginning REPORT reponse", resource->pool); goto cleanup; } if ((serr = dav_svn__brigade_puts(frb.bb, frb.output, "</S:file-revs-report>" DEBUG_CR))) { derr = dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR, "Error ending REPORT reponse", resource->pool); goto cleanup; } cleanup: /* We've detected a 'high level' svn action to log. */ dav_svn__operational_log(resource->info, svn_log__get_file_revs(abs_path, start, end, include_merged_revisions, resource->pool)); return dav_svn__final_flush_or_error(resource->info->r, frb.bb, output, derr, resource->pool); }