Change protocol from HTTP/2 to HTTP/1.1?

Hello everyone,

1. Caddy version (caddy version):

v2.1.1

2. How I run Caddy:

The piece of Caddy file where it is not working :

MYDOMAIN.net
{
handle /admin {
reverse_proxy http://127.0.0.1:81
}
}

a. System environment:

DietPi on Raspberry Pi 3B

I use Caddy only for reverse proxy.
First entry works to a Rocket.Chat installed locally.
The second one which is not working is the /admin which goes to a lighttpd with PiHole (working on port TCP/81)

b. Command:

Caddy works as a service. After I modify the Caddyfile in /etc/caddy/ I reload with
systemctl reload caddy

c. Service/unit/compose file:

systemctl status caddy.service
● caddy.service - Caddy
   Loaded: loaded (/lib/systemd/system/caddy.service; enabled; vendor preset: enabled)
   Active: active (running) since Fri 2020-09-04 09:55:33 CEST; 1 day 2h ago
     Docs: https://caddyserver.com/docs/
  Process: 5014 ExecReload=/usr/bin/caddy reload --config /etc/caddy/Caddyfile (code=exited, status=0/SUCCESS)
 Main PID: 6851 (caddy)
    Tasks: 10 (limit: 2184)
   CGroup: /system.slice/caddy.service
           └─6851 /usr/bin/caddy run --environ --config /etc/caddy/Caddyfile

d. My complete Caddyfile or JSON config:

more /etc/caddy/Caddyfile 
{
    # email to use on Let's Encrypt
    email mymail@blabla.com
    
    # Uncomment for debug
    #acme_ca https://acme-staging-v02.api.letsencrypt.org/directory
    #debug
}

# Add gzip compression to requests
(webconf) {
  encode gzip
}

# Add forward headers to requests
(theheaders) {
    header_up X-Forwarded-Ssl on
    header_up Host {host}
    header_up X-Real-IP {remote}
    header_up X-Forwarded-For {remote}
    header_up X-Forwarded-Port {server_port}
    header_up X-Forwarded-Proto {scheme}
    header_up X-Url-Scheme {scheme}
    header_up X-Forwarded-Host {host}
}


WORKING_DOMAIN.net
{
	reverse_proxy localhost:3000 {
		import theheaders
		}
	import webconf
}

NOT_WORKING_DOMAIN.net
{
handle /admin {
reverse_proxy http://127.0.0.1:81
}
}

3. The problem I’m having:

When I go to NOT_WORKING_DOMAIN.net in my browser I have a blank file (whatever browser I use).

4. Error messages and/or full log output:

In the Network debugger of Firefox I can see the first request is OK :

GET https://not-working-domain.net/
État 200 OK
Version HTTP/2

Second request has a 502 Bad gateway error :
GET
scheme https
host not-working-domain.net filename|/favicon.ico
État 502 Bad Gateway
Version HTTP/2

5. What I already tried:

I tried several changes in Caddyfile but same issue with the /admin

6. Links to relevant resources:

Well I read the forum and the docs of Caddy website :slight_smile:

I wonder if the issue can be due to the fact that the request is done with HTTP/2 request and I know for sure the lighttpd webserver does not support it yet. Hence the title of the thread : Do you know I if it possible for Caddy to change the protocol the HTTP/1.1 for specific requests? (Or maybe I am just wrong in my conf and understanding on how to achieve that).

Thanks!
K

Hi,
Before wasting time for the people who might help, this seems not be te the cause of my issue here.
I noticed my URL is always redirected to HTTPS (308 permanent move), so I changed my config with :

XXXXX.net
{
handle /admin {
reverse_proxy localhost:444
}
}

Still not working. So I wonder if the best option should be to make a redirect as the traffic is not going to port 444.

Path matching is exact-match in Caddy v2. Did you mean to use /admin* to match any request under /admin

Hi Francis,
You are right about the syntax, but I also tested that.
Current config is :

blahblah.net {
reverse_proxy /admin/* localhost:444{uri}
}

I tested the add of “{uri}” to check if the path was removed but it seems not to be the case.
On the other hand, it looks like it is not going to port 444…

Lot of testing have been done.

Here is my current Caddyfile:

    {
    # email to use on Let's Encrypt
    email mymail@supermail.com

    # Uncomment for debug
    #acme_ca https://acme-staging-v02.api.letsencrypt.org/directory
    #debug
    }

    # Add gzip compression to requests
    (webconf) {
      encode gzip
    }

    # Add forward headers to requests
    (theheaders) {
    header_up X-Forwarded-Ssl on
    header_up Host {host}
    header_up X-Real-IP {remote}
    header_up X-Forwarded-For {remote}
    header_up X-Forwarded-Port {server_port}
    header_up X-Forwarded-Proto {scheme}
    header_up X-Url-Scheme {scheme}
    header_up X-Forwarded-Host {host}
    }

    IT-WORKS.net {
    	reverse_proxy localhost:3000 {
    		import theheaders
    		}
    	import webconf
    }

    FAIL.net {
    	reverse_proxy /admin/* localhost:444{uri}
    		log { output file /var/log/caddy.log 
    		}
    }

So the IT-WORKS.net is OK → going to a Rocket.Chat installed locally via snap.
FAIL.net still doesn’t work, with HTTP 500 Internal Server Error
To be sure it is not related to the webserver, I also tried with nginx after Lighttpd.

I go to : https://FAIL.net/admin/ and here is the Caddy log :

2020/09/05 23:22:49.160 ERROR http.log.error.log0 making dial info: upstream localhost:444{http.request.uri}: invalid dial address localhost:444/admin/: address admin/: missing port in address {“request”: {“method”: “GET”, “uri”: “/admin/”, “proto”: “HTTP/2.0”, “remote_addr”: “192.168.1.2:57779”, “host”: “FAIL.net”, “headers”: {“Accept-Language”: [“fr,fr-FR;q=0.8,en-US;q=0.5,en;q=0.3”], “Accept-Encoding”: [“gzip, deflate, br”], “Dnt”: [“1”], “Cookie”: [“PHPSESSID=032m0ipfk6tvq8jc2con76ihos”], “Upgrade-Insecure-Requests”: [“1”], “Te”: [“trailers”], “User-Agent”: [“Mozilla/5.0 (Macintosh; Intel Mac OS X 10.13; rv:80.0) Gecko/20100101 Firefox/80.0”], “Accept”: [“text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,/;q=0.8”]}, “tls”: {“resumed”: false, “version”: 772, “ciphersuite”: 4867, “proto”: “h2”, “proto_mutual”: true, “server_name”: “FAIL.net”}}, “duration”: 0.00049849}

I suspect that part is the cause of the issue, but I do not know what to do next:
“invalid dial address localhost:444/admin/: address admin/: missing port in address”

Do you have an idea?

Cheers,
K

It’s not valid to put {uri} as a placeholder for proxy dial addresses. The error tells you that.

I’m not understanding what you’re trying to do. Do you expect /admin to be stripped? If so, use the handle_path directive for this.

1 Like

Hi Francis,
Thanks again for your answer.
Actually I do not really care about the /admin or /admin/ (even if just /admin would be easier I guess).
I would like to achieve that :
Browser requests : https://blabla.net/admin
Caddy redirects to : https://localhost:444/admin

(or /admin/, anyway).
I guess I have an issue to make it use the port and the path.

Thanks,
K

What I’m asking is whether your proxied service expects /admin to not be there. Caddy will preserve the path of the original request unless you strip a prefix using a rewrite. The handle_path directive does that.

Please read this wiki on the topic of proxying using a subpath:

I generally recommend using a subdomain instead as it avoids most of the issues with proxying to another service that doesn’t expect to be served under a subpath.

1 Like

Hi Francis,
Thanks for your answer and for your help.
My approch was indeed wrong and I fixed that.
Also, it was working before I even noticed because, to be sure I tested with another subfolder which worked. This issue seems to come from PiHole (which is what /admin/ refers to). Anyway, as I don’t want it to be reachable from the internet, I am OK with it.

Thanks again!
K

1 Like

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