Caddyfile Support

    To add Caddyfile support for your module, simply implement the interface. You get to choose the Caddyfile syntax your module has by how you parse the tokens.

    An unmarshaler’s job is simply to set up your module’s type, e.g. by populating its fields, using the passed to it. For example, a module type named Gizmo might have this method:

    It is a good idea to document the syntax in the godoc comment for the method. See the godoc for the caddyfile package for more information about parsing the Caddyfile.

    It is also important for an unmarshaler to accept multiple occurrences of its directive (rare, but can happen in some cases). Since the first token will typically be the module’s name or directive (and can often be skipped by the unmarshaler), this usually means wrapping your parsing logic in a for d.Next() { ... } loop.

    Make sure to check for missing or excess arguments.

    You should also add an to ensure the interface is satisfied properly:

    1. var _ caddyfile.Unmarshaler = (*Gizmo)(nil)

    As long as each iteration of the loop consumes the entire segment (line or block), then this is an elegant way to handle blocks.

    The HTTP Caddyfile is Caddy’s default Caddyfile adapter syntax (or “server type”). It is extensible, meaning you can register your own “top-level” directives for your module:

    1. func init() {
    2. httpcaddyfile.RegisterDirective("gizmo", parseCaddyfile)
    3. }

    If your directive only returns a single HTTP handler (as is common), you may find easier:

    The basic idea is that the parsing function you associate with your directive returns one or more values. (Or, if using , it simply returns the populated caddyhttp.MiddlewareHandler value directly.) Each config value is associated with a “class” which helps the HTTP Caddyfile adapter to know which part(s) of the final JSON config it can be used in. All the config values get dumped into a pile from which the adapter draws when constructing the final JSON config.

    This design allows your directive to return any config values for any recognized classes, which means it can influence any parts of the config that the HTTP Caddyfile adapter has a designated class for.

    If you’ve already implemented the UnmarshalCaddyfile() method, then your parse function could be as simple as:

    1. // parseCaddyfileHandler unmarshals tokens from h into a new middleware handler value.
    2. var g Gizmo
    3. err := g.UnmarshalCaddyfile(h.Dispenser)
    4. return g, err
    5. }

    All directives which return HTTP middleware/handler values need to be evaluated in the correct order. For example, a handler that sets the root directory of the site has to come before a handler that accesses the root directory, so that it will know what the directory path is.

    The HTTP Caddyfile . This ensures that users do not need to know the implementation details of the most common functions of their web server, and makes it easier for them to write correct configurations. A single, hard-coded list also prevents nondeterminism given the extensible nature of the Caddyfile.

    When you register a new handler directive, it must be added to that list before it can be used (outside of a route block). This is done in configuration using one of two methods:

    • The global option modifies the standard order for that configuration only. For example: order mydir before respond will insert a new directive mydir to be evaluated before the respond handler. Then the directive can be used normally.

    Please document for your users where in the list is the right place for your directive to be ordered so that they can use it properly.

    This table describes each class with exported types that is recognized by the HTTP Caddyfile adapter:

    Structurally, the Caddyfile is a simple format, so there can be different types of Caddyfile formats (sometimes called “server types”) to suit different needs.

    To configure apps other than HTTP, you may want to implement your own config adapter that uses . The Caddyfile adapter will actually parse the input for you and give you the list of server blocks, and options, and it’s up to your adapter to make sense of that structure and turn it into a JSON config.