Skip to content

Converting Add ons to Plugins

Matt Holt edited this page Jun 20, 2016 · 6 revisions

Caddy prior to version 0.9 had "add-ons" but Caddy 0.9+ has "plugins" which give more flexibility. Add-ons need to be converted to plugins if they are to be used in newer version of Caddy or made available on the Caddy website.

(Remember, this guide is for existing add-ons that are already recognized by Caddy. To create a new plugin from scratch, start with Extending Caddy.)

The switch from add-on to plugin can usually be done in a few minutes, or almost always less than an hour. Your actual handler will not need to change much; most of the changes are with the setup function and its tests.

The basic steps are:

  1. Search and replace
  2. Change setup function
  3. Update setup tests
  4. Register plugin

1. Search and replace

Search for the text on the left and replace with the text on the right (exact values, case-sensitive):

  • middleware. --> httpserver.
  • /caddy/middleware" --> /caddy/caddyhttp/httpserver"
  • setup. --> caddy.

Delete:

  • Any imports to github.com/mholt/caddy/caddy/setup that may remain
  • Any imports to github.com/mholt/caddy/middleware that may remain

Add:

  • Import github.com/mholt/caddy where needed
  • Import github.com/mholt/caddy/caddyhttp/httpserver where needed

2. Change setup function

If you had a setup function like this:

func Setup(c *setup.Controller) (middleware.Middleware, error) {
    ...
}

Change it to this:

func setup(c *caddy.Controller) error {
    ...
}

The setup function does not need to be exported, but you may capitalize it to export it if you wish.

Instead of accessing site config values directly like c.Root or c.Host, get the config from the HTTP server using the key from the controller:

siteConfig := httpserver.GetConfig(c)

Instead of adding startup callbacks by appending to c.Startup , call c.OnStartup() and pass in the function:

// or use OnRestart and OnShutdown
c.OnStartup(func() error {
    ...
})

Instead of returning a middleware, call siteConfig.AddMiddleware() and pass in your middleware instance:

siteConfig.AddMiddleware(func(next httpserver.Handler) httpserver.Handler {
	handler.Next = next
	return handler
})

3. Update setup tests

Instead of calling setup.NewTestController() like you did before, call caddy.NewTestController():

c := caddy.NewTestController("http", input)

To test that the middleware was set up properly, you'll need to get the config it was added to. The test controller uses an empty string key:

cfg := httpserver.GetConfig(c)
mids := cfg.Middleware() // []httpserver.Middleware

From there, you'll usually want the last middleware in the list, mids[len(mids)-1]. If you're not in a loop or you created a new controller each time, you can just assume mids[0]. Of course, if you didn't add any middleware, you can omit these checks.

4. Register plugin

In your plugin's package (usually by the setup function, if there's not already an init() function), create an init() function to register your plugin with Caddy:

func init() {
	caddy.RegisterPlugin("directive", caddy.Plugin{
		ServerType: "http",
		Action:     setup,
	})
}

Replace "directive" with the name of your plugin's directive and setup with the name of your setup function. The setup function does not need to be exported anymore if you choose.

Now give it a try to make sure everything works, and re-run your tests. Push your changes when everything looks good and we'll be updating the build server with the new 0.9 plugins soon.

Clone this wiki locally