Subversion Moved Permanently Error for GET Request

I spent the last hour or so trying to figure out why my Subversion server wasn’t handling diff requests properly. I first noticed it when I was examining a piece of source code and noticed a piece of code I added a while back was missing. Fortunately I’ve been moving all our source code over to a Subversion repository so I pulled up my subversion client and examined the log for the source code file. I noticed a recent revision committed to the repository and suspected that’s where the code was removed. When I tried to display the differences committed in that revision the following error was returned: “GET of ‘/svn/repository/!svn/bc/284/trunk/temp/application.cfm’: 301 Moved Permanently (http://localhost)“.

A quick google search for subversion and “Moved Permanently” returned a link to the Subversion FAQ’s but the answer didn’t seem to help much. First, the question dealt with a commit action which uses PROPFIND as opposed to a diff action which uses a GET request. I still read through the response and verified that the server was in compliance with the suggested configuration. After trying a few different searches I came across this which basically says if your Location tag in your Apache config file maps to /svn then you can’t have a .svn working directory in your document root. Sure enough renaming the .svn directory in the document root allowed me to successfully perform the diff statement but that wasn’t an exceptable solution. Since I want the code for the entire website in the repository, the document root must have a working directory named .svn and renaming it everytime I want to compare differences in a file didn’t seem like a good work around. I was debating changing the Location from /svn to /subvn or something like that but now that we’ve been using the repository for quite a while a URL change wouldn’t be fun.

I spent the next half hour searching the Subversion documentation and website trying to discover where it says you can’t have a .svn working directory if your repository location starts with /svn. I came up empty handed so I tried working the problem a different way. Clearly Apache was handling the GET request for /svn different than it was handling a PROPFIND request for /svn (since commits were working fine). To figure out why it was returning the .svn directory I created a directory in the document root called ‘.test’ and placed a basic index.html file inside of it. I opened my browser and pointed it to ‘http://localhost/test/’ and the index file popped up. However, I noticed the URL had been slightly modified to http://localhost/.test/. It took about 2 seconds for the answer to pop into my head…mod_speling. Mod Speling is an Apache module I installed a while back to help with a case sensitivity problem we were having. We’re moving our site from a windows machine (case insensitive) to a linux machine (case sensitive). To avoid breaking any links that weren’t using the proper case I installed mod_speling which tries to determine what an invalid request is looking for. For example, if a file was named index.html and a request came in for Index.html the Apache server would return a file not found error. With mod_speling the module looks at the invalid requests, sees there is a file called index.html and redirects the request to that file.

So, for my situation mod_speling was intercepting the GET request for /svn/… and was trying to redirect it to /.svn/… To fix the problem I turned off mod_speling on the Apache virtual server handling the subversion repository and the diff worked fine. Fortunately this virtual server is a test server and didn’t really need mod_speling. I was able to keep mod_speling running on the production server where it was really needed. If I ran into the situation where I absolutely needed mod_speling running the same virtual server as Subversion, I’m not sure what the solution would be. I suspect you’d have to turn mod_speling off on the first level of the document root folder entirely. I don’t see any way where you could exclude only the svn directory. I believe it’s a problem with the mod_speling module. Shouldn’t it check the Location tags to see if it’s a valid location before trying to redirect the request? That seems logical to me. If anyone comes up with a better solution, let me know.

As a little disclaimer, I know I’m going to get some complaints about my first post in 5 months being about something technical. I’m sure the complaints will come from the same friends that have complained about lack of updates over the past few months. I’m sorry, I’ll try and post something more interesting soon, but since there was no reference to this problem on the web, and I’m sure someone else will come across it sooner or later, I thought I’d better post it.

3 Responses to “Subversion Moved Permanently Error for GET Request”

  1. Wayne Jarvis Says:

    Jeff screw the weblog, I am just glad to see a new picture for your back ground.

  2. Kevin L. Says:

    Thats for the write up. I just spent an hour diagnosing this as well, but started to google and found this. Super useful.

  3. David Goodwin Says:

    Mod_speling vs subversion :

    Try the following :

    DAV svn
    SVNPath /where/ever
    AuthType Basic
    AuthName “Subversion Repository”
    AuthUserFile /etc/apache2/htpasswd
    AuthGroupFile /etc/apache2/htgroup
    Require group whatever

    CheckSpelling Off
    CheckCaseOnly Off

    CheckCaseOnly On
    CheckSpelling on

    That /should/ fix the problem - namely subversion stuff will remain case sensitive, and everything else will stay case in-sensitive.

    David.

Leave a Reply