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]