The valid characters are defined in RFC 7230 and RFC 3986

Spring Cloud 項目中須要使用這樣的URL地址(http://localhost:19001/work.html?a=b|c),且由於某種不可告知的緣由不能進行URLEncode轉換。

Spring Cloud報錯:
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.
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.
    at
    at
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.
    at

緣由 傳送門

RFC3986文檔規定,Url中只容許包含英文字母(a-z,A-Z)、數字(0-9)、- _ . ~ 4個特殊字符以及全部保留字符。
指定了如下字符爲保留字符:! * ’ ( ) ; : @ & = + $ , / ? # [ ]

解決方法是修改tomcat的catalina.properties 配置:
tomcat.util.http.parser.HttpParser.requestTargetAllow=|{}

但是咱們是Spring Cloud啊,哪有這個配置文件啊。

查看源碼發現讀取了系統環境變量tomcat.util.http.parser.HttpParser.requestTargetAllow(略過其中查找Spring配置、查找tomcat-embed-core-8.5.23.jar修改裏面配置等等步驟)。

String prop = System.getProperty("tomcat.util.http.parser.HttpParser.requestTargetAllow");
    int i;
    if (prop != null) {
        for(i = 0; i < prop.length(); ++i) {
            char c = prop.charAt(i);
            if (c != '{' && c != '}' && c != '|') {
                log.warn(sm.getString("httpparser.invalidRequestTargetChar acter", new Object[]{c}));
            } else {
                REQUEST_TARGET_ALLOW[c] = true;
            }
        }
    }

在啓動時增長VM參數
-Dtomcat.util.http.parser.HttpParser.requestTargetAllow=|{}

搞定!


補完:
後來發如今shell裏啓動時保留字符也出現問題,啓動腳本沒法傳入,最後直接在Application裏經過代碼直接設置系統屬性搞定。
System.setProperty("tomcat.util.http.parser.HttpParser.requestTargetAllow","|{}");
相關文章
相關標籤/搜索