darkweak / souin

An HTTP cache system, RFC compliant, compatible with @tyktechnologies, @traefik, @caddyserver, @go-chi, @bnkamalesh, @beego, @devfeel, @labstack, @gofiber, @go-goyave, @go-kratos, @gin-gonic, @roadrunner-server, @zalando, @zeromicro, @nginx and @apache
https://docs.souin.io
MIT License
721 stars 56 forks source link

[Traefik Plugin] post requests with data trigger error #314

Closed jonasengelmann closed 1 year ago

jonasengelmann commented 1 year ago

Sorry to bring this up again, but I just run a test with the refactored version. However, I was not able to load version v1.6.30 nor v1.6.31 as Traefik plugin.

But with the already refactored version (v.1.6.29) I do get this error:

- "plugins-storage/sources/gop-2015442608/src/github.com/darkweak/souin/plugins/traefik/vendor/github.com/darkweak/souin/pkg/middleware/middleware.go:95:9: panic" module=github.com/darkweak/souin plugin=plugin-souin
- "plugins-storage/sources/gop-2015442608/src/github.com/darkweak/souin/plugins/traefik/vendor/github.com/darkweak/souin/pkg/middleware/middleware.go:177:19: panic" module=github.com/darkweak/souin plugin=plugin-souin
- "plugins-storage/sources/gop-2015442608/src/github.com/darkweak/souin/plugins/traefik/main.go:226:6: panic" module=github.com/darkweak/souin plugin=plugin-souin
- "Recovered from panic in HTTP handler [172.18.0.1:56066 - /]: reflect.Set: value of type *struct {} is not assignable to type error" middlewareType=Recovery middlewareName=traefik-internal-recovery
- "Stack: goroutine 14 [running]:
github.com/traefik/traefik/v2/pkg/middlewares/recovery.recoverFunc({0x3c297f8, 0x400063a380}, 0x4003e07700)
    github.com/traefik/traefik/v2/pkg/middlewares/recovery/recovery.go:46 +0x270
panic({0x29ca800, 0x40029e5fb0})
    runtime/panic.go:1038 +0x224
github.com/traefik/yaegi/interp.runCfg.func1(0x4003fd0580, 0x4002f6e480, 0x0)
    github.com/traefik/yaegi@v0.12.0/interp/run.go:192 +0x164
panic({0x29ca800, 0x40029e5fb0})
    runtime/panic.go:1038 +0x224
github.com/traefik/yaegi/interp.runCfg.func1(0x4003fd0790, 0x4002fe70e0, 0x0)
    github.com/traefik/yaegi@v0.12.0/interp/run.go:192 +0x164
panic({0x29ca800, 0x40029e5fb0})
    runtime/panic.go:1038 +0x224
github.com/traefik/yaegi/interp.runCfg.func1(0x4003fd1e40, 0x4002fbc5a0, 0x0)
    github.com/traefik/yaegi@v0.12.0/interp/run.go:192 +0x164
panic({0x29ca800, 0x40029e5fb0})
    runtime/panic.go:1038 +0x224
reflect.Value.assignTo({0x29155a0, 0x5b0e250, 0x16}, {0x32698f1, 0xb}, 0x2c20560, 0x4000db49e0)
    reflect/value.go:2810 +0x2cc
reflect.Value.Set({0x2c20560, 0x4000db49e0, 0x194}, {0x29155a0, 0x5b0e250, 0x16})
    reflect/value.go:1918 +0xa4
github.com/traefik/yaegi/interp._new.func1(0x4003fd1e40)
    github.com/traefik/yaegi@v0.12.0/interp/run.go:3310 +0xa8
github.com/traefik/yaegi/interp.runCfg(0x4002fbc5a0, 0x4003fd1e40, 0x4003df0900, 0x40030158c0)
    github.com/traefik/yaegi@v0.12.0/interp/run.go:200 +0x268
github.com/traefik/yaegi/interp.call.func9(0x4003fd0790)
    github.com/traefik/yaegi@v0.12.0/interp/run.go:1433 +0x7cc
github.com/traefik/yaegi/interp.runCfg(0x4002fe70e0, 0x4003fd0790, 0x4003fd7d40, 0x4002f6e240)
    github.com/traefik/yaegi@v0.12.0/interp/run.go:200 +0x268
github.com/traefik/yaegi/interp.call.func9(0x4003fd0580)
    github.com/traefik/yaegi@v0.12.0/interp/run.go:1433 +0x7cc
github.com/traefik/yaegi/interp.runCfg(0x4002f6e480, 0x4003fd0580, 0x4002f6c7e0, 0x4003a5b560)
    github.com/traefik/yaegi@v0.12.0/interp/run.go:200 +0x268
github.com/traefik/yaegi/interp.genFunctionWrapper.func2.1({0x400291eb70, 0x2, 0x2})
    github.com/traefik/yaegi@v0.12.0/interp/run.go:1022 +0x418
github.com/traefik/yaegi/stdlib._net_http_Handler.ServeHTTP(...)
    github.com/traefik/yaegi@v0.12.0/stdlib/go1_17_net_http.go:288
github.com/traefik/traefik/v2/pkg/middlewares/accesslog.(*FieldHandler).ServeHTTP(0x4000da3540, {0x3c297f8, 0x400063a380}, 0x4003e07800)
    github.com/traefik/traefik/v2/pkg/middlewares/accesslog/field_middleware.go:29 +0x16c
github.com/gorilla/mux.(*Router).ServeHTTP(0x40007be7e0, {0x3c297f8, 0x400063a380}, 0x4003e07700)
    github.com/gorilla/mux@v1.8.0/mux.go:141 +0x22c
github.com/traefik/traefik/v2/pkg/middlewares/recovery.(*recovery).ServeHTTP(0x40029e5a80, {0x3c297f8, 0x400063a380}, 0x4003e07700)
    github.com/traefik/traefik/v2/pkg/middlewares/recovery/recovery.go:32 +0x8c
github.com/traefik/traefik/v2/pkg/middlewares/accesslog.(*FieldHandler).ServeHTTP(0x4000da3c80, {0x3c297f8, 0x400063a380}, 0x4003e07700)
    github.com/traefik/traefik/v2/pkg/middlewares/accesslog/field_middleware.go:29 +0x16c
github.com/traefik/traefik/v2/pkg/middlewares.(*HTTPHandlerSwitcher).ServeHTTP(0x4000129490, {0x3c297f8, 0x400063a380}, 0x4003e07700)
    github.com/traefik/traefik/v2/pkg/middlewares/handler_switcher.go:23 +0x70
github.com/traefik/traefik/v2/pkg/middlewares/requestdecorator.(*RequestDecorator).ServeHTTP(0x4000129488, {0x3c297f8, 0x400063a380}, 0x4003e07100, 0x4002a2b900)
    github.com/traefik/traefik/v2/pkg/middlewares/requestdecorator/request_decorator.go:47 +0x5e8
github.com/traefik/traefik/v2/pkg/middlewares/requestdecorator.WrapHandler.func1.1({0x3c297f8, 0x400063a380}, 0x4003e07100)
    github.com/traefik/traefik/v2/pkg/middlewares/requestdecorator/request_decorator.go:84 +0x70
net/http.HandlerFunc.ServeHTTP(0x400068bee0, {0x3c297f8, 0x400063a380}, 0x4003e07100)
    net/http/server.go:2047 +0x40
github.com/traefik/traefik/v2/pkg/middlewares/forwardedheaders.(*XForwarded).ServeHTTP(0x400004f4a0, {0x3c297f8, 0x400063a380}, 0x4003e07100)
    github.com/traefik/traefik/v2/pkg/middlewares/forwardedheaders/forwarded_header.go:189 +0xec
golang.org/x/net/http2/h2c.h2cHandler.ServeHTTP({{0x3bea380, 0x400004f4a0}, 0x400069b880}, {0x3c297f8, 0x400063a380}, 0x4003e07100)
    golang.org/x/net@v0.0.0-20220425223048-2871e0cb64e4/http2/h2c/h2c.go:104 +0x35c
net/http.serverHandler.ServeHTTP({0x400063a1c0}, {0x3c297f8, 0x400063a380}, 0x4003e07100)
    net/http/server.go:2879 +0x45c
net/http.(*conn).serve(0x40005cf180, {0x3c506c0, 0x40007b80c0})
    net/http/server.go:1930 +0xb54
created by net/http.(*Server).Serve
    net/http/server.go:3034 +0x4ac
" middlewareName=traefik-internal-recovery middlewareType=Recovery

Here is my test setup:

version: "3.8"
services:
  traefik:
    image: traefik:v2.7.0
    command:
      - --providers.docker=true
      - --entrypoints.web.address=:80
      - --experimental.plugins.souin.moduleName=github.com/darkweak/souin
      - --experimental.plugins.souin.version=v1.6.29
    ports:
      - 80:80
    networks:
      - default
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro

  whoami:
    image: traefik/whoami:latest
    labels:
      - traefik.enable=true
      - traefik.http.routers.whoami.rule=Host(`localhost`)
      - traefik.http.routers.whoami.entrypoints=web
      - traefik.http.middlewares.http-cache.plugin.souin.api.souin
      - traefik.http.middlewares.http-cache.plugin.souin.default_cache.ttl=60s
      - traefik.http.middlewares.http-cache.plugin.souin.default_cache.allowed_http_verbs=POST,GET,HEAD
      - traefik.http.middlewares.http-cache.plugin.souin.log_level=debug
      - traefik.http.routers.whoami.middlewares=http-cache

And this was my request, which does work fine without caching: curl -X POST -i http://localhost -H "Content-Type: application/json" -d '{"test": 1}'

darkweak commented 1 year ago

The commit 434dbdb7eaa08e6560d1b8bb5cb77ffb1d349556 in the PR #313 will fix your issue. TBH the Træfik interpreter is painful because it doesn't interpret the Go code like the compiler does. Here the issue was Yægi didn't like the nil return as a function even if we don't try to call it. About the index issue I already asked them if it was normal that the plugins catalog didn't index the new releases but the answer was without any explanations. Anyway I'll try to merge that PR, tag the new version and cross my finger they will index this new release.

darkweak commented 1 year ago

@jonasengelmann the version v1.6.32 is now available.

jonasengelmann commented 1 year ago

@darkweak Thanks for looking into this so quickly and also pushing Traefik to reindex their plugin index and keeping up with their unreliable interpreter. I can now successfully load all version! However unfortunately I still get the error in version v1.6.32. I noticed that I probably forget to post the most important log message, it only showed up in the Traefik debug log, and wasn't registered as an error, so that is why I missed it at first:

level=debug msg="'500 Internal Server Error' caused by: net/http: HTTP/1.x transport connection broken: http: ContentLength=11 with Body length 0"

I think this line is triggering the error, but I was not able to fix the issue as I am not so proficient in Go. Do you have any idea?

darkweak commented 1 year ago

Fixed by #317

darkweak commented 1 year ago

@jonasengelmann can you retry and tell me if that's okay for you too?

jonasengelmann commented 1 year ago

@darkweak I just did a test with version v1.6.34 but sadly I still get the error. I think it might have to do with the difference between rq and req here. I quickly checked and rq.Body is still being consumed, but I do not understand where exactly. Do you have an idea?

darkweak commented 1 year ago

New version available, it should fix everything 🤞

jonasengelmann commented 1 year ago

Just tested it and now everything works! Many many thanks!