├── go.sum ├── .gitignore ├── go.mod ├── docs └── img │ └── logo.png ├── .traefik.yml ├── Makefile ├── .github ├── dependabot.yml └── workflows │ ├── go-cross.yml │ └── main.yml ├── waeb.go ├── docker-compose.yml ├── .golangci.yml ├── LICENSE ├── waeb_test.go └── README.md /go.sum: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | vendor 2 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/tomMoulard/traefik-plugin-waeb 2 | 3 | go 1.20 4 | -------------------------------------------------------------------------------- /docs/img/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomMoulard/traefik-plugin-waeb/HEAD/docs/img/logo.png -------------------------------------------------------------------------------- /.traefik.yml: -------------------------------------------------------------------------------- 1 | displayName: Waeb 2 | type: middleware 3 | 4 | import: github.com/tomMoulard/traefik-plugin-waeb 5 | 6 | summary: 'A web server inside Traefik' 7 | 8 | iconPath: ./docs/img/logo.png 9 | 10 | testData: 11 | root: /var/www/html/ 12 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: lint test vendor clean 2 | 3 | default: lint test 4 | 5 | lint: 6 | golangci-lint run 7 | 8 | test: 9 | go test -v -cover ./... 10 | 11 | yaegi_test: 12 | yaegi test -v . 13 | 14 | vendor: 15 | go mod vendor 16 | 17 | entr: 18 | # https://github.com/eradman/entr 19 | find | entr -r -s "docker compose up --remove-orphans" 20 | 21 | clean: 22 | rm -rf ./vendor -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # To get started with Dependabot version updates, you'll need to specify which 2 | # package ecosystems to update and where the package manifests are located. 3 | # Please see the documentation for all configuration options: 4 | # https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates 5 | 6 | version: 2 7 | updates: 8 | - package-ecosystem: "gomod" # See documentation for possible values 9 | directory: "/" # Location of package manifests 10 | schedule: 11 | interval: "weekly" 12 | -------------------------------------------------------------------------------- /waeb.go: -------------------------------------------------------------------------------- 1 | // Package waeb builds a middleware that works like a web server 2 | package traefik_plugin_waeb 3 | 4 | import ( 5 | "context" 6 | "net/http" 7 | ) 8 | 9 | // Config the plugin configuration. 10 | type Config struct { 11 | Root string `json:"root,omitempty"` 12 | } 13 | 14 | // CreateConfig creates the default plugin configuration. 15 | func CreateConfig() *Config { 16 | return &Config{ 17 | Root: ".", 18 | } 19 | } 20 | 21 | // New created a new Waeb plugin. 22 | func New(_ context.Context, _ http.Handler, config *Config, _ string) (http.Handler, error) { 23 | return http.FileServer(http.Dir(config.Root)), nil 24 | } 25 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3.9' 2 | 3 | services: 4 | traefik: 5 | image: traefik:v3.0 6 | command: 7 | - --api.insecure=true 8 | - --providers.docker 9 | - --log.level=ERROR 10 | - --experimental.localPlugins.traefik-plugin-waeb.modulename=github.com/tomMoulard/traefik-plugin-waeb 11 | ports: 12 | - 80:80 13 | - 8080:8080 14 | volumes: 15 | - /var/run/docker.sock:/var/run/docker.sock 16 | - ./:/plugins-local/src/github.com/tomMoulard/traefik-plugin-waeb 17 | labels: 18 | traefik.http.routers.waeb.rule: Host(`waeb.localhost`) 19 | traefik.http.routers.waeb.middlewares: waeb 20 | traefik.http.middlewares.waeb.plugin.traefik-plugin-waeb.root: . 21 | -------------------------------------------------------------------------------- /.golangci.yml: -------------------------------------------------------------------------------- 1 | linters: 2 | enable-all: true 3 | disable: 4 | - scopelint # deprecated 5 | - deadcode # deprecated 6 | - ifshort # deprecated 7 | - nosnakecase # deprecated 8 | - interfacer # deprecated 9 | - varcheck # deprecated 10 | - exhaustivestruct # deprecated 11 | - golint # deprecated 12 | - structcheck # deprecated 13 | - maligned # deprecated 14 | 15 | issues: 16 | exclude-rules: 17 | - path: waeb.go 18 | text: "var-naming: don't use an underscore in package name" 19 | - path: waeb.go 20 | text: "ST1003: should not use underscores in package names" 21 | 22 | linters-settings: 23 | depguard: 24 | rules: 25 | main: 26 | allow: 27 | - $gostd 28 | - github.com/tomMoulard/traefik-plugin-waeb 29 | 30 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Tom Moulard 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /waeb_test.go: -------------------------------------------------------------------------------- 1 | package traefik_plugin_waeb_test 2 | 3 | import ( 4 | "context" 5 | "net/http" 6 | "net/http/httptest" 7 | "testing" 8 | 9 | waeb "github.com/tomMoulard/traefik-plugin-waeb" 10 | ) 11 | 12 | func TestWaeb(t *testing.T) { 13 | t.Parallel() 14 | 15 | cfg := waeb.CreateConfig() 16 | 17 | next := http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) { 18 | // Should NEVER go through the next handler 19 | t.Fail() 20 | }) 21 | 22 | handler, err := waeb.New(context.Background(), next, cfg, "waeb") 23 | if err != nil { 24 | t.Fatal(err) 25 | } 26 | 27 | recorder := httptest.NewRecorder() 28 | 29 | req, err := http.NewRequestWithContext(context.Background(), http.MethodGet, "http://localhost/waeb.go", nil) 30 | if err != nil { 31 | t.Fatal(err) 32 | } 33 | 34 | handler.ServeHTTP(recorder, req) 35 | 36 | if recorder.Code != http.StatusOK { 37 | t.Errorf("invalid recorder status code, expected: %d, got: %d", http.StatusOK, recorder.Code) 38 | } 39 | 40 | if recorder.Header().Get("Content-Type") != "text/x-go; charset=utf-8" { 41 | t.Errorf("invalid Content-Type, expected: %q, got: %q", 42 | "text/x-go; charset=utf-8", recorder.Header().Get("Content-Type")) 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /.github/workflows/go-cross.yml: -------------------------------------------------------------------------------- 1 | name: Go Matrix 2 | on: [push, pull_request] 3 | 4 | jobs: 5 | 6 | cross: 7 | name: Go 8 | runs-on: ${{ matrix.os }} 9 | strategy: 10 | matrix: 11 | go-version: [ '1.20', '1.x' ] 12 | os: [ubuntu-latest] 13 | 14 | steps: 15 | # https://github.com/marketplace/actions/setup-go-environment 16 | - name: Set up Go ${{ matrix.go-version }} 17 | uses: actions/setup-go@v3 18 | with: 19 | go-version: ${{ matrix.go-version }} 20 | 21 | # https://github.com/marketplace/actions/checkout 22 | - name: Checkout code 23 | uses: actions/checkout@v3 24 | 25 | # https://github.com/marketplace/actions/cache 26 | - name: Cache Go modules 27 | uses: actions/cache@v3 28 | with: 29 | path: | 30 | ~/go/pkg/mod # Module download cache 31 | ~/.cache/go-build # Build cache (Linux) 32 | ~/Library/Caches/go-build # Build cache (Mac) 33 | '%LocalAppData%\go-build' # Build cache (Windows) 34 | key: ${{ runner.os }}-${{ matrix.go-version }}-go-${{ hashFiles('**/go.sum') }} 35 | restore-keys: | 36 | ${{ runner.os }}-${{ matrix.go-version }}-go- 37 | 38 | - name: Test 39 | run: go test -v -cover ./... 40 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Waeb 2 | 3 | [![Build Status](https://github.com/tomMoulard/traefik-plugin-waeb/actions/workflows/main.yml/badge.svg)](https://github.com/tomMoulard/traefik-plugin-waeb/actions/workflows/main.yml) 4 | 5 | Make Traefik a web server ! 6 | 7 | This is a plugin for [Traefik](https://traefik.io) to build a **web server** as a middleware. 8 | 9 | > Not the plugin we deserved, but the plugin we needed. 10 | > 11 | > ~ [@mpl](https://github.com/mpl) ([src](https://twitter.com/lejatorn/status/1661750793232617477)) 12 | 13 | > Just because you can, doesn't mean you should 14 | > 15 | > ~ [@dtomcej](https://github.com/dtomcej) ([src](https://twitter.com/daniel_tomcej/status/1661746210485723136)) 16 | 17 | ## Usage 18 | 19 | ### Configuration 20 | 21 | Here is an example of a file provider dynamic configuration (given here in 22 | YAML), where the interesting part is the `http.middlewares` section: 23 | 24 | ```yaml 25 | # Dynamic configuration 26 | 27 | http: 28 | routers: 29 | my-waeb-router: 30 | rule: host(`waeb.localhost`) 31 | service: noop@internal # required 32 | middlewares: 33 | - traefik-plugin-waeb 34 | 35 | middlewares: 36 | traefik-plugin-waeb: 37 | plugin: 38 | traefik-plugin-waeb: 39 | root: "/var/www/html/" 40 | ``` 41 | 42 | #### `root` 43 | 44 | The `root` parameter is the root directory of the web server. 45 | 46 | ### Local test 47 | 48 | There is a `docker-compose.yml` file to test the plugin locally: 49 | 50 | ```bash 51 | docker-compose up -d 52 | ``` 53 | 54 | Then, you can go to [http://waeb.localhost](http://waeb.localhost) to see the 55 | result. 56 | -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: Main 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | tags: 8 | - v* 9 | pull_request: 10 | 11 | env: 12 | GO_VERSION: '1.20' 13 | GOLANGCI_LINT_VERSION: v1.53.3 14 | YAEGI_VERSION: v0.15.1 15 | 16 | jobs: 17 | 18 | main: 19 | name: Main Process 20 | runs-on: ubuntu-latest 21 | defaults: 22 | run: 23 | working-directory: ${{ github.workspace }}/go/src/github.com/${{ github.repository }} 24 | 25 | steps: 26 | # https://github.com/marketplace/actions/setup-go-environment 27 | - name: Set up Go ${{ env.GO_VERSION }} 28 | uses: actions/setup-go@v3 29 | with: 30 | go-version: ${{ env.GO_VERSION }} 31 | 32 | # https://github.com/marketplace/actions/checkout 33 | - name: Check out code 34 | uses: actions/checkout@v3 35 | with: 36 | path: go/src/github.com/${{ github.repository }} 37 | fetch-depth: 0 38 | 39 | # https://github.com/marketplace/actions/cache 40 | - name: Cache Go modules 41 | uses: actions/cache@v3 42 | with: 43 | path: ${{ github.workspace }}/go/pkg/mod 44 | key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} 45 | restore-keys: | 46 | ${{ runner.os }}-go- 47 | 48 | # https://golangci-lint.run/usage/install#other-ci 49 | - name: Install golangci-lint ${{ env.GOLANGCI_LINT_VERSION }} 50 | run: curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin ${GOLANGCI_LINT_VERSION} 51 | 52 | - name: Install Yaegi ${{ env.YAEGI_VERSION }} 53 | run: curl -sfL https://raw.githubusercontent.com/traefik/yaegi/master/install.sh | bash -s -- -b $(go env GOPATH)/bin ${YAEGI_VERSION} 54 | 55 | - name: Setup GOPATH 56 | run: go env -w GOPATH=${{ github.workspace }}/go 57 | 58 | - name: Check and get dependencies 59 | run: | 60 | go mod tidy 61 | git diff --exit-code go.mod 62 | # git diff --exit-code go.sum 63 | go mod download 64 | go mod vendor 65 | # git diff --exit-code ./vendor/ 66 | 67 | - name: Lint and Tests 68 | run: make 69 | 70 | - name: Run tests with Yaegi 71 | run: make yaegi_test 72 | env: 73 | GOPATH: ${{ github.workspace }}/go 74 | --------------------------------------------------------------------------------