好了,通过上篇文章文章 动手撸个Caddy(十二)| 插件开发之HelloWorld 你已经学会了开发Caddy插件,可以按自己的需求来定制Caddy了,Caddy没有的功能我们也可以自己做出来。

不过相信你也发现,上个例子中浏览网页只会显示 Hello 世界 ,我们能不能改变显示的内容呢?那么这篇文章呢,就带你实现一个可以通过Caddyfile配置显示内容的HelloWorld插件。

Unmarshaler接口

要想让你的插件支持Caddyfile,只需要实现 caddyfile.Unmarshaler 接口就可以了。现在让我们的 HelloWorld 结构体来实现该接口,从Caddyfile中读取要显示的内容。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
func (h *HelloWorld) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
   for d.Next() {
      if !d.Args(&h.Text) {
         // not enough args
         return d.ArgErr()
      }
      if d.NextArg() {
         // too many args
         return d.ArgErr()
      }
   }
   return nil
}

这里讲解下这段代码的逻辑。首先的 d.Next 是一个for循环,它是为了处理多个相同的指令的,比如Caddyfile中有多个 hello_world 指令,这种情况非常少。

然后紧跟着的 d.Args 是获取指令hello_world 后的参数,这里我们只获取第一个参数并且赋值给 h.Text 。如果d.Args 方法返回false,则意味着没有配置参数,就会返回 d.ArgErr 错误。

当然我们通过d.Args 方法获取参数后,如果还能通过 d.NextArg 方法获取参数,就说明我们给hello_world 设置了太多的参数,返回错误。

也就是说,以上的代码除了获取我们需要的参数外,还对参数的数量进行了校验,告诉使用者我们只需要一个参数,多了不行,少了也不行。

解析Caddyfile

我们已经实现好了caddyfile.Unmarshaler ,就可以在解析Caddyfile的时候使用它了。还记得我们在注册 hello_world 指令的时候,使用的 parseCaddyfile 函数吗?

1
2
3
4
func parseCaddyfile(h httpcaddyfile.Helper) (caddyhttp.MiddlewareHandler, error) {
   hw := new(HelloWorld)
   return hw, nil
}

除了返回一个 *HelloWorld 啥也没做,现在呢?我们就在这个函数中对Caddyfile中的 hello_world 指令进行解析, 解析出我们需要的文本。改造后的parseCaddyfile 函数如下所示:

1
2
3
4
5
func parseCaddyfile(h httpcaddyfile.Helper) (caddyhttp.MiddlewareHandler, error) {
   hw := new(HelloWorld)
   err := hw.UnmarshalCaddyfile(h.Dispenser)
   return hw, err
}

非常简单,只需要调用我们刚刚写好的 UnmarshalCaddyfile 方法即可。

收尾

好了,现在解析也写好了,就剩下最后的收尾工作了。首先呢,我们既然从Caddyfile中获取要显示的文本,那么在 Provision 方法中初始化的 Hello 世界 就不需要了,修改代码如下所示:

1
2
3
4
5
// Provision sets up the module.
func (h *HelloWorld) Provision(ctx caddy.Context) error {
   //h.Text = "Hello 世界"
   return nil
}

这里我为了便于大家理解,采用了注释的方式,其实你完全可以把它删除。 然后呢,就是我们永远不能忘记的「接口守卫」,也就是我们要对实现的接口进行编译期校验。

1
2
3
4
5
// Interface guards
var (

   _ caddyfile.Unmarshaler       = (*HelloWorld)(nil)
)

配置Caddyfile

好了,万事俱备了,只需要配置下Caddyfile就可以看看我们插件的效果了。

1
2
3
4
5
6
{
  order hello_world last
}
localhost {
  hello_world 飞雪无情
}

现在通过如下命令运行caddy,然后在浏览器中打开 https://localhost 就可以看到 飞雪无情 了。

1
➜ xcaddy run -config ~/Desktop/Caddyfile

你也可以把我上面Caddyfile中的 飞雪无情 改成其他文字,都是可以显示的,灵活性大大增强。

小结

这篇文章主要为你介绍了Caddyfile的参数化配置,让你的插件具备定制化的能力。我这里演示的是自定义一个文本,但是Caddy的自定义功能非常强大,你可以结合Caddyfile来自定义你的插件能力。

本文为原创文章,转载注明出处,欢迎扫码关注公众号flysnow_org或者网站 https://www.flysnow.org/ ,第一时间看后续精彩文章。觉得好的话,请猛击文章右下角「在看」,感谢支持。

扫码关注