Tomcat8.x Servlet应用 req.getCookies() 的内部机制


Tomcat8.x Servlet应用 req.getCookies() 的内部机制


Cookie[] cookies = req.getCookies();
		for(Cookie cookie :cookies){
			String valueStr = "";
			valueStr += "domain = " + cookie.getDomain() + ";";
			valueStr += "value = " + cookie.getValue() + ";";
			valueStr += "path = " + cookie.getPath() + ";";
			valueStr += "version = " + cookie.getVersion() + ";";
			valueStr += "comment = " + cookie.getComment() + ";";
			valueStr += "version = " + cookie.getVersion() + ";";
			valueStr += "secure = " + cookie.getSecure() + ";";
			valueStr += "isHttpOnly = " + cookie.isHttpOnly() + ";";
			// 除了cookieName 和cookieValue外,其他值读取都没有意义,因为那些值是控制客户端的
			this.consoleWrite(System.out, cookie.getName(), valueStr);
		}
		
		class org.apache.catalina.connector.RequestFacade{
			public Cookie[] getCookies() {
	            ret = request.getCookies();
		        return ret;
		    }
		}
		
		class org.apache.catalina.connector.Request{
			// 读取cookie
			public Cookie[] getCookies() {
		        if (!cookiesConverted) {
		            convertCookies();//!!!
		        }
		        return cookies;
		    }
	        
			// 转换cookie
	        protected void convertCookies() {
	            if (cookiesConverted) {
	                return;
	            }

	            cookiesConverted = true;

	            // !!! 从头部的字节流中,解析出cookie,并添加到 coyoteRequest.getCookies()
	            parseCookies();

	            // org.apache.tomcat.util.http.ServerCookies
	            ServerCookies serverCookies = coyoteRequest.getCookies();
	            // cookieProcessor == org.apache.tomcat.util.http.Rfc6265CookieProcessor
	            CookieProcessor cookieProcessor = getContext().getCookieProcessor();

	            int count = serverCookies.getCookieCount();
	            if (count <= 0) {
	                return;
	            }
	            // javax.servlet.http.Cookie
	            cookies = new Cookie[count];
	            int idx=0;
	            for (int i = 0; i < count; i++) {
	                ServerCookie scookie = serverCookies.getCookie(i);
                    Cookie cookie = new Cookie(scookie.getName().toString(),null); // 创建cookie对象
                    int version = scookie.getVersion();
                    cookie.setVersion(version); // 版本
                    scookie.getValue().getByteChunk().setCharset(cookieProcessor.getCharset());
                    cookie.setValue(unescape(scookie.getValue().toString())); // cookie值
                    cookie.setPath(unescape(scookie.getPath().toString())); // cookie作用路径
                    String domain = scookie.getDomain().toString(); 
                    if (domain!=null)
                     {
                        cookie.setDomain(unescape(domain));//avoid NPE // cookie作用域名
                    }
                    String comment = scookie.getComment().toString();
                    cookie.setComment(version==1?unescape(comment):null);
                    cookies[idx++] = cookie;
	            }
	        }
	        
	        protected void parseCookies() {
	            if (cookiesParsed) {
	                return;
	            }

	            cookiesParsed = true;

	            ServerCookies serverCookies = coyoteRequest.getCookies();
	            // getContext() == org.apache.catalina.core.StandardContext
	            // cookieProcessor == org.apache.tomcat.util.http.Rfc6265CookieProcessor
	            CookieProcessor cookieProcessor = getContext().getCookieProcessor();
	            cookieProcessor.parseCookieHeader(coyoteRequest.getMimeHeaders(), serverCookies); // 从http中的解析出cookie 放入serverCookies
	        }
		}
		
		// 解析头部的CookIE串
		class org.apache.tomcat.util.http.Rfc6265CookieProcessor{
			public void parseCookieHeader(MimeHeaders headers,
		            ServerCookies serverCookies) {
		        // process each "cookie" header
		        int pos = headers.findHeader("Cookie", 0); // 找出第一个cookie头
		        while (pos >= 0) {
		            MessageBytes cookieValue = headers.getValue(pos);

		            if (cookieValue != null && !cookieValue.isNull() ) {
		                ByteChunk bc = cookieValue.getByteChunk(); // http头中的cookie值
		                // 解析cookie!!!!
		                // org.apache.tomcat.util.http.parser.Cookie
		                Cookie.parseCookie(bc.getBytes(), bc.getOffset(), bc.getLength(),
		                        serverCookies);
		            }
		            // search from the next position
		            pos = headers.findHeader("Cookie", ++pos); // 找出第二个cookie的值
		        }
		    }
		}

		// 解析出cookie
		class org.apache.tomcat.util.http.parser.Cookie{
			
			public static void parseCookie(byte[] bytes, int offset, int len,
		            ServerCookies serverCookies) {
		    	 // bytes == http头中的cookie值  如: Cookie:cookie2=value2; JSESSIONID=98FC8479489BA7717095AACFB5E51573; cookie1=value1; cookie1=value1
		        ByteBuffer bb = new ByteBuffer(bytes, offset, len);
		        skipLWS(bb); // 定位到下一个合法字节

		        // Record position in case we need to return.
		        int mark = bb.position();
		        SkipResult skipResult = skipBytes(bb, VERSION_BYTES); // 跳过  $Version
		        if (skipResult != SkipResult.FOUND) { // 如果不存在$Version标志
		            // No need to reset position since skipConstant() will have done it
		            parseCookieRfc6265(bb, serverCookies); // !!! 解析出Cookie
		            return;
		        }
			}
			
			private static void parseCookieRfc6265(ByteBuffer bb, ServerCookies serverCookies) {
		        boolean moreToProcess = true;
		        // bb == http头中的cookie值  如: Cookie:cookie2=value2; JSESSIONID=98FC8479489BA7717095AACFB5E51573; cookie1=value1; cookie1=value1
		        while (moreToProcess) {
		            skipLWS(bb); // 定位到下一个合法字节

		            ByteBuffer name = readToken(bb); // 读取cookie名称
		            ByteBuffer value = null;

		            skipLWS(bb); // 忽略掉tab符号和空格

		            SkipResult skipResult = skipByte(bb, EQUALS_BYTE); // 跳过“=” 等于号
		            if (skipResult == SkipResult.FOUND) { // 下一个字符是 “=”
		                skipLWS(bb); // 定位到下一个合法字节
		                value = readCookieValueRfc6265(bb); // cookie的值
		                if (value == null) {
		                    logInvalidHeader(bb);
		                    // Invalid cookie value. Skip to the next semi-colon
		                    skipUntilSemiColon(bb);
		                    continue; // 没有值,直接进入下一个循环
		                }
		                skipLWS(bb);// 忽略掉tab符号和空格
		            }

		            skipResult = skipByte(bb, SEMICOLON_BYTE); // 跳过 “;” 分号
		            if (skipResult == SkipResult.FOUND) {
		                // NO-OP
		            } else if (skipResult == SkipResult.NOT_FOUND) {
		                logInvalidHeader(bb);
		                // Invalid cookie. Ignore it and skip to the next semi-colon
		                skipUntilSemiColon(bb);
		                continue;
		            } else {
		                // SkipResult.EOF
		                moreToProcess = false;
		            }

		            if (name.hasRemaining()) {
		                ServerCookie sc = serverCookies.addCookie(); // 创建一个cookie
		                sc.getName().setBytes(name.array(), name.position(), name.remaining()); // 设置cookie名
		                if (value == null) {
		                    sc.getValue().setBytes(EMPTY_BYTES, 0, EMPTY_BYTES.length); // 设置cookie值
		                } else {
		                    sc.getValue().setBytes(value.array(), value.position(), value.remaining());
		                }
		            }
		        }
		    }
		}




  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值