[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

[PATCH] Incorrect `svn log` behavior from mod_dav_svn from

From: Daniel Rall <dlr_at_finemaltcoding.com>
Date: 2002-11-15 08:20:41 CET

Karl Fogel <kfogel@newton.ch.collab.net> writes:

> Daniel Rall <dlr@finemaltcoding.com> writes:
> > The output that I'm getting from `svn log` from the latest code seems
> > a bit odd:
>
> Whups.
>
> That should be easy to fix (note that -1 is the real value of
> SVN_INVALID_REVNUM). Can you file a quick issue on it? I'll bet it
> gets squashed in no time; well, *almost* no time -- I'm going to bed
> now :-).
>
> You may find it faster to patch than to make an issue, even.

It turned it that no, it was not faster to patch. But I took a stab
at it anyhow, with some debugging assistence from Ben and a solution
suggestion from Greg.

The log message problem is not reproducable over ra_local (you need at
least 1 revnum to have a shot at it), but is reproducable over ra_dav.

The problem is not in the client library, but on the server-side.
Specifically, the response returned by mod_dav_svn wraps the
SVN_ERR_FS_NOT_FOUND produced when determining the response in a
<S:log-report> element, rather than in the <D:error> element which the
client-side recognizes as an error.

REPORT /repos/svn/trunk HTTP/1.1
Host: 216.127.237.133:81
User-Agent: neon/0.23.5 SVN/0.15.0 (dev build)
Connection: TE
TE: trailers
Content-Length: 142
Content-Type: text/xml

<S:log-report xmlns:S="svn:">
<S:start-revision>3782</S:start-revision><S:end-revision>1</S:end-revision><S:path>asdf</S:path></S:log-report>
HTTP/1.1 200 OK
Date: Thu, 14 Nov 2002 05:44:31 GMT
Server: Apache/2.0.44-dev (Unix) mod_ssl/2.0.44-dev OpenSSL/0.9.6 DAV/2 SVN/0.14.5 (dev build)
Transfer-Encoding: chunked
Content-Type: text/xml; charset="utf-8"

130
<?xml version="1.0" encoding="utf-8"?>
<S:log-report xmlns:S="svn:" xmlns:D="DAV:">
<S:log-item>
<D:version-name>-1</D:version-name>
<D:creator-displayname></D:creator-displayname>
<S:date></S:date>
<D:comment>file not found: revision `3782', path `/trunk/asdf'</D:comment>
</S:log-item>
</S:log-report>

0

Note that the response body actually comes back gzipped. I used
ethereal to record the transaction (thanks Ben), then used telnet to
reply the response, leaving out the "Accept-Encoding: gzip" HTTP
header (which I assume Neon is generating). This allowed me to see
the plaintext of the response.

Here's a completely untested patch to mod_dav_svn (having difficulties
getting mod_dav_svn built), approximating the lazy writing of the DAV
XML header fix suggested by gstein. Even though we should always get
a SVN_ERR_FS_NOT_FOUND, I left in the old error handling for the case
where we've already started writing the response.

Some up for reviewing this/testing it out? If not, be certain that I
will corner YOU @ ApacheCon. ;-)

* subversion/mod_dav_svn/log.c

  (struct log_receiver_baton): Added a needs_header flag to the
  internal baton to indicate whether we've written the <S:log-report>
  header. Allows for lazy writes to support mod_dav-based error
  handling.

  (svn_types.h): Imported for svn_boolean_t for needs_header flag.

  (dav_svn__log_report): Initialized the baton's needs_header flag to
  true. Moved writing of DAV XML header into log_receiver. Return
  with a dav_error * if an error is detected before we start sending
  the response (e.g. when a we get a SVN_ERR_FS_NOT_FOUND from a
  request for a non-existent resource).

  (log_receiver): Send DAV XML header and <S:log-report> start if we
  still need to send the header (determined by the needs_header flag
  on our baton).

Index: subversion/mod_dav_svn/log.c
===================================================================
--- subversion/mod_dav_svn/log.c (revision 3793)
+++ subversion/mod_dav_svn/log.c (working copy)
@@ -26,6 +26,7 @@
 #include "svn_pools.h"
 #include "svn_repos.h"
 #include "svn_fs.h"
+#include "svn_types.h"
 #include "svn_xml.h"
 #include "svn_path.h"
 
@@ -40,6 +41,10 @@
 
   /* where to deliver the output */
   ap_filter_t *output;
+
+ /* Whether we've written the <S:log-report> header. Allows for lazy
+ writes to support mod_dav-based error handling. */
+ svn_boolean_t needs_header;
 };
 
 
@@ -65,6 +70,16 @@
 {
   struct log_receiver_baton *lrb = baton;
 
+ if (lrb->needs_header)
+ {
+ /* Start the log report. */
+ send_xml(lrb,
+ DAV_XML_HEADER DEBUG_CR
+ "<S:log-report xmlns:S=\"" SVN_XML_NAMESPACE "\" "
+ "xmlns:D=\"DAV:\">" DEBUG_CR);
+ lrb->needs_header = FALSE;
+ }
+
   send_xml(lrb,
            "<S:log-item>" DEBUG_CR
            "<D:version-name>%" SVN_REVNUM_T_FMT "</D:version-name>" DEBUG_CR
@@ -236,12 +251,12 @@
   lrb.bb = apr_brigade_create(resource->pool, /* not the subpool! */
                               output->c->bucket_alloc);
   lrb.output = output;
+ lrb.needs_header = TRUE;
 
- /* Start the log report. */
- send_xml(&lrb,
- DAV_XML_HEADER DEBUG_CR
- "<S:log-report xmlns:S=\"" SVN_XML_NAMESPACE "\" "
- "xmlns:D=\"DAV:\">" DEBUG_CR);
+ /* Our svn_log_message_receiver_t sends the <S:log-report> header in
+ a lazy fashion. Before writing the first log message, it assures
+ that the header has already been sent (checking the needs_header
+ flag in our log_receiver_baton structure). */
 
   /* Send zero or more log items. */
   serr = svn_repos_get_logs(repos->repos,
@@ -256,27 +271,32 @@
 
   if (serr)
     {
- /* ### We've definitely generated some content into the output
- ### filter, which means that we cannot return an error here.
- ### In the future, mod_dav may specify a way to signal an
- ### error even after the response stream has begun.
- ###
- ### So for now, we "return" the error by invoking the
- ### log_receiver on the error message itself.
- ###
- ### http://subversion.tigris.org/issues/show_bug.cgi?id=816
- ### describes a situation where this helps. */
-
- /* Don't bother to check for error; we can't do anything with it
- if we get one. */
- log_receiver(&lrb,
- NULL,
- SVN_INVALID_REVNUM,
- "", "",
- serr->message,
- resource->pool);
-
- serr = NULL;
+ /* If we can, report a DAV error. */
+ if (lrb.needs_header)
+ {
+ /* Bail out before writing any of <S:log-report>. */
+ return dav_svn_convert_err(serr, HTTP_BAD_REQUEST, serr->message);
+ }
+ else
+ {
+ /* ### We've sent some content to the output filter, meaning
+ ### that we cannot simply return an error here. In the
+ ### future, mod_dav may specify a way to signal an error
+ ### even after the response stream has begun.
+
+ ### For now we punt, sending the error message to the
+ ### client as a <S:log-item> (using its <D:version-name>
+ ### and <D:comment> children).
+
+ ### http://subversion.tigris.org/issues/show_bug.cgi?id=816
+ ### describes a situation where this helps.*/
+ log_receiver(&lrb,
+ NULL,
+ SVN_INVALID_REVNUM,
+ "", "",
+ serr->message,
+ resource->pool);
+ }
     }
   
   /* End the log report. */

-- 
Daniel Rall <dlr@finemaltcoding.com>
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Received on Fri Nov 15 08:21:15 2002

This is an archived mail posted to the Subversion Dev mailing list.

This site is subject to the Apache Privacy Policy and the Apache Public Forum Archive Policy.