Apache 虚拟主机 proxypass 不适用于 HTTPS 中的根 url

Apache Virtual Host proxypass not working for root url in HTTPS

我为强制 https 编写了这些虚拟主机条目,并将请求代理到本地 8080 的嵌入 tomcat 运行,用于 Java Spring JSF 应用程序。 它适用于像 https://my.site.com/something.jsf 这样的子目录,但不适用于根 https 域 https://my.site.com,重定向到 index.html(没有域前缀)。

对于 http 请求 http://my.site.com,它可以正确重定向到 https,没有任何问题。

当我 *:80 使用相同的 proxypass 时,它工作得很好。

<VirtualHost *:80>
        ServerName my.site.com
        RedirectPermanent / https://my.site.com/
</VirtualHost>

<VirtualHost *:443>
        ServerName my.site.com
        ServerAlias my.site.com
        ProxyPreserveHost On
        ProxyPass / http://localhost:8080/
        ProxyPassReverse / http://localhost:8080/
        SSLEngine On
        SSLCertificateFile /etc/pki/tls/certs/localhost.crt
</VirtualHost>

httpd access_log:

对 root 的 https 请求产生此日志行:

201.8.25.80 - - [12/Feb/2021:14:37:21 -0300] "GET / HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.150 Safari/537.36"

httpd没有报错error_log.

Tomcat 日志:

我在应用程序日志中得到了这个堆栈跟踪,但我不确定这是否相关,因为每次调用根 https 时都不会记录下来。

INFO 3093 --- [http-nio-8080-exec-3] o.apache.coyote.http11.Http11Processor   : Error parsing HTTP request header
 Note: further occurrences of HTTP header parsing errors will be logged at DEBUG level.

java.lang.IllegalArgumentException: Invalid character found in the request target. The valid characters are defined in RFC 7230 and RFC 3986
    at org.apache.coyote.http11.Http11InputBuffer.parseRequestLine(Http11InputBuffer.java:479) ~[tomcat-embed-core-8.5.34.jar!/:8.5.34]
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:684) ~[tomcat-embed-core-8.5.34.jar!/:8.5.34]
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) ~[tomcat-embed-core-8.5.34.jar!/:8.5.34]
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:806) ~[tomcat-embed-core-8.5.34.jar!/:8.5.34]
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1498) ~[tomcat-embed-core-8.5.34.jar!/:8.5.34]
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) ~[tomcat-embed-core-8.5.34.jar!/:8.5.34]
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) ~[na:na]
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) ~[na:na]
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-8.5.34.jar!/:8.5.34]
    at java.base/java.lang.Thread.run(Thread.java:834) ~[na:na]

几天来我一直在寻找可能的解决方案和这种行为的原因,但一无所获... 如果有人能提供帮助,我将不胜感激。

我没有发现为什么 https 中的 root 请求被错误重定向。但它已经通过添加一个 <LocationMatch> 匹配到 root 并重定向到 index.jsf 来解决,保留代理指令,如下所示:

<VirtualHost *:443>
        ServerName my.site.com
        SSLEngine On
        SSLCertificateFile /etc/pki/tls/certs/localhost.crt

        <LocationMatch "^/?$">
                Redirect / /index.jsf
        </LocationMatch>

        ProxyPreserveHost On
        ProxyPass / http://localhost:8080/
        ProxyPassReverse / http://localhost:8080/
</VirtualHost>