Eu acho que este é provavelmente um bug em como o Apache 2.2 e inferior lida com essa circunstância particular.
Parece que em um erro 400 Bad Request
de leitura SSL, o Apache 2.2 não retorna o código ou os cabeçalhos de resposta HTTP, apenas o corpo da resposta HTTP. Eu testo por telnet para a porta 443 e enviando:
GET / HTTP/1.1
O servidor retorna imediatamente (para mim):
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>400 Bad Request</title>
</head><body>
<h1>Bad Request</h1>
<p>Your browser sent a request that this server could not understand.<br />
Reason: You're speaking plain HTTP to an SSL-enabled server port.<br />
Instead use the HTTPS scheme to access this URL, please.<br />
<blockquote>Hint: <a href="https://server.tld/"><b>https://server.tld/</b></a></blockquote></p>
</body></html>
Observe a falta de um código de resposta HTTP ou de qualquer cabeçalho HTTP.
Quando faço isso em um servidor Apache 2.4, recebo:
HTTP/1.1 400 Bad Request
Date: Sun, 10 Feb 2013 00:47:23 GMT
Server: Apache/2.4.3 (Unix) OpenSSL/1.0.0g
Content-Length: 462
Connection: close
Content-Type: text/html; charset=iso-8859-1
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>400 Bad Request</title>
</head><body>
<h1>Bad Request</h1>
<p>Your browser sent a request that this server could not understand.<br />
Reason: You're speaking plain HTTP to an SSL-enabled server port.<br />
Instead use the HTTPS scheme to access this URL, please.<br />
</p>
<hr>
<address>Apache/2.4.3 (Unix) OpenSSL/1.0.0g Server at server.tld Port 443</address>
</body></html>
Se eu configurar uma linha ErrorDocument como você fez:
ErrorDocument 400 https://server.tld/
Depois, recebo o HTML de um redirecionamento 302, mas, novamente, nenhum dos cabeçalhos. Sem o código de resposta de redirecionamento 302 e o cabeçalho Location:
, o navegador não redirecionará.
Tente atualizar para o Apache 2.4 e veja se funciona. Eu testei e confirmei com pelo menos o Apache 2.4.3, mas não passei pelo esforço de descobrir exatamente quando esse comportamento foi atualizado. Eu suspeito que na grande quantidade de trabalho que eles fizeram preparando o 2.4, eles corrigiram o comportamento indesejável como um efeito colateral.
Bugs httpd relevantes do Apache:
UPDATE
Você pode forçar um Apache buggy a fornecer o comportamento desejado (o redirecionamento) fazendo com que o script imprima seus cabeçalhos (que não serão enviados ao cliente) e, em seguida, imprima manualmente os cabeçalhos desejados. Aqui está um script Perl básico que funciona sob o Apache 2.2.22:
#!/usr/bin/perl
use strict;
use CGI;
my $q = CGI->new();
# this will cause Apache to handle the response properly, but is meaningless otherwise
print $q->redirect("https://localhost/");
# this actually performs the redirect
print "HTTP/1.1 302 Found\r\n";
print "Location: https://localhost/\r\n";
print "\r\n";
# you can do whatever you want here; this will be the HTML body
Você deve estar ciente de que há outras razões pelas quais um 400 pode ser gerado, além de apenas conversar com uma porta SSL sem SSL. A maneira fácil de determinar isso é procurar a variável de ambiente HTTPS
. Se estiver definido, o SSL foi negociado corretamente e outra coisa está causando o 400 (não faça o truque de cabeçalho duplo, se for o caso). Se HTTPS
não estiver definido, retorne seu redirecionamento como acima.