3

jenkins源码阅读:渲染主页

 2 years ago
source link: https://myzhan.github.io/posts/jenkins-src-render-index/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

jenkins源码阅读:渲染主页

calendar Jul 18, 2016
clock 1 min read

jenkins 的一切 URL 请求,都托管给了 Stapler,要了解主页是如何渲染的,依然要从 Stapler 开始。用现在 Web 开发的目光来看 Stapler,它是一个纯粹的路由组件,即根据用户访问的 URL ,找到对应的处理代码。不过对于 Stapler 来说,“约定”优于“配置”,除了在 web.xml 中将 /* 交给 Stapler 处理,再也没有任何配置。免“配置”,对于开发来说,省了很多麻烦,只要在文档中详细说明“约定”,大家通读一遍文档,也就知道了。

Stapler 的文档里面记录了很多细节,与主页(Index)有关的,有“Index View”和“Index Action Method”这两个。不过 $JENKINS_SRC/core/src/main/resources/jenkins/model/Jenkins 目录下面,并没有 index.jelly 文件,jenkins.model.Jenkins 类里面,也没有 doIndex 方法。

Google 了一下,找到了一份PPT一篇文章,原来 jenkins.model.Jenkins 实现了 StaplerFallback 接口。Stapler 实在找不到处理方法的时候,会调用 getStaplerFallback 方法,jenkins.model.Jenkins 就是靠这个方法,实现了主页的渲染。

getStaplerFallback 方法返回了一个 hudson.model.View 对象,Stapler 会根据这个对象,再去找对应的模板,这是最后的方法了,如果还是找不到,就会返回 404。终于,在 $JENKINS_SRC/core/src/main/resources/hudson/model/View 目录下,找到了 index.jelly 文件,主页的模板!

来试着“劫持”一下 jenkins 的主页。修改 Jenkins.java 文件,加上下面的方法。

$JENKINS_SRC/core/src/main/java/jenkins/model/Jenkins.java

public void doIndex( StaplerRequest req, StaplerResponse rsp ) throws IOException, ServletException {
    rsp.getWriter().println("Index hijack");
}

用浏览器访问 http://localhost:8080/ ,成功看到了“Index hijack”!

继续翻看 Stapler 的源码,找到了比文档更清楚的答案。

/org/kohsuke/stapler/Stapler.java

boolean tryInvoke(RequestImpl req, ResponseImpl rsp, Object node ) throws IOException, ServletException {
    //省略很多代码
    if(node instanceof StaplerFallback) {
        if(traceable())
            traceEval(req,rsp,node,"((StaplerFallback)",").getStaplerFallback()");
        Object n;
        try {
            n = ((StaplerFallback)node).getStaplerFallback();
        } catch (RuntimeException e) {
            if (Function.renderResponse(req,rsp,node,e))
                return true; // let the exception serve the request and we are done
            else
                throw e;     // unprocessed exception
        }
        if(n!=node && n!=null) {
            // delegate to the fallback object
            invoke(req,rsp,n);
            return true;
        }
   }
}

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK