zoukankan      html  css  js  c++  java
  • Tomcat : Invalid character found in the request target

    Invalid character found in the request target. The valid characters are defined in RFC 7230 and RFC 3986

    Tomcat的coyote-connector解析到请求中包含了不合法的字符,比如  { }  ( )  ^ `  | #  \

    这是典型的400错误,不合法的请求,根据RFC (Request Format Comment)文档的规定,以上字符不能被用在Request Header,也就是request的URI中。

    我遇到这个问题是两个tomcat应用之间通讯时发送了一个请求,这个请求包含片段.*.(css|js|jpg|jpeg|png|gif|ico|woff)$,

    很显然,这个请求中包含 ( | 这三个不合法的字符;转义是不能解决问题的;因为tomcat会对请求中每个字符都进行检查;

    我的解决办法就是 将 .*.(css|js|jpg|jpeg|png|gif|ico|woff)$ 换成 .*tpl$,.*css$,.*js$,.*jpg$,.*jpeg$,.*bmp$,.*png$,.*gif$,.*ico$,.*woff$

     

     

    查看tomcat源码

    apache-tomcat-7.0.73-srcjavaorgapachecoyotehttp11InternalInputBuffer.java 

    public class InternalInputBuffer extends AbstractInputBuffer<Socket> {
       ....省略
        /**
         * Read the request line. This function is meant to be used during the
         * HTTP request header parsing. Do NOT attempt to read the request body
         * using it.
         *
         * @throws IOException If an exception occurs during the underlying socket
         * read operations, or if the given buffer is not big enough to accommodate
         * the whole line.
         */
        @Override
        public boolean parseRequestLine(boolean useAvailableDataOnly)
            throws IOException {
        ...省略
            //
            // Reading the URI
            //
            boolean eol = false;
            while (!space) {
                // Read new bytes if needed
                if (pos >= lastValid) {
                    if (!fill())
                        throw new EOFException(sm.getString("iib.eof.error"));
                }
                // Spec says single SP but it also says be tolerant of HT
                if (buf[pos] == Constants.SP || buf[pos] == Constants.HT) {
                    space = true;
                    end = pos;
                }else if (HttpParser.isNotRequestTarget(buf[pos])) {  
            //如果请求参数中的字符不是被允许的字符,则抛异常 HttpParser这个类 看下面代码片
    throw new IllegalArgumentException(sm.getString("iib.invalidRequestTarget")); } pos++; } ... 省略 return true; } }

    apache-tomcat-7.0.73-srcjavaorgapache omcatutilhttpparserHttpParser.java

    private static final int ARRAY_SIZE = 128;
    private static final boolean[] IS_NOT_REQUEST_TARGET = new boolean[ARRAY_SIZE];
    static { // Digest field types.for (int i = 0; i < ARRAY_SIZE; i++) { // Control> 0-31, 127 if (i < 32 || i == 127) { IS_CONTROL[i] = true; }// Not valid for request target. // Combination of multiple rules from RFC7230 and RFC 3986. Must be // ASCII, no controls plus a few additional characters excluded        // 不合法的字符在这里都会导致请求不合法而抛异常 请求失败 if (IS_CONTROL[i] || i > 127 || i == ' ' || i == '"' || i == '#' || i == '<' || i == '>' || i == '\' || i == '^' || i == '`' || i == '{' || i == '|' || i == '}') { IS_NOT_REQUEST_TARGET[i] = true; } } }

     HTTP协议只是一个OSI应用层通讯的标准,在tomcat源码中对HTTP进行了实现,可能在一些Tomcat版本中没有实现对请求字符的限制,可以预见,在Tomcat7.0.64之后的版本以及 Tomcat8、9都会对请求头的字符进行限制。

  • 相关阅读:
    Java并发编程基本概念
    详解TCP:顺序和丢包问题
    详解TCP:三次握手、四次挥手
    使用DockerFile构建运行GoWeb
    Go之Gorm和BeegoORM简介及配置使用
    Nginx WebUI管理
    Kibana配置nginx反代并本地ca加密nginx
    07 . ELK Stack7.2一键多机部署脚本
    腾讯蓝鲸自动化运维平台简介部署及常见报错解决
    Go操作Redis
  • 原文地址:https://www.cnblogs.com/zhengwenqiang/p/6909798.html
Copyright © 2011-2022 走看看