我认为这可能是Apache 2.2及更低版本如何处理这种特殊情况的错误。
似乎在发生SSL读取400 Bad Request
错误时,Apache 2.2不会返回HTTP响应代码或标头,而仅返回HTTP响应正文。我通过远程登录到端口443并发送来进行测试:
GET / HTTP/1.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 />
<blockquote>Hint: <a href="https://server.tld/"><b>https://server.tld/</b></a></blockquote></p>
</body></html>
请注意缺少HTTP响应代码或任何HTTP标头。
当我对Apache 2.4服务器执行此操作时,我得到:
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>
如果我像您一样设置ErrorDocument行:
ErrorDocument 400 https://server.tld/
然后,我获得了302重定向的HTML,但是同样,没有任何标头。没有302重定向响应代码和Location:
标头,浏览器将无法重定向。
尝试升级到Apache 2.4,看看它是否有效。我已经至少使用Apache 2.4.3进行了测试和确认,但是我还没有进行确切的行为更新时间。我怀疑他们在准备2.4的大量工作中都将不良行为作为副作用进行了纠正。
相关的Apache httpd错误:
更新
您可以通过让脚本打印出其标头(不会发送到客户端),然后再手动输出所需的标头,来强制有问题的Apache为您提供所需的行为(重定向)。这是在Apache 2.2.22下工作的基本Perl脚本:
#!/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
您应该意识到,除了仅与不带SSL的SSL端口通信外,还有其他原因可能会生成400。确定这一点的简单方法是寻找HTTPS
环境变量。如果已设置,则说明SSL已正确协商,并且其他原因导致了400(如果是这种情况,请勿执行双重标头技巧)。如果HTTPS
未设置,则按上述方式返回您的重定向。