我們在上篇文章分析了http request line tomcat的解析。本文主要講header 的解析
tomcat 默認對header的個數(shù)做了限制每聪,通過maxHeaderCount 參數(shù)設(shè)置旦棉,默認
maxHeaderCount = 100
//解析header 部分前齿风,設(shè)置了header 個數(shù)的限制
request.getMimeHeaders().setLimit(endpoint.getMaxHeaderCount());
if (!inputBuffer.parseHeaders()) {
// head 部分數(shù)據(jù)缺少,半包的情況绑洛,需要等待后面的數(shù)據(jù)報到來繼續(xù)讀救斑。
// We've read part of the request, don't recycle it
// instead associate it with the socket
openSocket = true;
readComplete = false;
break;
}
parseHeaders 是循環(huán)解析所有的header name 和value 對,并添加到
MimeHeaders 的headers 數(shù)組中真屯,headers 數(shù)組的大小是maxHeaderCount脸候,也就是100,
do {
//循環(huán)讀所有的header頭
status = parseHeader();
// Checking that
// (1) Headers plus request line size does not exceed its limit
// (2) There are enough bytes to avoid expanding the buffer when
// reading body
// Technically, (2) is technical limitation, (1) is logical
// limitation to enforce the meaning of headerBufferSize
// From the way how buf is allocated and how blank lines are being
// read, it should be enough to check (1) only.
if (byteBuffer.position() > headerBufferSize || byteBuffer.capacity() - byteBuffer.position() < socketReadBufferSize) {
throw new IllegalArgumentException(sm.getString("iib.requestheadertoolarge.error"));
}
} while (status == HeaderParseStatus.HAVE_MORE_HEADERS);
if (status == HeaderParseStatus.DONE) {
parsingHeader = false;
end = byteBuffer.position();
return true;
} else {
return false;
}
讀到':' 時绑蔫,就添加一個header 并返回value的引用纪他,后面value 解析完后,直接設(shè)置headerData.headerValue 即可晾匠,headers.addValue() 會判斷大小是否超過maxHeaderCount茶袒,如超過,則拋headers.maxCountFail
錯誤凉馆。
if (chr == Constants.COLON) {
headerParsePos = HeaderParsePosition.HEADER_VALUE_START;
//header name 讀完了薪寓,創(chuàng)建一個MimeHeaderField 標記該name 的在buffer 里的 offset 和 length headerData.headerValue = headers.addValue(byteBuffer.array(), headerData.start,
pos - headerData.start);
headers 里存放的是MimeHeaderField,代表一個header澜共,MimeHeaderField 有兩個MessageBytes 類型的nameB和valueB,分別表示header name 和 header value
MessageBytes 只是對上篇講到的httpinputbuffer的引用向叉,并記錄偏移量和長度。這樣所有的header name 和value 都引用了tomcat input buffer嗦董,只是每一個的offset 和length 不一樣而已母谎。