searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

Jetty解析http报文过程介绍

2023-05-22 07:38:27
17
0

http报文结构

start-line: 起始行,描述请求或响应的基本信息
*( header-field CRLF ): 头
CRLF
[message-body]: 消息body,实际传输的数据

 

状态机

jetty通过状态机解析这些字符串。具体看org.eclipse.jetty.http.HttpParse类

public enum State
{
    START,
    METHOD,
    SPACE1,
    STATUS,
    URI,
    SPACE2,
    REQUEST_VERSION,
    REASON,
    PROXY,
    HEADER,
    CONTENT,
    EOF_CONTENT,
    CHUNKED_CONTENT,
    CHUNK_SIZE,
    CHUNK_PARAMS,
    CHUNK,
    TRAILER,
    END,
    CLOSE,
    CLOSED
}

      

总共分成了21种状态,然后进行状态间的流转。在parseNext方法中分别对起始行 -> header -> body content分别解析

public boolean parseNext(ByteBuffer buffer)
{
	……
    // Start a request/response
    if (_state==State.START)
    {
        // 快速判断
        if (quickStart(buffer))
            return true;
    }

    // Request/response line 转换
    if (_state.ordinal()>= State.START.ordinal() && _state.ordinal()<State.HEADER.ordinal())
    {
        if (parseLine(buffer))
            return true;
    }

    // headers转换
    if (_state== State.HEADER)
    {
        if (parseFields(buffer))
            return true;
    }

    // content转换
    if (_state.ordinal()>= State.CONTENT.ordinal() && _state.ordinal()<State.TRAILER.ordinal())
    {
        // Handle HEAD response
        if (_responseStatus>0 && _headResponse)
        {
            setState(State.END);
            return handleContentMessage();
        }
        else
        {
            if (parseContent(buffer))
                return true;
        }
    }

    return false;
}

 

整体流程

有三条路径

1、开始 -> start-line -> header -> 结束

2、开始 -> start-line -> header -> content -> 结束

3、开始 -> start-line -> header -> chunk-content -> 结束

 

起始行

start-line = request-line(请求起始行)/(响应起始行)status-line

1、请求报文解析状态迁移 请求行:START -> METHOD -> SPACE1 -> URI -> SPACE2 -> REQUEST_VERSION

2、响应报文解析状态迁移 响应行:START -> RESPONSE_VERSION -> SPACE1 -> STATUS -> SPACE2 -> REASON

 

header 头

HEADER 的状态只有一种了,在jetty的老版本中还区分了HEADER_IN_NAM, HEADER_VALUE, HEADER_IN_VALUE等,新版本中去除了。为了提高匹配效率,jetty使用了Trie树快速匹配header头。

static
{
    CACHE.put(new HttpField(HttpHeader.CONNECTION,HttpHeaderValue.CLOSE));
    CACHE.put(new HttpField(HttpHeader.CONNECTION,HttpHeaderValue.KEEP_ALIVE));       
    // 以下省略了很多了通用header头

 

content

请求体:

1、CONTENT -> END,这种是普通的带Content-Length头的报文,HttpParser一直运行CONTENT状态,直到最后ContentLength达到了指定的数量,则进入END状态

2、chunked分块传输的数据 CHUNKED_CONTENT -> CHUNK_SIZE -> CHUNK -> CHUNK_END -> END

0条评论
0 / 1000
a****k
15文章数
0粉丝数
a****k
15 文章 | 0 粉丝
原创

Jetty解析http报文过程介绍

2023-05-22 07:38:27
17
0

http报文结构

start-line: 起始行,描述请求或响应的基本信息
*( header-field CRLF ): 头
CRLF
[message-body]: 消息body,实际传输的数据

 

状态机

jetty通过状态机解析这些字符串。具体看org.eclipse.jetty.http.HttpParse类

public enum State
{
    START,
    METHOD,
    SPACE1,
    STATUS,
    URI,
    SPACE2,
    REQUEST_VERSION,
    REASON,
    PROXY,
    HEADER,
    CONTENT,
    EOF_CONTENT,
    CHUNKED_CONTENT,
    CHUNK_SIZE,
    CHUNK_PARAMS,
    CHUNK,
    TRAILER,
    END,
    CLOSE,
    CLOSED
}

      

总共分成了21种状态,然后进行状态间的流转。在parseNext方法中分别对起始行 -> header -> body content分别解析

public boolean parseNext(ByteBuffer buffer)
{
	……
    // Start a request/response
    if (_state==State.START)
    {
        // 快速判断
        if (quickStart(buffer))
            return true;
    }

    // Request/response line 转换
    if (_state.ordinal()>= State.START.ordinal() && _state.ordinal()<State.HEADER.ordinal())
    {
        if (parseLine(buffer))
            return true;
    }

    // headers转换
    if (_state== State.HEADER)
    {
        if (parseFields(buffer))
            return true;
    }

    // content转换
    if (_state.ordinal()>= State.CONTENT.ordinal() && _state.ordinal()<State.TRAILER.ordinal())
    {
        // Handle HEAD response
        if (_responseStatus>0 && _headResponse)
        {
            setState(State.END);
            return handleContentMessage();
        }
        else
        {
            if (parseContent(buffer))
                return true;
        }
    }

    return false;
}

 

整体流程

有三条路径

1、开始 -> start-line -> header -> 结束

2、开始 -> start-line -> header -> content -> 结束

3、开始 -> start-line -> header -> chunk-content -> 结束

 

起始行

start-line = request-line(请求起始行)/(响应起始行)status-line

1、请求报文解析状态迁移 请求行:START -> METHOD -> SPACE1 -> URI -> SPACE2 -> REQUEST_VERSION

2、响应报文解析状态迁移 响应行:START -> RESPONSE_VERSION -> SPACE1 -> STATUS -> SPACE2 -> REASON

 

header 头

HEADER 的状态只有一种了,在jetty的老版本中还区分了HEADER_IN_NAM, HEADER_VALUE, HEADER_IN_VALUE等,新版本中去除了。为了提高匹配效率,jetty使用了Trie树快速匹配header头。

static
{
    CACHE.put(new HttpField(HttpHeader.CONNECTION,HttpHeaderValue.CLOSE));
    CACHE.put(new HttpField(HttpHeader.CONNECTION,HttpHeaderValue.KEEP_ALIVE));       
    // 以下省略了很多了通用header头

 

content

请求体:

1、CONTENT -> END,这种是普通的带Content-Length头的报文,HttpParser一直运行CONTENT状态,直到最后ContentLength达到了指定的数量,则进入END状态

2、chunked分块传输的数据 CHUNKED_CONTENT -> CHUNK_SIZE -> CHUNK -> CHUNK_END -> END

文章来自个人专栏
云组件
15 文章 | 1 订阅
0条评论
0 / 1000
请输入你的评论
0
0