知识库--Processing Requests

Processing Requests

At this point, you already understand about the request and response objects and how the HttpConnector object creates them. Now is the last bit of the process. In this section we focus on the process method of the HttpProcessor class, which is called by the HttpProcessor class’s run method after a socket is assigned to it. The process method does the following:

first:  parse the connection
second: parse the request
third:  parse the headers

Each operation is discussed in the following after the process method is explained.

The process method uses the boolean ok to indicate that there is no error during the process and boolean finishResponse to indicate that the finishResponse method of Response interface should be called.

    boolean ok = true;
    boolean finishResponse = true;

In addition, the process method also uses the instance boolean variables keepAlive, stopped, and http11. keepAlive indicates that the connection is persistent, stopped indicates that the HttpProcessor instance has been stopped by the connector so that the process method should also stop, and http11 indicates that the HTTP request is coming from a web client that supports HTTP 1.1.

A SocketInputStream instance is used to wrap the socket’s input stream. Note that, the constructor of SocketInputStream is also passed the buffer size from the connector, not from a local variable in the HttpProcessor class. This is because HttpProcessor is not accessible by the user of the default connector. By putting the buffer size in the Connector interface, this allow anyone using the connector to set the buffer size.

    SocketInputStream input = null;
    OutputStream output = null;
    //construct and initialize the objects we will need
    try{
        input = new SocketInputStream(socket.getInputStream(), connector.getBufferSize());
    }catch(Exception e){
        ok = false;
    }

Then, there is a while loop which keeps reading the input stream until
the HttpProcessor is stopped, an exception is thrown, or the connection
is closed.

    keepAlive = true;
    while(!stoped &&  keepAlive){
        ...
    }

Inside the while loop, the process method starts by setting finishResponse
to true and obtaining the output stream and performing some initialization
to the request and response objects.

    finishResponse = true;
    try{
        request.setStream(input);
        request.setResponse(response);
        output = socket.getOutputStream();
        response.setStream(output);
        response.setRequest(request);
        ((HttpServletResponse)reponse.getResponse()).setHeader("Server",SERVER_INFO);   
    }catch(Exception e){
        log("process.create",e);
        ok = false;
    }

Afterwards, the process method start parsing the incoming HTTP requeat by calling the parseConnection, parseRequest,
and parseHeaders methods, all of which are discussed in the sub_section in this section.

    try{
        if(ok){
            parseConnection(socket);
            parseRequest(input,output);
            if(!request.getRequest().getProtocol().startsWith("HTTP/0")){
                parseHeaders(input);
            }
        }
    }

The parseConnection method obtains the value of the protocol, which can be HTTP 0.9 ,HTTP 1.0 or HTTTP 1.1. If the protoctol is HTTP 1.0, the keepAlive
boolean is set to false because HTTP 1.0 does not support persistent connections. The parseHeaders method will set the sendAck boolean to true if an Expect: 100-continue header is found in the HTTP request.

//HTTP1.1 协议包含100-continue header时,回应ackRequest
If the protocol is HTTP 1.1, it will response to the Expect: 100-continue header, if the web client sent this header, by calling the ackRequest method. It will also check if chunking is allowed.

    if(http11){
        //sending a request acknowledge back to the client if requested.
        ackRequest(output);
        //if the protocol is HTTP/1.1, chunking is allowed.
        if(connector.isChunkingAllowed()){
            response.setAllowChunking(true);
        }
    }

The ackRequest method checks the value of sentAck and sends the following
string if sendAck is true:

    HTTP/1.1 100 Continue \r\n\r\n

During the parsing of the HTTP request, one of the many exceptions might be thrown. Any exception will set ok or finishRequest to false. After the parsing, the process method passes the request and response objects to the container’s invoke method.

    try{
        ((HttpServletResponse)reponse).setHeader("Date",FastHttpDateFormat.getCurrentDate());
        if(ok){
            connector.getContainer().invoke(request,response);
        }
    }

Afterwards,if finishResponse is still true, the response object’s finishResponse method and the request’s object finishRequest methods are called, and the ouput is flushed.

            if(finishResponse){
                ...
            response.finishReponse();
                ...
            request.finishRequest();
            ...
            output.flush();
            }

The last part of the while loop checks if the response’s Connection header has been set to close from inside the servlet or if the protocol is HTTP 1.0 . If this is the case, keepAlive is set to false. Also, the request and response objects are then recycled.

if("close".equals(response.getHeader("Connection"))){
        keepAlive = false;
}
//End of request processing
status = Constants.PROCESSOR_IDLE;
//Recycling the request and response objects
request.recycle();
response.recycle();

At this stage, the while loop will start from the begining if keepAlive is true, there is no error during the previous parsing and from the container’s
invoke method, or the HttpProcessor instance has not been stopped. Otherwise, the shutdownInput method is called and the socket is closed.

    try{
        shutdownInput(input);
        socket.close();
    }
    ...

The shutdownInput method checks if there are any unread bytes. If there are, it skips those bytes.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值