zoukankan      html  css  js  c++  java
  • 让tomcat支持中文cookie

    这的确是一个不正常的需求,按照规范,开发者需要将cookie进行编码,因为tomcat不支持中文cookie。

    但有时候,你不得不面对这样的情况,比如请求是由他人开发的软件,比如,浏览器控件发出的。

    这个时候就需要修改tomcat源码来支持了。

    直接上源码

    /*
     * Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *      http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    package org.apache.tomcat.util.http;
    
    
    /**
     * Static constants for this package.
     */
    public final class CookieSupport {
    
        // --------------------------------------------------------------- Constants
        /**
         * If set to true, we parse cookies strictly according to the servlet,
         * cookie and HTTP specs by default.
         */
        public static final boolean STRICT_SERVLET_COMPLIANCE;
    
        /**
         * If true, cookie values are allowed to contain an equals character without
         * being quoted.
         */
        public static final boolean ALLOW_EQUALS_IN_VALUE;
    
        /**
         * If true, separators that are not explicitly dis-allowed by the v0 cookie
         * spec but are disallowed by the HTTP spec will be allowed in v0 cookie
         * names and values. These characters are: "()/:<=>?@[\]{} Note that the
         * inclusion of / depends on the value of {@link #FWD_SLASH_IS_SEPARATOR}.
         */
        public static final boolean ALLOW_HTTP_SEPARATORS_IN_V0;
    
        /**
         * If set to false, we don't use the IE6/7 Max-Age/Expires work around.
         * Default is usually true. If STRICT_SERVLET_COMPLIANCE==true then default
         * is false. Explicitly setting always takes priority.
         */
        public static final boolean ALWAYS_ADD_EXPIRES;
    
        /**
         * If set to true, the <code>/</code> character will be treated as a
         * separator. Default is usually false. If STRICT_SERVLET_COMPLIANCE==true
         * then default is true. Explicitly setting always takes priority.
         */
        public static final boolean FWD_SLASH_IS_SEPARATOR;
    
        /**
         * If true, name only cookies will be permitted.
         */
        public static final boolean ALLOW_NAME_ONLY;
    
        /**
         * If set to true, the cookie header will be preserved. In most cases 
         * except debugging, this is not useful.
         */
        public static final boolean PRESERVE_COOKIE_HEADER;
    
        /**
         * The list of separators that apply to version 0 cookies. To quote the
         * spec, these are comma, semi-colon and white-space. The HTTP spec
         * definition of linear white space is [CRLF] 1*( SP | HT )
         */
        private static final char[] V0_SEPARATORS = {',', ';', ' ', '	'};
        private static final boolean[] V0_SEPARATOR_FLAGS = new boolean[65536];
    
        /**
         * The list of separators that apply to version 1 cookies. This may or may
         * not include '/' depending on the setting of
         * {@link #FWD_SLASH_IS_SEPARATOR}.
         */
        private static final char[] HTTP_SEPARATORS;
        private static final boolean[] HTTP_SEPARATOR_FLAGS = new boolean[65536];
    
        static {
            STRICT_SERVLET_COMPLIANCE = Boolean.parseBoolean(System.getProperty(
                    "org.apache.catalina.STRICT_SERVLET_COMPLIANCE",
                    "false"));
    
            ALLOW_EQUALS_IN_VALUE = Boolean.parseBoolean(System.getProperty(
                    "org.apache.tomcat.util.http.ServerCookie.ALLOW_EQUALS_IN_VALUE",
                    "false"));
    
            ALLOW_HTTP_SEPARATORS_IN_V0 = Boolean.parseBoolean(System.getProperty(
                    "org.apache.tomcat.util.http.ServerCookie.ALLOW_HTTP_SEPARATORS_IN_V0",
                    "false"));
    
            String alwaysAddExpires = System.getProperty(
            "org.apache.tomcat.util.http.ServerCookie.ALWAYS_ADD_EXPIRES");
            if (alwaysAddExpires == null) {
                ALWAYS_ADD_EXPIRES = !STRICT_SERVLET_COMPLIANCE;
            } else {
                ALWAYS_ADD_EXPIRES = Boolean.parseBoolean(alwaysAddExpires);
            }
    
            String preserveCookieHeader = System.getProperty(
                    "org.apache.tomcat.util.http.ServerCookie.PRESERVE_COOKIE_HEADER");
            if (preserveCookieHeader == null) {
                PRESERVE_COOKIE_HEADER = STRICT_SERVLET_COMPLIANCE;
            } else {
                PRESERVE_COOKIE_HEADER = Boolean.parseBoolean(preserveCookieHeader);
            }
    
            String  fwdSlashIsSeparator = System.getProperty(
                    "org.apache.tomcat.util.http.ServerCookie.FWD_SLASH_IS_SEPARATOR");
            if (fwdSlashIsSeparator == null) {
                FWD_SLASH_IS_SEPARATOR = STRICT_SERVLET_COMPLIANCE;
            } else {
                FWD_SLASH_IS_SEPARATOR = Boolean.parseBoolean(fwdSlashIsSeparator);
            }
    
            ALLOW_NAME_ONLY = Boolean.parseBoolean(System.getProperty(
                    "org.apache.tomcat.util.http.ServerCookie.ALLOW_NAME_ONLY",
                    "false"));
    
    
            /*
            Excluding the '/' char by default violates the RFC, but
            it looks like a lot of people put '/'
            in unquoted values: '/': ; //47
            '	':9 ' ':32 '"':34 '(':40 ')':41 ',':44 ':':58 ';':59 '<':60
            '=':61 '>':62 '?':63 '@':64 '[':91 '\':92 ']':93 '{':123 '}':125
            */
            if (CookieSupport.FWD_SLASH_IS_SEPARATOR) {
                HTTP_SEPARATORS = new char[] { '	', ' ', '"', '(', ')', ',', '/',
                        ':', ';', '<', '=', '>', '?', '@', '[', '\', ']', '{', '}' };
            } else {
                HTTP_SEPARATORS = new char[] { '	', ' ', '"', '(', ')', ',',
                        ':', ';', '<', '=', '>', '?', '@', '[', '\', ']', '{', '}' };
            }
            for (int i = 0; i < 65536; i++) {
                V0_SEPARATOR_FLAGS[i] = false;
                HTTP_SEPARATOR_FLAGS[i] = false;
            }
            for (int i = 0; i < V0_SEPARATORS.length; i++) {
                V0_SEPARATOR_FLAGS[V0_SEPARATORS[i]] = true;
            }
            for (int i = 0; i < HTTP_SEPARATORS.length; i++) {
                HTTP_SEPARATOR_FLAGS[HTTP_SEPARATORS[i]] = true;
            }
    
        }
    
        // ----------------------------------------------------------------- Methods
    
        /**
         * Returns true if the byte is a separator as defined by V0 of the cookie
         * spec.
         */
        public static final boolean isV0Separator(final char c) {
    //        if (c < 0x20 || c >= 0x7f) {
    //            if (c != 0x09) {
    //                throw new IllegalArgumentException(
    //                        "Control character in cookie value or attribute.");
    //            }
    //        }
    
            return V0_SEPARATOR_FLAGS[c];
        }
    
        public static boolean isV0Token(String value) {
            if( value==null) {
                return false;
            }
    
            int i = 0;
            int len = value.length();
    
            if (alreadyQuoted(value)) {
                i++;
                len--;
            }
    
            for (; i < len; i++) {
                char c = value.charAt(i);
                if (isV0Separator(c)) {
                    return true;
                }
            }
            return false;
        }
    
        /**
         * Returns true if the byte is a separator as defined by V1 of the cookie
         * spec, RFC2109.
         * @throws IllegalArgumentException if a control character was supplied as
         *         input
         */
        public static final boolean isHttpSeparator(final char c) {
    //        if (c < 0x20 || c >= 0x7f) {
    //            if (c != 0x09) {
    //                throw new IllegalArgumentException(
    //                        "Control character in cookie value or attribute.");
    //            }
    //        }
    
            return HTTP_SEPARATOR_FLAGS[c];
        }
    
        public static boolean isHttpToken(String value) {
            if( value==null) {
                return false;
            }
    
            int i = 0;
            int len = value.length();
    
            if (alreadyQuoted(value)) {
                i++;
                len--;
            }
    
            for (; i < len; i++) {
                char c = value.charAt(i);
    
                if (isHttpSeparator(c)) {
                    return true;
                }
            }
            return false;
        }
    
        public static boolean alreadyQuoted (String value) {
            if (value==null || value.length() < 2) {
                return false;
            }
            return (value.charAt(0)=='"' && value.charAt(value.length()-1)=='"');
        }
    
    
        // ------------------------------------------------------------- Constructor
        private CookieSupport() {
            // Utility class. Don't allow instances to be created.
        }
    }
    

      

  • 相关阅读:
    以您熟悉的编程语言为例完成一个hello/hi的简单的网络聊天程序——网络程序设计课第二次作业
    逆波兰表达式改写(C++)
    侯捷老师的C++代码:基于对象的类别之二带指针的成员函数 Mystring实现
    侯捷老师的C++代码: 基于对象之一 无指针类型 复数类实现
    雇员记录系统(C++)
    设计模式-Interpreter(行为模式) 使用解释器给用户提供一个一门定义语言的语法表示的解释器,通过该解释器解释语言中的句子。
    设计模式-Iterator(行为模式) 将聚合的遍历封装到一个类中
    设计模式-Chain of Responsibility (行为模式) 降低系统的耦合性
    设计模式-Visitor(行为模式) 一个类在不修改自己的同时增加了新的操作,存在问题是 1:破坏了封装性 2:扩展困难
    设计模式-Command(行为模式) 将一个请求封装到一个Command类中,提供一个处理对象Receiver,将Command由Invoker激活。
  • 原文地址:https://www.cnblogs.com/srszzw/p/5169162.html
Copyright © 2011-2022 走看看