traefik / plugin-rewritebody

Rewrite body is a middleware plugin for Traefik which rewrites the HTTP response body by replacing a search regex by a replacement string
https://plugins.traefik.io/plugins/628c9ec2ffc0cd18356a97a2/log4-shell
Apache License 2.0
56 stars 21 forks source link

Docker Label Setup Static and Dynamic Config #13

Open wjbridge opened 4 years ago

wjbridge commented 4 years ago

Hi,

I am trying to get this plugin to work using docker labels. I am not having any success to get it working. For testing, I am trying to replace 'en' to 'es' in the page but cannot get this to work. My goal is to use this to change the theme.

Static Config:

command:
--pilot.token=$TOKEN
--experimental.plugins.theme_changer.modulename=github.com/traefik/plugin-rewritebody
--experimental.plugins.theme_changer.version=v0.3.1

Dynamic Config:

    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.sonarr-rtr.entrypoints=web"
      - "traefik.http.routers.sonarr-rtr.rule=Host(`sonarr.$BASE_HOST`)"+
      - "traefik.http.routers.sonarr-rtr.service=sonarr-svc"
      - "traefik.http.middlewares.rewrite_theme.plugin.theme_changer.rewrites[0].regex=en"
      - "traefik.http.middlewares.rewrite_theme.plugin.theme_changer.rewrites[0].replacement=es"
      - "traefik.http.routers.sonarr-rtr.middlewares=rewrite_theme"
      - "traefik.http.services.sonarr-svc.loadbalancer.server.port=8989"

Thank you for any help / direction.

wjbridge commented 4 years ago

I have debugged a little more. I created a TOML file:

[http.middlewares]
  [http.middlewares.rewrite_theme.plugin.theme_changer]
    lastModified = true
    [[http.middlewares.rewrite_theme.plugin.theme_changer.rewrites]]
      regex = "System"
      replacement = "ITWORKS"

From previous post replaced the line: "traefik.http.routers.sonarr-rtr.middlewares=rewrite_theme" to "traefik.http.routers.sonarr-rtr.middlewares=rewrite_theme@file"

Removed these lines:

"traefik.http.middlewares.rewrite_theme.plugin.theme_changer.rewrites[0].regex=en"
"traefik.http.middlewares.rewrite_theme.plugin.theme_changer.rewrites[0].replacement=es"

Now I am getting this error output:

plugins-storage/sources/gop-574596048/src/github.com/traefik/plugin-rewritebody/rewritebody.go:70:19: panic
plugins-storage/sources/gop-574596048/src/github.com/traefik/plugin-rewritebody/rewritebody.go:70:19: panic
reverseproxy.go:476: httputil: ReverseProxy read error during body copy: malformed chunked encodin
youkoulayley commented 4 years ago

Hello,

I tried something like this and it works perfectly :

version: "3.3"

services:

  traefik:
    image: "traefik:v2.3"
    container_name: "traefik"
    command:
      - "--providers.docker=true"
      - "--entrypoints.web.address=:80"
      - "--pilot.token=$TOKEN"
      - "--experimental.plugins.theme_changer.modulename=github.com/traefik/plugin-rewritebody" 
      - "--experimental.plugins.theme_changer.version=v0.3.1"
    ports:
      - "80:80"
      - "8080:8080"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock:ro"

  whoami:
    image: "traefik/whoami"
    container_name: "simple-service"
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.whoami.rule=Host(`whoami.localhost`)"
      - "traefik.http.routers.whoami.entrypoints=web"
      - "traefik.http.routers.whoami.middlewares=rewrite_theme"
      - "traefik.http.middlewares.rewrite_theme.plugin.theme_changer.rewrites[0].regex=Hostname"
      - "traefik.http.middlewares.rewrite_theme.plugin.theme_changer.rewrites[0].replacement=Pouet"

Do you have any logs informations with your first test ? (by passing --log.level=DEBUG to traefik )

wjbridge commented 4 years ago

Hi youkoulayley,

Thanks for the reply. I tried the whoami container also and it works on my system so I am happy that we established that it works via docker labels. However, it will not work with my sonarr container.

plugins-storage/sources/gop-219529169/src/github.com/traefik/plugin-rewritebody/rewritebody.go:70:19: panic
reverseproxy.go:476: httputil: ReverseProxy read error during body copy: malformed chunked encoding

Docker container compose file

  sonarr:
    image: ghcr.io/linuxserver/sonarr:preview
    container_name: sonarr
    restart: unless-stopped
    environment:
      - PUID=$PUID
      - PGID=$PGID
      - TZ=$TZ
    networks:
      - $T2_NETWORK
    security_opt:
      - no-new-privileges:true
    volumes:
      - $DOCUMENTS/Sonarr:/config
      - $DOCUMENTS/Nzbget/Completed:/downloads
      - $MEDIA:/media
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.sonarr-rtr.entrypoints=web"
      - "traefik.http.routers.sonarr-rtr.rule=Host(`sonarr.$BASE_HOST`)"
      - "traefik.http.routers.sonarr-rtr.service=sonarr-svc"
      - "traefik.http.middlewares.rewrite_sonarr_theme.plugin.theme_changer.rewrites[0].regex=System"
      - "traefik.http.middlewares.rewrite_sonarr_theme.plugin.theme_changer.rewrites[0].replacement=WORKS"
      - "traefik.http.routers.sonarr-rtr.middlewares=rewrite_sonarr_theme"
      - "traefik.http.services.sonarr-svc.loadbalancer.server.port=8989"

This is the debug output but I did not see anything useful that I could discern

plugins-storage/sources/gop-136806649/src/github.com/traefik/plugin-rewritebody/rewritebody.go:70:19: panic
time="2020-11-05T16:45:20Z" level=debug msg="Request has been aborted [192.168.1.105:53435 - /signalr/connect?transport=serverSentEvents&clientProtocol=2.1&apiKey=161a9fa49480426a8e59947f63b7ed99&connectionToken=W4hAo8A6z5qG749PKhAKP4oGqC0QSZx%2BfcmJw5RHPrt1N5ixEM7Y5cHRLnWwwO8gn8tO%2BP6u3LAHD0URq2gpjD66orboa4Jrl6YHMKpMZHWnboihljEZTw%2B2fuoypx0ZxvOGp01pqmSBkyws6i30MXw%2FC4sqUwePyhxBOSn73g0h1Cqysq37EorZKiCJDVvGpNOAruMzJsRr5997eIQrOf3UU0mxt%2BDblz3F%2FDVD6WXI8Vg61MRQeSzVt4qUJcQlcPvcoRGuBhNti%2Be%2BS1CJo1q6m4amkE2rFaOvjiv5Rbv7eKrdAutUC8D20UEwkEv3&tid=9]: net/http: abort Handler" middlewareName=traefik-internal-recovery middlewareType=Recovery
time="2020-11-05T16:45:20Z" level=debug msg="vulcand/oxy/roundrobin/rr: begin ServeHttp on request" Request="{\"Method\":\"GET\",\"URL\":{\"Scheme\":\"\",\"Opaque\":\"\",\"User\":null,\"Host\":\"\",\"Path\":\"/initialize.js\",\"RawPath\":\"\",\"ForceQuery\":false,\"RawQuery\":\"\",\"Fragment\":\"\",\"RawFragment\":\"\"},\"Proto\":\"HTTP/1.1\",\"ProtoMajor\":1,\"ProtoMinor\":1,\"Header\":{\"Accept\":[\"*/*\"],\"Accept-Encoding\":[\"gzip, deflate\"],\"Accept-Language\":[\"en-US,en;q=0.9\"],\"Connection\":[\"keep-alive\"],\"Cookie\":[\"_ga=GA1.2.779723594.1595343911; organizr_token_361b47ec-4119-4002-a56e-b554e35b8b79=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiIsImp0aSI6IjRmMWcyM2ExMmFhIn0.eyJpc3MiOiJPcmdhbml6ciIsImF1ZCI6Ik9yZ2FuaXpyIiwianRpIjoiNGYxZzIzYTEyYWEiLCJpYXQiOjE2MDQxMDA2NzgsImV4cCI6MTYwNDcwNTQ3OCwidXNlcm5hbWUiOiJncm9vdCIsImdyb3VwIjoiQWRtaW4iLCJncm91cElEIjowLCJlbWFpbCI6IndqYnJpZGdlQGxpdmUuY29tIiwiaW1hZ2UiOiJodHRwczpcL1wvd3d3LmdyYXZhdGFyLmNvbVwvYXZhdGFyXC83NjVjZGQ0OGZkZTVlY2NiMGMyNjMzM2UyYjU3N2Y5OD9zPTEwMCZkPW1tIiwidXNlcklEIjoxfQ.2Dg8HKjsdn-GJn0ui-_zsS6r59cD-BpuXh48GkuiQH0\"],\"Dnt\":[\"1\"],\"Referer\":[\"http://sonarr.groot.com/\"],\"User-Agent\":[\"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.183 Safari/537.36\"],\"X-Forwarded-Host\":[\"sonarr.groot.com\"],\"X-Forwarded-Port\":[\"80\"],\"X-Forwarded-Proto\":[\"http\"],\"X-Forwarded-Server\":[\"98dc577ac990\"],\"X-Real-Ip\":[\"192.168.1.105\"]},\"ContentLength\":0,\"TransferEncoding\":null,\"Host\":\"sonarr.groot.com\",\"Form\":null,\"PostForm\":null,\"MultipartForm\":null,\"Trailer\":null,\"RemoteAddr\":\"192.168.1.105:53440\",\"RequestURI\":\"/initialize.js\",\"TLS\":null}"
time="2020-11-05T16:45:20Z" level=debug msg="vulcand/oxy/roundrobin/rr: Forwarding this request to URL" ForwardURL="http://172.19.0.3:8989" Request="{\"Method\":\"GET\",\"URL\":{\"Scheme\":\"\",\"Opaque\":\"\",\"User\":null,\"Host\":\"\",\"Path\":\"/initialize.js\",\"RawPath\":\"\",\"ForceQuery\":false,\"RawQuery\":\"\",\"Fragment\":\"\",\"RawFragment\":\"\"},\"Proto\":\"HTTP/1.1\",\"ProtoMajor\":1,\"ProtoMinor\":1,\"Header\":{\"Accept\":[\"*/*\"],\"Accept-Encoding\":[\"gzip, deflate\"],\"Accept-Language\":[\"en-US,en;q=0.9\"],\"Connection\":[\"keep-alive\"],\"Cookie\":[\"_ga=GA1.2.779723594.1595343911; organizr_token_361b47ec-4119-4002-a56e-b554e35b8b79=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiIsImp0aSI6IjRmMWcyM2ExMmFhIn0.eyJpc3MiOiJPcmdhbml6ciIsImF1ZCI6Ik9yZ2FuaXpyIiwianRpIjoiNGYxZzIzYTEyYWEiLCJpYXQiOjE2MDQxMDA2NzgsImV4cCI6MTYwNDcwNTQ3OCwidXNlcm5hbWUiOiJncm9vdCIsImdyb3VwIjoiQWRtaW4iLCJncm91cElEIjowLCJlbWFpbCI6IndqYnJpZGdlQGxpdmUuY29tIiwiaW1hZ2UiOiJodHRwczpcL1wvd3d3LmdyYXZhdGFyLmNvbVwvYXZhdGFyXC83NjVjZGQ0OGZkZTVlY2NiMGMyNjMzM2UyYjU3N2Y5OD9zPTEwMCZkPW1tIiwidXNlcklEIjoxfQ.2Dg8HKjsdn-GJn0ui-_zsS6r59cD-BpuXh48GkuiQH0\"],\"Dnt\":[\"1\"],\"Referer\":[\"http://sonarr.groot.com/\"],\"User-Agent\":[\"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.183 Safari/537.36\"],\"X-Forwarded-Host\":[\"sonarr.groot.com\"],\"X-Forwarded-Port\":[\"80\"],\"X-Forwarded-Proto\":[\"http\"],\"X-Forwarded-Server\":[\"98dc577ac990\"],\"X-Real-Ip\":[\"192.168.1.105\"]},\"ContentLength\":0,\"TransferEncoding\":null,\"Host\":\"sonarr.groot.com\",\"Form\":null,\"PostForm\":null,\"MultipartForm\":null,\"Trailer\":null,\"RemoteAddr\":\"192.168.1.105:53440\",\"RequestURI\":\"/initialize.js\",\"TLS\":null}"
youkoulayley commented 4 years ago

Here's a setup that is working :

version: "3.3"

services:
  traefik:
    image: "traefik:v2.3"
    container_name: "traefik"
    command:
      - "--log.level=DEBUG"
      - "--providers.docker=true"
      - "--entrypoints.web.address=:80"
      - "--pilot.token=$TOKEN"
      - "--experimental.plugins.theme_changer.modulename=github.com/traefik/plugin-rewritebody" 
      - "--experimental.plugins.theme_changer.version=v0.3.1"
    ports:
      - "80:80"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock:ro"

  sonarr:
    image: ghcr.io/linuxserver/sonarr:preview
    container_name: sonarr
    security_opt:
      - no-new-privileges:true
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.sonarr-rtr.entrypoints=web"
      - "traefik.http.routers.sonarr-rtr.rule=Host(`sonar.localhost`)"
      - "traefik.http.routers.sonarr-rtr.middlewares=rewritesonarrtheme"
      - "traefik.http.routers.sonarr-rtr.service=sonarr-svc"
      - "traefik.http.services.sonarr-svc.loadbalancer.server.port=8989"
      - "traefik.http.middlewares.rewritesonarrtheme.plugin.theme_changer.rewrites[0].regex=System"
      - "traefik.http.middlewares.rewritesonarrtheme.plugin.theme_changer.rewrites[0].replacement=WORKS"

I see in your configuration that you specify a custom network :

networks:
  - $T2_NETWORK

Have you tried to add this label on the sonarr container :

- "traefik.docker.network=$T2_NETWORK"
wjbridge commented 4 years ago

I tried a fresh sonarr container and copied all the settings that you referred too. I am still getting a panic error. I have no idea why and I wish there was more debug information as to why it is happening.

This is my traefik settings. I did try adding the - "traefik.docker.network=$T2_NETWORK" but it made no difference.

traefik:
    container_name: traefik
    image: traefik:latest
    restart: unless-stopped
    command:
      - --global.checkNewVersion=true
      - --api.insecure=true
      - --entrypoints.web.address=:80

      # (Default: error) DEBUG, INFO, WARN, ERROR, FATAL, PANIC
      - --log.level=INFO

      # Do not expose containers unless explicitly told so
      - --providers.docker=true
      - --providers.docker.exposedbydefault=false
      - --providers.docker.network=$T2_NETWORK

      # Traefik Plugins Config
      - --pilot.token=$TRAEFIK_TOKEN
      - --experimental.plugins.theme_changer.modulename=github.com/traefik/plugin-rewritebody
      - --experimental.plugins.theme_changer.version=v0.3.1
    networks:
      - $T2_NETWORK
    ports:
      - target: 80
        published: 80
        protocol: tcp
        mode: host
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
    labels:
    - "traefik.enable=true"
    - "traefik.http.routers.traefik-rtr.entrypoints=web"
    - "traefik.http.routers.traefik-rtr.rule=Host(`traefik.$BASE_HOST`)"
    - "traefik.http.routers.traefik-rtr.service=traefik-svc"
    - "traefik.http.services.traefik-svc.loadbalancer.server.port=8080"

I am experimenting with develop mode for the plugin and added:

func (r *rewriteBody) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
    wrappedWriter := &responseWriter{
        lastModified:   r.lastModified,
        ResponseWriter: rw,
    }
        defer func() {
            if err := recover(); err != nil {
                log.Println("panic occurred:", err)
            }
        }()

    r.next.ServeHTTP(wrappedWriter, req)

    bodyBytes := wrappedWriter.buffer.Bytes()

    contentEncoding := wrappedWriter.Header().Get("Content-Encoding")

    if contentEncoding != "" && contentEncoding != "identity" {
        if _, err := rw.Write(bodyBytes); err != nil {
            log.Printf("unable to write body: %v", err)
        }

        return
    }

    for _, rewrite := range r.rewrites {
        bodyBytes = rewrite.regex.ReplaceAll(bodyBytes, rewrite.replacement)
    }

    if _, err := rw.Write(bodyBytes); err != nil {
        log.Printf("unable to write rewrited body: %v", err)
    }
}

The "additional" error information I got from the log is but not sure what this signifies: panic occurred: net/http: abort Handler

youkoulayley commented 4 years ago

I see you have an image with the latest tag : image: traefik:latest

Are you sure your docker has downloaded the very latest version of traefik ? Could you try to put a specific version like this : image: traefik:v2.3.2

wjbridge commented 4 years ago

Tried that and still getting the panic error.

youkoulayley commented 4 years ago

Could you send me all the logs since the Traefik startup with the panic stack in DEBUG level ?

wjbridge commented 4 years ago

See attached log. I removed my token in the log. Is there a way to get a version of the plugin that outputs more information since this is a "panic" event... Just shooting ideas. Thank you so much for your continued help. Log_Panic.txt

ldez commented 4 years ago

I able to reproduce, so I confirm the issue. I think that it's related to a bug inside Yaegi.