Apache Tomcat升级到8.5.51会引发400错误。

huangapple go评论53阅读模式
英文:

Apache Tomcat upgrade to 8.5.51 causes 400 errors

问题

以下是你要翻译的内容:

我们在将Tomcat从8.5.50升级到8.5.51时遇到了问题。自从升级到这个版本以后,发送到HTTP端口的请求失败并返回400错误码(错误的请求)。server.xml被配置为将HTTP端口重定向到HTTPS端口。这个配置已经使用了多年,直到升级之后才开始出问题。以下是连接器配置和用于向服务器发送测试事务的Java类。

我已经查阅了变更日志,唯一可能引起此问题的变更是Bug 63966的修复 - TLS消息的字符集被硬编码为ISO-8859-1。这个Bug修复是在8.5.51中引入的。我认为可能的原因是,当我们将此请求发送到Tomcat 8.5.50时,响应的Content-Type看起来是这样的:

Content-Type: text/plain;charset=ISO-8859-1

但在Tomcat 8.5.51中,我得到的是:

Content-Type: text/html;charset=utf-8

你有任何想法为什么升级到8.5.51及更高版本后会出现400错误吗?

连接器配置:

<Connector port="5555" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="7777" />
 
<Connector port="7777" protocol="HTTP/1.1" SSLEnabled="true"
           scheme="https" secure="true" ciphers="TLS_DHE_DSS_WITH_AES_128_GCM_SHA256,TLS_DHE_DSS_WITH_AES_256_GCM_SHA384,TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,TLS_DHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"
           clientAuth="false" sslProtocol="TLS" sslEnabledProtocols="TLSv1.2"
           keyAlias="myKey"
           keystore="NONE"
           keystorePass="password"
           keystoreType="PKCS11"
           keystoreProvider="myprovider"
           enableLookups="false"
           server="server" />

用于发送测试事务的Java类:

package com.testing;
 
import java.io.*;
import java.net.*;
import java.util.Date;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
 
public class RunTestTran{
 
    public  RunTestTran() {
    }
 
    public static void main(String [] args){
        RunTestTran recordProcessorTest = new RunTestTran();
        recordProcessorTest.runTran("localhost", 5555, "/requestProcessor/rp");
    }
 
    private void runTran(String ip, int port, String appName){
        // 代码略
    }
}

请注意,我已经将你提供的内容翻译成中文。如果你还有其他问题或需要进一步的帮助,请随时问我。

英文:

We’re having an issue when upgrading Tomcat from 8.5.50 to 8.5.51. Since moving to this version, requests sent to the http port are failing with a 400 error code(bad request). The server.xml is configured to redirect the http port to the https port. This has worked for years and did not start failing until the upgrade. Below is the connector config and the java class used to send a test transaction to the server.

I’ve searched the change log and the only change I can see that might cause this is the Bug fix for bug 63966 – Charset of TLS message is hard coded to ISO-8859-1. This bug fix was introduced into 8.5.51. The reason I believe this might be the reason is when we would send this request to tomcat 8.5.50 the reply Content-Type would look like this:

Content-Type: text/plain;charset=ISO-8859-1

With tomcat 8.5.51, I get this:
Content-Type: text/html;charset=utf-8

Any ideas why I’m getting the 400 error when upgrading to 8.5.51 and beyond ?

Connector config:

&lt;Connector port=&quot;5555&quot; protocol=&quot;HTTP/1.1&quot;
               connectionTimeout=&quot;20000&quot;
               redirectPort=&quot;7777&quot;
                /&gt;
 
       &lt;Connector port=&quot;7777&quot; protocol=&quot;HTTP/1.1&quot; SSLEnabled=&quot;true&quot;
           scheme=&quot;https&quot; secure=&quot;true&quot;             ciphers=&quot;TLS_DHE_DSS_WITH_AES_128_GCM_SHA256,TLS_DHE_DSS_WITH_AES_256_GCM_SHA384,TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,TLS_DHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384&quot;
           clientAuth=&quot;false&quot; sslProtocol=&quot;TLS&quot; sslEnabledProtocols=&quot;TLSv1.2&quot;
           keyAlias=&quot;myKey&quot;
           keystore=&quot;NONE&quot;
           keystorePass=&quot;password&quot;
           keystoreType=&quot;PKCS11&quot;
           keystoreProvider=&quot;myprovider&quot;
           enableLookups=&quot;false&quot;
           server=&quot;server&quot;
           &quot;/&gt;

Java class used to send the test transaction:

package com.testing;
 
import java.io.*;
import java.net.*;
import java.util.Date;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
 
public class RunTestTran{
 
    public  RunTestTran() {
    }
 
    public static void main(String [] args){
        RunTestTran recordProcessorTest = new RunTestTran();
        recordProcessorTest.runTran(&quot;localhost&quot;, 5555, &quot;/requestProcessor/rp&quot;);
    }
 
        private void runTran(String ip, int port, String appName){
                Socket socket = null;
                PrintWriter out = null;
                BufferedReader in = null;
                String dataToSend = &quot;&quot;;
 
                //Create socket connection
                try {
                        socket = new Socket(ip, port);
                        out = new PrintWriter(socket.getOutputStream(), true);
                        in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                } catch  (Exception e) {
                        System.out.println(&quot;Exception:&quot; + e.toString() );
                        System.exit(1);
                }
 
                DateFormat dateFormat = new SimpleDateFormat(&quot;MMddHHmmsss&quot;);
                //get current date time with Date() to create a 11 digit tran id
                Date date = new Date();
                String tranId = dateFormat.format(date);
                String PRIMER_TRAN = &quot;     V &quot; + tranId + &quot;9999999999000000000JANE       DOE         100 Redwood Shores Pkwy             Redwood City       CA94065000000000000000  PRIMER TRAN&quot;;
 
 
                try{
                        dataToSend = URLEncoder.encode(&quot;inputRecord&quot;, &quot;UTF-8&quot;) + &quot;=&quot; + URLEncoder.encode(PRIMER_TRAN, &quot;UTF-8&quot;);
 
                }catch(Exception e){
                        System.out.println(&quot;Exception caught!&quot; + e.toString());
                }
                 // send message
                StringBuffer sb = new StringBuffer();
                sb.append(&quot;POST /&quot; + appName + &quot;/wrp HTTP/1.1\r\n&quot;);
                // Try connection close-- see if it does close
                sb.append(&quot;Connection: close\r\n&quot;);
                sb.append(&quot;Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-powerpoint, application/vnd.ms-excel, application/msword\n&quot;);
                sb.append(&quot;Accept-Language: en-us\n&quot;);
                sb.append(&quot;Accept-Encoding: gzip, deflate\n&quot;);
                sb.append(&quot;User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)\n&quot;);
                // Authorization
                sb.append(&quot;Authorization: Basic DK34a3RvbWVydGVzddkK7WCx\n&quot;);
                sb.append(&quot;Host: &quot; + ip + &quot;:&quot; + port + &quot;\n&quot;);
                sb.append(&quot;Content-Length: &quot; + dataToSend.length() + &quot;\r\n&quot;);
                sb.append(&quot;Content-Type: application/x-www-form-urlencoded\r\n&quot;);
                sb.append(&quot;\r\n&quot;);
                sb.append(dataToSend);
                 // Send data
                String text = sb.toString();
                out.println(text);
 
                System.out.println(&quot;\nText sent &quot; + text.length() + &quot; bytes:&quot;);
                System.out.println(text + &quot;\n\n&quot;);
 
                try{
                        String gotBack1 = in.readLine();
                        System.out.println(&quot;Text received:&quot; + gotBack1 );
                        String gotBack = null;
                        while (  (gotBack = in.readLine()) != null){
                                System.out.println(&quot;Text received:&quot; + gotBack );
                                if ( (gotBack.indexOf(&quot;TQ!&quot;) != -1)){
                                        break;
                                }
                        }
                } catch (Exception e){
                        System.out.println(&quot;Read failed! &quot; + e.toString());
                        System.exit(1);
                }
        }
 
 
 
 
}

答案1

得分: 1

已修复。显然,8.5.51 版的 Tomcat 不喜欢使用 \n 结束标头。我将所有标头行的结束符更改为 \r\n,现在我收到了 200 的成功代码。

英文:

Fixed it. Apparently the 8.5.51 tomcat did not like terminating the headers with \n. I changed all the header line terminators to \r\n and I'm now getting 200 success codes.

huangapple
  • 本文由 发表于 2020年9月11日 04:04:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/63836938.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定