I know this is a very old thread, but judging by the number of views it's still a question that comes up from time to time, so I thought I'd share a method I used to resolve this.
First note that Director::redirect() simply calls the redirect() function of the current controller, which will usually result in a call to the implementation of the function down in the base ContentController class and it is in that implementation that the double redirect warning is generated. I note that some people propose commenting out the offending lines of code, but for the record you can simply override that function in your Page class, and exclude the 3 lines of code. So in your Page_Controller class just have this function:
function redirect($url, $code=302) {
// Attach site-root to relative links, if they have a slash in them
if($url == "" || $url[0] == '?' || (substr($url,0,4) != "http" && $url[0] != "/" && strpos($url,'/') !== false)){
$url = Director::baseURL() . $url;
}
$this->response->redirect($url, $code);
}
which is simply the default base implementation sans the few lines of code that generate the warning. No need to touch the core code (as if that's ever the correct answer)
As a side discussion:
I'm not satisfied that there's any need for that warning in the first place. For example, in some sites I have a function that is called from within Page_Controller Init() which checks to see if the current page should be in SSL and redirects the user into the https:// version of the URL if they aren't (it also transitions them out of SSL when I want them out as well). So that results in the first instance of the HTTP header "location" being set... BUT my understanding is that the PHP side of things hasn't finished executing yet, and the user's browser hasn't yet been sent the HTTP headers. Correct? So then later on in my code let's say I have a function that determines the user is trying to access a secure page and I want to redirect them to a login screen (or it could be Silverstripe's own redirector page type, or even Silverstripe's own "canView()" security check etc...), this will result in the second attempt to set the HTTP header "location" to some value, and if things are allowed to continue without the warning then that should be the one and only 302 that ends up getting sent to the user's browser isn't it?
Now I could put all sorts of code in there to have my SSL check and my secure access check act in unison with all other pieces of custom code that might want to do a redirect for some reason, and if they all are aware of the status of each other's redirection desires then I could probably orchestrate a situation where Director::redirect() only gets called once, but if my underlying assumption is correct that the headers only end up getting sent to the browser once anyway, why not just allow multiple calls to the redirect function without a warning?
Finally, as noted in some other threads on this subject, warnings are suppressed in "test" and "live" mode anyway, but it does bug me that my warning log file on disk can tend to fill up with these messages.