|
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;
-
- }
|
|