异常:Invalid character found in the request target. The valid characters are defined in RFC 3986

 

One, background

  The way it is, a few days before doing basic database "CRUD" demand distal parameter passing mode is "the JSON string", after receiving the rear end of this parameter, use Alibaba fastjson parse, then the library. Demand is very simple, but it happens've got a problem.

  When I found out, JSON string inside numerous groups, time is pure json structure, that is "{}", does not complain, mass participation storage no problem. But as long as the value of parameter passing inside the array, i.e., when there is "[]" of the structure, it is given. Error reads as follows (my tomcat version is 8.5.45 ):

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)
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:684)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:800)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1471)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:748)

 

Second, the cause

  The reason the tomcat. tomcat resolved in strict accordance with the RFC specification essay, along with changes in the network environment, the RFC specification are constantly modified and upgraded, the version released a lot. The different versions of tomcat, the RFC specification version used is different. So below you will find some low tomcat version does not have this problem.

  Since tomcat tomcat 8.0.35 version of the URL parameters were compared specification limits, we must follow RFC 7230 and RFC 3986 specifications for the non-reserved word character (request parameter json format) must make an escape operation. For example: RFC 3986 specification defines the Url contains only letters (a-zA-Z), numbers (0-9), 1-4 -_ special characters and all reserved characters (specified in RFC3986 following characters are reserved. character: * '();:! @ & = + $, / # [])?.

  Request For Comments (RFC), is scheduled a series of numbered files. Internet-related files collected information, as well as UNIX and the Internet community software files related. RFC documents are currently issued by the Internet Society (ISOC) sponsorship. Basic Internet communication protocols are described in the RFC document in detail. RFC document also joined a number of additional topics in the standards, for example, all records for the new Internet protocol developed and developing. Therefore almost all Internet standards are included in the RFC documents - Baidu Encyclopedia.

  Daniel network attached source code analysis:

分析的是org.apache.tomcat.util.http.parser.HttpParser

//tomcat 8.2.3 版本及 tomcat 7.0.82 ,都有如下代码,读取配置
String prop = System.getProperty("tomcat.util.http.parser.HttpParser.requestTargetAllow");
if (prop != null) {
    for (int i = 0; i < prop.length(); i++) {
        char c = prop.charAt(i);
        if (c == '{' || c == '}' || c == '|') {
            REQUEST_TARGET_ALLOW[c] = true;
        } else {
            log.warn(sm.getString("httpparser.invalidRequestTargetCharacter", Character.valueOf (c))); 
        } 
    } 
} 

and Tomcat 8.0.14 version did not read the configuration of | handling {}, but the default is legitimate character.
static { 
    for ( int I = 0; I <128; I ++ ) {
         IF (I <32 ) { 
            isToken [I] = to false ; 
        } the else  IF (I == '(' || I == ')' || == I '<' || I == '>' || I == '@' || 
                   I == ',' || I == ';' || I == ':' I = || = '\\' || I == '\ "' || 
                   I == '/' || I == '[' || I == ']'== '{' || i == '}' || i == ' ' || i == '\t') {
            isToken[i] = false;
        } else {
            isToken[i] = true;
        }
        if (i >= '0' && i <= '9' || i >= 'A' && i <= 'F' ||i >= 'a' && i <= 'f') {
            isHex[i] = true;
        } else {
            isHex[i] = false;
        }
    }
}
可以看出在 Some versions of the left and right 8.0.x, tomcat.util.http.parser.HttpParser requestTargetAllow (hereinafter Method C) This configuration is not in force, i.e., | {} three symbols considered legitimate.

 

Third, resolve

  Note: I am using the "method Five" to solve the problem, recommended "Method five."

  Method one : change to low version of Tomcat.

  Method Two : Add Catalina.properties in tomcat.util.http.parser.HttpParser.requestTargetAllow = | {} This thing obviously is to allow "|" and braces, but my question now is in parentheses.

  Method three : Add tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH = true This is to allow the url with special characters. I tried, not so that.

  Method four : After passing "the JSON string" url coding performed in the transmission, the brackets can be circumvented. Distal end with "encodeURI (xxx)" method for encoding, a rear end with "URLDecoder.decode (xxx," utf- 8 ")" can be decoded.

  Method five : tomcat directory under the conf file folder, Connector server.xml added this relaxedQueryChars = "[,]".

      Note:

1, if there are other special string, you can also be added directly to the property inside;

2, if you are springboot project, you can increase the main method of SpringBootApplication in: System.setProperty ( "tomcat.util.http.parser.HttpParser.requestTargetAllow", "[]");       

reference

1、https://blog.csdn.net/Hitler698/article/details/85720156

2、https://my.oschina.net/pding/blog/1794176

 

Guess you like

Origin www.cnblogs.com/DDgougou/p/11668073.html