Hi Daniel, Michael, I've created a branch with patch, branches/proxy-move-copy-fix
> I wanted to include this in the normal davautocheck (subversion/tests/cmdline/ > davautocheck.sh) so we can test mirroring as well as part of the normal > testing I've done this too now > I don't have the setup to verify this situation today, but I suspect that > Jordan does. What > happens when you repository URIs differ and a, say, a text file that contains > the URL of > the master repository is committed? Does that file's content on the slave > mirror > repository still carry the URL of the master repository, or has it been > tweaked to look like > a mixture of master hostname and slave path? In my latest commit on the branch I added a test for this based on the issue you linked and it does indeed fail, although not silently. In the test case the URLs "master" and "slave" have different lengths, which causes the commit to abort due to "E185004: Unexpected end of svndiff input". I also tested with "master" and "slavex" which instead triggers a "E200014: Checksum mismatch", so I don't think any silent corruption is occurring. My fix to the move/copy proxy shouldn't be affected by this at all, as it's only rewriting the destination header which will never contain file data. Thanks, Jordan On Fri, 3 Jul 2026 at 14:29, C. Michael Pilato <[email protected]> wrote: > > This patch hasn't left my sphere of interest since it first arrived. It has, > however, stirred some quite humorous (and hallucination-filled) interactions > with Gemini, plus some frustratingly unproductive spelunking through our > mailing list archives on multiple occasions. The question I was trying to > answer was: Why didn't I/we make this (rather simple and obvious) change > when developing the WebDAV proxy feature in the first place? > > This morning -- halfway through writing this email -- I decided to try a > complete read of the mirror.c code to see if triggered anything. And by > golly, I think I found it. > > In svn_dav__location_in_filter(), I found this comment: > > /* ### FIXME: While we want to fix up any locations in proxied XML > ### requests, we do *not* want to be futzing with versioned (or > ### to-be-versioned) data, such as the file contents present in > ### PUT requests and properties in PROPPATCH requests. > ### See issue #3445 for details. */ > > At the time, "issue #3445" referred to the old Tigris issue tracker, but > thankfully our move to JIRA was so incredibly well-planned that the analogous > issue there was easy enough to find. And at > https://issues.apache.org/jira/browse/SVN-3445, you can read the history of > the problem. TL;DR: If the master and slave paths differ, actual versioned > file content can be munged. > > I don't have the setup to verify this situation today, but I suspect that > Jordan does. What happens when you repository URIs differ and a, say, a text > file that contains the URL of the master repository is committed? Does that > file's content on the slave mirror repository still carry the URL of the > master repository, or has it been tweaked to look like a mixture of master > hostname and slave path? > > -- Mike > > On Wed, Jan 14, 2026 at 3:20 PM C. Michael Pilato <[email protected]> wrote: >> >> I'm too long out of the game to offer meaningful review and testing on this, >> but I definitely appreciate the thorough write-up. And given the comments I >> left sprinkled in that source file (so many years ago...) about how >> inefficient some of the filtering was when the master/slave repository paths >> were identical, chances are pretty good that I did most of my testing in >> exactly that configuration. >> >> -- Mike >> >> On Wed, Jan 14, 2026 at 7:18 AM Jordan Peck via dev >> <[email protected]> wrote: >>> >>> Hi, >>> >>> I've identified and fixed a bug in mod_dav_svn's master/slave proxy >>> functionality (SVNMasterURI) that causes COPY and MOVE operations to >>> fail with a 400 error when the slave and master repositories are >>> hosted at different paths. >>> >>> >>> STEPS TO REPRODUCE >>> ================== >>> >>> 1. Configure a master SVN server with the repository at /repo: >>> >>> # Master server (master-server.example.com) >>> <Location /repo> >>> DAV svn >>> SVNPath /var/svn/myrepo >>> </Location> >>> >>> 2. Configure a slave SVN server with the repository at a different >>> path (/svn/repo) and SVNMasterURI pointing to the master: >>> >>> # Slave server (slave-server.example.com) >>> <Location /svn/repo> >>> DAV svn >>> SVNPath /var/svn/myrepo-slave >>> SVNMasterURI http://master-server.example.com/repo >>> </Location> >>> >>> 3. Ensure the slave repository is a synced mirror of the master >>> (via svnsync). >>> >>> 4. Attempt a COPY operation through the slave to create a branch: >>> >>> svn copy http://slave-server.example.com/svn/repo/trunk \ >>> http://slave-server.example.com/svn/repo/branches/new-feature \ >>> -m "Creating new feature branch" >>> >>> >>> EXPECTED RESULT >>> =============== >>> >>> The COPY request is proxied to the master and the branch is created >>> successfully. >>> >>> >>> ACTUAL RESULT >>> ============= >>> >>> The operation fails with HTTP 400 Bad Request. Server logs show the >>> master receiving a Destination header with path >>> /svn/repo/branches/new-feature which does not exist on the master >>> (the correct path would be /repo/branches/new-feature). >>> >>> >>> ROOT CAUSE >>> ========== >>> >>> In subversion/mod_dav_svn/mirror.c, the proxy_request_fixup() function >>> correctly rewrites the Request-URI when proxying requests to the master. >>> However, WebDAV COPY and MOVE operations specify their destination in >>> the Destination HTTP header, which is not rewritten. >>> >>> The existing filters handle: >>> - Request body rewriting (dav_svn__location_in_filter) >>> - Response body rewriting (dav_svn__location_body_filter) >>> - Response Location header rewriting (dav_svn__location_header_filter) >>> >>> But there is no rewriting for the incoming Destination request header. >>> >>> When paths are identical on slave and master, this bug is masked >>> because the path portion extracted from the Destination header happens >>> to be valid on both servers. The bug only manifests when the repository >>> paths differ. >>> >>> >>> FIX >>> === >>> >>> The attached patch adds rewriting of the Destination header in >>> proxy_request_fixup(). It parses the header, replaces the slave's root >>> path with the master's path, and updates the header before the request >>> is proxied. >>> >>> I have tested this fix and can confirm it fixes the issue in my testing. >>> >>> Please review the attached patch. >>> >>> Thanks, >>> Jordan Peck

