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());
}
}
}
}
}