78144666 发表于 2017-2-7 06:30:44

tomcat 代码分析 为获取HTTP head body 解析

Http11Processor class是获得一个Http请求后就由这个class来进行处理,处理函数当然就是 process,然后将获得的inputstream 传递给 InternalInputBuffer class ,这个class 中存放了 所
信息等,InternalInputBuffer 将各个head信息分解后会 传递给 Request 对象,之后我们程序中的想要获得某个页面的信息就可以从 request对象中获得了。

J2ee 只是规定了 HttpServletRequest 所需要获得的一些配置参数,本来还想从j2ee5 sdk中获得 http head body的实现,搞了半天全是interface ,真正的实现是 放在 各个不同容器当中的,所以resin和tomcat或者其他web container 都可能不同。好了,
接下去把其中的宝藏挖出来把。

完成WVBAII项目的 server,汗就是为了不每次http请求都response,费那么经,要我写个 server。

有必要提一下实现InputBuffer 接口的class:
InternalAprInputBuffer 其方法
parseRequestLine()
parseHeader()
...
对HTTP Head 真正的进行了解析。


java 代码
 

[*]/** 
[*] * Process pipelined HTTP requests using the specified input and output 
[*] * streams. 
[*] * 
[*] * @throws IOException error during an I/O operation 
[*] */  
[*]public boolean process(long socket)  
[*]    throws IOException {  
[*]    ThreadWithAttributes thrA=  
[*]            (ThreadWithAttributes)Thread.currentThread();  
[*]    RequestInfo rp = request.getRequestProcessor();  
[*]    thrA.setCurrentStage(endpoint, "parsing http request");  
[*]    rp.setStage(org.apache.coyote.Constants.STAGE_PARSE);  
[*]  
[*]    // Set the remote address  
[*]    remoteAddr = null;  
[*]    remoteHost = null;  
[*]    localAddr = null;  
[*]    localName = null;  
[*]    remotePort = -1;  
[*]    localPort = -1;  
[*]  
[*]    // Setting up the socket  
[*]    this.socket = socket;  
[*]    inputBuffer.setSocket(socket);  
[*]    outputBuffer.setSocket(socket);  
[*]  
[*]    // Error flag  
[*]    error = false;  
[*]    keepAlive = true;  
[*]  
[*]    int keepAliveLeft = maxKeepAliveRequests;  
[*]    long soTimeout = endpoint.getSoTimeout();  
[*]      
[*]    int limit = 0;  
[*]    if (endpoint.getFirstReadTimeout() > 0 || endpoint.getFirstReadTimeout() < -1) {  
[*]        limit = endpoint.getMaxThreads() / 2;  
[*]    }  
[*]  
[*]    boolean keptAlive = false;  
[*]    boolean openSocket = false;  
[*]  
[*]    while (started && !error && keepAlive) {  
[*]  
[*]        // Parsing the request header  
[*]        try {  
[*]            if( !disableUploadTimeout && keptAlive && soTimeout > 0 ) {  
[*]                Socket.timeoutSet(socket, soTimeout * 1000);  
[*]            }  
[*]            if (!inputBuffer.parseRequestLine  
[*]                    (keptAlive && (endpoint.getCurrentThreadsBusy() > limit))) {  
[*]                // This means that no data is available right now  
[*]                // (long keepalive), so that the processor should be recycled  
[*]                // and the method should return true  
[*]                openSocket = true;  
[*]                // Add the socket to the poller  
[*]                endpoint.getPoller().add(socket);  
[*]                break;  
[*]            }  
[*]            request.setStartTime(System.currentTimeMillis());  
[*]            thrA.setParam(endpoint, request.requestURI());  
[*]            keptAlive = true;  
[*]            if (!disableUploadTimeout) {  
[*]                Socket.timeoutSet(socket, timeout * 1000);  
[*]            }  
[*]            inputBuffer.parseHeaders();  
[*]        } catch (IOException e) {  
[*]            error = true;  
[*]            break;  
[*]        } catch (Throwable t) {  
[*]            if (log.isDebugEnabled()) {  
[*]                log.debug(sm.getString("http11processor.header.parse"), t);  
[*]            }  
[*]            // 400 - Bad Request  
[*]            response.setStatus(400);  
[*]            error = true;  
[*]        }  
[*]  
[*]        // Setting up filters, and parse some request headers  
[*]        thrA.setCurrentStage(endpoint, "prepareRequest");  
[*]        rp.setStage(org.apache.coyote.Constants.STAGE_PREPARE);  
[*]        try {  
[*]            prepareRequest();  
[*]        } catch (Throwable t) {  
[*]            if (log.isDebugEnabled()) {  
[*]                log.debug(sm.getString("http11processor.request.prepare"), t);  
[*]            }  
[*]            // 400 - Internal Server Error  
[*]            response.setStatus(400);  
[*]            error = true;  
[*]        }  
[*]  
[*]        if (maxKeepAliveRequests > 0 && --keepAliveLeft == 0)  
[*]            keepAlive = false;  
[*]  
[*]        // Process the request in the adapter  
[*]        if (!error) {  
[*]            try {  
[*]                thrA.setCurrentStage(endpoint, "service");  
[*]                rp.setStage(org.apache.coyote.Constants.STAGE_SERVICE);  
[*]                adapter.service(request, response);  
[*]                // Handle when the response was committed before a serious  
[*]                // error occurred.  Throwing a ServletException should both  
[*]                // set the status to 500 and set the errorException.  
[*]                // If we fail here, then the response is likely already  
[*]                // committed, so we can't try and set headers.  
[*]                if(keepAlive && !error) { // Avoid checking twice.  
[*]                    error = response.getErrorException() != null ||  
[*]                            statusDropsConnection(response.getStatus());  
[*]                }  
[*]  
[*]            } catch (InterruptedIOException e) {  
[*]                error = true;  
[*]            } catch (Throwable t) {  
[*]                log.error(sm.getString("http11processor.request.process"), t);  
[*]                // 500 - Internal Server Error  
[*]                response.setStatus(500);  
[*]                error = true;  
[*]            }  
[*]        }  
[*]  
[*]        // Finish the handling of the request  
[*]        try {  
[*]            thrA.setCurrentStage(endpoint, "endRequestIB");  
[*]            rp.setStage(org.apache.coyote.Constants.STAGE_ENDINPUT);  
[*]            inputBuffer.endRequest();  
[*]        } catch (IOException e) {  
[*]            error = true;  
[*]        } catch (Throwable t) {  
[*]            log.error(sm.getString("http11processor.request.finish"), t);  
[*]            // 500 - Internal Server Error  
[*]            response.setStatus(500);  
[*]            error = true;  
[*]        }  
[*]        try {  
[*]            thrA.setCurrentStage(endpoint, "endRequestOB");  
[*]            rp.setStage(org.apache.coyote.Constants.STAGE_ENDOUTPUT);  
[*]            outputBuffer.endRequest();  
[*]        } catch (IOException e) {  
[*]            error = true;  
[*]        } catch (Throwable t) {  
[*]            log.error(sm.getString("http11processor.response.finish"), t);  
[*]            error = true;  
[*]        }  
[*]  
[*]        // If there was an error, make sure the request is counted as  
[*]        // and error, and update the statistics counter  
[*]        if (error) {  
[*]            response.setStatus(500);  
[*]        }  
[*]        request.updateCounters();  
[*]  
[*]        thrA.setCurrentStage(endpoint, "ended");  
[*]        rp.setStage(org.apache.coyote.Constants.STAGE_KEEPALIVE);  
[*]  
[*]        // Don't reset the param - we'll see it as ended. Next request  
[*]        // will reset it  
[*]        // thrA.setParam(null);  
[*]        // Next request  
[*]        inputBuffer.nextRequest();  
[*]        outputBuffer.nextRequest();  
[*]  
[*]        // Do sendfile as needed: add socket to sendfile and end  
[*]        if (sendfileData != null) {  
[*]            sendfileData.socket = socket;  
[*]            sendfileData.keepAlive = keepAlive;  
[*]            if (!endpoint.getSendfile().add(sendfileData)) {  
[*]                openSocket = true;  
[*]                break;  
[*]            }  
[*]        }  
[*]          
[*]    }  
[*]  
[*]    rp.setStage(org.apache.coyote.Constants.STAGE_ENDED);  
[*]  
[*]    // Recycle  
[*]    inputBuffer.recycle();  
[*]    outputBuffer.recycle();  
[*]    this.socket = 0;  
[*]  
[*]    return openSocket;  
[*]      
[*]}  
页: [1]
查看完整版本: tomcat 代码分析 为获取HTTP head body 解析