协议解析,http协议的解析实际与流程

接收Request请求

在用户请求进来的时候,Acceptor会接收该Socket请求,接收该请求后会执行setSocketOptions方法,这个时候会对socket做初步的封装(设置socket的属性值,如tcpnodeplay,keepalive等),

然后会创建SocketBufferHandler,设置读写的缓存大小为8k,将SocketBufferHandler与socket一同封装成NioChannel。

调用Poller.register()将NioChannel(socket)先进一步封装成NioSocketWrapper类,再封装成PollerEvent然后注册到Poller的events队列中去。

protected boolean setSocketOptions(SocketChannel socket) {
    // Process the connection
 try {
        //disable blocking, APR style, we are gonna be polling it
 socket.configureBlocking(false);
        Socket sock = socket.socket();
        socketProperties.setProperties(sock);

        NioChannel channel = nioChannels.pop();
        if (channel == null) {
            SocketBufferHandler bufhandler = new SocketBufferHandler(
                    socketProperties.getAppReadBufSize(),
                    socketProperties.getAppWriteBufSize(),
                    socketProperties.getDirectBuffer());
            if (isSSLEnabled()) {
                channel = new SecureNioChannel(socket, bufhandler, selectorPool, this);
            } else {
                channel = new NioChannel(socket, bufhandler);
            }
        } else {
            channel.setIOChannel(socket);
            channel.reset();
        }
        getPoller0().register(channel);
    } catch (Throwable t) {
        ExceptionUtils.handleThrowable(t);
        try {
            log.error("",t);
        } catch (Throwable tt) {
            ExceptionUtils.handleThrowable(tt);
        }
        // Tell to close the socket
 return false;
    }
    return true;
}

Poller.run()消费队列的PollerEvent事件。将PollerEvent中准备就绪的socketWrapper注册到Selector。

try {
    socket.getIOChannel().register(
            socket.getPoller().getSelector(), SelectionKey.OP_READ, socketWrapper);
} catch (Exception x) {
    log.error(sm.getString("endpoint.nio.registerFail"), x);
}

从selector中选择就绪的channel,根据selectorkey是否可读,可写执行对应的处理逻辑

if (sk.isReadable()) {
    if (!processSocket(attachment, SocketEvent.OPEN_READ, true)) {
        closeSocket = true;
    }
}
if (!closeSocket && sk.isWritable()) {
    if (!processSocket(attachment, SocketEvent.OPEN_WRITE, true)) {
        closeSocket = true;
    }
}

processSocket会创建一个SocketProcessor对象,进行socket处理握手完成后会进行协议的处理

if (event == null) {
    state = getHandler().process(socketWrapper, SocketEvent.OPEN_READ);
} else {
    state = getHandler().process(socketWrapper, event);
}

HTTP1.1协议初始化

process方法会创建Http11Processor处理器,然后回调用Http11Processor的process进行处理。

if (processor == null) {
    processor = getProtocol().createProcessor();
    register(processor);
}

processor.setSslSupport(
        wrapper.getSslSupport(getProtocol().getClientCertProvider()));

// Associate the processor with the connection
connections.put(socket, processor);

SocketState state = SocketState.CLOSED;
do {
    state = processor.process(wrapper, status);

在AbstractProcessor的构造方法中会创建Request,Response对象,在Http11Processor构造方法中会添加一系列的过滤器,用于对输入输出请求的过滤

userDataHelper = new UserDataHelper(log);

inputBuffer = new Http11InputBuffer(request, maxHttpHeaderSize,rejectIllegalHeaderName);
request.setInputBuffer(inputBuffer);

outputBuffer = new Http11OutputBuffer(response, maxHttpHeaderSize, sendReasonPhrase);
response.setOutputBuffer(outputBuffer);

// Create and add the identity filters.
inputBuffer.addFilter(new IdentityInputFilter(maxSwallowSize));
outputBuffer.addFilter(new IdentityOutputFilter());

// Create and add the chunked filters.
inputBuffer.addFilter(new ChunkedInputFilter(maxTrailerSize, allowedTrailerHeaders,
        maxExtensionSize, maxSwallowSize));
outputBuffer.addFilter(new ChunkedOutputFilter());

// Create and add the void filters.
inputBuffer.addFilter(new VoidInputFilter());
outputBuffer.addFilter(new VoidOutputFilter());

// Create and add buffered input filter
inputBuffer.addFilter(new BufferedInputFilter());

// Create and add the chunked filters.
//inputBuffer.addFilter(new GzipInputFilter());
outputBuffer.addFilter(new GzipOutputFilter());

pluggableFilterIndex = inputBuffer.getFilters().length;

this.httpUpgradeProtocols = httpUpgradeProtocols;
this.allowHostHeaderMismatch = allowHostHeaderMismatch;

在service方法中会先进行输入输出缓存的初始化,然后根据请求报文格式进行解析,这个时候也会对request的header进行填充

setSocketWrapper(socketWrapper);
inputBuffer.init(socketWrapper);
outputBuffer.init(socketWrapper);
if (!inputBuffer.parseRequestLine(keptAlive)) {
    if (inputBuffer.getParsingRequestLinePhase() == -1) {
        return SocketState.UPGRADING;
    } else if (handleIncompleteRequestLineRead()) {
        break;
    }
}

如果支持HTTP/2.0则调用UpgradeProtocol接收用户的请求

String requestedProtocol = request.getHeader("Upgrade");

UpgradeProtocol upgradeProtocol = httpUpgradeProtocols.get(requestedProtocol);
if (upgradeProtocol != null) {
    if (upgradeProtocol.accept(request)) {

调用CoyoteAdapter.service(request, response):将tomcat的内部coyoteRequest和coyoteReponse转换为servlet规范request ,response对象。然后将coyoteRequest,coyoteReponse分别设置给request,response 接下来就是调用各级容器,走过filter到达servlet中

request = connector.createRequest();
request.setCoyoteRequest(req);
response = connector.createResponse();
response.setCoyoteResponse(res);
request.setAsyncSupported(
        connector.getService().getContainer().getPipeline().isAsyncSupported());
// Calling the container
connector.getService().getContainer().getPipeline().getFirst().invoke(
        request, response);

AJP协议初始化

AJP协议的处理流程可自行观看,AJP协议的消息包结构跟HTTP有差别,解析请求的时候跟HTTP不太一样,整体处理流程跟HTTP类似

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值