任务
找到如何截获http的socket请求,然后才能干预tomcat处理http请求。
编译jsp文件的跟踪:
网站访问日志阀AccessLogValve
可以看到两个过程的公共之处。那就是前四个
是跟Socket有关的,属于底层协议处理。在第4个调用再往后就是跟request和response打交道了。
因此,我需要研究前4个函数的作用。下面就逐一进行。
(一) 首先是thread.run肯定就是我们的jre运行java程序的共用部分,所以无需细致研究。
(二) 然后就是JIoEndpoint的Worker的run方法.
让我们耐心一点,看一看JIoEndpoint的结构吧。
首先这个jioEndpoint文件其中包含:1个内部接口和3个内部类,剩下的就是本身的属性和方法。其中的serverSocket成员让我们想到了《网络编程详解》中的讲解。
可以看出1个内部接口和3个内部类都是为了声明内部成员变量的类型而进行定义的。
接着切入正题吧,看来是Thread中的
public void run() {
if (target != null) {
target.run();
}
}
调用了jioEndpoint.java中的worker类型对象的run()方法。
public void run() {
//直到收到关闭信号,否则一直处理请求
while (running) {
// 等到指派来的下一个socket对象
Socket socket = await();
//await函数是worker的内部方法,作用是Await a newly assigned Socket from our Connector
if (socket == null)
continue;
// 处理这个socket发出的请求,
//setSocketOption是JIoEndpoint的方法,作用是为这个socket设置一些timeout, linger。
//handler.process其中handler是JIoEndpoint的一个成员变量,实际上就是结果socket处理的接力棒,通过它来处理这个socket对象
if (!setSocketOptions(socket) || !handler.process(socket)) {红色部分就是下一部分要讨论的内容
// Close socket
try {
socket.close();
} catch (IOException e) {
}
}
// Finish up this request
socket = null;
recycleWorkerThread(this);
}
}
(三) 这个handler好像在初始化的时候被设置成了Http11ConnectionHandler,这样我们就到达了Http11Protocol文件的Http11ConnectionHandler内部类的public boolean process(Socket socket)方法,这个方法实现是这样的:
public boolean process(Socket socket) {
Http11Processor processor = null;
try {
processor = localProcessor.get();
if (processor == null) {
processor =
new Http11Processor(protocol.maxHttpHeaderSize, protocol.endpoint);
processor.setAdapter(protocol.adapter);
…
processor.setServer(protocol.server);
localProcessor.set(processor);
if (protocol.getDomain() != null) {
synchronized (this) {
try {
RequestInfo rp = processor.getRequest().getRequestProcessor();
rp.setGlobalProcessor(global);
ObjectName rpName = new ObjectName
(protocol.getDomain() + ":type=RequestProcessor,worker="
+ protocol.getName() + ",name=HttpRequest" + count++);
Registry.getRegistry(null, null).registerComponent(rp, rpName, null);
} catch (Exception e) {
log.warn("Error registering request");
}
}
}
}
if (processor instanceof ActionHook) {
((ActionHook) processor).action(ActionCode.ACTION_START, null);
}
if (protocol.secure && (protocol.sslImplementation != null)) {
processor.setSSLSupport
(protocol.sslImplementation.getSSLSupport(socket));
} else {
processor.setSSLSupport(null);
}
processor.process(socket);
return false;
} catch(java.net.SocketException e) {
// SocketExceptions are normal
Http11Protocol.log.debug