Decompress gzip reverse proxy reponse

1. The problem I’m having:

Hi all. I have a Powerline Ethernet device that I am trying to put behind Caddy so I can manage it remotely . The issue I am running into is that whatever Accept-Encoding values I set, the responses are always gzipped:

$ curl -v -H 'Accept-Encoding: identity' http://devolo0:80
*   Trying 10.10.1.18:80...
* Connected to devolo0 (10.10.1.18) port 80 (#0)
> GET / HTTP/1.1
> Host: devolo0
> User-Agent: curl/7.88.1
> Accept: */*
> Accept-Encoding: identity
> 
< HTTP/1.1 200 OK
< Content-Type: text/html
< Content-Length: 355
< Cache-Control: max-age=315360000
< Content-Encoding: gzip
< 
Warning: Binary output can mess up your terminal. Use "--output -" to tell 
Warning: curl to output it to your terminal anyway, or consider "--output 
Warning: <FILE>" to save to a file.
* Failure writing output to destination
* Closing connection 0

When I try to proxy this device via Caddy I get 400 Bad Request, presumably because Caddy expects a raw HTML response and not a compressed response.

My question is, is there a way I can tell Caddy that the request is compressed and how to deal with it properly?

$ curl -v -H 'Accept-Encoding: identity' http://devolo0:80 | gzip -d | head -n 2
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0*   Trying 10.10.1.18:80...
* Connected to devolo0 (10.10.1.18) port 80 (#0)
> GET / HTTP/1.1
> Host: devolo0
> User-Agent: curl/7.88.1
> Accept: */*
> Accept-Encoding: identity
> 
< HTTP/1.1 200 OK
< Content-Type: text/html
< Content-Length: 355
< Cache-Control: max-age=315360000
< Content-Encoding: gzip
< 
{ [355 bytes data]
100   355  100   355    0     0  28640      0 --:--:-- --:--:-- --:--:-- 29583
* Connection #0 to host devolo0 left intact
<!doctype html>
<html lang="en">

2. Error messages and/or full log output:

2023/06/25 18:35:49.056	ERROR	http.log.access.log1	handled request	{"request": {"remote_ip": "172.71.255.7", "remote_port": "35556", "proto": "HTTP/2.0", "method": "GET", "host": "devolo0.CENSORED", "uri": "/overview", "headers": {"Priority": ["u=1"], "Sec-Fetch-Site": ["same-site"], "Cf-Connecting-Ip": ["108.90.65.178"], "Cf-Ray": ["7dcf4ffeede922fe-ORD"], "User-Agent": ["Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/114.0"], "Accept": ["text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8"], "Upgrade-Insecure-Requests": ["1"], "Sec-Fetch-Dest": ["document"], "Accept-Encoding": ["gzip"], "Cf-Visitor": ["{\"scheme\":\"https\"}"], "Sec-Fetch-Mode": ["navigate"], "Cf-Ipcountry": ["US"], "Accept-Language": ["en-US,en;q=0.5"], "Dnt": ["1"], "Cookie": [], "Cdn-Loop": ["cloudflare"], "X-Forwarded-For": ["108.90.65.178"], "X-Forwarded-Proto": ["https"]}, "tls": {"resumed": false, "version": 772, "cipher_suite": 4865, "proto": "h2", "server_name": "devolo0.CENSORED"}}, "user_id": "CENSORED", "duration": 0.020139066, "size": 162, "status": 400, "resp_headers": {"Alt-Svc": ["h3=\":443\"; ma=2592000"], "Content-Type": ["text/html"], "Content-Length": ["162"], "Server": ["Caddy"]}}

3. Caddy version:

From my docker-compose file:

        - CADDY_GO_VERSION=1.20.3-alpine3.17
        - CADDY_SECURITY_VERSION=v1.1.19
        - CADDY_XCADDY_VERSION=v0.3.2
        - CADDY_VERSION=v2.6.4

4. How I installed and ran Caddy:

Built with xcaddy.

a. System environment:

Running in a Docker container.

d. My complete Caddy config:

{
	log {
		output stdout
		format console
	}

	order authenticate before respond
	order authorize before basicauth

	security {
		oauth identity provider google {
			CENSORED
		}

		authentication portal authportal {
			CENSORED
		}

		authorization policy admin {
			CENSORED
		}

		authorization policy user {
			CENSORED
		}

		authorization policy garage {
			CENSORED
		}
	}
}

http://localhost, http://127.0.0.1, http://home1, http://home1.lan {
	log {
		output stdout
		format console
	}

	encode gzip zstd
	metrics /metrics
}

*.CENSORED, CENSORED {
	log {
		output stdout
		format console
	}

	encode gzip zstd

	# # use cloudflare cert
	# tls /home/caddy/cloudflare.pem /home/caddy/cloudflare.key

	tls {
		dns cloudflare CENSORED
		resolvers 1.1.1.1
	}

	@devolo0 host devolo0.CENSORED
	handle @devolo0 {
		authorize with admin
		reverse_proxy devolo0:80
	}

	respond "OK" 200
}

Wow, that’s awful.

Yeah I can’t think of any way to resolve that. And I don’t think it’s worth it for us to spend time writing functionality in Caddy to support upstream servers that don’t respect HTTP.

You’d probably be better off using remote desktop software to get access to a machine on your network with a browser that can directly connect to it. I doubt you’ll be connecting to it often enough that it has to be publicly accessible, that should be enough, no? Alternatively, set up wireguard (or whatever vpn solution) so that your remote device could join your private network to access it directly

Yeah, it is awful. I’m definitely not going to spend a lot of time on this. Maybe I’ll just bang out a quick python script to proxy the requests and decompress them.

Annoyingly the browsers seem to be smart enough to figure out what is going on and deal with it, so I don’t think there’s much incentive for the vendor to actually fix the issue.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.