📄 version.c
字号:
/* Respond to a get-locks-report request. See description of this report in libsvn_ra_dav/fetch.c. */static dav_error * dav_svn__get_locks_report(const dav_resource *resource, const apr_xml_doc *doc, ap_filter_t *output){ apr_bucket_brigade *bb; svn_error_t *err; apr_status_t apr_err; apr_hash_t *locks; dav_svn_authz_read_baton arb; apr_hash_index_t *hi; apr_pool_t *subpool; /* The request URI should be a public one representing an fs path. */ if ((! resource->info->repos_path) || (! resource->info->repos->repos)) return dav_new_error(resource->pool, HTTP_BAD_REQUEST, 0, "get-locks-report run on resource which doesn't " "represent a path within a repository."); arb.r = resource->info->r; arb.repos = resource->info->repos; /* Fetch the locks, but allow authz_read checks to happen on each. */ if ((err = svn_repos_fs_get_locks(&locks, resource->info->repos->repos, resource->info->repos_path, dav_svn_authz_read_func(&arb), &arb, resource->pool)) != SVN_NO_ERROR) return dav_svn_convert_err(err, HTTP_INTERNAL_SERVER_ERROR, err->message, resource->pool); bb = apr_brigade_create(resource->pool, output->c->bucket_alloc); /* start sending report */ apr_err = ap_fprintf(output, bb, DAV_XML_HEADER DEBUG_CR "<S:get-locks-report xmlns:S=\"" SVN_XML_NAMESPACE "\" " "xmlns:D=\"DAV:\">" DEBUG_CR); if (apr_err) return dav_svn_convert_err(svn_error_create(apr_err, 0, NULL), HTTP_INTERNAL_SERVER_ERROR, "Error writing REPORT response.", resource->pool); /* stream the locks */ subpool = svn_pool_create(resource->pool); for (hi = apr_hash_first(resource->pool, locks); hi; hi = apr_hash_next(hi)) { const void *key; void *val; const svn_lock_t *lock; const char *path_quoted, *token_quoted; const char *creation_str, *expiration_str; const char *owner_to_send, *comment_to_send; svn_boolean_t owner_base64 = FALSE, comment_base64 = FALSE; svn_pool_clear(subpool); apr_hash_this(hi, &key, NULL, &val); lock = val; path_quoted = apr_xml_quote_string(subpool, lock->path, 1); token_quoted = apr_xml_quote_string(subpool, lock->token, 1); creation_str = svn_time_to_cstring(lock->creation_date, subpool); apr_err = ap_fprintf(output, bb, "<S:lock>" DEBUG_CR "<S:path>%s</S:path>" DEBUG_CR "<S:token>%s</S:token>" DEBUG_CR "<S:creationdate>%s</S:creationdate>" DEBUG_CR, path_quoted, token_quoted, creation_str); if (apr_err) return dav_svn_convert_err(svn_error_create(apr_err, 0, NULL), HTTP_INTERNAL_SERVER_ERROR, "Error writing REPORT response.", resource->pool); if (lock->expiration_date) { expiration_str = svn_time_to_cstring(lock->expiration_date, subpool); apr_err = ap_fprintf(output, bb, "<S:expirationdate>%s</S:expirationdate>" DEBUG_CR, expiration_str); if (apr_err) return dav_svn_convert_err(svn_error_create(apr_err, 0, NULL), HTTP_INTERNAL_SERVER_ERROR, "Error writing REPORT response.", resource->pool); } if (svn_xml_is_xml_safe(lock->owner, strlen(lock->owner))) { owner_to_send = apr_xml_quote_string(subpool, lock->owner, 1); } else { svn_string_t owner_string; const svn_string_t *encoded_owner; owner_string.data = lock->owner; owner_string.len = strlen(lock->owner); encoded_owner = svn_base64_encode_string(&owner_string, subpool); owner_to_send = encoded_owner->data; owner_base64 = TRUE; } apr_err = ap_fprintf(output, bb, "<S:owner %s>%s</S:owner>" DEBUG_CR, owner_base64 ? "encoding=\"base64\"" : "", owner_to_send); if (apr_err) return dav_svn_convert_err(svn_error_create(apr_err, 0, NULL), HTTP_INTERNAL_SERVER_ERROR, "Error writing REPORT response.", resource->pool); if (lock->comment) { if (svn_xml_is_xml_safe(lock->comment, strlen(lock->comment))) { comment_to_send = apr_xml_quote_string(subpool, lock->comment, 1); } else { svn_string_t comment_string; const svn_string_t *encoded_comment; comment_string.data = lock->comment; comment_string.len = strlen(lock->comment); encoded_comment = svn_base64_encode_string(&comment_string, subpool); comment_to_send = encoded_comment->data; comment_base64 = TRUE; } apr_err = ap_fprintf(output, bb, "<S:comment %s>%s</S:comment>" DEBUG_CR, comment_base64 ? "encoding=\"base64\"" : "", comment_to_send); if (apr_err) return dav_svn_convert_err(svn_error_create(apr_err, 0, NULL), HTTP_INTERNAL_SERVER_ERROR, "Error writing REPORT response.", resource->pool); } apr_err = ap_fprintf(output, bb, "</S:lock>" DEBUG_CR); if (apr_err) return dav_svn_convert_err(svn_error_create(apr_err, 0, NULL), HTTP_INTERNAL_SERVER_ERROR, "Error writing REPORT response.", resource->pool); } /* end of hash loop */ svn_pool_destroy(subpool); /* finish the report */ apr_err = ap_fprintf(output, bb, "</S:get-locks-report>" DEBUG_CR); if (apr_err) return dav_svn_convert_err(svn_error_create(apr_err, 0, NULL), HTTP_INTERNAL_SERVER_ERROR, "Error writing REPORT response.", resource->pool); /* Flush the contents of the brigade (returning an error only if we don't already have one). */ if ((apr_err = ap_fflush(output, bb))) return dav_svn_convert_err(svn_error_create(apr_err, 0, NULL), HTTP_INTERNAL_SERVER_ERROR, "Error flushing brigade.", resource->pool); return NULL;}static apr_status_t send_get_locations_report(ap_filter_t *output, apr_bucket_brigade *bb, const dav_resource *resource, apr_hash_t *fs_locations){ apr_hash_index_t *hi; apr_pool_t *pool; apr_status_t apr_err; pool = resource->pool; apr_err = ap_fprintf(output, bb, DAV_XML_HEADER DEBUG_CR "<S:get-locations-report xmlns:S=\"" SVN_XML_NAMESPACE "\" xmlns:D=\"DAV:\">" DEBUG_CR); if (apr_err) return apr_err; for (hi = apr_hash_first(pool, fs_locations); hi; hi = apr_hash_next(hi)) { const void *key; void *value; const char *path_quoted; apr_hash_this(hi, &key, NULL, &value); path_quoted = apr_xml_quote_string(pool, value, 1); apr_err = ap_fprintf(output, bb, "<S:location " "rev=\"%ld\" path=\"%s\"/>" DEBUG_CR, *(const svn_revnum_t *)key, path_quoted); if (apr_err) return apr_err; } return ap_fprintf(output, bb, "</S:get-locations-report>" DEBUG_CR);}dav_error *dav_svn__get_locations_report(const dav_resource *resource, const apr_xml_doc *doc, ap_filter_t *output){ svn_error_t *serr; dav_error *derr = NULL; apr_status_t apr_err; apr_bucket_brigade *bb; dav_svn_authz_read_baton arb; /* The parameters to do the operation on. */ const char *relative_path = NULL; const char *abs_path; svn_revnum_t peg_revision = SVN_INVALID_REVNUM; apr_array_header_t *location_revisions; /* XML Parsing Variables */ int ns; apr_xml_elem *child; apr_hash_t *fs_locations; location_revisions = apr_array_make(resource->pool, 0, sizeof(svn_revnum_t)); /* Sanity check. */ ns = dav_svn_find_ns(doc->namespaces, SVN_XML_NAMESPACE); 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); } /* Gather the parameters. */ 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, "peg-revision") == 0) peg_revision = SVN_STR_TO_REV(dav_xml_get_cdata(child, resource->pool, 1)); else if (strcmp(child->name, "location-revision") == 0) { svn_revnum_t revision = SVN_STR_TO_REV(dav_xml_get_cdata(child, resource->pool, 1)); APR_ARRAY_PUSH(location_revisions, svn_revnum_t) = revision; } else if (strcmp(child->name, "path") == 0) { relative_path = dav_xml_get_cdata(child, resource->pool, 0); if ((derr = dav_svn__test_canonical(relative_path, resource->pool))) return derr; } } /* Now we should have the parameters ready - let's check if they are all present. */ if (! (relative_path && SVN_IS_VALID_REVNUM(peg_revision))) { return dav_svn__new_error_tag(resource->pool, HTTP_BAD_REQUEST, 0, "Not all parameters passed.", SVN_DAV_ERROR_NAMESPACE, SVN_DAV_ERROR_TAG); } /* Append the relative path to the base FS path to get an absolute repository path. */ abs_path = svn_path_join(resource->info->repos_path, relative_path, resource->pool); /* Build an authz read baton */ arb.r = resource->info->r; arb.repos = resource->info->repos; serr = svn_repos_trace_node_locations(resource->info->repos->fs, &fs_locations, abs_path, peg_revision, location_revisions, dav_svn_authz_read_func(&arb), &arb, resource->pool); if (serr) { return dav_svn_convert_err(serr, HTTP_INTERNAL_SERVER_ERROR, serr->message, resource->pool); } bb = apr_brigade_create(resource->pool, output->c->bucket_alloc); apr_err = send_get_locations_report(output, bb, resource, fs_locations); if (apr_err) derr = dav_svn_convert_err(svn_error_create(apr_err, 0, NULL), HTTP_INTERNAL_SERVER_ERROR, "Error writing REPORT response.", resource->pool); /* Flush the contents of the brigade (returning an error only if we don't already have one). */ if (((apr_err = ap_fflush(output, bb))) && (! derr)) return dav_svn_convert_err(svn_error_create(apr_err, 0, NULL), HTTP_INTERNAL_SERVER_ERROR, "Error flushing brigade.", resource->pool); return derr;}static dav_error *dav_svn_deliver_report(request_rec *r, const dav_resource *resource, const apr_xml_doc *doc, ap_filter_t *output){ int ns = dav_svn_find_ns(doc->namespaces, SVN_XML_NAMESPACE); if (doc->root->ns == ns) { /* ### note that these report names should have symbols... */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -