{"id":20271894,"url":"https://github.com/point-c/caddy","last_synced_at":"2025-04-11T04:32:44.337Z","repository":{"id":216229985,"uuid":"740773480","full_name":"point-c/caddy","owner":"point-c","description":"Caddy modules for WireGuard integration and network routing.","archived":false,"fork":false,"pushed_at":"2024-08-09T01:11:13.000Z","size":533,"stargazers_count":39,"open_issues_count":2,"forks_count":1,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-03-25T02:39:51.962Z","etag":null,"topics":["caddy","caddy-plugin","generics","golang","golang-library","networking","vpn","wireguard","wireguard-go"],"latest_commit_sha":null,"homepage":"https://godocs.io/github.com/point-c/caddy@v0.1.0","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/point-c.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-01-09T03:12:15.000Z","updated_at":"2025-02-11T05:41:36.000Z","dependencies_parsed_at":"2024-01-28T23:24:02.622Z","dependency_job_id":"74aa1836-be3a-4c99-96bf-4b0a6bf1cddf","html_url":"https://github.com/point-c/caddy","commit_stats":null,"previous_names":["point-c/caddy"],"tags_count":22,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/point-c%2Fcaddy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/point-c%2Fcaddy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/point-c%2Fcaddy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/point-c%2Fcaddy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/point-c","download_url":"https://codeload.github.com/point-c/caddy/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248345202,"owners_count":21088231,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["caddy","caddy-plugin","generics","golang","golang-library","networking","vpn","wireguard","wireguard-go"],"created_at":"2024-11-14T12:39:53.249Z","updated_at":"2025-04-11T04:32:44.274Z","avatar_url":"https://github.com/point-c.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# point-c\n\n[![Go Reference](https://img.shields.io/badge/godoc-reference-%23007d9c.svg)](https://godocs.io/github.com/point-c/caddy@v0.1.0)\n[![Go Coverage](https://github.com/point-c/caddy/wiki/coverage.svg)](https://raw.githack.com/wiki/point-c/caddy/coverage.html)\n\n`point-c` is a collection of Caddy modules designed to handle network traffic between host systems and WireGuard tunnels. This library is for users looking to integrate network handling into their Caddy server configurations, particularly in VPN scenarios.\n\n- [point-c](#point-c)\n  - [Features](#features)\n  - [Installation](#installation)\n  - [Quickstart](#quickstart)\n    - [Caddy as Server Configuration](#caddy-as-server-configuration)\n    - [Remote Listen Configuration](#remote-listen-configuration)\n      - [Server](#server)\n      - [Client](#client)\n    - [Forward Non-HTTPS Traffic](#forward-non-https-traffic)\n      - [Caddy As Server](#caddy-as-server)\n      - [Server/Client Pair - Server](#serverclient-pair---server)\n      - [Server/Client Pair - Client](#serverclient-pair---client)\n  - [Modules](#modules)\n    - [`merge-listener-wrapper`](#merge-listener-wrapper)\n      - [Caddyfile](#caddyfile)\n      - [JSON](#json)\n    - [`point-c`](#point-c-1)\n      - [Caddyfile](#caddyfile-1)\n      - [JSON](#json-1)\n    - [`sysnet`](#sysnet)\n      - [Caddyfile](#caddyfile-2)\n      - [JSON](#json-2)\n    - [`wg`](#wg)\n      - [Caddyfile](#caddyfile-3)\n      - [JSON](#json-3)\n    - [`listener`](#listener)\n      - [Caddyfile](#caddyfile-4)\n      - [JSON](#json-4)\n    - [`forward`](#forward)\n      - [Caddyfile](#caddyfile-5)\n      - [JSON](#json-5)\n    - [`forward-tcp`](#forward-tcp)\n      - [Caddyfile](#caddyfile-6)\n      - [JSON](#json-6)\n    - [`stub-listener`](#stub-listener)\n      - [Caddyfile](#caddyfile-7)\n      - [JSON](#json-7)\n    - [`rand`](#rand)\n      - [Caddyfile](#caddyfile-8)\n      - [JSON Configuration](#json-configuration)\n  - [Full Configuration](#full-configuration)\n    - [Caddyfile](#caddyfile-9)\n    - [JSON Configuration](#json-configuration-1)\n  - [Testing](#testing)\n\n## Features\n\n- Easy integration with Caddy and WireGuard.\n- Customizable modules for different network operations.\n- Streamlined handling of TCP traffic and listener wrapping.\n- [Full test of these modules using Docker.](https://github.com/point-c/integration)\n\n## Installation\n\nTo install the modules from `point-c`, you will need to build a custom Caddy binary that includes that module. This can be achieved using the `xcaddy` utility:\n\n1. **Install xcaddy**:\n\n   ```sh\n   go install github.com/caddyserver/xcaddy/cmd/xcaddy@latest\n   ```\n\n2. **Build Caddy with all modules**:\n\n   ```sh\n   xcaddy build --with github.com/point-c/caddy/module@latest\n   ```\n\n3. **Run Your Custom Caddy Build**:\n\n   ```sh\n   ./caddy run\n   ```\n\n## Quickstart\n\n### Caddy as Server Configuration\n\n```Caddyfile\n{\n    # (Optional) Don't bind to the host system\n    default_bind stub://0.0.0.0\n    point-c {\n        # WireGuard server config\n        wgserver \u003cserver hostname\u003e {\n            ip \u003cserver address in private network\u003e\n            port \u003cserver listening port\u003e\n            private \u003cserver private key\u003e\n            # Add peer blocks for each client\n            peer \u003cclient hostname\u003e {\n                ip \u003cclient address in private network\u003e\n                public \u003cclient public key\u003e\n                shared \u003cshared key\u003e\n            }\n        }\n    }\n    servers :443 {\n        listener_wrappers {\n            merge {\n                point-c \u003cclient hostname\u003e 443\n                # Add `point-c` for each client\n            }\n        }\n    }\n}\n\n# Rest of Caddy config\n```\n\n### Remote Listen Configuration\n\n#### Server\n\n```Caddyfile\n{\n    # Don't bind to the host system\n    default_bind stub://0.0.0.0\n    point-c {\n        # Default network\n        system sys 0.0.0.0 0.0.0.0\n        # WireGuard server config\n        wgserver \u003cserver hostname\u003e {\n            ip \u003cserver address in private network\u003e\n            port \u003cserver listening port\u003e\n            private \u003cserver private key\u003e\n            peer \u003cclient hostname\u003e {\n                ip \u003cclient address in private network\u003e\n                public \u003cclient public key\u003e\n                shared \u003cshared key\u003e\n            }\n        }\n    }\n    # Forward traffic\n    point-c netops {\n        forward sys:\u003cclient hostname\u003e {\n            tcp 443:443\n        }\n    }\n}\n\n:80 {\n   # Run HTTP server to prevent HTTPS from being used\n}\n```\n\n#### Client\n\n```Caddyfile\n{\n    # (Optional) Don't bind to the host system\n    default_bind stub://0.0.0.0\n    point-c {\n        wgclient \u003cclient hostname\u003e {\n            ip \u003cclient address in private network\u003e\n            endpoint \u003cserver ip/hostname\u003e:\u003cserver port\u003e\n            private \u003cclient private key\u003e\n            public \u003cserver public key\u003e\n            shared \u003cshared key\u003e\n        }\n    }\n    servers :443 {\n        listener_wrappers {\n            merge {\n                point-c \u003cclient hostname\u003e 443\n            }\n        }\n    }\n}\n\n# Rest of Caddy config\n```\n\n### Forward Non-HTTPS Traffic\n\n#### Caddy As Server\n\n```Caddyfile\n{\n    point-c {\n        system ssh 0.0.0.0 ssh-host\n        system sys 0.0.0.0 localhost\n        wgserver server {\n            # config...\n        }\n    }\n    point-c netops {\n        forward server:sys {\n            tcp 80:80\n        }\n        forward server:ssh {\n            tcp 22:22\n        }\n    }\n}\n```\n\n#### Server/Client Pair - Server\n\n```Caddyfile\n{\n    default_bind stub://0.0.0.0\n    point-c {\n        system sys 0.0.0.0 0.0.0.0\n        wgserver server {\n            # config...\n        }\n    }\n    point-c netops {\n        forward sys:server {\n            tcp 443:443\n            tcp 80:80\n            tcp 22:22\n        }\n    }\n}\n\n:80 {\n}\n```\n\n#### Server/Client Pair - Client\n\n```Caddyfile\n{\n   point-c {\n      system ssh 0.0.0.0 ssh-host\n      system sys 0.0.0.0 localhost\n      wgclient client {\n         # config...\n      }\n   }\n   point-c netops {\n      forward client:sys {\n         tcp 80:80\n      }\n      forward client:ssh {\n         tcp 22:22\n      }\n   }\n   servers :443 {\n      listener_wrappers {\n         merge {\n            point-c client 443\n         }\n         tls\n      }\n   }\n}\n```\n\n## Modules\n\n### `merge-listener-wrapper`\n\nThe merge-listener-wrapper module acts as a wrapper for TCP listeners within the Caddy server. This module enables the bundling of multiple listeners into a single `net.Listener`. It's useful for allowing different networks to combine traffic.\n\n#### Caddyfile\n\n```Caddyfile\n{\n    servers \u003clisten address\u003e {\n        listener_wrappers {\n            merge {\n               # Listener definitions go here \n            }\n        }\n    }\n}\n```\n\n#### JSON\n\n```json\n{\n  \"apps\": {\n    \"http\": {\n      \"servers\": {\n        \"srv0\": {\n          \"listen\": [\n            \"\u003clisten address\u003e\"\n          ],\n          \"listener_wrappers\": [\n            {\n              \"listeners\": [],\n              \"wrapper\": \"merge\"\n            },\n            {\n              \"wrapper\": \"tls\"\n            }\n          ]\n        }\n      }\n    }\n  }\n}\n```\n\n### `point-c`\n\nThe centerpiece of this library, `point-c`, is designed to handle and manage registered networks and their associated operations within Caddy. This module serves as the backbone for integrating Caddy with various network setups, including both system networks and WireGuard configurations. It's essential for users looking to leverage Caddy in network-intensive applications or in scenarios requiring network control.\n\n#### Caddyfile\n\n```Caddyfile\n{\n   point-c {\n   }\n   point-c netops {\n   }\n}\n```\n\n#### JSON\n\n```json\n{\n   \"apps\": {\n      \"point-c\": {\n         \"networks\": [],\n         \"net-ops\": []\n      }\n   }\n}\n```\n\n### `sysnet`\n\n`sysnet` is a dedicated point-c network module for the host system. It provides a streamlined way to integrate the host's network settings into the point-c ecosystem. This module is for scenarios where the host system's network needs to be used in a `point-c` network operation.\n\nThe dial address is the address used as the local IP when dialing. The local address is returned by the `LocalAddr` method.\nThe hostname is resolved against the system to get an IP address, it is not a `point-c` network.\n\n#### Caddyfile\n\n```Caddyfile\n{\n   point-c {\n      system \u003cnetwork name\u003e \u003cdial ip address or hostname\u003e \u003clocal ip address or hostname\u003e\n   }\n}\n```\n\n#### JSON\n\n```json\n{\n   \"apps\": {\n      \"point-c\": {\n         \"networks\": [\n            {\n               \"dial-addr\": \"\u003cip address or hostname\u003e\",\n               \"local\": \"\u003cip address or hostname\u003e\",\n               \"hostname\": \"\u003cnetwork name\u003e\",\n               \"type\": \"system\"\n            }\n         ]\n      }\n   }\n}\n```\n\n### `wg`\n\nThe `wg` module enables registration of WireGuard tunnels, allowing integration of WireGuard-based VPN configurations with Caddy. The module is for users looking to combine WireGuard Caddy's web-serving functionality.\n\n#### Caddyfile\n\n```Caddyfile\n{\n   point-c {\n      wgclient \u003chostname\u003e {\n         ip \u003caddress on the virtual network\u003e\n         endpoint \u003cserver address\u003e\n         private \u003cclient private key\u003e\n         public \u003cserver public key\u003e\n         shared \u003cshared key\u003e\n      }\n      wgserver \u003chostname\u003e {\n         ip \u003caddress on the virtual network\u003e\n         port \u003cserver listen port\u003e\n         private \u003cserver private key\u003e\n         peer \u003chostname\u003e {\n            ip \u003caddress on the virtual network\u003e\n            public \u003cclient public key\u003e\n            shared \u003cshared key\u003e\n         }\n      }\n   }\n}\n```\n\n#### JSON\n\n```json\n{\n   \"apps\": {\n      \"point-c\": {\n         \"networks\": [\n            {\n               \"endpoint\": \"\u003cserver address\u003e\",\n               \"ip\": \"\u003caddress on the virtual network\u003e\",\n               \"name\": \"\u003chostname\u003e\",\n               \"preshared\": \"\u003cshared key\u003e\",\n               \"private\": \"\u003cclient private key\u003e\",\n               \"public\": \"\u003cserver public key\u003e\",\n               \"type\": \"wgclient\"\n            },\n            {\n               \"hostname\": \"\u003chostname\u003e\",\n               \"ip\": \"\u003caddress on the virtual network\u003e\",\n               \"listen-port\": \u003cserver listen port\u003e,\n               \"peers\": [\n                  {\n                     \"hostname\": \"\u003chostname\u003e\",\n                     \"ip\": \"\u003caddress on the virtual network\u003e\",\n                     \"preshared\": \"\u003cshared key\u003e\",\n                     \"public\": \"\u003cclient public key\u003e\"\n                  }\n               ],\n               \"private\": \"\u003cserver private key\u003e\",\n               \"type\": \"wgserver\"\n            }\n         ]\n      }\n   }\n}\n```\n\n### `listener`\n\nThe `listener` module for `point-c` allows for the use of registered networks with the `merge-listener-wrapper`. This module allows using networks as Caddy listeners.\n\n#### Caddyfile\n\n```Caddyfile\n{\n    servers \u003clisten address\u003e {\n        listener_wrappers {\n            merge {\n               point-c \u003chostname\u003e \u003clisten port\u003e\n            }\n            tls # should always be last\n        }\n    }\n}\n```\n\n#### JSON\n\n```json\n{\n  \"apps\": {\n    \"http\": {\n      \"servers\": {\n        \"srv0\": {\n          \"listen\": [\n            \"\u003clisten address\u003e\"\n          ],\n          \"listener_wrappers\": [\n            {\n              \"listeners\": [\n                {\n                  \"listener\": \"\u003chostname\u003e\",\n                  \"name\": \"server\",\n                  \"port\": \u003clisten port\u003e\n                }\n              ],\n              \"wrapper\": \"merge\"\n            },\n            {\n              \"wrapper\": \"tls\"\n            }\n          ]\n        }\n      }\n    }\n  }\n}\n```\n\n### `forward`\n\nThe `forward` module specializes in directing traffic from a source to a destination. It allows multiple port forwards to be made for a `src host:dst host` pair.\n\n#### Caddyfile\n\n```Caddyfile\n{\n   point-c netops {\n      forward \u003csrc host\u003e:\u003cdst host\u003e {\n      }\n   }\n}\n```\n\n#### JSON\n\n```json\n{\n   \"apps\": {\n      \"point-c\": {\n         \"net-ops\": [\n            {\n               \"forwards\": [],\n               \"hosts\": \"\u003csrc host\u003e:\u003cdst host\u003e\",\n               \"op\": \"forward\"\n            }\n         ]\n      }\n   }\n}\n```\n\n### `forward-tcp`\n\nAs a submodule of `forward`, `forward-tcp` focuses on forwarding TCP traffic. It allows specifying a specific buffer size in bytes. The default is `4096`.\n\n#### Caddyfile\n\n```Caddyfile\n{\n   point-c netops {\n      forward \u003csrc host\u003e:\u003cdst host\u003e {\n         tcp \u003csrc port\u003e:\u003cdst port\u003e [buffer size in bytes]\n      }\n   }\n}\n```\n\n#### JSON\n\n```json\n{\n   \"apps\": {\n      \"point-c\": {\n         \"net-ops\": [\n            {\n               \"forwards\": [\n                  {\n                     \"buf\": \u003cnull | buffer size in bytes\u003e,\n                     \"forward\": \"tcp\",\n                     \"ports\": \"\u003csrc port\u003e:\u003cdst port\u003e\"\n                  }\n               ],\n               \"hosts\": \"\u003csrc host\u003e:\u003cdst host\u003e\",\n               \"op\": \"forward\"\n            }\n         ]\n      }\n   }\n}\n```\n\n### `stub-listener`\n\n`stub-listener` allows binding to nothing, preventing Caddy from listening on the host system. This is useful for isolating Caddy from the host environment, such as when it is unable to open ports on the host system.\n\n#### Caddyfile\n\n```Caddyfile\n{\n\tdefault_bind stub://\u003cip address\u003e\n}\n```\n\n#### JSON\n\n```json\n\n{\n  \"apps\": {\n    \"http\": {\n      \"servers\": {\n        \"srv0\": {\n          \"listen\": [\n            \"stub://\u003cip address\u003e:\u003cport\u003e\"\n          ]\n        }\n      }\n    }\n  }\n}\n```\n\n### `rand`\n\n`rand` is a `caddyhttp.MiddlewareHandler` that returns random data, useful for testing.\n\nAccepts the following headers:\n\n- `Rand-Seed`: The seed for the random data generator. If not specified, the current Unix microsecond timestamp is used.\n- `Rand-Size`: The size of the random data in bytes. If not specified or set to a negative value, the module will stream random data indefinitely.\n\n#### Caddyfile\n\n```Caddyfile\n\u003csite block\u003e {\n    route {\n        rand\n    }\n}\n```\n\n#### JSON Configuration\n\n```json\n{\n   \"apps\": {\n      \"http\": {\n         \"servers\": {\n            \"srv0\": {\n               \"routes\": [\n                  {\n                     \"handle\": [\n                        {\n                           \"handler\": \"subroute\",\n                           \"routes\": [{\"handle\": [{\"handler\": \"rand\"}]}]\n                        }\n                     ]\n                  }\n               ]\n            }\n         }\n      }\n   }\n}\n```\n\n## Full Configuration\n\nFor advanced users, point-c offers extended configuration options to tailor the modules to specific needs.\n\n### Caddyfile\n\n```Caddyfile\n{\n   default_bind stub://0.0.0.0\n   point-c {\n      system sys 0.0.0.0 0.0.0.0\n      wgclient client {\n         ip 192.168.45.2\n         endpoint 127.0.0.1:51820\n         private UCoEdsc8Mw7ZY81jSAHOGIw23QxqxfN8SQ8YktOrw0I=\n         public 5GIGlLmvYnTyoQ59QIUYEo2FFUgubTibAO2qFI859hY=\n         shared Z9Ad3ZhTQbIUCLEKATYXS1m380vYrYFhGA75tspxsOU=\n      }\n      wgserver server {\n         ip 192.168.45.1\n         port 51820\n         private 2Jgm2q3tFu21cO1IMyhjENqp7t5qep0++novkdKHe0k=\n         peer client-1 {\n            ip 192.168.45.3\n            public Tdbxgh9AHWXodT60AiwCUPDTEITyVD+ecMhp2TDY1xw=\n            shared Z9Ad3ZhTQbIUCLEKATYXS1m380vYrYFhGA75tspxsOU=\n         }\n      }\n   }\n   point-c netops {\n      forward server:client-1 {\n         tcp 443:443\n      }\n      forward sys:server {\n         tcp 443:443 8192\n      }\n   }\n   servers :443 {\n      listener_wrappers {\n         merge {\n            point-c server 443\n            point-c client 443\n         }\n         tls\n      }\n   }\n}\n\n:443 {\n   route {\n      rand\n   }\n}\n```\n\n### JSON Configuration\n\n```json5\n{\n   \"apps\": {\n      \"http\": {\n         \"servers\": {\n            \"srv0\": {\n               \"listen\": [\n                  \"stub://0.0.0.0:443\"\n               ],\n               \"listener_wrappers\": [\n                  {\n                     \"listeners\": [\n                        {\n                           \"listener\": \"point-c\",\n                           \"name\": \"server\",\n                           \"port\": 443\n                        },\n                        {\n                           \"listener\": \"point-c\",\n                           \"name\": \"client\",\n                           \"port\": 443\n                        }\n                     ],\n                     \"wrapper\": \"merge\"\n                  },\n                  {\n                     \"wrapper\": \"tls\"\n                  }\n               ],\n               \"routes\": [\n                  {\n                     \"handle\": [\n                        {\n                           \"handler\": \"subroute\",\n                           \"routes\": [\n                              {\n                                 \"handle\": [\n                                    {\n                                       \"handler\": \"rand\"\n                                    }\n                                 ]\n                              }\n                           ]\n                        }\n                     ]\n                  }\n               ]\n            }\n         }\n      },\n      \"point-c\": {\n         \"networks\": [\n            {\n               \"dial-addr\": \"0.0.0.0\",\n               \"local\": \"0.0.0.0\",\n               \"hostname\": \"sys\",\n               \"type\": \"system\"\n            },\n            {\n               \"endpoint\": \"127.0.0.1:51820\",\n               \"ip\": \"192.168.45.2\",\n               \"name\": \"client\",\n               \"preshared\": \"Z9Ad3ZhTQbIUCLEKATYXS1m380vYrYFhGA75tspxsOU=\",\n               \"private\": \"UCoEdsc8Mw7ZY81jSAHOGIw23QxqxfN8SQ8YktOrw0I=\",\n               \"public\": \"5GIGlLmvYnTyoQ59QIUYEo2FFUgubTibAO2qFI859hY=\",\n               \"type\": \"wgclient\"\n            },\n            {\n               \"hostname\": \"server\",\n               \"ip\": \"192.168.45.1\",\n               \"listen-port\": 51820,\n               \"peers\": [\n                  {\n                     \"hostname\": \"client-1\",\n                     \"ip\": \"192.168.45.3\",\n                     \"preshared\": \"Z9Ad3ZhTQbIUCLEKATYXS1m380vYrYFhGA75tspxsOU=\",\n                     \"public\": \"Tdbxgh9AHWXodT60AiwCUPDTEITyVD+ecMhp2TDY1xw=\"\n                  }\n               ],\n               \"private\": \"2Jgm2q3tFu21cO1IMyhjENqp7t5qep0++novkdKHe0k=\",\n               \"type\": \"wgserver\"\n            }\n         ],\n         \"net-ops\": [\n            {\n               \"forwards\": [\n                  {\n                     \"buf\": null,\n                     \"forward\": \"tcp\",\n                     \"ports\": \"443:443\"\n                  }\n               ],\n               \"hosts\": \"server:client-1\",\n               \"op\": \"forward\"\n            },\n            {\n               \"forwards\": [\n                  {\n                     \"buf\": 8192,\n                     \"forward\": \"tcp\",\n                     \"ports\": \"443:443\"\n                  }\n               ],\n               \"hosts\": \"sys:server\",\n               \"op\": \"forward\"\n            }\n         ]\n      }\n   }\n}\n```\n\n## Testing\n\nThe package includes tests that demonstrate its functionality. Use Go's testing tools to run the tests:\n\n```bash\ngo test ./...\n```\n\nMore tests are also available [here](https://github.com/point-c/integration).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpoint-c%2Fcaddy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpoint-c%2Fcaddy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpoint-c%2Fcaddy/lists"}