59
61
return dav_new_error(pool, status, error_id, 0, desc);
62
errno = 0; /* For the same reason as in dav_svn__new_error_tag */
64
errno = 0; /* For the same reason as in dav_svn__new_error_svn */
64
66
return dav_new_error(pool, status, error_id, desc);
69
dav_svn__new_error_tag(apr_pool_t *pool,
71
dav_svn__new_error_svn(apr_pool_t *pool,
73
const char *namespace,
77
77
error_id = SVN_ERR_RA_DAV_REQUEST_FAILED;
79
79
#if AP_MODULE_MAGIC_AT_LEAST(20091119,0)
80
80
return dav_new_error_tag(pool, status, error_id, 0,
81
desc, namespace, tagname);
81
desc, SVN_DAV_ERROR_NAMESPACE, SVN_DAV_ERROR_TAG);
83
83
/* dav_new_error_tag will record errno but Subversion makes no attempt
84
84
to ensure that it is valid. We reset it to avoid putting incorrect
97
98
build_error_chain(apr_pool_t *pool, svn_error_t *err, int status)
99
char *msg = err->message ? apr_pstrdup(pool, err->message) : NULL;
101
const char *msg = svn_err_best_message(err, buffer, sizeof(buffer));
101
dav_error *derr = dav_svn__new_error_tag(pool, status, err->apr_err, msg,
102
SVN_DAV_ERROR_NAMESPACE,
103
dav_error *derr = dav_svn__new_error_svn(pool, status, err->apr_err,
104
apr_pstrdup(pool, msg));
106
107
derr->prev = build_error_chain(pool, err->child, status);
115
116
const char *message,
116
117
apr_pool_t *pool)
120
/* Remove the trace-only error chain links. We need predictable
121
protocol behavior regardless of whether or not we're in a
123
svn_error_t *purged_serr = svn_error_purge_tracing(serr);
125
/* ### someday mod_dav_svn will send back 'rich' error tags, much
126
finer grained than plain old svn_error_t's. But for now, all
127
svn_error_t's are marshalled to the client via the single
128
generic <svn:error/> tag nestled within a <D:error> block. */
130
/* Examine the Subverion error code, and select the most
131
appropriate HTTP status code. If no more appropriate HTTP
132
status code maps to the Subversion error code, use the one
133
suggested status provided by the caller. */
134
switch (purged_serr->apr_err)
136
case SVN_ERR_FS_NOT_FOUND:
137
status = HTTP_NOT_FOUND;
139
case SVN_ERR_UNSUPPORTED_FEATURE:
140
status = HTTP_NOT_IMPLEMENTED;
142
case SVN_ERR_FS_LOCK_OWNER_MISMATCH:
143
case SVN_ERR_FS_PATH_ALREADY_LOCKED:
144
status = HTTP_LOCKED;
146
case SVN_ERR_FS_PROP_BASEVALUE_MISMATCH:
147
status = HTTP_PRECONDITION_FAILED;
149
/* add other mappings here */
152
derr = build_error_chain(pool, purged_serr, status);
154
&& purged_serr->apr_err != SVN_ERR_REPOS_HOOK_FAILURE)
155
/* Don't hide hook failures; we might hide the error text */
156
derr = dav_push_error(pool, status, purged_serr->apr_err,
159
/* Now, destroy the Subversion error. */
160
svn_error_clear(serr);
121
/* Remove the trace-only error chain links. We need predictable
122
protocol behavior regardless of whether or not we're in a
124
svn_error_t *purged_serr = svn_error_purge_tracing(serr);
126
/* ### someday mod_dav_svn will send back 'rich' error tags, much
127
finer grained than plain old svn_error_t's. But for now, all
128
svn_error_t's are marshalled to the client via the single
129
generic <svn:error/> tag nestled within a <D:error> block. */
131
/* Examine the Subverion error code, and select the most
132
appropriate HTTP status code. If no more appropriate HTTP
133
status code maps to the Subversion error code, use the one
134
suggested status provided by the caller. */
135
switch (purged_serr->apr_err)
137
case SVN_ERR_FS_NOT_FOUND:
138
case SVN_ERR_FS_NO_SUCH_REVISION:
139
status = HTTP_NOT_FOUND;
141
case SVN_ERR_UNSUPPORTED_FEATURE:
142
status = HTTP_NOT_IMPLEMENTED;
144
case SVN_ERR_FS_LOCK_OWNER_MISMATCH:
145
case SVN_ERR_FS_PATH_ALREADY_LOCKED:
146
status = HTTP_LOCKED;
148
case SVN_ERR_FS_PROP_BASEVALUE_MISMATCH:
149
status = HTTP_PRECONDITION_FAILED;
151
/* add other mappings here */
154
derr = build_error_chain(pool, purged_serr, status);
156
&& !svn_error_find_cause(purged_serr, SVN_ERR_REPOS_HOOK_FAILURE))
157
/* Don't hide hook failures; we might hide the error text */
158
derr = dav_push_error(pool, status, purged_serr->apr_err,
161
/* Now, destroy the Subversion error. */
162
svn_error_clear(serr);
176
178
const char *ignored;
178
180
/* Get an initial HISTORY baton. */
179
SVN_ERR(svn_fs_node_history(&history, root, path, pool));
181
SVN_ERR(svn_fs_node_history2(&history, root, path, pool, pool));
181
183
/* Now get the first *real* point of interesting history. */
182
SVN_ERR(svn_fs_history_prev(&history, history, FALSE, pool));
184
SVN_ERR(svn_fs_history_prev2(&history, history, FALSE, pool, pool));
184
186
/* Fetch the location information for this history step. */
185
187
return svn_fs_history_location(&ignored, revision, history, pool);
193
195
svn_revnum_t history_rev;
194
196
svn_fs_root_t *other_root;
195
197
svn_fs_t *fs = svn_fs_root_fs(root);
196
const svn_fs_id_t *id, *other_id;
198
svn_fs_node_relation_t node_relation;
197
199
svn_error_t *err;
199
if ((err = svn_fs_node_id(&id, root, path, pool)))
201
svn_error_clear(err);
202
return revision; /* couldn't get id of root/path */
205
201
if ((err = get_last_history_rev(&history_rev, root, path, pool)))
207
203
svn_error_clear(err);
214
210
return revision; /* couldn't open the history rev */
217
if ((err = svn_fs_node_id(&other_id, other_root, path, pool)))
213
if ((err = svn_fs_node_relation(&node_relation, root, path,
214
other_root, path, pool)))
219
216
svn_error_clear(err);
220
return revision; /* couldn't get id of other_root/path */
223
if (svn_fs_compare_ids(id, other_id) == 0)
220
if (node_relation == svn_fs_node_unchanged)
224
221
return history_rev; /* the history rev is safe! the same node
225
222
exists at the same path in both revisions. */
543
540
/* Otherwise, generate a generic HTTP_BAD_REQUEST error. */
544
return dav_svn__new_error_tag
545
(pool, HTTP_BAD_REQUEST, 0,
541
return dav_svn__new_error_svn(
542
pool, HTTP_BAD_REQUEST, 0,
546
543
apr_psprintf(pool,
547
544
"Path '%s' is not canonicalized; "
548
"there is a problem with the client.", path),
549
SVN_DAV_ERROR_NAMESPACE, SVN_DAV_ERROR_TAG);
545
"there is a problem with the client.", path));
576
572
"%s", purged_serr->message);
579
svn_error_clear(serr);
581
return dav_svn__convert_err(safe_err, http_status,
582
apr_psprintf(r->pool, "%s", safe_err->message),
575
svn_error_clear(serr);
578
return dav_svn__convert_err(safe_err, http_status,
579
apr_psprintf(r->pool, "%s", safe_err->message),
757
754
content_length_str = apr_table_get(r->headers_in, "Content-Length");
758
755
if (content_length_str)
760
if (svn__strtoff(&content_length, content_length_str, &endp, 10)
757
if (apr_strtoff(&content_length, content_length_str, &endp, 10)
761
758
|| endp == content_length_str || *endp || content_length < 0)
763
760
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "Invalid Content-Length");