您的位置:首页 > 运维架构 > Tomcat

[Tomcat6.0源码]请求的处理二Request

2012-09-25 16:21 363 查看
Worker.run()取到socke后,往下执行handler.process(socket)。handler来源于Http11Protocol.init():

public void init() throws Exception {
endpoint.setName(getName());
endpoint.setHandler(cHandler);

cHandler是在Http11Protocol的属性中直接new的:

protected Http11ConnectionHandler cHandler = new Http11ConnectionHandler(this);

Http11ConnectionHandler是Http11Protocol的内部类。handler.process(socket)即执行Http11ConnectionHandler.process(socket):

public boolean process(Socket socket) {
Http11Processor processor = recycledProcessors.poll();
try {

if (processor == null) {
processor = createProcessor();
}

if (processor instanceof ActionHook) {
((ActionHook) processor).action(ActionCode.ACTION_START, null);
}

if (proto.isSSLEnabled() && (proto.sslImplementation != null)) {
processor.setSSLSupport
(proto.sslImplementation.getSSLSupport(socket));
} else {
processor.setSSLSupport(null);
}

processor.process(socket);
return false;

} catch(java.net.SocketException e) {
// SocketExceptions are normal
Http11Protocol.log.debug
(sm.getString
("http11protocol.proto.socketexception.debug"), e);
} catch (java.io.IOException e) {
// IOExceptions are normal
Http11Protocol.log.debug
(sm.getString
("http11protocol.proto.ioexception.debug"), e);
}
// Future developers: if you discover any other
// rare-but-nonfatal exceptions, catch them here, and log as
// above.
catch (Throwable e) {
// any other exception or error is odd. Here we log it
// with "ERROR" level, so it will show up even on
// less-than-verbose logs.
Http11Protocol.log.error
(sm.getString("http11protocol.proto.error"), e);
} finally {
//       if(proto.adapter != null) proto.adapter.recycle();
//                processor.recycle();

if (processor instanceof ActionHook) {
((ActionHook) processor).action(ActionCode.ACTION_STOP, null);
}
recycledProcessors.offer(processor);
}
return false;
}

Http11ConnectionHandler.createProcessor():

protected Http11Processor createProcessor() {
Http11Processor processor =
new Http11Processor(proto.maxHttpHeaderSize, proto.endpoint);
processor.setAdapter(proto.adapter);
processor.setMaxKeepAliveRequests(proto.maxKeepAliveRequests);
processor.setKeepAliveTimeout(proto.keepAliveTimeout);
processor.setTimeout(proto.timeout);
processor.setDisableUploadTimeout(proto.disableUploadTimeout);
processor.setCompressionMinSize(proto.compressionMinSize);
processor.setCompression(proto.compression);
processor.setNoCompressionUserAgents(proto.noCompressionUserAgents);
processor.setCompressableMimeTypes(proto.compressableMimeTypes);
processor.setRestrictedUserAgents(proto.restrictedUserAgents);
processor.setSocketBuffer(proto.socketBuffer);
processor.setMaxSavePostSize(proto.maxSavePostSize);
processor.setServer(proto.server);
register(processor);
return processor;
}

processor.process(socket);即Http11Processor.process():

public void process(Socket theSocket)
throws IOException {
RequestInfo rp = request.getRequestProcessor();
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 I/O
this.socket = theSocket;
inputBuffer.setInputStream(socket.getInputStream());
outputBuffer.setOutputStream(socket.getOutputStream());

// Error flag
error = false;
keepAlive = true;

int keepAliveLeft = maxKeepAliveRequests;
int soTimeout = endpoint.getSoTimeout();

// When using an executor, these values may return non-positive values
int curThreads = endpoint.getCurrentThreadsBusy();
int maxThreads = endpoint.getMaxThreads();
if (curThreads > 0 && maxThreads > 0) {
// Only auto-disable keep-alive if the current thread usage % can be
// calculated correctly
if ((curThreads*100)/maxThreads > 75) {
keepAliveLeft = 1;
}
}

try {
socket.setSoTimeout(soTimeout);
} catch (Throwable t) {
log.debug(sm.getString("http11processor.socket.timeout"), t);
error = true;
}

boolean keptAlive = false;

while (started && !error && keepAlive && !endpoint.isPaused()) {

// Parsing the request header
try {
if (keptAlive) {
if (keepAliveTimeout > 0) {
socket.setSoTimeout(keepAliveTimeout);
}
else if (soTimeout > 0) {
socket.setSoTimeout(soTimeout);
}
}
inputBuffer.parseRequestLine();
request.setStartTime(System.currentTimeMillis());
keptAlive = true;
if (disableUploadTimeout) {
socket.setSoTimeout(soTimeout);
} else {
socket.setSoTimeout(timeout);
}
// Set this every time in case limit has been changed via JMX
request.getMimeHeaders().setLimit(endpoint.getMaxHeaderCount());
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);
adapter.log(request, response, 0);
error = true;
}

if (!error) {
// Setting up filters, and parse some request headers
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);
adapter.log(request, response, 0);
error = true;
}
}

if (maxKeepAliveRequests > 0 && --keepAliveLeft == 0)
keepAlive = false;

// Process the request in the adapter
if (!error) {
try {
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);
adapter.log(request, response, 0);
error = true;
}
}

// Finish the handling of the request
try {
rp.setStage(org.apache.coyote.Constants.STAGE_ENDINPUT);
// If we know we are closing the connection, don't drain input.
// This way uploading a 100GB file doesn't tie up the thread
// if the servlet has rejected it.
if(error)
inputBuffer.setSwallowInput(false);
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);
// No access logging since after service method
error = true;
}
try {
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();

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();

}

rp.setStage(org.apache.coyote.Constants.STAGE_ENDED);

// Recycle
inputBuffer.recycle();
outputBuffer.recycle();
this.socket = null;
// Recycle ssl info
sslSupport = null;
}

adapter.service(request, response);这个adapter是Http11Protocol.Http11ConnectionHandler.createProcessor()中创建Http11Processor对象时设置的:

protected Http11Processor createProcessor() {
Http11Processor processor =
new Http11Processor(proto.maxHttpHeaderSize, proto.endpoint);
processor.setAdapter(proto.adapter);

而这个Http11ConnectionHandler的proto是在其构造函数中赋值的:

Http11ConnectionHandler(Http11Protocol proto) {
this.proto = proto;
}

Http11ConnectionHandler对象是在Http11Protocol的属性中new出来的:

protected Http11ConnectionHandler cHandler = new Http11ConnectionHandler(this);

这个this就是Http11Protocol自身对象,那么proto.adapter既是Http11Protocol.adapter,是在Connector.initialize()中赋值的(Connector初始化的时候):

adapter = new CoyoteAdapter(this);
protocolHandler.setAdapter(adapter);

绕了一圈。也就是adapter.service(request, response);即CoyoteAdapter.service(request, response):

public void service(org.apache.coyote.Request req,
org.apache.coyote.Response res)
throws Exception {

Request request = (Request) req.getNote(ADAPTER_NOTES);
Response response = (Response) res.getNote(ADAPTER_NOTES);

if (request == null) {

// Create objects
request = (Request) connector.createRequest();
request.setCoyoteRequest(req);
response = (Response) connector.createResponse();
response.setCoyoteResponse(res);

// Link objects
request.setResponse(response);
response.setRequest(request);

// Set as notes
req.setNote(ADAPTER_NOTES, request);
res.setNote(ADAPTER_NOTES, response);

// Set query string encoding
req.getParameters().setQueryStringEncoding
(connector.getURIEncoding());

}

if (connector.getXpoweredBy()) {
response.addHeader("X-Powered-By", POWERED_BY);
}

boolean comet = false;

try {

// Parse and set Catalina and configuration specific
// request parameters
req.getRequestProcessor().setWorkerThreadName(Thread.currentThread().getName());
if (postParseRequest(req, request, res, response)) {
// Calling the container
connector.getContainer().getPipeline().getFirst().invoke(request, response);

if (request.isComet()) {
if (!response.isClosed() && !response.isError()) {
if (request.getAvailable() || (request.getContentLength() > 0 && (!request.isParametersParsed()))) {
// Invoke a read event right away if there are available bytes
if (event(req, res, SocketStatus.OPEN)) {
comet = true;
res.action(ActionCode.ACTION_COMET_BEGIN, null);
}
} else {
comet = true;
res.action(ActionCode.ACTION_COMET_BEGIN, null);
}
} else {
// Clear the filter chain, as otherwise it will not be reset elsewhere
// since this is a Comet request
request.setFilterChain(null);
}
}

}

if (!comet) {
response.finishResponse();
req.action(ActionCode.ACTION_POST_REQUEST , null);
}

} catch (IOException e) {
;
} finally {
req.getRequestProcessor().setWorkerThreadName(null);
// Recycle the wrapper request and response
if (!comet) {
request.recycle();
response.recycle();
} else {
// Clear converters so that the minimum amount of memory
// is used by this processor
request.clearEncoders();
response.clearEncoders();
}
}

}

将org.apache.coyote.Request包装成org.apache.catalina.connector.Request,实现HttpServletRequest接口

将org.apache.coyote.Response包装成org.apache.catalina.connector.Response,实现HttpServletResponse接口
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: